🛠️🐜 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.

4025 lines
123 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_ALSA
  210. { "alsa", AlsaBackendFactory::getFactory },
  211. #endif
  212. #ifdef HAVE_SOLARIS
  213. { "solaris", SolarisBackendFactory::getFactory },
  214. #endif
  215. #ifdef HAVE_SNDIO
  216. { "sndio", SndIOBackendFactory::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((DisabledEffects[EAXREVERB_EFFECT] || DisabledEffects[CHORUS_EFFECT])
  1153. && eax_g_is_enabled)
  1154. {
  1155. eax_g_is_enabled = false;
  1156. TRACE("EAX disabled because %s disabled.\n",
  1157. (DisabledEffects[EAXREVERB_EFFECT] && DisabledEffects[CHORUS_EFFECT])
  1158. ? "EAXReverb and Chorus are" :
  1159. DisabledEffects[EAXREVERB_EFFECT] ? "EAXReverb is" :
  1160. DisabledEffects[CHORUS_EFFECT] ? "Chorus is" : "");
  1161. }
  1162. }
  1163. #endif // ALSOFT_EAX
  1164. }
  1165. inline void InitConfig()
  1166. { std::call_once(alc_config_once, [](){alc_initconfig();}); }
  1167. /************************************************
  1168. * Device enumeration
  1169. ************************************************/
  1170. void ProbeAllDevicesList()
  1171. {
  1172. InitConfig();
  1173. std::lock_guard<std::recursive_mutex> _{ListLock};
  1174. if(!PlaybackFactory)
  1175. decltype(alcAllDevicesList){}.swap(alcAllDevicesList);
  1176. else
  1177. {
  1178. std::string names{PlaybackFactory->probe(BackendType::Playback)};
  1179. if(names.empty()) names += '\0';
  1180. names.swap(alcAllDevicesList);
  1181. }
  1182. }
  1183. void ProbeCaptureDeviceList()
  1184. {
  1185. InitConfig();
  1186. std::lock_guard<std::recursive_mutex> _{ListLock};
  1187. if(!CaptureFactory)
  1188. decltype(alcCaptureDeviceList){}.swap(alcCaptureDeviceList);
  1189. else
  1190. {
  1191. std::string names{CaptureFactory->probe(BackendType::Capture)};
  1192. if(names.empty()) names += '\0';
  1193. names.swap(alcCaptureDeviceList);
  1194. }
  1195. }
  1196. struct DevFmtPair { DevFmtChannels chans; DevFmtType type; };
  1197. al::optional<DevFmtPair> DecomposeDevFormat(ALenum format)
  1198. {
  1199. static const struct {
  1200. ALenum format;
  1201. DevFmtChannels channels;
  1202. DevFmtType type;
  1203. } list[] = {
  1204. { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
  1205. { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
  1206. { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
  1207. { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
  1208. { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
  1209. { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
  1210. { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
  1211. { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
  1212. { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
  1213. { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
  1214. { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
  1215. { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
  1216. { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
  1217. { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
  1218. { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
  1219. { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
  1220. { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
  1221. { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
  1222. };
  1223. for(const auto &item : list)
  1224. {
  1225. if(item.format == format)
  1226. return al::make_optional(DevFmtPair{item.channels, item.type});
  1227. }
  1228. return al::nullopt;
  1229. }
  1230. al::optional<DevFmtType> DevFmtTypeFromEnum(ALCenum type)
  1231. {
  1232. switch(type)
  1233. {
  1234. case ALC_BYTE_SOFT: return al::make_optional(DevFmtByte);
  1235. case ALC_UNSIGNED_BYTE_SOFT: return al::make_optional(DevFmtUByte);
  1236. case ALC_SHORT_SOFT: return al::make_optional(DevFmtShort);
  1237. case ALC_UNSIGNED_SHORT_SOFT: return al::make_optional(DevFmtUShort);
  1238. case ALC_INT_SOFT: return al::make_optional(DevFmtInt);
  1239. case ALC_UNSIGNED_INT_SOFT: return al::make_optional(DevFmtUInt);
  1240. case ALC_FLOAT_SOFT: return al::make_optional(DevFmtFloat);
  1241. }
  1242. WARN("Unsupported format type: 0x%04x\n", type);
  1243. return al::nullopt;
  1244. }
  1245. ALCenum EnumFromDevFmt(DevFmtType type)
  1246. {
  1247. switch(type)
  1248. {
  1249. case DevFmtByte: return ALC_BYTE_SOFT;
  1250. case DevFmtUByte: return ALC_UNSIGNED_BYTE_SOFT;
  1251. case DevFmtShort: return ALC_SHORT_SOFT;
  1252. case DevFmtUShort: return ALC_UNSIGNED_SHORT_SOFT;
  1253. case DevFmtInt: return ALC_INT_SOFT;
  1254. case DevFmtUInt: return ALC_UNSIGNED_INT_SOFT;
  1255. case DevFmtFloat: return ALC_FLOAT_SOFT;
  1256. }
  1257. throw std::runtime_error{"Invalid DevFmtType: "+std::to_string(int(type))};
  1258. }
  1259. al::optional<DevFmtChannels> DevFmtChannelsFromEnum(ALCenum channels)
  1260. {
  1261. switch(channels)
  1262. {
  1263. case ALC_MONO_SOFT: return al::make_optional(DevFmtMono);
  1264. case ALC_STEREO_SOFT: return al::make_optional(DevFmtStereo);
  1265. case ALC_QUAD_SOFT: return al::make_optional(DevFmtQuad);
  1266. case ALC_5POINT1_SOFT: return al::make_optional(DevFmtX51);
  1267. case ALC_6POINT1_SOFT: return al::make_optional(DevFmtX61);
  1268. case ALC_7POINT1_SOFT: return al::make_optional(DevFmtX71);
  1269. case ALC_BFORMAT3D_SOFT: return al::make_optional(DevFmtAmbi3D);
  1270. }
  1271. WARN("Unsupported format channels: 0x%04x\n", channels);
  1272. return al::nullopt;
  1273. }
  1274. ALCenum EnumFromDevFmt(DevFmtChannels channels)
  1275. {
  1276. switch(channels)
  1277. {
  1278. case DevFmtMono: return ALC_MONO_SOFT;
  1279. case DevFmtStereo: return ALC_STEREO_SOFT;
  1280. case DevFmtQuad: return ALC_QUAD_SOFT;
  1281. case DevFmtX51: return ALC_5POINT1_SOFT;
  1282. case DevFmtX61: return ALC_6POINT1_SOFT;
  1283. case DevFmtX71: return ALC_7POINT1_SOFT;
  1284. case DevFmtAmbi3D: return ALC_BFORMAT3D_SOFT;
  1285. /* FIXME: Shouldn't happen. */
  1286. case DevFmtX3D71: break;
  1287. }
  1288. throw std::runtime_error{"Invalid DevFmtChannels: "+std::to_string(int(channels))};
  1289. }
  1290. al::optional<DevAmbiLayout> DevAmbiLayoutFromEnum(ALCenum layout)
  1291. {
  1292. switch(layout)
  1293. {
  1294. case ALC_FUMA_SOFT: return al::make_optional(DevAmbiLayout::FuMa);
  1295. case ALC_ACN_SOFT: return al::make_optional(DevAmbiLayout::ACN);
  1296. }
  1297. WARN("Unsupported ambisonic layout: 0x%04x\n", layout);
  1298. return al::nullopt;
  1299. }
  1300. ALCenum EnumFromDevAmbi(DevAmbiLayout layout)
  1301. {
  1302. switch(layout)
  1303. {
  1304. case DevAmbiLayout::FuMa: return ALC_FUMA_SOFT;
  1305. case DevAmbiLayout::ACN: return ALC_ACN_SOFT;
  1306. }
  1307. throw std::runtime_error{"Invalid DevAmbiLayout: "+std::to_string(int(layout))};
  1308. }
  1309. al::optional<DevAmbiScaling> DevAmbiScalingFromEnum(ALCenum scaling)
  1310. {
  1311. switch(scaling)
  1312. {
  1313. case ALC_FUMA_SOFT: return al::make_optional(DevAmbiScaling::FuMa);
  1314. case ALC_SN3D_SOFT: return al::make_optional(DevAmbiScaling::SN3D);
  1315. case ALC_N3D_SOFT: return al::make_optional(DevAmbiScaling::N3D);
  1316. }
  1317. WARN("Unsupported ambisonic scaling: 0x%04x\n", scaling);
  1318. return al::nullopt;
  1319. }
  1320. ALCenum EnumFromDevAmbi(DevAmbiScaling scaling)
  1321. {
  1322. switch(scaling)
  1323. {
  1324. case DevAmbiScaling::FuMa: return ALC_FUMA_SOFT;
  1325. case DevAmbiScaling::SN3D: return ALC_SN3D_SOFT;
  1326. case DevAmbiScaling::N3D: return ALC_N3D_SOFT;
  1327. }
  1328. throw std::runtime_error{"Invalid DevAmbiScaling: "+std::to_string(int(scaling))};
  1329. }
  1330. /* Downmixing channel arrays, to map the given format's missing channels to
  1331. * existing ones. Based on Wine's DSound downmix values, which are based on
  1332. * PulseAudio's.
  1333. */
  1334. const std::array<InputRemixMap,6> StereoDownmix{{
  1335. { FrontCenter, {{{FrontLeft, 0.5f}, {FrontRight, 0.5f}}} },
  1336. { SideLeft, {{{FrontLeft, 1.0f/9.0f}, {FrontRight, 0.0f}}} },
  1337. { SideRight, {{{FrontLeft, 0.0f}, {FrontRight, 1.0f/9.0f}}} },
  1338. { BackLeft, {{{FrontLeft, 1.0f/9.0f}, {FrontRight, 0.0f}}} },
  1339. { BackRight, {{{FrontLeft, 0.0f}, {FrontRight, 1.0f/9.0f}}} },
  1340. { BackCenter, {{{FrontLeft, 0.5f/9.0f}, {FrontRight, 0.5f/9.0f}}} },
  1341. }};
  1342. const std::array<InputRemixMap,4> QuadDownmix{{
  1343. { FrontCenter, {{{FrontLeft, 0.5f}, {FrontRight, 0.5f}}} },
  1344. { SideLeft, {{{FrontLeft, 0.5f}, {BackLeft, 0.5f}}} },
  1345. { SideRight, {{{FrontRight, 0.5f}, {BackRight, 0.5f}}} },
  1346. { BackCenter, {{{BackLeft, 0.5f}, {BackRight, 0.5f}}} },
  1347. }};
  1348. const std::array<InputRemixMap,3> X51Downmix{{
  1349. { BackLeft, {{{SideLeft, 1.0f}, {SideRight, 0.0f}}} },
  1350. { BackRight, {{{SideLeft, 0.0f}, {SideRight, 1.0f}}} },
  1351. { BackCenter, {{{SideLeft, 0.5f}, {SideRight, 0.5f}}} },
  1352. }};
  1353. const std::array<InputRemixMap,2> X61Downmix{{
  1354. { BackLeft, {{{BackCenter, 0.5f}, {SideLeft, 0.5f}}} },
  1355. { BackRight, {{{BackCenter, 0.5f}, {SideRight, 0.5f}}} },
  1356. }};
  1357. const std::array<InputRemixMap,1> X71Downmix{{
  1358. { BackCenter, {{{BackLeft, 0.5f}, {BackRight, 0.5f}}} },
  1359. }};
  1360. /** Stores the latest ALC device error. */
  1361. void alcSetError(ALCdevice *device, ALCenum errorCode)
  1362. {
  1363. WARN("Error generated on device %p, code 0x%04x\n", voidp{device}, errorCode);
  1364. if(TrapALCError)
  1365. {
  1366. #ifdef _WIN32
  1367. /* DebugBreak() will cause an exception if there is no debugger */
  1368. if(IsDebuggerPresent())
  1369. DebugBreak();
  1370. #elif defined(SIGTRAP)
  1371. raise(SIGTRAP);
  1372. #endif
  1373. }
  1374. if(device)
  1375. device->LastError.store(errorCode);
  1376. else
  1377. LastNullDeviceError.store(errorCode);
  1378. }
  1379. std::unique_ptr<Compressor> CreateDeviceLimiter(const ALCdevice *device, const float threshold)
  1380. {
  1381. static constexpr bool AutoKnee{true};
  1382. static constexpr bool AutoAttack{true};
  1383. static constexpr bool AutoRelease{true};
  1384. static constexpr bool AutoPostGain{true};
  1385. static constexpr bool AutoDeclip{true};
  1386. static constexpr float LookAheadTime{0.001f};
  1387. static constexpr float HoldTime{0.002f};
  1388. static constexpr float PreGainDb{0.0f};
  1389. static constexpr float PostGainDb{0.0f};
  1390. static constexpr float Ratio{std::numeric_limits<float>::infinity()};
  1391. static constexpr float KneeDb{0.0f};
  1392. static constexpr float AttackTime{0.02f};
  1393. static constexpr float ReleaseTime{0.2f};
  1394. return Compressor::Create(device->RealOut.Buffer.size(), static_cast<float>(device->Frequency),
  1395. AutoKnee, AutoAttack, AutoRelease, AutoPostGain, AutoDeclip, LookAheadTime, HoldTime,
  1396. PreGainDb, PostGainDb, threshold, Ratio, KneeDb, AttackTime, ReleaseTime);
  1397. }
  1398. /**
  1399. * Updates the device's base clock time with however many samples have been
  1400. * done. This is used so frequency changes on the device don't cause the time
  1401. * to jump forward or back. Must not be called while the device is running/
  1402. * mixing.
  1403. */
  1404. static inline void UpdateClockBase(ALCdevice *device)
  1405. {
  1406. IncrementRef(device->MixCount);
  1407. device->ClockBase += nanoseconds{seconds{device->SamplesDone}} / device->Frequency;
  1408. device->SamplesDone = 0;
  1409. IncrementRef(device->MixCount);
  1410. }
  1411. /**
  1412. * Updates device parameters according to the attribute list (caller is
  1413. * responsible for holding the list lock).
  1414. */
  1415. ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
  1416. {
  1417. if((!attrList || !attrList[0]) && device->Type == DeviceType::Loopback)
  1418. {
  1419. WARN("Missing attributes for loopback device\n");
  1420. return ALC_INVALID_VALUE;
  1421. }
  1422. al::optional<StereoEncoding> stereomode{};
  1423. al::optional<bool> optlimit{};
  1424. int hrtf_id{-1};
  1425. // Check for attributes
  1426. if(attrList && attrList[0])
  1427. {
  1428. uint numMono{device->NumMonoSources};
  1429. uint numStereo{device->NumStereoSources};
  1430. uint numSends{device->NumAuxSends};
  1431. al::optional<DevFmtChannels> optchans;
  1432. al::optional<DevFmtType> opttype;
  1433. al::optional<DevAmbiLayout> optlayout;
  1434. al::optional<DevAmbiScaling> optscale;
  1435. al::optional<bool> opthrtf;
  1436. ALenum outmode{ALC_ANY_SOFT};
  1437. uint aorder{0u};
  1438. uint freq{0u};
  1439. #define ATTRIBUTE(a) a: TRACE("%s = %d\n", #a, attrList[attrIdx + 1]);
  1440. size_t attrIdx{0};
  1441. while(attrList[attrIdx])
  1442. {
  1443. switch(attrList[attrIdx])
  1444. {
  1445. case ATTRIBUTE(ALC_FORMAT_CHANNELS_SOFT)
  1446. optchans = DevFmtChannelsFromEnum(attrList[attrIdx + 1]);
  1447. break;
  1448. case ATTRIBUTE(ALC_FORMAT_TYPE_SOFT)
  1449. opttype = DevFmtTypeFromEnum(attrList[attrIdx + 1]);
  1450. break;
  1451. case ATTRIBUTE(ALC_FREQUENCY)
  1452. freq = static_cast<uint>(attrList[attrIdx + 1]);
  1453. break;
  1454. case ATTRIBUTE(ALC_AMBISONIC_LAYOUT_SOFT)
  1455. optlayout = DevAmbiLayoutFromEnum(attrList[attrIdx + 1]);
  1456. break;
  1457. case ATTRIBUTE(ALC_AMBISONIC_SCALING_SOFT)
  1458. optscale = DevAmbiScalingFromEnum(attrList[attrIdx + 1]);
  1459. break;
  1460. case ATTRIBUTE(ALC_AMBISONIC_ORDER_SOFT)
  1461. aorder = static_cast<uint>(attrList[attrIdx + 1]);
  1462. break;
  1463. case ATTRIBUTE(ALC_MONO_SOURCES)
  1464. numMono = static_cast<uint>(attrList[attrIdx + 1]);
  1465. if(numMono > INT_MAX) numMono = 0;
  1466. break;
  1467. case ATTRIBUTE(ALC_STEREO_SOURCES)
  1468. numStereo = static_cast<uint>(attrList[attrIdx + 1]);
  1469. if(numStereo > INT_MAX) numStereo = 0;
  1470. break;
  1471. case ATTRIBUTE(ALC_MAX_AUXILIARY_SENDS)
  1472. numSends = static_cast<uint>(attrList[attrIdx + 1]);
  1473. if(numSends > INT_MAX) numSends = 0;
  1474. else numSends = minu(numSends, MAX_SENDS);
  1475. break;
  1476. case ATTRIBUTE(ALC_HRTF_SOFT)
  1477. if(attrList[attrIdx + 1] == ALC_FALSE)
  1478. opthrtf = false;
  1479. else if(attrList[attrIdx + 1] == ALC_TRUE)
  1480. opthrtf = true;
  1481. else if(attrList[attrIdx + 1] == ALC_DONT_CARE_SOFT)
  1482. opthrtf = al::nullopt;
  1483. break;
  1484. case ATTRIBUTE(ALC_HRTF_ID_SOFT)
  1485. hrtf_id = attrList[attrIdx + 1];
  1486. break;
  1487. case ATTRIBUTE(ALC_OUTPUT_LIMITER_SOFT)
  1488. if(attrList[attrIdx + 1] == ALC_FALSE)
  1489. optlimit = false;
  1490. else if(attrList[attrIdx + 1] == ALC_TRUE)
  1491. optlimit = true;
  1492. else if(attrList[attrIdx + 1] == ALC_DONT_CARE_SOFT)
  1493. optlimit = al::nullopt;
  1494. break;
  1495. case ATTRIBUTE(ALC_OUTPUT_MODE_SOFT)
  1496. outmode = attrList[attrIdx + 1];
  1497. break;
  1498. default:
  1499. TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
  1500. attrList[attrIdx + 1], attrList[attrIdx + 1]);
  1501. break;
  1502. }
  1503. attrIdx += 2;
  1504. }
  1505. #undef ATTRIBUTE
  1506. const bool loopback{device->Type == DeviceType::Loopback};
  1507. if(loopback)
  1508. {
  1509. if(!optchans || !opttype)
  1510. return ALC_INVALID_VALUE;
  1511. if(freq < MIN_OUTPUT_RATE || freq > MAX_OUTPUT_RATE)
  1512. return ALC_INVALID_VALUE;
  1513. if(*optchans == DevFmtAmbi3D)
  1514. {
  1515. if(!optlayout || !optscale)
  1516. return ALC_INVALID_VALUE;
  1517. if(aorder < 1 || aorder > MaxAmbiOrder)
  1518. return ALC_INVALID_VALUE;
  1519. if((*optlayout == DevAmbiLayout::FuMa || *optscale == DevAmbiScaling::FuMa)
  1520. && aorder > 3)
  1521. return ALC_INVALID_VALUE;
  1522. }
  1523. }
  1524. /* If a context is already running on the device, stop playback so the
  1525. * device attributes can be updated.
  1526. */
  1527. if(device->Flags.test(DeviceRunning))
  1528. device->Backend->stop();
  1529. device->Flags.reset(DeviceRunning);
  1530. UpdateClockBase(device);
  1531. /* Calculate the max number of sources, and split them between the mono
  1532. * and stereo count given the requested number of stereo sources.
  1533. */
  1534. if(auto srcsopt = device->configValue<uint>(nullptr, "sources"))
  1535. {
  1536. if(*srcsopt <= 0) numMono = 256;
  1537. else numMono = *srcsopt;
  1538. }
  1539. else
  1540. {
  1541. if(numMono > INT_MAX-numStereo)
  1542. numMono = INT_MAX-numStereo;
  1543. numMono = maxu(numMono+numStereo, 256);
  1544. }
  1545. numStereo = minu(numStereo, numMono);
  1546. numMono -= numStereo;
  1547. device->SourcesMax = numMono + numStereo;
  1548. device->NumMonoSources = numMono;
  1549. device->NumStereoSources = numStereo;
  1550. if(auto sendsopt = device->configValue<int>(nullptr, "sends"))
  1551. numSends = minu(numSends, static_cast<uint>(clampi(*sendsopt, 0, MAX_SENDS)));
  1552. device->NumAuxSends = numSends;
  1553. if(loopback)
  1554. {
  1555. device->Frequency = freq;
  1556. device->FmtChans = *optchans;
  1557. device->FmtType = *opttype;
  1558. if(device->FmtChans == DevFmtAmbi3D)
  1559. {
  1560. device->mAmbiOrder = aorder;
  1561. device->mAmbiLayout = *optlayout;
  1562. device->mAmbiScale = *optscale;
  1563. }
  1564. else if(device->FmtChans == DevFmtStereo)
  1565. {
  1566. if(opthrtf)
  1567. stereomode = *opthrtf ? StereoEncoding::Hrtf : StereoEncoding::Default;
  1568. if(outmode == ALC_STEREO_BASIC_SOFT)
  1569. stereomode = StereoEncoding::Basic;
  1570. else if(outmode == ALC_STEREO_UHJ_SOFT)
  1571. stereomode = StereoEncoding::Uhj;
  1572. else if(outmode == ALC_STEREO_HRTF_SOFT)
  1573. stereomode = StereoEncoding::Hrtf;
  1574. }
  1575. device->Flags.set(FrequencyRequest).set(ChannelsRequest).set(SampleTypeRequest);
  1576. }
  1577. else
  1578. {
  1579. device->Flags.reset(FrequencyRequest).reset(ChannelsRequest).reset(SampleTypeRequest);
  1580. device->FmtType = DevFmtTypeDefault;
  1581. device->FmtChans = DevFmtChannelsDefault;
  1582. device->mAmbiOrder = 0;
  1583. device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
  1584. device->UpdateSize = DEFAULT_UPDATE_SIZE;
  1585. device->Frequency = DEFAULT_OUTPUT_RATE;
  1586. freq = device->configValue<uint>(nullptr, "frequency").value_or(freq);
  1587. if(freq > 0)
  1588. {
  1589. freq = clampu(freq, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE);
  1590. const double scale{static_cast<double>(freq) / device->Frequency};
  1591. device->UpdateSize = static_cast<uint>(device->UpdateSize*scale + 0.5);
  1592. device->BufferSize = static_cast<uint>(device->BufferSize*scale + 0.5);
  1593. device->Frequency = freq;
  1594. device->Flags.set(FrequencyRequest);
  1595. }
  1596. auto set_device_mode = [device](DevFmtChannels chans) noexcept
  1597. {
  1598. device->FmtChans = chans;
  1599. device->Flags.set(ChannelsRequest);
  1600. };
  1601. if(opthrtf)
  1602. {
  1603. if(*opthrtf)
  1604. {
  1605. set_device_mode(DevFmtStereo);
  1606. stereomode = StereoEncoding::Hrtf;
  1607. }
  1608. else
  1609. stereomode = StereoEncoding::Default;
  1610. }
  1611. using OutputMode = ALCdevice::OutputMode;
  1612. switch(OutputMode(outmode))
  1613. {
  1614. case OutputMode::Any: break;
  1615. case OutputMode::Mono: set_device_mode(DevFmtMono); break;
  1616. case OutputMode::Stereo: set_device_mode(DevFmtStereo); break;
  1617. case OutputMode::StereoBasic:
  1618. set_device_mode(DevFmtStereo);
  1619. stereomode = StereoEncoding::Basic;
  1620. break;
  1621. case OutputMode::Uhj2:
  1622. set_device_mode(DevFmtStereo);
  1623. stereomode = StereoEncoding::Uhj;
  1624. break;
  1625. case OutputMode::Hrtf:
  1626. set_device_mode(DevFmtStereo);
  1627. stereomode = StereoEncoding::Hrtf;
  1628. break;
  1629. case OutputMode::Quad: set_device_mode(DevFmtQuad); break;
  1630. case OutputMode::X51: set_device_mode(DevFmtX51); break;
  1631. case OutputMode::X61: set_device_mode(DevFmtX61); break;
  1632. case OutputMode::X71: set_device_mode(DevFmtX71); break;
  1633. }
  1634. }
  1635. }
  1636. if(device->Flags.test(DeviceRunning))
  1637. return ALC_NO_ERROR;
  1638. device->AvgSpeakerDist = 0.0f;
  1639. device->mNFCtrlFilter = NfcFilter{};
  1640. device->mUhjEncoder = nullptr;
  1641. device->AmbiDecoder = nullptr;
  1642. device->Bs2b = nullptr;
  1643. device->PostProcess = nullptr;
  1644. device->Limiter = nullptr;
  1645. device->ChannelDelays = nullptr;
  1646. std::fill(std::begin(device->HrtfAccumData), std::end(device->HrtfAccumData), float2{});
  1647. device->Dry.AmbiMap.fill(BFChannelConfig{});
  1648. device->Dry.Buffer = {};
  1649. std::fill(std::begin(device->NumChannelsPerOrder), std::end(device->NumChannelsPerOrder), 0u);
  1650. device->RealOut.RemixMap = {};
  1651. device->RealOut.ChannelIndex.fill(INVALID_CHANNEL_INDEX);
  1652. device->RealOut.Buffer = {};
  1653. device->MixBuffer.clear();
  1654. device->MixBuffer.shrink_to_fit();
  1655. UpdateClockBase(device);
  1656. device->FixedLatency = nanoseconds::zero();
  1657. device->DitherDepth = 0.0f;
  1658. device->DitherSeed = DitherRNGSeed;
  1659. device->mHrtfStatus = ALC_HRTF_DISABLED_SOFT;
  1660. /*************************************************************************
  1661. * Update device format request from the user configuration
  1662. */
  1663. if(device->Type != DeviceType::Loopback)
  1664. {
  1665. if(auto typeopt = device->configValue<std::string>(nullptr, "sample-type"))
  1666. {
  1667. static constexpr struct TypeMap {
  1668. const char name[8];
  1669. DevFmtType type;
  1670. } typelist[] = {
  1671. { "int8", DevFmtByte },
  1672. { "uint8", DevFmtUByte },
  1673. { "int16", DevFmtShort },
  1674. { "uint16", DevFmtUShort },
  1675. { "int32", DevFmtInt },
  1676. { "uint32", DevFmtUInt },
  1677. { "float32", DevFmtFloat },
  1678. };
  1679. const ALCchar *fmt{typeopt->c_str()};
  1680. auto iter = std::find_if(std::begin(typelist), std::end(typelist),
  1681. [fmt](const TypeMap &entry) -> bool
  1682. { return al::strcasecmp(entry.name, fmt) == 0; });
  1683. if(iter == std::end(typelist))
  1684. ERR("Unsupported sample-type: %s\n", fmt);
  1685. else
  1686. {
  1687. device->FmtType = iter->type;
  1688. device->Flags.set(SampleTypeRequest);
  1689. }
  1690. }
  1691. if(auto chanopt = device->configValue<std::string>(nullptr, "channels"))
  1692. {
  1693. static constexpr struct ChannelMap {
  1694. const char name[16];
  1695. DevFmtChannels chans;
  1696. uint8_t order;
  1697. } chanlist[] = {
  1698. { "mono", DevFmtMono, 0 },
  1699. { "stereo", DevFmtStereo, 0 },
  1700. { "quad", DevFmtQuad, 0 },
  1701. { "surround51", DevFmtX51, 0 },
  1702. { "surround61", DevFmtX61, 0 },
  1703. { "surround71", DevFmtX71, 0 },
  1704. { "surround3d71", DevFmtX3D71, 0 },
  1705. { "surround51rear", DevFmtX51, 0 },
  1706. { "ambi1", DevFmtAmbi3D, 1 },
  1707. { "ambi2", DevFmtAmbi3D, 2 },
  1708. { "ambi3", DevFmtAmbi3D, 3 },
  1709. };
  1710. const ALCchar *fmt{chanopt->c_str()};
  1711. auto iter = std::find_if(std::begin(chanlist), std::end(chanlist),
  1712. [fmt](const ChannelMap &entry) -> bool
  1713. { return al::strcasecmp(entry.name, fmt) == 0; });
  1714. if(iter == std::end(chanlist))
  1715. ERR("Unsupported channels: %s\n", fmt);
  1716. else
  1717. {
  1718. device->FmtChans = iter->chans;
  1719. device->mAmbiOrder = iter->order;
  1720. device->Flags.set(ChannelsRequest);
  1721. }
  1722. }
  1723. if(auto ambiopt = device->configValue<std::string>(nullptr, "ambi-format"))
  1724. {
  1725. const ALCchar *fmt{ambiopt->c_str()};
  1726. if(al::strcasecmp(fmt, "fuma") == 0)
  1727. {
  1728. if(device->mAmbiOrder > 3)
  1729. ERR("FuMa is incompatible with %d%s order ambisonics (up to 3rd order only)\n",
  1730. device->mAmbiOrder,
  1731. (((device->mAmbiOrder%100)/10) == 1) ? "th" :
  1732. ((device->mAmbiOrder%10) == 1) ? "st" :
  1733. ((device->mAmbiOrder%10) == 2) ? "nd" :
  1734. ((device->mAmbiOrder%10) == 3) ? "rd" : "th");
  1735. else
  1736. {
  1737. device->mAmbiLayout = DevAmbiLayout::FuMa;
  1738. device->mAmbiScale = DevAmbiScaling::FuMa;
  1739. }
  1740. }
  1741. else if(al::strcasecmp(fmt, "acn+fuma") == 0)
  1742. {
  1743. if(device->mAmbiOrder > 3)
  1744. ERR("FuMa is incompatible with %d%s order ambisonics (up to 3rd order only)\n",
  1745. device->mAmbiOrder,
  1746. (((device->mAmbiOrder%100)/10) == 1) ? "th" :
  1747. ((device->mAmbiOrder%10) == 1) ? "st" :
  1748. ((device->mAmbiOrder%10) == 2) ? "nd" :
  1749. ((device->mAmbiOrder%10) == 3) ? "rd" : "th");
  1750. else
  1751. {
  1752. device->mAmbiLayout = DevAmbiLayout::ACN;
  1753. device->mAmbiScale = DevAmbiScaling::FuMa;
  1754. }
  1755. }
  1756. else if(al::strcasecmp(fmt, "ambix") == 0 || al::strcasecmp(fmt, "acn+sn3d") == 0)
  1757. {
  1758. device->mAmbiLayout = DevAmbiLayout::ACN;
  1759. device->mAmbiScale = DevAmbiScaling::SN3D;
  1760. }
  1761. else if(al::strcasecmp(fmt, "acn+n3d") == 0)
  1762. {
  1763. device->mAmbiLayout = DevAmbiLayout::ACN;
  1764. device->mAmbiScale = DevAmbiScaling::N3D;
  1765. }
  1766. else
  1767. ERR("Unsupported ambi-format: %s\n", fmt);
  1768. }
  1769. if(auto persizeopt = device->configValue<uint>(nullptr, "period_size"))
  1770. device->UpdateSize = clampu(*persizeopt, 64, 8192);
  1771. if(auto peropt = device->configValue<uint>(nullptr, "periods"))
  1772. device->BufferSize = device->UpdateSize * clampu(*peropt, 2, 16);
  1773. else
  1774. device->BufferSize = maxu(device->BufferSize, device->UpdateSize*2);
  1775. if(auto hrtfopt = device->configValue<std::string>(nullptr, "hrtf"))
  1776. {
  1777. const char *hrtf{hrtfopt->c_str()};
  1778. if(al::strcasecmp(hrtf, "true") == 0)
  1779. {
  1780. stereomode = StereoEncoding::Hrtf;
  1781. device->FmtChans = DevFmtStereo;
  1782. device->Flags.set(ChannelsRequest);
  1783. }
  1784. else if(al::strcasecmp(hrtf, "false") == 0)
  1785. {
  1786. if(!stereomode || *stereomode == StereoEncoding::Hrtf)
  1787. stereomode = StereoEncoding::Default;
  1788. }
  1789. else if(al::strcasecmp(hrtf, "auto") != 0)
  1790. ERR("Unexpected hrtf value: %s\n", hrtf);
  1791. }
  1792. }
  1793. TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u / %u buffer\n",
  1794. device->Flags.test(ChannelsRequest)?"*":"", DevFmtChannelsString(device->FmtChans),
  1795. device->Flags.test(SampleTypeRequest)?"*":"", DevFmtTypeString(device->FmtType),
  1796. device->Flags.test(FrequencyRequest)?"*":"", device->Frequency,
  1797. device->UpdateSize, device->BufferSize);
  1798. const uint oldFreq{device->Frequency};
  1799. const DevFmtChannels oldChans{device->FmtChans};
  1800. const DevFmtType oldType{device->FmtType};
  1801. try {
  1802. auto backend = device->Backend.get();
  1803. if(!backend->reset())
  1804. throw al::backend_exception{al::backend_error::DeviceError, "Device reset failure"};
  1805. }
  1806. catch(std::exception &e) {
  1807. ERR("Device error: %s\n", e.what());
  1808. device->handleDisconnect("%s", e.what());
  1809. return ALC_INVALID_DEVICE;
  1810. }
  1811. if(device->FmtChans != oldChans && device->Flags.test(ChannelsRequest))
  1812. {
  1813. ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
  1814. DevFmtChannelsString(device->FmtChans));
  1815. device->Flags.reset(ChannelsRequest);
  1816. }
  1817. if(device->FmtType != oldType && device->Flags.test(SampleTypeRequest))
  1818. {
  1819. ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
  1820. DevFmtTypeString(device->FmtType));
  1821. device->Flags.reset(SampleTypeRequest);
  1822. }
  1823. if(device->Frequency != oldFreq && device->Flags.test(FrequencyRequest))
  1824. {
  1825. WARN("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
  1826. device->Flags.reset(FrequencyRequest);
  1827. }
  1828. TRACE("Post-reset: %s, %s, %uhz, %u / %u buffer\n",
  1829. DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
  1830. device->Frequency, device->UpdateSize, device->BufferSize);
  1831. if(device->Type != DeviceType::Loopback)
  1832. {
  1833. if(auto modeopt = device->configValue<std::string>(nullptr, "stereo-mode"))
  1834. {
  1835. const char *mode{modeopt->c_str()};
  1836. if(al::strcasecmp(mode, "headphones") == 0)
  1837. device->Flags.set(DirectEar);
  1838. else if(al::strcasecmp(mode, "speakers") == 0)
  1839. device->Flags.reset(DirectEar);
  1840. else if(al::strcasecmp(mode, "auto") != 0)
  1841. ERR("Unexpected stereo-mode: %s\n", mode);
  1842. }
  1843. if(auto encopt = device->configValue<std::string>(nullptr, "stereo-encoding"))
  1844. {
  1845. const char *mode{encopt->c_str()};
  1846. if(al::strcasecmp(mode, "panpot") == 0)
  1847. stereomode = al::make_optional(StereoEncoding::Basic);
  1848. else if(al::strcasecmp(mode, "uhj") == 0)
  1849. stereomode = al::make_optional(StereoEncoding::Uhj);
  1850. else if(al::strcasecmp(mode, "hrtf") == 0)
  1851. stereomode = al::make_optional(StereoEncoding::Hrtf);
  1852. else
  1853. ERR("Unexpected stereo-encoding: %s\n", mode);
  1854. }
  1855. }
  1856. aluInitRenderer(device, hrtf_id, stereomode);
  1857. TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
  1858. device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
  1859. device->AuxiliaryEffectSlotMax, device->NumAuxSends);
  1860. switch(device->FmtChans)
  1861. {
  1862. case DevFmtMono: break;
  1863. case DevFmtStereo:
  1864. if(!device->mUhjEncoder)
  1865. device->RealOut.RemixMap = StereoDownmix;
  1866. break;
  1867. case DevFmtQuad: device->RealOut.RemixMap = QuadDownmix; break;
  1868. case DevFmtX51: device->RealOut.RemixMap = X51Downmix; break;
  1869. case DevFmtX61: device->RealOut.RemixMap = X61Downmix; break;
  1870. case DevFmtX71: device->RealOut.RemixMap = X71Downmix; break;
  1871. case DevFmtX3D71: device->RealOut.RemixMap = X51Downmix; break;
  1872. case DevFmtAmbi3D: break;
  1873. }
  1874. nanoseconds::rep sample_delay{0};
  1875. if(device->mUhjEncoder)
  1876. sample_delay += UhjEncoder::sFilterDelay;
  1877. if(auto *ambidec = device->AmbiDecoder.get())
  1878. {
  1879. if(ambidec->hasStablizer())
  1880. sample_delay += FrontStablizer::DelayLength;
  1881. }
  1882. if(device->getConfigValueBool(nullptr, "dither", true))
  1883. {
  1884. int depth{device->configValue<int>(nullptr, "dither-depth").value_or(0)};
  1885. if(depth <= 0)
  1886. {
  1887. switch(device->FmtType)
  1888. {
  1889. case DevFmtByte:
  1890. case DevFmtUByte:
  1891. depth = 8;
  1892. break;
  1893. case DevFmtShort:
  1894. case DevFmtUShort:
  1895. depth = 16;
  1896. break;
  1897. case DevFmtInt:
  1898. case DevFmtUInt:
  1899. case DevFmtFloat:
  1900. break;
  1901. }
  1902. }
  1903. if(depth > 0)
  1904. {
  1905. depth = clampi(depth, 2, 24);
  1906. device->DitherDepth = std::pow(2.0f, static_cast<float>(depth-1));
  1907. }
  1908. }
  1909. if(!(device->DitherDepth > 0.0f))
  1910. TRACE("Dithering disabled\n");
  1911. else
  1912. TRACE("Dithering enabled (%d-bit, %g)\n", float2int(std::log2(device->DitherDepth)+0.5f)+1,
  1913. device->DitherDepth);
  1914. if(auto limopt = device->configValue<bool>(nullptr, "output-limiter"))
  1915. optlimit = limopt;
  1916. /* If the gain limiter is unset, use the limiter for integer-based output
  1917. * (where samples must be clamped), and don't for floating-point (which can
  1918. * take unclamped samples).
  1919. */
  1920. if(!optlimit)
  1921. {
  1922. switch(device->FmtType)
  1923. {
  1924. case DevFmtByte:
  1925. case DevFmtUByte:
  1926. case DevFmtShort:
  1927. case DevFmtUShort:
  1928. case DevFmtInt:
  1929. case DevFmtUInt:
  1930. optlimit = true;
  1931. break;
  1932. case DevFmtFloat:
  1933. break;
  1934. }
  1935. }
  1936. if(optlimit.value_or(false) == false)
  1937. TRACE("Output limiter disabled\n");
  1938. else
  1939. {
  1940. float thrshld{1.0f};
  1941. switch(device->FmtType)
  1942. {
  1943. case DevFmtByte:
  1944. case DevFmtUByte:
  1945. thrshld = 127.0f / 128.0f;
  1946. break;
  1947. case DevFmtShort:
  1948. case DevFmtUShort:
  1949. thrshld = 32767.0f / 32768.0f;
  1950. break;
  1951. case DevFmtInt:
  1952. case DevFmtUInt:
  1953. case DevFmtFloat:
  1954. break;
  1955. }
  1956. if(device->DitherDepth > 0.0f)
  1957. thrshld -= 1.0f / device->DitherDepth;
  1958. const float thrshld_dB{std::log10(thrshld) * 20.0f};
  1959. auto limiter = CreateDeviceLimiter(device, thrshld_dB);
  1960. sample_delay += limiter->getLookAhead();
  1961. device->Limiter = std::move(limiter);
  1962. TRACE("Output limiter enabled, %.4fdB limit\n", thrshld_dB);
  1963. }
  1964. /* Convert the sample delay from samples to nanosamples to nanoseconds. */
  1965. device->FixedLatency += nanoseconds{seconds{sample_delay}} / device->Frequency;
  1966. TRACE("Fixed device latency: %" PRId64 "ns\n", int64_t{device->FixedLatency.count()});
  1967. FPUCtl mixer_mode{};
  1968. for(ContextBase *ctxbase : *device->mContexts.load())
  1969. {
  1970. auto *context = static_cast<ALCcontext*>(ctxbase);
  1971. auto GetEffectBuffer = [](ALbuffer *buffer) noexcept -> EffectState::Buffer
  1972. {
  1973. if(!buffer) return EffectState::Buffer{};
  1974. return EffectState::Buffer{buffer, buffer->mData};
  1975. };
  1976. std::unique_lock<std::mutex> proplock{context->mPropLock};
  1977. std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock};
  1978. /* Clear out unused wet buffers. */
  1979. auto buffer_not_in_use = [](WetBufferPtr &wetbuffer) noexcept -> bool
  1980. { return !wetbuffer->mInUse; };
  1981. auto wetbuffer_iter = std::remove_if(context->mWetBuffers.begin(),
  1982. context->mWetBuffers.end(), buffer_not_in_use);
  1983. context->mWetBuffers.erase(wetbuffer_iter, context->mWetBuffers.end());
  1984. if(ALeffectslot *slot{context->mDefaultSlot.get()})
  1985. {
  1986. aluInitEffectPanning(&slot->mSlot, context);
  1987. EffectState *state{slot->Effect.State.get()};
  1988. state->mOutTarget = device->Dry.Buffer;
  1989. state->deviceUpdate(device, GetEffectBuffer(slot->Buffer));
  1990. slot->updateProps(context);
  1991. }
  1992. if(EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)})
  1993. std::fill_n(curarray->end(), curarray->size(), nullptr);
  1994. for(auto &sublist : context->mEffectSlotList)
  1995. {
  1996. uint64_t usemask{~sublist.FreeMask};
  1997. while(usemask)
  1998. {
  1999. const int idx{al::countr_zero(usemask)};
  2000. ALeffectslot *slot{sublist.EffectSlots + idx};
  2001. usemask &= ~(1_u64 << idx);
  2002. aluInitEffectPanning(&slot->mSlot, context);
  2003. EffectState *state{slot->Effect.State.get()};
  2004. state->mOutTarget = device->Dry.Buffer;
  2005. state->deviceUpdate(device, GetEffectBuffer(slot->Buffer));
  2006. slot->updateProps(context);
  2007. }
  2008. }
  2009. slotlock.unlock();
  2010. const uint num_sends{device->NumAuxSends};
  2011. std::unique_lock<std::mutex> srclock{context->mSourceLock};
  2012. for(auto &sublist : context->mSourceList)
  2013. {
  2014. uint64_t usemask{~sublist.FreeMask};
  2015. while(usemask)
  2016. {
  2017. const int idx{al::countr_zero(usemask)};
  2018. ALsource *source{sublist.Sources + idx};
  2019. usemask &= ~(1_u64 << idx);
  2020. auto clear_send = [](ALsource::SendData &send) -> void
  2021. {
  2022. if(send.Slot)
  2023. DecrementRef(send.Slot->ref);
  2024. send.Slot = nullptr;
  2025. send.Gain = 1.0f;
  2026. send.GainHF = 1.0f;
  2027. send.HFReference = LOWPASSFREQREF;
  2028. send.GainLF = 1.0f;
  2029. send.LFReference = HIGHPASSFREQREF;
  2030. };
  2031. auto send_begin = source->Send.begin() + static_cast<ptrdiff_t>(num_sends);
  2032. std::for_each(send_begin, source->Send.end(), clear_send);
  2033. source->mPropsDirty = true;
  2034. }
  2035. }
  2036. auto voicelist = context->getVoicesSpan();
  2037. for(Voice *voice : voicelist)
  2038. {
  2039. /* Clear extraneous property set sends. */
  2040. std::fill(std::begin(voice->mProps.Send)+num_sends, std::end(voice->mProps.Send),
  2041. VoiceProps::SendData{});
  2042. std::fill(voice->mSend.begin()+num_sends, voice->mSend.end(), Voice::TargetData{});
  2043. for(auto &chandata : voice->mChans)
  2044. {
  2045. std::fill(chandata.mWetParams.begin()+num_sends, chandata.mWetParams.end(),
  2046. SendParams{});
  2047. }
  2048. if(VoicePropsItem *props{voice->mUpdate.exchange(nullptr, std::memory_order_relaxed)})
  2049. AtomicReplaceHead(context->mFreeVoiceProps, props);
  2050. /* Force the voice to stopped if it was stopping. */
  2051. Voice::State vstate{Voice::Stopping};
  2052. voice->mPlayState.compare_exchange_strong(vstate, Voice::Stopped,
  2053. std::memory_order_acquire, std::memory_order_acquire);
  2054. if(voice->mSourceID.load(std::memory_order_relaxed) == 0u)
  2055. continue;
  2056. voice->prepare(device);
  2057. }
  2058. /* Clear all voice props to let them get allocated again. */
  2059. context->mVoicePropClusters.clear();
  2060. context->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
  2061. srclock.unlock();
  2062. context->mPropsDirty = false;
  2063. UpdateContextProps(context);
  2064. UpdateAllSourceProps(context);
  2065. }
  2066. mixer_mode.leave();
  2067. if(!device->Flags.test(DevicePaused))
  2068. {
  2069. try {
  2070. auto backend = device->Backend.get();
  2071. backend->start();
  2072. device->Flags.set(DeviceRunning);
  2073. }
  2074. catch(al::backend_exception& e) {
  2075. ERR("%s\n", e.what());
  2076. device->handleDisconnect("%s", e.what());
  2077. return ALC_INVALID_DEVICE;
  2078. }
  2079. TRACE("Post-start: %s, %s, %uhz, %u / %u buffer\n",
  2080. DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
  2081. device->Frequency, device->UpdateSize, device->BufferSize);
  2082. }
  2083. return ALC_NO_ERROR;
  2084. }
  2085. /**
  2086. * Updates device parameters as above, and also first clears the disconnected
  2087. * status, if set.
  2088. */
  2089. bool ResetDeviceParams(ALCdevice *device, const int *attrList)
  2090. {
  2091. /* If the device was disconnected, reset it since we're opened anew. */
  2092. if UNLIKELY(!device->Connected.load(std::memory_order_relaxed))
  2093. {
  2094. /* Make sure disconnection is finished before continuing on. */
  2095. device->waitForMix();
  2096. for(ContextBase *ctxbase : *device->mContexts.load(std::memory_order_acquire))
  2097. {
  2098. auto *ctx = static_cast<ALCcontext*>(ctxbase);
  2099. if(!ctx->mStopVoicesOnDisconnect.load(std::memory_order_acquire))
  2100. continue;
  2101. /* Clear any pending voice changes and reallocate voices to get a
  2102. * clean restart.
  2103. */
  2104. std::lock_guard<std::mutex> __{ctx->mSourceLock};
  2105. auto *vchg = ctx->mCurrentVoiceChange.load(std::memory_order_acquire);
  2106. while(auto *next = vchg->mNext.load(std::memory_order_acquire))
  2107. vchg = next;
  2108. ctx->mCurrentVoiceChange.store(vchg, std::memory_order_release);
  2109. ctx->mVoicePropClusters.clear();
  2110. ctx->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
  2111. ctx->mVoiceClusters.clear();
  2112. ctx->allocVoices(std::max<size_t>(256,
  2113. ctx->mActiveVoiceCount.load(std::memory_order_relaxed)));
  2114. }
  2115. device->Connected.store(true);
  2116. }
  2117. ALCenum err{UpdateDeviceParams(device, attrList)};
  2118. if LIKELY(err == ALC_NO_ERROR) return ALC_TRUE;
  2119. alcSetError(device, err);
  2120. return ALC_FALSE;
  2121. }
  2122. /** Checks if the device handle is valid, and returns a new reference if so. */
  2123. DeviceRef VerifyDevice(ALCdevice *device)
  2124. {
  2125. std::lock_guard<std::recursive_mutex> _{ListLock};
  2126. auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
  2127. if(iter != DeviceList.end() && *iter == device)
  2128. {
  2129. (*iter)->add_ref();
  2130. return DeviceRef{*iter};
  2131. }
  2132. return nullptr;
  2133. }
  2134. /**
  2135. * Checks if the given context is valid, returning a new reference to it if so.
  2136. */
  2137. ContextRef VerifyContext(ALCcontext *context)
  2138. {
  2139. std::lock_guard<std::recursive_mutex> _{ListLock};
  2140. auto iter = std::lower_bound(ContextList.begin(), ContextList.end(), context);
  2141. if(iter != ContextList.end() && *iter == context)
  2142. {
  2143. (*iter)->add_ref();
  2144. return ContextRef{*iter};
  2145. }
  2146. return nullptr;
  2147. }
  2148. } // namespace
  2149. /** Returns a new reference to the currently active context for this thread. */
  2150. ContextRef GetContextRef(void)
  2151. {
  2152. ALCcontext *context{ALCcontext::getThreadContext()};
  2153. if(context)
  2154. context->add_ref();
  2155. else
  2156. {
  2157. std::lock_guard<std::recursive_mutex> _{ListLock};
  2158. context = ALCcontext::sGlobalContext.load(std::memory_order_acquire);
  2159. if(context) context->add_ref();
  2160. }
  2161. return ContextRef{context};
  2162. }
  2163. /************************************************
  2164. * Standard ALC functions
  2165. ************************************************/
  2166. ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
  2167. START_API_FUNC
  2168. {
  2169. DeviceRef dev{VerifyDevice(device)};
  2170. if(dev) return dev->LastError.exchange(ALC_NO_ERROR);
  2171. return LastNullDeviceError.exchange(ALC_NO_ERROR);
  2172. }
  2173. END_API_FUNC
  2174. ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context)
  2175. START_API_FUNC
  2176. {
  2177. if(!SuspendDefers)
  2178. return;
  2179. ContextRef ctx{VerifyContext(context)};
  2180. if(!ctx)
  2181. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2182. else
  2183. {
  2184. std::lock_guard<std::mutex> _{ctx->mPropLock};
  2185. ctx->deferUpdates();
  2186. }
  2187. }
  2188. END_API_FUNC
  2189. ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context)
  2190. START_API_FUNC
  2191. {
  2192. if(!SuspendDefers)
  2193. return;
  2194. ContextRef ctx{VerifyContext(context)};
  2195. if(!ctx)
  2196. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2197. else
  2198. {
  2199. std::lock_guard<std::mutex> _{ctx->mPropLock};
  2200. ctx->processUpdates();
  2201. }
  2202. }
  2203. END_API_FUNC
  2204. ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
  2205. START_API_FUNC
  2206. {
  2207. const ALCchar *value{nullptr};
  2208. switch(param)
  2209. {
  2210. case ALC_NO_ERROR:
  2211. value = alcNoError;
  2212. break;
  2213. case ALC_INVALID_ENUM:
  2214. value = alcErrInvalidEnum;
  2215. break;
  2216. case ALC_INVALID_VALUE:
  2217. value = alcErrInvalidValue;
  2218. break;
  2219. case ALC_INVALID_DEVICE:
  2220. value = alcErrInvalidDevice;
  2221. break;
  2222. case ALC_INVALID_CONTEXT:
  2223. value = alcErrInvalidContext;
  2224. break;
  2225. case ALC_OUT_OF_MEMORY:
  2226. value = alcErrOutOfMemory;
  2227. break;
  2228. case ALC_DEVICE_SPECIFIER:
  2229. value = alcDefaultName;
  2230. break;
  2231. case ALC_ALL_DEVICES_SPECIFIER:
  2232. if(DeviceRef dev{VerifyDevice(Device)})
  2233. {
  2234. if(dev->Type == DeviceType::Capture)
  2235. alcSetError(dev.get(), ALC_INVALID_ENUM);
  2236. else if(dev->Type == DeviceType::Loopback)
  2237. value = alcDefaultName;
  2238. else
  2239. {
  2240. std::lock_guard<std::mutex> _{dev->StateLock};
  2241. value = dev->DeviceName.c_str();
  2242. }
  2243. }
  2244. else
  2245. {
  2246. ProbeAllDevicesList();
  2247. value = alcAllDevicesList.c_str();
  2248. }
  2249. break;
  2250. case ALC_CAPTURE_DEVICE_SPECIFIER:
  2251. if(DeviceRef dev{VerifyDevice(Device)})
  2252. {
  2253. if(dev->Type != DeviceType::Capture)
  2254. alcSetError(dev.get(), ALC_INVALID_ENUM);
  2255. else
  2256. {
  2257. std::lock_guard<std::mutex> _{dev->StateLock};
  2258. value = dev->DeviceName.c_str();
  2259. }
  2260. }
  2261. else
  2262. {
  2263. ProbeCaptureDeviceList();
  2264. value = alcCaptureDeviceList.c_str();
  2265. }
  2266. break;
  2267. /* Default devices are always first in the list */
  2268. case ALC_DEFAULT_DEVICE_SPECIFIER:
  2269. value = alcDefaultName;
  2270. break;
  2271. case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
  2272. if(alcAllDevicesList.empty())
  2273. ProbeAllDevicesList();
  2274. /* Copy first entry as default. */
  2275. alcDefaultAllDevicesSpecifier = alcAllDevicesList.c_str();
  2276. value = alcDefaultAllDevicesSpecifier.c_str();
  2277. break;
  2278. case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
  2279. if(alcCaptureDeviceList.empty())
  2280. ProbeCaptureDeviceList();
  2281. /* Copy first entry as default. */
  2282. alcCaptureDefaultDeviceSpecifier = alcCaptureDeviceList.c_str();
  2283. value = alcCaptureDefaultDeviceSpecifier.c_str();
  2284. break;
  2285. case ALC_EXTENSIONS:
  2286. if(VerifyDevice(Device))
  2287. value = alcExtensionList;
  2288. else
  2289. value = alcNoDeviceExtList;
  2290. break;
  2291. case ALC_HRTF_SPECIFIER_SOFT:
  2292. if(DeviceRef dev{VerifyDevice(Device)})
  2293. {
  2294. std::lock_guard<std::mutex> _{dev->StateLock};
  2295. value = (dev->mHrtf ? dev->mHrtfName.c_str() : "");
  2296. }
  2297. else
  2298. alcSetError(nullptr, ALC_INVALID_DEVICE);
  2299. break;
  2300. default:
  2301. alcSetError(VerifyDevice(Device).get(), ALC_INVALID_ENUM);
  2302. break;
  2303. }
  2304. return value;
  2305. }
  2306. END_API_FUNC
  2307. static size_t GetIntegerv(ALCdevice *device, ALCenum param, const al::span<int> values)
  2308. {
  2309. size_t i;
  2310. if(values.empty())
  2311. {
  2312. alcSetError(device, ALC_INVALID_VALUE);
  2313. return 0;
  2314. }
  2315. if(!device)
  2316. {
  2317. switch(param)
  2318. {
  2319. case ALC_MAJOR_VERSION:
  2320. values[0] = alcMajorVersion;
  2321. return 1;
  2322. case ALC_MINOR_VERSION:
  2323. values[0] = alcMinorVersion;
  2324. return 1;
  2325. case ALC_EFX_MAJOR_VERSION:
  2326. values[0] = alcEFXMajorVersion;
  2327. return 1;
  2328. case ALC_EFX_MINOR_VERSION:
  2329. values[0] = alcEFXMinorVersion;
  2330. return 1;
  2331. case ALC_MAX_AUXILIARY_SENDS:
  2332. values[0] = MAX_SENDS;
  2333. return 1;
  2334. case ALC_ATTRIBUTES_SIZE:
  2335. case ALC_ALL_ATTRIBUTES:
  2336. case ALC_FREQUENCY:
  2337. case ALC_REFRESH:
  2338. case ALC_SYNC:
  2339. case ALC_MONO_SOURCES:
  2340. case ALC_STEREO_SOURCES:
  2341. case ALC_CAPTURE_SAMPLES:
  2342. case ALC_FORMAT_CHANNELS_SOFT:
  2343. case ALC_FORMAT_TYPE_SOFT:
  2344. case ALC_AMBISONIC_LAYOUT_SOFT:
  2345. case ALC_AMBISONIC_SCALING_SOFT:
  2346. case ALC_AMBISONIC_ORDER_SOFT:
  2347. case ALC_MAX_AMBISONIC_ORDER_SOFT:
  2348. alcSetError(nullptr, ALC_INVALID_DEVICE);
  2349. return 0;
  2350. default:
  2351. alcSetError(nullptr, ALC_INVALID_ENUM);
  2352. }
  2353. return 0;
  2354. }
  2355. std::lock_guard<std::mutex> _{device->StateLock};
  2356. if(device->Type == DeviceType::Capture)
  2357. {
  2358. static constexpr int MaxCaptureAttributes{9};
  2359. switch(param)
  2360. {
  2361. case ALC_ATTRIBUTES_SIZE:
  2362. values[0] = MaxCaptureAttributes;
  2363. return 1;
  2364. case ALC_ALL_ATTRIBUTES:
  2365. i = 0;
  2366. if(values.size() < MaxCaptureAttributes)
  2367. alcSetError(device, ALC_INVALID_VALUE);
  2368. else
  2369. {
  2370. values[i++] = ALC_MAJOR_VERSION;
  2371. values[i++] = alcMajorVersion;
  2372. values[i++] = ALC_MINOR_VERSION;
  2373. values[i++] = alcMinorVersion;
  2374. values[i++] = ALC_CAPTURE_SAMPLES;
  2375. values[i++] = static_cast<int>(device->Backend->availableSamples());
  2376. values[i++] = ALC_CONNECTED;
  2377. values[i++] = device->Connected.load(std::memory_order_relaxed);
  2378. values[i++] = 0;
  2379. assert(i == MaxCaptureAttributes);
  2380. }
  2381. return i;
  2382. case ALC_MAJOR_VERSION:
  2383. values[0] = alcMajorVersion;
  2384. return 1;
  2385. case ALC_MINOR_VERSION:
  2386. values[0] = alcMinorVersion;
  2387. return 1;
  2388. case ALC_CAPTURE_SAMPLES:
  2389. values[0] = static_cast<int>(device->Backend->availableSamples());
  2390. return 1;
  2391. case ALC_CONNECTED:
  2392. values[0] = device->Connected.load(std::memory_order_acquire);
  2393. return 1;
  2394. default:
  2395. alcSetError(device, ALC_INVALID_ENUM);
  2396. }
  2397. return 0;
  2398. }
  2399. /* render device */
  2400. auto NumAttrsForDevice = [](ALCdevice *aldev) noexcept
  2401. {
  2402. if(aldev->Type == DeviceType::Loopback && aldev->FmtChans == DevFmtAmbi3D)
  2403. return 37;
  2404. return 31;
  2405. };
  2406. switch(param)
  2407. {
  2408. case ALC_ATTRIBUTES_SIZE:
  2409. values[0] = NumAttrsForDevice(device);
  2410. return 1;
  2411. case ALC_ALL_ATTRIBUTES:
  2412. i = 0;
  2413. if(values.size() < static_cast<size_t>(NumAttrsForDevice(device)))
  2414. alcSetError(device, ALC_INVALID_VALUE);
  2415. else
  2416. {
  2417. values[i++] = ALC_MAJOR_VERSION;
  2418. values[i++] = alcMajorVersion;
  2419. values[i++] = ALC_MINOR_VERSION;
  2420. values[i++] = alcMinorVersion;
  2421. values[i++] = ALC_EFX_MAJOR_VERSION;
  2422. values[i++] = alcEFXMajorVersion;
  2423. values[i++] = ALC_EFX_MINOR_VERSION;
  2424. values[i++] = alcEFXMinorVersion;
  2425. values[i++] = ALC_FREQUENCY;
  2426. values[i++] = static_cast<int>(device->Frequency);
  2427. if(device->Type != DeviceType::Loopback)
  2428. {
  2429. values[i++] = ALC_REFRESH;
  2430. values[i++] = static_cast<int>(device->Frequency / device->UpdateSize);
  2431. values[i++] = ALC_SYNC;
  2432. values[i++] = ALC_FALSE;
  2433. }
  2434. else
  2435. {
  2436. if(device->FmtChans == DevFmtAmbi3D)
  2437. {
  2438. values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
  2439. values[i++] = EnumFromDevAmbi(device->mAmbiLayout);
  2440. values[i++] = ALC_AMBISONIC_SCALING_SOFT;
  2441. values[i++] = EnumFromDevAmbi(device->mAmbiScale);
  2442. values[i++] = ALC_AMBISONIC_ORDER_SOFT;
  2443. values[i++] = static_cast<int>(device->mAmbiOrder);
  2444. }
  2445. values[i++] = ALC_FORMAT_CHANNELS_SOFT;
  2446. values[i++] = EnumFromDevFmt(device->FmtChans);
  2447. values[i++] = ALC_FORMAT_TYPE_SOFT;
  2448. values[i++] = EnumFromDevFmt(device->FmtType);
  2449. }
  2450. values[i++] = ALC_MONO_SOURCES;
  2451. values[i++] = static_cast<int>(device->NumMonoSources);
  2452. values[i++] = ALC_STEREO_SOURCES;
  2453. values[i++] = static_cast<int>(device->NumStereoSources);
  2454. values[i++] = ALC_MAX_AUXILIARY_SENDS;
  2455. values[i++] = static_cast<int>(device->NumAuxSends);
  2456. values[i++] = ALC_HRTF_SOFT;
  2457. values[i++] = (device->mHrtf ? ALC_TRUE : ALC_FALSE);
  2458. values[i++] = ALC_HRTF_STATUS_SOFT;
  2459. values[i++] = device->mHrtfStatus;
  2460. values[i++] = ALC_OUTPUT_LIMITER_SOFT;
  2461. values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
  2462. values[i++] = ALC_MAX_AMBISONIC_ORDER_SOFT;
  2463. values[i++] = MaxAmbiOrder;
  2464. values[i++] = ALC_OUTPUT_MODE_SOFT;
  2465. values[i++] = static_cast<ALCenum>(device->getOutputMode1());
  2466. values[i++] = 0;
  2467. }
  2468. return i;
  2469. case ALC_MAJOR_VERSION:
  2470. values[0] = alcMajorVersion;
  2471. return 1;
  2472. case ALC_MINOR_VERSION:
  2473. values[0] = alcMinorVersion;
  2474. return 1;
  2475. case ALC_EFX_MAJOR_VERSION:
  2476. values[0] = alcEFXMajorVersion;
  2477. return 1;
  2478. case ALC_EFX_MINOR_VERSION:
  2479. values[0] = alcEFXMinorVersion;
  2480. return 1;
  2481. case ALC_FREQUENCY:
  2482. values[0] = static_cast<int>(device->Frequency);
  2483. return 1;
  2484. case ALC_REFRESH:
  2485. if(device->Type == DeviceType::Loopback)
  2486. {
  2487. alcSetError(device, ALC_INVALID_DEVICE);
  2488. return 0;
  2489. }
  2490. values[0] = static_cast<int>(device->Frequency / device->UpdateSize);
  2491. return 1;
  2492. case ALC_SYNC:
  2493. if(device->Type == DeviceType::Loopback)
  2494. {
  2495. alcSetError(device, ALC_INVALID_DEVICE);
  2496. return 0;
  2497. }
  2498. values[0] = ALC_FALSE;
  2499. return 1;
  2500. case ALC_FORMAT_CHANNELS_SOFT:
  2501. if(device->Type != DeviceType::Loopback)
  2502. {
  2503. alcSetError(device, ALC_INVALID_DEVICE);
  2504. return 0;
  2505. }
  2506. values[0] = EnumFromDevFmt(device->FmtChans);
  2507. return 1;
  2508. case ALC_FORMAT_TYPE_SOFT:
  2509. if(device->Type != DeviceType::Loopback)
  2510. {
  2511. alcSetError(device, ALC_INVALID_DEVICE);
  2512. return 0;
  2513. }
  2514. values[0] = EnumFromDevFmt(device->FmtType);
  2515. return 1;
  2516. case ALC_AMBISONIC_LAYOUT_SOFT:
  2517. if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
  2518. {
  2519. alcSetError(device, ALC_INVALID_DEVICE);
  2520. return 0;
  2521. }
  2522. values[0] = EnumFromDevAmbi(device->mAmbiLayout);
  2523. return 1;
  2524. case ALC_AMBISONIC_SCALING_SOFT:
  2525. if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
  2526. {
  2527. alcSetError(device, ALC_INVALID_DEVICE);
  2528. return 0;
  2529. }
  2530. values[0] = EnumFromDevAmbi(device->mAmbiScale);
  2531. return 1;
  2532. case ALC_AMBISONIC_ORDER_SOFT:
  2533. if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
  2534. {
  2535. alcSetError(device, ALC_INVALID_DEVICE);
  2536. return 0;
  2537. }
  2538. values[0] = static_cast<int>(device->mAmbiOrder);
  2539. return 1;
  2540. case ALC_MONO_SOURCES:
  2541. values[0] = static_cast<int>(device->NumMonoSources);
  2542. return 1;
  2543. case ALC_STEREO_SOURCES:
  2544. values[0] = static_cast<int>(device->NumStereoSources);
  2545. return 1;
  2546. case ALC_MAX_AUXILIARY_SENDS:
  2547. values[0] = static_cast<int>(device->NumAuxSends);
  2548. return 1;
  2549. case ALC_CONNECTED:
  2550. values[0] = device->Connected.load(std::memory_order_acquire);
  2551. return 1;
  2552. case ALC_HRTF_SOFT:
  2553. values[0] = (device->mHrtf ? ALC_TRUE : ALC_FALSE);
  2554. return 1;
  2555. case ALC_HRTF_STATUS_SOFT:
  2556. values[0] = device->mHrtfStatus;
  2557. return 1;
  2558. case ALC_NUM_HRTF_SPECIFIERS_SOFT:
  2559. device->enumerateHrtfs();
  2560. values[0] = static_cast<int>(minz(device->mHrtfList.size(),
  2561. std::numeric_limits<int>::max()));
  2562. return 1;
  2563. case ALC_OUTPUT_LIMITER_SOFT:
  2564. values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
  2565. return 1;
  2566. case ALC_MAX_AMBISONIC_ORDER_SOFT:
  2567. values[0] = MaxAmbiOrder;
  2568. return 1;
  2569. case ALC_OUTPUT_MODE_SOFT:
  2570. values[0] = static_cast<ALCenum>(device->getOutputMode1());
  2571. return 1;
  2572. default:
  2573. alcSetError(device, ALC_INVALID_ENUM);
  2574. }
  2575. return 0;
  2576. }
  2577. ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
  2578. START_API_FUNC
  2579. {
  2580. DeviceRef dev{VerifyDevice(device)};
  2581. if(size <= 0 || values == nullptr)
  2582. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2583. else
  2584. GetIntegerv(dev.get(), param, {values, static_cast<uint>(size)});
  2585. }
  2586. END_API_FUNC
  2587. ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
  2588. START_API_FUNC
  2589. {
  2590. DeviceRef dev{VerifyDevice(device)};
  2591. if(size <= 0 || values == nullptr)
  2592. {
  2593. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2594. return;
  2595. }
  2596. if(!dev || dev->Type == DeviceType::Capture)
  2597. {
  2598. auto ivals = al::vector<int>(static_cast<uint>(size));
  2599. if(size_t got{GetIntegerv(dev.get(), pname, ivals)})
  2600. std::copy_n(ivals.begin(), got, values);
  2601. return;
  2602. }
  2603. /* render device */
  2604. auto NumAttrsForDevice = [](ALCdevice *aldev) noexcept
  2605. {
  2606. if(aldev->Type == DeviceType::Loopback && aldev->FmtChans == DevFmtAmbi3D)
  2607. return 41;
  2608. return 35;
  2609. };
  2610. std::lock_guard<std::mutex> _{dev->StateLock};
  2611. switch(pname)
  2612. {
  2613. case ALC_ATTRIBUTES_SIZE:
  2614. *values = NumAttrsForDevice(dev.get());
  2615. break;
  2616. case ALC_ALL_ATTRIBUTES:
  2617. if(size < NumAttrsForDevice(dev.get()))
  2618. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2619. else
  2620. {
  2621. size_t i{0};
  2622. values[i++] = ALC_FREQUENCY;
  2623. values[i++] = dev->Frequency;
  2624. if(dev->Type != DeviceType::Loopback)
  2625. {
  2626. values[i++] = ALC_REFRESH;
  2627. values[i++] = dev->Frequency / dev->UpdateSize;
  2628. values[i++] = ALC_SYNC;
  2629. values[i++] = ALC_FALSE;
  2630. }
  2631. else
  2632. {
  2633. values[i++] = ALC_FORMAT_CHANNELS_SOFT;
  2634. values[i++] = EnumFromDevFmt(dev->FmtChans);
  2635. values[i++] = ALC_FORMAT_TYPE_SOFT;
  2636. values[i++] = EnumFromDevFmt(dev->FmtType);
  2637. if(dev->FmtChans == DevFmtAmbi3D)
  2638. {
  2639. values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
  2640. values[i++] = EnumFromDevAmbi(dev->mAmbiLayout);
  2641. values[i++] = ALC_AMBISONIC_SCALING_SOFT;
  2642. values[i++] = EnumFromDevAmbi(dev->mAmbiScale);
  2643. values[i++] = ALC_AMBISONIC_ORDER_SOFT;
  2644. values[i++] = dev->mAmbiOrder;
  2645. }
  2646. }
  2647. values[i++] = ALC_MONO_SOURCES;
  2648. values[i++] = dev->NumMonoSources;
  2649. values[i++] = ALC_STEREO_SOURCES;
  2650. values[i++] = dev->NumStereoSources;
  2651. values[i++] = ALC_MAX_AUXILIARY_SENDS;
  2652. values[i++] = dev->NumAuxSends;
  2653. values[i++] = ALC_HRTF_SOFT;
  2654. values[i++] = (dev->mHrtf ? ALC_TRUE : ALC_FALSE);
  2655. values[i++] = ALC_HRTF_STATUS_SOFT;
  2656. values[i++] = dev->mHrtfStatus;
  2657. values[i++] = ALC_OUTPUT_LIMITER_SOFT;
  2658. values[i++] = dev->Limiter ? ALC_TRUE : ALC_FALSE;
  2659. ClockLatency clock{GetClockLatency(dev.get(), dev->Backend.get())};
  2660. values[i++] = ALC_DEVICE_CLOCK_SOFT;
  2661. values[i++] = clock.ClockTime.count();
  2662. values[i++] = ALC_DEVICE_LATENCY_SOFT;
  2663. values[i++] = clock.Latency.count();
  2664. values[i++] = ALC_OUTPUT_MODE_SOFT;
  2665. values[i++] = static_cast<ALCenum>(device->getOutputMode1());
  2666. values[i++] = 0;
  2667. }
  2668. break;
  2669. case ALC_DEVICE_CLOCK_SOFT:
  2670. {
  2671. uint samplecount, refcount;
  2672. nanoseconds basecount;
  2673. do {
  2674. refcount = dev->waitForMix();
  2675. basecount = dev->ClockBase;
  2676. samplecount = dev->SamplesDone;
  2677. } while(refcount != ReadRef(dev->MixCount));
  2678. basecount += nanoseconds{seconds{samplecount}} / dev->Frequency;
  2679. *values = basecount.count();
  2680. }
  2681. break;
  2682. case ALC_DEVICE_LATENCY_SOFT:
  2683. *values = GetClockLatency(dev.get(), dev->Backend.get()).Latency.count();
  2684. break;
  2685. case ALC_DEVICE_CLOCK_LATENCY_SOFT:
  2686. if(size < 2)
  2687. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2688. else
  2689. {
  2690. ClockLatency clock{GetClockLatency(dev.get(), dev->Backend.get())};
  2691. values[0] = clock.ClockTime.count();
  2692. values[1] = clock.Latency.count();
  2693. }
  2694. break;
  2695. default:
  2696. auto ivals = al::vector<int>(static_cast<uint>(size));
  2697. if(size_t got{GetIntegerv(dev.get(), pname, ivals)})
  2698. std::copy_n(ivals.begin(), got, values);
  2699. break;
  2700. }
  2701. }
  2702. END_API_FUNC
  2703. ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
  2704. START_API_FUNC
  2705. {
  2706. DeviceRef dev{VerifyDevice(device)};
  2707. if(!extName)
  2708. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2709. else
  2710. {
  2711. size_t len = strlen(extName);
  2712. const char *ptr = (dev ? alcExtensionList : alcNoDeviceExtList);
  2713. while(ptr && *ptr)
  2714. {
  2715. if(al::strncasecmp(ptr, extName, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len])))
  2716. return ALC_TRUE;
  2717. if((ptr=strchr(ptr, ' ')) != nullptr)
  2718. {
  2719. do {
  2720. ++ptr;
  2721. } while(isspace(*ptr));
  2722. }
  2723. }
  2724. }
  2725. return ALC_FALSE;
  2726. }
  2727. END_API_FUNC
  2728. ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
  2729. START_API_FUNC
  2730. {
  2731. if(!funcName)
  2732. {
  2733. DeviceRef dev{VerifyDevice(device)};
  2734. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2735. return nullptr;
  2736. }
  2737. #ifdef ALSOFT_EAX
  2738. if(eax_g_is_enabled)
  2739. {
  2740. for(const auto &func : eaxFunctions)
  2741. {
  2742. if(strcmp(func.funcName, funcName) == 0)
  2743. return func.address;
  2744. }
  2745. }
  2746. #endif
  2747. for(const auto &func : alcFunctions)
  2748. {
  2749. if(strcmp(func.funcName, funcName) == 0)
  2750. return func.address;
  2751. }
  2752. return nullptr;
  2753. }
  2754. END_API_FUNC
  2755. ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
  2756. START_API_FUNC
  2757. {
  2758. if(!enumName)
  2759. {
  2760. DeviceRef dev{VerifyDevice(device)};
  2761. alcSetError(dev.get(), ALC_INVALID_VALUE);
  2762. return 0;
  2763. }
  2764. #ifdef ALSOFT_EAX
  2765. if(eax_g_is_enabled)
  2766. {
  2767. for(const auto &enm : eaxEnumerations)
  2768. {
  2769. if(strcmp(enm.enumName, enumName) == 0)
  2770. return enm.value;
  2771. }
  2772. }
  2773. #endif
  2774. for(const auto &enm : alcEnumerations)
  2775. {
  2776. if(strcmp(enm.enumName, enumName) == 0)
  2777. return enm.value;
  2778. }
  2779. return 0;
  2780. }
  2781. END_API_FUNC
  2782. ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
  2783. START_API_FUNC
  2784. {
  2785. /* Explicitly hold the list lock while taking the StateLock in case the
  2786. * device is asynchronously destroyed, to ensure this new context is
  2787. * properly cleaned up after being made.
  2788. */
  2789. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  2790. DeviceRef dev{VerifyDevice(device)};
  2791. if(!dev || dev->Type == DeviceType::Capture || !dev->Connected.load(std::memory_order_relaxed))
  2792. {
  2793. listlock.unlock();
  2794. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  2795. return nullptr;
  2796. }
  2797. std::unique_lock<std::mutex> statelock{dev->StateLock};
  2798. listlock.unlock();
  2799. dev->LastError.store(ALC_NO_ERROR);
  2800. ALCenum err{UpdateDeviceParams(dev.get(), attrList)};
  2801. if(err != ALC_NO_ERROR)
  2802. {
  2803. alcSetError(dev.get(), err);
  2804. return nullptr;
  2805. }
  2806. ContextRef context{new ALCcontext{dev}};
  2807. context->init();
  2808. if(auto volopt = dev->configValue<float>(nullptr, "volume-adjust"))
  2809. {
  2810. const float valf{*volopt};
  2811. if(!std::isfinite(valf))
  2812. ERR("volume-adjust must be finite: %f\n", valf);
  2813. else
  2814. {
  2815. const float db{clampf(valf, -24.0f, 24.0f)};
  2816. if(db != valf)
  2817. WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
  2818. context->mGainBoost = std::pow(10.0f, db/20.0f);
  2819. TRACE("volume-adjust gain: %f\n", context->mGainBoost);
  2820. }
  2821. }
  2822. {
  2823. using ContextArray = al::FlexArray<ContextBase*>;
  2824. /* Allocate a new context array, which holds 1 more than the current/
  2825. * old array.
  2826. */
  2827. auto *oldarray = device->mContexts.load();
  2828. const size_t newcount{oldarray->size()+1};
  2829. std::unique_ptr<ContextArray> newarray{ContextArray::Create(newcount)};
  2830. /* Copy the current/old context handles to the new array, appending the
  2831. * new context.
  2832. */
  2833. auto iter = std::copy(oldarray->begin(), oldarray->end(), newarray->begin());
  2834. *iter = context.get();
  2835. /* Store the new context array in the device. Wait for any current mix
  2836. * to finish before deleting the old array.
  2837. */
  2838. dev->mContexts.store(newarray.release());
  2839. if(oldarray != &DeviceBase::sEmptyContextArray)
  2840. {
  2841. dev->waitForMix();
  2842. delete oldarray;
  2843. }
  2844. }
  2845. statelock.unlock();
  2846. {
  2847. std::lock_guard<std::recursive_mutex> _{ListLock};
  2848. auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context.get());
  2849. ContextList.emplace(iter, context.get());
  2850. }
  2851. if(ALeffectslot *slot{context->mDefaultSlot.get()})
  2852. {
  2853. ALenum sloterr{slot->initEffect(ALCcontext::sDefaultEffect.type,
  2854. ALCcontext::sDefaultEffect.Props, context.get())};
  2855. if(sloterr == AL_NO_ERROR)
  2856. slot->updateProps(context.get());
  2857. else
  2858. ERR("Failed to initialize the default effect\n");
  2859. }
  2860. TRACE("Created context %p\n", voidp{context.get()});
  2861. return context.release();
  2862. }
  2863. END_API_FUNC
  2864. ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context)
  2865. START_API_FUNC
  2866. {
  2867. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  2868. auto iter = std::lower_bound(ContextList.begin(), ContextList.end(), context);
  2869. if(iter == ContextList.end() || *iter != context)
  2870. {
  2871. listlock.unlock();
  2872. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2873. return;
  2874. }
  2875. /* Hold a reference to this context so it remains valid until the ListLock
  2876. * is released.
  2877. */
  2878. ContextRef ctx{*iter};
  2879. ContextList.erase(iter);
  2880. ALCdevice *Device{ctx->mALDevice.get()};
  2881. std::lock_guard<std::mutex> _{Device->StateLock};
  2882. if(!ctx->deinit() && Device->Flags.test(DeviceRunning))
  2883. {
  2884. Device->Backend->stop();
  2885. Device->Flags.reset(DeviceRunning);
  2886. }
  2887. }
  2888. END_API_FUNC
  2889. ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
  2890. START_API_FUNC
  2891. {
  2892. ALCcontext *Context{ALCcontext::getThreadContext()};
  2893. if(!Context) Context = ALCcontext::sGlobalContext.load();
  2894. return Context;
  2895. }
  2896. END_API_FUNC
  2897. /** Returns the currently active thread-local context. */
  2898. ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
  2899. START_API_FUNC
  2900. { return ALCcontext::getThreadContext(); }
  2901. END_API_FUNC
  2902. ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
  2903. START_API_FUNC
  2904. {
  2905. /* context must be valid or nullptr */
  2906. ContextRef ctx;
  2907. if(context)
  2908. {
  2909. ctx = VerifyContext(context);
  2910. if(!ctx)
  2911. {
  2912. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2913. return ALC_FALSE;
  2914. }
  2915. }
  2916. /* Release this reference (if any) to store it in the GlobalContext
  2917. * pointer. Take ownership of the reference (if any) that was previously
  2918. * stored there.
  2919. */
  2920. ctx = ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())};
  2921. /* Reset (decrement) the previous global reference by replacing it with the
  2922. * thread-local context. Take ownership of the thread-local context
  2923. * reference (if any), clearing the storage to null.
  2924. */
  2925. ctx = ContextRef{ALCcontext::getThreadContext()};
  2926. if(ctx) ALCcontext::setThreadContext(nullptr);
  2927. /* Reset (decrement) the previous thread-local reference. */
  2928. return ALC_TRUE;
  2929. }
  2930. END_API_FUNC
  2931. /** Makes the given context the active context for the current thread. */
  2932. ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
  2933. START_API_FUNC
  2934. {
  2935. /* context must be valid or nullptr */
  2936. ContextRef ctx;
  2937. if(context)
  2938. {
  2939. ctx = VerifyContext(context);
  2940. if(!ctx)
  2941. {
  2942. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2943. return ALC_FALSE;
  2944. }
  2945. }
  2946. /* context's reference count is already incremented */
  2947. ContextRef old{ALCcontext::getThreadContext()};
  2948. ALCcontext::setThreadContext(ctx.release());
  2949. return ALC_TRUE;
  2950. }
  2951. END_API_FUNC
  2952. ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
  2953. START_API_FUNC
  2954. {
  2955. ContextRef ctx{VerifyContext(Context)};
  2956. if(!ctx)
  2957. {
  2958. alcSetError(nullptr, ALC_INVALID_CONTEXT);
  2959. return nullptr;
  2960. }
  2961. return ctx->mALDevice.get();
  2962. }
  2963. END_API_FUNC
  2964. ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
  2965. START_API_FUNC
  2966. {
  2967. InitConfig();
  2968. if(!PlaybackFactory)
  2969. {
  2970. alcSetError(nullptr, ALC_INVALID_VALUE);
  2971. return nullptr;
  2972. }
  2973. if(deviceName)
  2974. {
  2975. if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0
  2976. #ifdef _WIN32
  2977. /* Some old Windows apps hardcode these expecting OpenAL to use a
  2978. * specific audio API, even when they're not enumerated. Creative's
  2979. * router effectively ignores them too.
  2980. */
  2981. || al::strcasecmp(deviceName, "DirectSound3D") == 0
  2982. || al::strcasecmp(deviceName, "DirectSound") == 0
  2983. || al::strcasecmp(deviceName, "MMSYSTEM") == 0
  2984. #endif
  2985. /* Some old Linux apps hardcode configuration strings that were
  2986. * supported by the OpenAL SI. We can't really do anything useful
  2987. * with them, so just ignore.
  2988. */
  2989. || (deviceName[0] == '\'' && deviceName[1] == '(')
  2990. || al::strcasecmp(deviceName, "openal-soft") == 0)
  2991. deviceName = nullptr;
  2992. }
  2993. const uint DefaultSends{
  2994. #ifdef ALSOFT_EAX
  2995. eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
  2996. #endif // ALSOFT_EAX
  2997. DEFAULT_SENDS
  2998. };
  2999. DeviceRef device{new ALCdevice{DeviceType::Playback}};
  3000. /* Set output format */
  3001. device->FmtChans = DevFmtChannelsDefault;
  3002. device->FmtType = DevFmtTypeDefault;
  3003. device->Frequency = DEFAULT_OUTPUT_RATE;
  3004. device->UpdateSize = DEFAULT_UPDATE_SIZE;
  3005. device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
  3006. device->SourcesMax = 256;
  3007. device->AuxiliaryEffectSlotMax = 64;
  3008. device->NumAuxSends = DefaultSends;
  3009. try {
  3010. auto backend = PlaybackFactory->createBackend(device.get(), BackendType::Playback);
  3011. std::lock_guard<std::recursive_mutex> _{ListLock};
  3012. backend->open(deviceName);
  3013. device->Backend = std::move(backend);
  3014. }
  3015. catch(al::backend_exception &e) {
  3016. WARN("Failed to open playback device: %s\n", e.what());
  3017. alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
  3018. ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
  3019. return nullptr;
  3020. }
  3021. if(uint freq{device->configValue<uint>(nullptr, "frequency").value_or(0u)})
  3022. {
  3023. if(freq < MIN_OUTPUT_RATE || freq > MAX_OUTPUT_RATE)
  3024. {
  3025. const uint newfreq{clampu(freq, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE)};
  3026. ERR("%uhz request clamped to %uhz\n", freq, newfreq);
  3027. freq = newfreq;
  3028. }
  3029. const double scale{static_cast<double>(freq) / device->Frequency};
  3030. device->UpdateSize = static_cast<uint>(device->UpdateSize*scale + 0.5);
  3031. device->BufferSize = static_cast<uint>(device->BufferSize*scale + 0.5);
  3032. device->Frequency = freq;
  3033. device->Flags.set(FrequencyRequest);
  3034. }
  3035. if(auto srcsmax = device->configValue<uint>(nullptr, "sources").value_or(0))
  3036. device->SourcesMax = srcsmax;
  3037. if(auto slotsmax = device->configValue<uint>(nullptr, "slots").value_or(0))
  3038. device->AuxiliaryEffectSlotMax = minu(slotsmax, INT_MAX);
  3039. if(auto sendsopt = device->configValue<int>(nullptr, "sends"))
  3040. {
  3041. const int max_sends{clampi(*sendsopt, 0, MAX_SENDS)};
  3042. device->NumAuxSends = minu(DefaultSends, static_cast<uint>(max_sends));
  3043. }
  3044. device->NumStereoSources = 1;
  3045. device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
  3046. {
  3047. std::lock_guard<std::recursive_mutex> _{ListLock};
  3048. auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
  3049. DeviceList.emplace(iter, device.get());
  3050. }
  3051. TRACE("Created device %p, \"%s\"\n", voidp{device.get()}, device->DeviceName.c_str());
  3052. return device.release();
  3053. }
  3054. END_API_FUNC
  3055. ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
  3056. START_API_FUNC
  3057. {
  3058. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  3059. auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
  3060. if(iter == DeviceList.end() || *iter != device)
  3061. {
  3062. alcSetError(nullptr, ALC_INVALID_DEVICE);
  3063. return ALC_FALSE;
  3064. }
  3065. if((*iter)->Type == DeviceType::Capture)
  3066. {
  3067. alcSetError(*iter, ALC_INVALID_DEVICE);
  3068. return ALC_FALSE;
  3069. }
  3070. /* Erase the device, and any remaining contexts left on it, from their
  3071. * respective lists.
  3072. */
  3073. DeviceRef dev{*iter};
  3074. DeviceList.erase(iter);
  3075. std::unique_lock<std::mutex> statelock{dev->StateLock};
  3076. al::vector<ContextRef> orphanctxs;
  3077. for(ContextBase *ctx : *dev->mContexts.load())
  3078. {
  3079. auto ctxiter = std::lower_bound(ContextList.begin(), ContextList.end(), ctx);
  3080. if(ctxiter != ContextList.end() && *ctxiter == ctx)
  3081. {
  3082. orphanctxs.emplace_back(ContextRef{*ctxiter});
  3083. ContextList.erase(ctxiter);
  3084. }
  3085. }
  3086. listlock.unlock();
  3087. for(ContextRef &context : orphanctxs)
  3088. {
  3089. WARN("Releasing orphaned context %p\n", voidp{context.get()});
  3090. context->deinit();
  3091. }
  3092. orphanctxs.clear();
  3093. if(dev->Flags.test(DeviceRunning))
  3094. dev->Backend->stop();
  3095. dev->Flags.reset(DeviceRunning);
  3096. return ALC_TRUE;
  3097. }
  3098. END_API_FUNC
  3099. /************************************************
  3100. * ALC capture functions
  3101. ************************************************/
  3102. ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
  3103. START_API_FUNC
  3104. {
  3105. InitConfig();
  3106. if(!CaptureFactory)
  3107. {
  3108. alcSetError(nullptr, ALC_INVALID_VALUE);
  3109. return nullptr;
  3110. }
  3111. if(samples <= 0)
  3112. {
  3113. alcSetError(nullptr, ALC_INVALID_VALUE);
  3114. return nullptr;
  3115. }
  3116. if(deviceName)
  3117. {
  3118. if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0
  3119. || al::strcasecmp(deviceName, "openal-soft") == 0)
  3120. deviceName = nullptr;
  3121. }
  3122. DeviceRef device{new ALCdevice{DeviceType::Capture}};
  3123. auto decompfmt = DecomposeDevFormat(format);
  3124. if(!decompfmt)
  3125. {
  3126. alcSetError(nullptr, ALC_INVALID_ENUM);
  3127. return nullptr;
  3128. }
  3129. device->Frequency = frequency;
  3130. device->FmtChans = decompfmt->chans;
  3131. device->FmtType = decompfmt->type;
  3132. device->Flags.set(FrequencyRequest);
  3133. device->Flags.set(ChannelsRequest);
  3134. device->Flags.set(SampleTypeRequest);
  3135. device->UpdateSize = static_cast<uint>(samples);
  3136. device->BufferSize = static_cast<uint>(samples);
  3137. try {
  3138. TRACE("Capture format: %s, %s, %uhz, %u / %u buffer\n",
  3139. DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
  3140. device->Frequency, device->UpdateSize, device->BufferSize);
  3141. auto backend = CaptureFactory->createBackend(device.get(), BackendType::Capture);
  3142. std::lock_guard<std::recursive_mutex> _{ListLock};
  3143. backend->open(deviceName);
  3144. device->Backend = std::move(backend);
  3145. }
  3146. catch(al::backend_exception &e) {
  3147. WARN("Failed to open capture device: %s\n", e.what());
  3148. alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
  3149. ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
  3150. return nullptr;
  3151. }
  3152. {
  3153. std::lock_guard<std::recursive_mutex> _{ListLock};
  3154. auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
  3155. DeviceList.emplace(iter, device.get());
  3156. }
  3157. TRACE("Created capture device %p, \"%s\"\n", voidp{device.get()}, device->DeviceName.c_str());
  3158. return device.release();
  3159. }
  3160. END_API_FUNC
  3161. ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
  3162. START_API_FUNC
  3163. {
  3164. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  3165. auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
  3166. if(iter == DeviceList.end() || *iter != device)
  3167. {
  3168. alcSetError(nullptr, ALC_INVALID_DEVICE);
  3169. return ALC_FALSE;
  3170. }
  3171. if((*iter)->Type != DeviceType::Capture)
  3172. {
  3173. alcSetError(*iter, ALC_INVALID_DEVICE);
  3174. return ALC_FALSE;
  3175. }
  3176. DeviceRef dev{*iter};
  3177. DeviceList.erase(iter);
  3178. listlock.unlock();
  3179. std::lock_guard<std::mutex> _{dev->StateLock};
  3180. if(dev->Flags.test(DeviceRunning))
  3181. dev->Backend->stop();
  3182. dev->Flags.reset(DeviceRunning);
  3183. return ALC_TRUE;
  3184. }
  3185. END_API_FUNC
  3186. ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
  3187. START_API_FUNC
  3188. {
  3189. DeviceRef dev{VerifyDevice(device)};
  3190. if(!dev || dev->Type != DeviceType::Capture)
  3191. {
  3192. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3193. return;
  3194. }
  3195. std::lock_guard<std::mutex> _{dev->StateLock};
  3196. if(!dev->Connected.load(std::memory_order_acquire))
  3197. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3198. else if(!dev->Flags.test(DeviceRunning))
  3199. {
  3200. try {
  3201. auto backend = dev->Backend.get();
  3202. backend->start();
  3203. dev->Flags.set(DeviceRunning);
  3204. }
  3205. catch(al::backend_exception& e) {
  3206. ERR("%s\n", e.what());
  3207. dev->handleDisconnect("%s", e.what());
  3208. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3209. }
  3210. }
  3211. }
  3212. END_API_FUNC
  3213. ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
  3214. START_API_FUNC
  3215. {
  3216. DeviceRef dev{VerifyDevice(device)};
  3217. if(!dev || dev->Type != DeviceType::Capture)
  3218. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3219. else
  3220. {
  3221. std::lock_guard<std::mutex> _{dev->StateLock};
  3222. if(dev->Flags.test(DeviceRunning))
  3223. dev->Backend->stop();
  3224. dev->Flags.reset(DeviceRunning);
  3225. }
  3226. }
  3227. END_API_FUNC
  3228. ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
  3229. START_API_FUNC
  3230. {
  3231. DeviceRef dev{VerifyDevice(device)};
  3232. if(!dev || dev->Type != DeviceType::Capture)
  3233. {
  3234. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3235. return;
  3236. }
  3237. if(samples < 0 || (samples > 0 && buffer == nullptr))
  3238. {
  3239. alcSetError(dev.get(), ALC_INVALID_VALUE);
  3240. return;
  3241. }
  3242. if(samples < 1)
  3243. return;
  3244. std::lock_guard<std::mutex> _{dev->StateLock};
  3245. BackendBase *backend{dev->Backend.get()};
  3246. const auto usamples = static_cast<uint>(samples);
  3247. if(usamples > backend->availableSamples())
  3248. {
  3249. alcSetError(dev.get(), ALC_INVALID_VALUE);
  3250. return;
  3251. }
  3252. backend->captureSamples(static_cast<al::byte*>(buffer), usamples);
  3253. }
  3254. END_API_FUNC
  3255. /************************************************
  3256. * ALC loopback functions
  3257. ************************************************/
  3258. /** Open a loopback device, for manual rendering. */
  3259. ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
  3260. START_API_FUNC
  3261. {
  3262. InitConfig();
  3263. /* Make sure the device name, if specified, is us. */
  3264. if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
  3265. {
  3266. alcSetError(nullptr, ALC_INVALID_VALUE);
  3267. return nullptr;
  3268. }
  3269. const uint DefaultSends{
  3270. #ifdef ALSOFT_EAX
  3271. eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
  3272. #endif // ALSOFT_EAX
  3273. DEFAULT_SENDS
  3274. };
  3275. DeviceRef device{new ALCdevice{DeviceType::Loopback}};
  3276. device->SourcesMax = 256;
  3277. device->AuxiliaryEffectSlotMax = 64;
  3278. device->NumAuxSends = DefaultSends;
  3279. //Set output format
  3280. device->BufferSize = 0;
  3281. device->UpdateSize = 0;
  3282. device->Frequency = DEFAULT_OUTPUT_RATE;
  3283. device->FmtChans = DevFmtChannelsDefault;
  3284. device->FmtType = DevFmtTypeDefault;
  3285. if(auto srcsmax = ConfigValueUInt(nullptr, nullptr, "sources").value_or(0))
  3286. device->SourcesMax = srcsmax;
  3287. if(auto slotsmax = ConfigValueUInt(nullptr, nullptr, "slots").value_or(0))
  3288. device->AuxiliaryEffectSlotMax = minu(slotsmax, INT_MAX);
  3289. if(auto sendsopt = ConfigValueInt(nullptr, nullptr, "sends"))
  3290. {
  3291. const int max_sends{clampi(*sendsopt, 0, MAX_SENDS)};
  3292. device->NumAuxSends = minu(DefaultSends, static_cast<uint>(max_sends));
  3293. }
  3294. device->NumStereoSources = 1;
  3295. device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
  3296. try {
  3297. auto backend = LoopbackBackendFactory::getFactory().createBackend(device.get(),
  3298. BackendType::Playback);
  3299. backend->open("Loopback");
  3300. device->Backend = std::move(backend);
  3301. }
  3302. catch(al::backend_exception &e) {
  3303. WARN("Failed to open loopback device: %s\n", e.what());
  3304. alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
  3305. ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
  3306. return nullptr;
  3307. }
  3308. {
  3309. std::lock_guard<std::recursive_mutex> _{ListLock};
  3310. auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
  3311. DeviceList.emplace(iter, device.get());
  3312. }
  3313. TRACE("Created loopback device %p\n", voidp{device.get()});
  3314. return device.release();
  3315. }
  3316. END_API_FUNC
  3317. /**
  3318. * Determines if the loopback device supports the given format for rendering.
  3319. */
  3320. ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
  3321. START_API_FUNC
  3322. {
  3323. DeviceRef dev{VerifyDevice(device)};
  3324. if(!dev || dev->Type != DeviceType::Loopback)
  3325. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3326. else if(freq <= 0)
  3327. alcSetError(dev.get(), ALC_INVALID_VALUE);
  3328. else
  3329. {
  3330. if(DevFmtTypeFromEnum(type).has_value() && DevFmtChannelsFromEnum(channels).has_value()
  3331. && freq >= MIN_OUTPUT_RATE && freq <= MAX_OUTPUT_RATE)
  3332. return ALC_TRUE;
  3333. }
  3334. return ALC_FALSE;
  3335. }
  3336. END_API_FUNC
  3337. /**
  3338. * Renders some samples into a buffer, using the format last set by the
  3339. * attributes given to alcCreateContext.
  3340. */
  3341. FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
  3342. START_API_FUNC
  3343. {
  3344. if(!device || device->Type != DeviceType::Loopback)
  3345. alcSetError(device, ALC_INVALID_DEVICE);
  3346. else if(samples < 0 || (samples > 0 && buffer == nullptr))
  3347. alcSetError(device, ALC_INVALID_VALUE);
  3348. else
  3349. device->renderSamples(buffer, static_cast<uint>(samples), device->channelsFromFmt());
  3350. }
  3351. END_API_FUNC
  3352. /************************************************
  3353. * ALC DSP pause/resume functions
  3354. ************************************************/
  3355. /** Pause the DSP to stop audio processing. */
  3356. ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
  3357. START_API_FUNC
  3358. {
  3359. DeviceRef dev{VerifyDevice(device)};
  3360. if(!dev || dev->Type != DeviceType::Playback)
  3361. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3362. else
  3363. {
  3364. std::lock_guard<std::mutex> _{dev->StateLock};
  3365. if(dev->Flags.test(DeviceRunning))
  3366. dev->Backend->stop();
  3367. dev->Flags.reset(DeviceRunning);
  3368. dev->Flags.set(DevicePaused);
  3369. }
  3370. }
  3371. END_API_FUNC
  3372. /** Resume the DSP to restart audio processing. */
  3373. ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
  3374. START_API_FUNC
  3375. {
  3376. DeviceRef dev{VerifyDevice(device)};
  3377. if(!dev || dev->Type != DeviceType::Playback)
  3378. {
  3379. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3380. return;
  3381. }
  3382. std::lock_guard<std::mutex> _{dev->StateLock};
  3383. if(!dev->Flags.test(DevicePaused))
  3384. return;
  3385. dev->Flags.reset(DevicePaused);
  3386. if(dev->mContexts.load()->empty())
  3387. return;
  3388. try {
  3389. auto backend = dev->Backend.get();
  3390. backend->start();
  3391. dev->Flags.set(DeviceRunning);
  3392. }
  3393. catch(al::backend_exception& e) {
  3394. ERR("%s\n", e.what());
  3395. dev->handleDisconnect("%s", e.what());
  3396. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3397. return;
  3398. }
  3399. TRACE("Post-resume: %s, %s, %uhz, %u / %u buffer\n",
  3400. DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
  3401. device->Frequency, device->UpdateSize, device->BufferSize);
  3402. }
  3403. END_API_FUNC
  3404. /************************************************
  3405. * ALC HRTF functions
  3406. ************************************************/
  3407. /** Gets a string parameter at the given index. */
  3408. ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
  3409. START_API_FUNC
  3410. {
  3411. DeviceRef dev{VerifyDevice(device)};
  3412. if(!dev || dev->Type == DeviceType::Capture)
  3413. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3414. else switch(paramName)
  3415. {
  3416. case ALC_HRTF_SPECIFIER_SOFT:
  3417. if(index >= 0 && static_cast<uint>(index) < dev->mHrtfList.size())
  3418. return dev->mHrtfList[static_cast<uint>(index)].c_str();
  3419. alcSetError(dev.get(), ALC_INVALID_VALUE);
  3420. break;
  3421. default:
  3422. alcSetError(dev.get(), ALC_INVALID_ENUM);
  3423. break;
  3424. }
  3425. return nullptr;
  3426. }
  3427. END_API_FUNC
  3428. /** Resets the given device output, using the specified attribute list. */
  3429. ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
  3430. START_API_FUNC
  3431. {
  3432. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  3433. DeviceRef dev{VerifyDevice(device)};
  3434. if(!dev || dev->Type == DeviceType::Capture)
  3435. {
  3436. listlock.unlock();
  3437. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3438. return ALC_FALSE;
  3439. }
  3440. std::lock_guard<std::mutex> _{dev->StateLock};
  3441. listlock.unlock();
  3442. /* Force the backend to stop mixing first since we're resetting. Also reset
  3443. * the connected state so lost devices can attempt recover.
  3444. */
  3445. if(dev->Flags.test(DeviceRunning))
  3446. dev->Backend->stop();
  3447. dev->Flags.reset(DeviceRunning);
  3448. return ResetDeviceParams(dev.get(), attribs) ? ALC_TRUE : ALC_FALSE;
  3449. }
  3450. END_API_FUNC
  3451. /************************************************
  3452. * ALC device reopen functions
  3453. ************************************************/
  3454. /** Reopens the given device output, using the specified name and attribute list. */
  3455. FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device,
  3456. const ALCchar *deviceName, const ALCint *attribs)
  3457. START_API_FUNC
  3458. {
  3459. if(deviceName)
  3460. {
  3461. if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0)
  3462. deviceName = nullptr;
  3463. }
  3464. std::unique_lock<std::recursive_mutex> listlock{ListLock};
  3465. DeviceRef dev{VerifyDevice(device)};
  3466. if(!dev || dev->Type != DeviceType::Playback)
  3467. {
  3468. listlock.unlock();
  3469. alcSetError(dev.get(), ALC_INVALID_DEVICE);
  3470. return ALC_FALSE;
  3471. }
  3472. std::lock_guard<std::mutex> _{dev->StateLock};
  3473. /* Force the backend to stop mixing first since we're reopening. */
  3474. if(dev->Flags.test(DeviceRunning))
  3475. {
  3476. auto backend = dev->Backend.get();
  3477. backend->stop();
  3478. dev->Flags.reset(DeviceRunning);
  3479. }
  3480. BackendPtr newbackend;
  3481. try {
  3482. newbackend = PlaybackFactory->createBackend(dev.get(), BackendType::Playback);
  3483. newbackend->open(deviceName);
  3484. }
  3485. catch(al::backend_exception &e) {
  3486. listlock.unlock();
  3487. newbackend = nullptr;
  3488. WARN("Failed to reopen playback device: %s\n", e.what());
  3489. alcSetError(dev.get(), (e.errorCode() == al::backend_error::OutOfMemory)
  3490. ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
  3491. /* If the device is connected, not paused, and has contexts, ensure it
  3492. * continues playing.
  3493. */
  3494. if(dev->Connected.load(std::memory_order_relaxed) && !dev->Flags.test(DevicePaused)
  3495. && !dev->mContexts.load(std::memory_order_relaxed)->empty())
  3496. {
  3497. try {
  3498. auto backend = dev->Backend.get();
  3499. backend->start();
  3500. dev->Flags.set(DeviceRunning);
  3501. }
  3502. catch(al::backend_exception &be) {
  3503. ERR("%s\n", be.what());
  3504. dev->handleDisconnect("%s", be.what());
  3505. }
  3506. }
  3507. return ALC_FALSE;
  3508. }
  3509. listlock.unlock();
  3510. dev->Backend = std::move(newbackend);
  3511. TRACE("Reopened device %p, \"%s\"\n", voidp{dev.get()}, dev->DeviceName.c_str());
  3512. /* Always return true even if resetting fails. It shouldn't fail, but this
  3513. * is primarily to avoid confusion by the app seeing the function return
  3514. * false while the device is on the new output anyway. We could try to
  3515. * restore the old backend if this fails, but the configuration would be
  3516. * changed with the new backend and would need to be reset again with the
  3517. * old one, and the provided attributes may not be appropriate or desirable
  3518. * for the old device.
  3519. *
  3520. * In this way, we essentially act as if the function succeeded, but
  3521. * immediately disconnects following it.
  3522. */
  3523. ResetDeviceParams(dev.get(), attribs);
  3524. return ALC_TRUE;
  3525. }
  3526. END_API_FUNC