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

1017 lines
28 KiB

  1. #include "config.h"
  2. #include <stddef.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <mutex>
  7. #include <algorithm>
  8. #include <array>
  9. #include "AL/alc.h"
  10. #include "alstring.h"
  11. #include "router.h"
  12. #define DECL(x) { #x, reinterpret_cast<void*>(x) }
  13. struct FuncExportEntry {
  14. const char *funcName;
  15. void *address;
  16. };
  17. static const std::array<FuncExportEntry,128> alcFunctions{{
  18. DECL(alcCreateContext),
  19. DECL(alcMakeContextCurrent),
  20. DECL(alcProcessContext),
  21. DECL(alcSuspendContext),
  22. DECL(alcDestroyContext),
  23. DECL(alcGetCurrentContext),
  24. DECL(alcGetContextsDevice),
  25. DECL(alcOpenDevice),
  26. DECL(alcCloseDevice),
  27. DECL(alcGetError),
  28. DECL(alcIsExtensionPresent),
  29. DECL(alcGetProcAddress),
  30. DECL(alcGetEnumValue),
  31. DECL(alcGetString),
  32. DECL(alcGetIntegerv),
  33. DECL(alcCaptureOpenDevice),
  34. DECL(alcCaptureCloseDevice),
  35. DECL(alcCaptureStart),
  36. DECL(alcCaptureStop),
  37. DECL(alcCaptureSamples),
  38. DECL(alcSetThreadContext),
  39. DECL(alcGetThreadContext),
  40. DECL(alEnable),
  41. DECL(alDisable),
  42. DECL(alIsEnabled),
  43. DECL(alGetString),
  44. DECL(alGetBooleanv),
  45. DECL(alGetIntegerv),
  46. DECL(alGetFloatv),
  47. DECL(alGetDoublev),
  48. DECL(alGetBoolean),
  49. DECL(alGetInteger),
  50. DECL(alGetFloat),
  51. DECL(alGetDouble),
  52. DECL(alGetError),
  53. DECL(alIsExtensionPresent),
  54. DECL(alGetProcAddress),
  55. DECL(alGetEnumValue),
  56. DECL(alListenerf),
  57. DECL(alListener3f),
  58. DECL(alListenerfv),
  59. DECL(alListeneri),
  60. DECL(alListener3i),
  61. DECL(alListeneriv),
  62. DECL(alGetListenerf),
  63. DECL(alGetListener3f),
  64. DECL(alGetListenerfv),
  65. DECL(alGetListeneri),
  66. DECL(alGetListener3i),
  67. DECL(alGetListeneriv),
  68. DECL(alGenSources),
  69. DECL(alDeleteSources),
  70. DECL(alIsSource),
  71. DECL(alSourcef),
  72. DECL(alSource3f),
  73. DECL(alSourcefv),
  74. DECL(alSourcei),
  75. DECL(alSource3i),
  76. DECL(alSourceiv),
  77. DECL(alGetSourcef),
  78. DECL(alGetSource3f),
  79. DECL(alGetSourcefv),
  80. DECL(alGetSourcei),
  81. DECL(alGetSource3i),
  82. DECL(alGetSourceiv),
  83. DECL(alSourcePlayv),
  84. DECL(alSourceStopv),
  85. DECL(alSourceRewindv),
  86. DECL(alSourcePausev),
  87. DECL(alSourcePlay),
  88. DECL(alSourceStop),
  89. DECL(alSourceRewind),
  90. DECL(alSourcePause),
  91. DECL(alSourceQueueBuffers),
  92. DECL(alSourceUnqueueBuffers),
  93. DECL(alGenBuffers),
  94. DECL(alDeleteBuffers),
  95. DECL(alIsBuffer),
  96. DECL(alBufferData),
  97. DECL(alBufferf),
  98. DECL(alBuffer3f),
  99. DECL(alBufferfv),
  100. DECL(alBufferi),
  101. DECL(alBuffer3i),
  102. DECL(alBufferiv),
  103. DECL(alGetBufferf),
  104. DECL(alGetBuffer3f),
  105. DECL(alGetBufferfv),
  106. DECL(alGetBufferi),
  107. DECL(alGetBuffer3i),
  108. DECL(alGetBufferiv),
  109. DECL(alDopplerFactor),
  110. DECL(alDopplerVelocity),
  111. DECL(alSpeedOfSound),
  112. DECL(alDistanceModel),
  113. /* EFX 1.0 */
  114. DECL(alGenFilters),
  115. DECL(alDeleteFilters),
  116. DECL(alIsFilter),
  117. DECL(alFilterf),
  118. DECL(alFilterfv),
  119. DECL(alFilteri),
  120. DECL(alFilteriv),
  121. DECL(alGetFilterf),
  122. DECL(alGetFilterfv),
  123. DECL(alGetFilteri),
  124. DECL(alGetFilteriv),
  125. DECL(alGenEffects),
  126. DECL(alDeleteEffects),
  127. DECL(alIsEffect),
  128. DECL(alEffectf),
  129. DECL(alEffectfv),
  130. DECL(alEffecti),
  131. DECL(alEffectiv),
  132. DECL(alGetEffectf),
  133. DECL(alGetEffectfv),
  134. DECL(alGetEffecti),
  135. DECL(alGetEffectiv),
  136. DECL(alGenAuxiliaryEffectSlots),
  137. DECL(alDeleteAuxiliaryEffectSlots),
  138. DECL(alIsAuxiliaryEffectSlot),
  139. DECL(alAuxiliaryEffectSlotf),
  140. DECL(alAuxiliaryEffectSlotfv),
  141. DECL(alAuxiliaryEffectSloti),
  142. DECL(alAuxiliaryEffectSlotiv),
  143. DECL(alGetAuxiliaryEffectSlotf),
  144. DECL(alGetAuxiliaryEffectSlotfv),
  145. DECL(alGetAuxiliaryEffectSloti),
  146. DECL(alGetAuxiliaryEffectSlotiv),
  147. }};
  148. #undef DECL
  149. #define DECL(x) { #x, (x) }
  150. struct EnumExportEntry {
  151. const ALCchar *enumName;
  152. ALCenum value;
  153. };
  154. static const std::array<EnumExportEntry,92> alcEnumerations{{
  155. DECL(ALC_INVALID),
  156. DECL(ALC_FALSE),
  157. DECL(ALC_TRUE),
  158. DECL(ALC_MAJOR_VERSION),
  159. DECL(ALC_MINOR_VERSION),
  160. DECL(ALC_ATTRIBUTES_SIZE),
  161. DECL(ALC_ALL_ATTRIBUTES),
  162. DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
  163. DECL(ALC_DEVICE_SPECIFIER),
  164. DECL(ALC_ALL_DEVICES_SPECIFIER),
  165. DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
  166. DECL(ALC_EXTENSIONS),
  167. DECL(ALC_FREQUENCY),
  168. DECL(ALC_REFRESH),
  169. DECL(ALC_SYNC),
  170. DECL(ALC_MONO_SOURCES),
  171. DECL(ALC_STEREO_SOURCES),
  172. DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
  173. DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
  174. DECL(ALC_CAPTURE_SAMPLES),
  175. DECL(ALC_NO_ERROR),
  176. DECL(ALC_INVALID_DEVICE),
  177. DECL(ALC_INVALID_CONTEXT),
  178. DECL(ALC_INVALID_ENUM),
  179. DECL(ALC_INVALID_VALUE),
  180. DECL(ALC_OUT_OF_MEMORY),
  181. DECL(AL_INVALID),
  182. DECL(AL_NONE),
  183. DECL(AL_FALSE),
  184. DECL(AL_TRUE),
  185. DECL(AL_SOURCE_RELATIVE),
  186. DECL(AL_CONE_INNER_ANGLE),
  187. DECL(AL_CONE_OUTER_ANGLE),
  188. DECL(AL_PITCH),
  189. DECL(AL_POSITION),
  190. DECL(AL_DIRECTION),
  191. DECL(AL_VELOCITY),
  192. DECL(AL_LOOPING),
  193. DECL(AL_BUFFER),
  194. DECL(AL_GAIN),
  195. DECL(AL_MIN_GAIN),
  196. DECL(AL_MAX_GAIN),
  197. DECL(AL_ORIENTATION),
  198. DECL(AL_REFERENCE_DISTANCE),
  199. DECL(AL_ROLLOFF_FACTOR),
  200. DECL(AL_CONE_OUTER_GAIN),
  201. DECL(AL_MAX_DISTANCE),
  202. DECL(AL_SEC_OFFSET),
  203. DECL(AL_SAMPLE_OFFSET),
  204. DECL(AL_BYTE_OFFSET),
  205. DECL(AL_SOURCE_TYPE),
  206. DECL(AL_STATIC),
  207. DECL(AL_STREAMING),
  208. DECL(AL_UNDETERMINED),
  209. DECL(AL_SOURCE_STATE),
  210. DECL(AL_INITIAL),
  211. DECL(AL_PLAYING),
  212. DECL(AL_PAUSED),
  213. DECL(AL_STOPPED),
  214. DECL(AL_BUFFERS_QUEUED),
  215. DECL(AL_BUFFERS_PROCESSED),
  216. DECL(AL_FORMAT_MONO8),
  217. DECL(AL_FORMAT_MONO16),
  218. DECL(AL_FORMAT_STEREO8),
  219. DECL(AL_FORMAT_STEREO16),
  220. DECL(AL_FREQUENCY),
  221. DECL(AL_BITS),
  222. DECL(AL_CHANNELS),
  223. DECL(AL_SIZE),
  224. DECL(AL_UNUSED),
  225. DECL(AL_PENDING),
  226. DECL(AL_PROCESSED),
  227. DECL(AL_NO_ERROR),
  228. DECL(AL_INVALID_NAME),
  229. DECL(AL_INVALID_ENUM),
  230. DECL(AL_INVALID_VALUE),
  231. DECL(AL_INVALID_OPERATION),
  232. DECL(AL_OUT_OF_MEMORY),
  233. DECL(AL_VENDOR),
  234. DECL(AL_VERSION),
  235. DECL(AL_RENDERER),
  236. DECL(AL_EXTENSIONS),
  237. DECL(AL_DOPPLER_FACTOR),
  238. DECL(AL_DOPPLER_VELOCITY),
  239. DECL(AL_DISTANCE_MODEL),
  240. DECL(AL_SPEED_OF_SOUND),
  241. DECL(AL_INVERSE_DISTANCE),
  242. DECL(AL_INVERSE_DISTANCE_CLAMPED),
  243. DECL(AL_LINEAR_DISTANCE),
  244. DECL(AL_LINEAR_DISTANCE_CLAMPED),
  245. DECL(AL_EXPONENT_DISTANCE),
  246. DECL(AL_EXPONENT_DISTANCE_CLAMPED),
  247. }};
  248. #undef DECL
  249. static const ALCchar alcNoError[] = "No Error";
  250. static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
  251. static const ALCchar alcErrInvalidContext[] = "Invalid Context";
  252. static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
  253. static const ALCchar alcErrInvalidValue[] = "Invalid Value";
  254. static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
  255. static const ALCchar alcExtensionList[] =
  256. "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
  257. "ALC_EXT_thread_local_context";
  258. static const ALCint alcMajorVersion = 1;
  259. static const ALCint alcMinorVersion = 1;
  260. static std::recursive_mutex EnumerationLock;
  261. static std::mutex ContextSwitchLock;
  262. static std::atomic<ALCenum> LastError{ALC_NO_ERROR};
  263. static PtrIntMap DeviceIfaceMap;
  264. static PtrIntMap ContextIfaceMap;
  265. typedef struct EnumeratedList {
  266. std::vector<ALCchar> Names;
  267. std::vector<ALCint> Indicies;
  268. void clear()
  269. {
  270. Names.clear();
  271. Indicies.clear();
  272. }
  273. } EnumeratedList;
  274. static EnumeratedList DevicesList;
  275. static EnumeratedList AllDevicesList;
  276. static EnumeratedList CaptureDevicesList;
  277. static void AppendDeviceList(EnumeratedList *list, const ALCchar *names, ALint idx)
  278. {
  279. const ALCchar *name_end = names;
  280. if(!name_end) return;
  281. ALCsizei count = 0;
  282. while(*name_end)
  283. {
  284. TRACE("Enumerated \"%s\", driver %d\n", name_end, idx);
  285. ++count;
  286. name_end += strlen(name_end)+1;
  287. }
  288. if(names == name_end)
  289. return;
  290. list->Names.reserve(list->Names.size() + (name_end - names) + 1);
  291. list->Names.insert(list->Names.cend(), names, name_end);
  292. list->Indicies.reserve(list->Indicies.size() + count);
  293. list->Indicies.insert(list->Indicies.cend(), count, idx);
  294. }
  295. static ALint GetDriverIndexForName(const EnumeratedList *list, const ALCchar *name)
  296. {
  297. const ALCchar *devnames = list->Names.data();
  298. const ALCint *index = list->Indicies.data();
  299. while(devnames && *devnames)
  300. {
  301. if(strcmp(name, devnames) == 0)
  302. return *index;
  303. devnames += strlen(devnames)+1;
  304. index++;
  305. }
  306. return -1;
  307. }
  308. static void InitCtxFuncs(DriverIface &iface)
  309. {
  310. ALCdevice *device{iface.alcGetContextsDevice(iface.alcGetCurrentContext())};
  311. #define LOAD_PROC(x) do { \
  312. iface.x = reinterpret_cast<decltype(iface.x)>(iface.alGetProcAddress(#x));\
  313. if(!iface.x) \
  314. ERR("Failed to find entry point for %s in %ls\n", #x, \
  315. iface.Name.c_str()); \
  316. } while(0)
  317. if(iface.alcIsExtensionPresent(device, "ALC_EXT_EFX"))
  318. {
  319. LOAD_PROC(alGenFilters);
  320. LOAD_PROC(alDeleteFilters);
  321. LOAD_PROC(alIsFilter);
  322. LOAD_PROC(alFilterf);
  323. LOAD_PROC(alFilterfv);
  324. LOAD_PROC(alFilteri);
  325. LOAD_PROC(alFilteriv);
  326. LOAD_PROC(alGetFilterf);
  327. LOAD_PROC(alGetFilterfv);
  328. LOAD_PROC(alGetFilteri);
  329. LOAD_PROC(alGetFilteriv);
  330. LOAD_PROC(alGenEffects);
  331. LOAD_PROC(alDeleteEffects);
  332. LOAD_PROC(alIsEffect);
  333. LOAD_PROC(alEffectf);
  334. LOAD_PROC(alEffectfv);
  335. LOAD_PROC(alEffecti);
  336. LOAD_PROC(alEffectiv);
  337. LOAD_PROC(alGetEffectf);
  338. LOAD_PROC(alGetEffectfv);
  339. LOAD_PROC(alGetEffecti);
  340. LOAD_PROC(alGetEffectiv);
  341. LOAD_PROC(alGenAuxiliaryEffectSlots);
  342. LOAD_PROC(alDeleteAuxiliaryEffectSlots);
  343. LOAD_PROC(alIsAuxiliaryEffectSlot);
  344. LOAD_PROC(alAuxiliaryEffectSlotf);
  345. LOAD_PROC(alAuxiliaryEffectSlotfv);
  346. LOAD_PROC(alAuxiliaryEffectSloti);
  347. LOAD_PROC(alAuxiliaryEffectSlotiv);
  348. LOAD_PROC(alGetAuxiliaryEffectSlotf);
  349. LOAD_PROC(alGetAuxiliaryEffectSlotfv);
  350. LOAD_PROC(alGetAuxiliaryEffectSloti);
  351. LOAD_PROC(alGetAuxiliaryEffectSlotiv);
  352. }
  353. #undef LOAD_PROC
  354. }
  355. ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename)
  356. {
  357. ALCdevice *device = nullptr;
  358. ALint idx = 0;
  359. /* Prior to the enumeration extension, apps would hardcode these names as a
  360. * quality hint for the wrapper driver. Ignore them since there's no sane
  361. * way to map them.
  362. */
  363. if(devicename && (devicename[0] == '\0' ||
  364. strcmp(devicename, "DirectSound3D") == 0 ||
  365. strcmp(devicename, "DirectSound") == 0 ||
  366. strcmp(devicename, "MMSYSTEM") == 0))
  367. devicename = nullptr;
  368. if(devicename)
  369. {
  370. {
  371. std::lock_guard<std::recursive_mutex> _{EnumerationLock};
  372. if(DevicesList.Names.empty())
  373. (void)alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
  374. idx = GetDriverIndexForName(&DevicesList, devicename);
  375. if(idx < 0)
  376. {
  377. if(AllDevicesList.Names.empty())
  378. (void)alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
  379. idx = GetDriverIndexForName(&AllDevicesList, devicename);
  380. }
  381. }
  382. if(idx < 0)
  383. {
  384. LastError.store(ALC_INVALID_VALUE);
  385. TRACE("Failed to find driver for name \"%s\"\n", devicename);
  386. return nullptr;
  387. }
  388. TRACE("Found driver %d for name \"%s\"\n", idx, devicename);
  389. device = DriverList[idx]->alcOpenDevice(devicename);
  390. }
  391. else
  392. {
  393. for(const auto &drv : DriverList)
  394. {
  395. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  396. || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
  397. {
  398. TRACE("Using default device from driver %d\n", idx);
  399. device = drv->alcOpenDevice(nullptr);
  400. break;
  401. }
  402. ++idx;
  403. }
  404. }
  405. if(device)
  406. {
  407. if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR)
  408. {
  409. DriverList[idx]->alcCloseDevice(device);
  410. device = nullptr;
  411. }
  412. }
  413. return device;
  414. }
  415. ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
  416. {
  417. ALint idx;
  418. if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
  419. {
  420. LastError.store(ALC_INVALID_DEVICE);
  421. return ALC_FALSE;
  422. }
  423. if(!DriverList[idx]->alcCloseDevice(device))
  424. return ALC_FALSE;
  425. DeviceIfaceMap.removeByKey(device);
  426. return ALC_TRUE;
  427. }
  428. ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrlist)
  429. {
  430. ALCcontext *context;
  431. ALint idx;
  432. if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
  433. {
  434. LastError.store(ALC_INVALID_DEVICE);
  435. return nullptr;
  436. }
  437. context = DriverList[idx]->alcCreateContext(device, attrlist);
  438. if(context)
  439. {
  440. if(ContextIfaceMap.insert(context, idx) != ALC_NO_ERROR)
  441. {
  442. DriverList[idx]->alcDestroyContext(context);
  443. context = nullptr;
  444. }
  445. }
  446. return context;
  447. }
  448. ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
  449. {
  450. ALint idx = -1;
  451. std::lock_guard<std::mutex> _{ContextSwitchLock};
  452. if(context)
  453. {
  454. idx = ContextIfaceMap.lookupByKey(context);
  455. if(idx < 0)
  456. {
  457. LastError.store(ALC_INVALID_CONTEXT);
  458. return ALC_FALSE;
  459. }
  460. if(!DriverList[idx]->alcMakeContextCurrent(context))
  461. return ALC_FALSE;
  462. auto do_init = [idx]() { InitCtxFuncs(*DriverList[idx]); };
  463. std::call_once(DriverList[idx]->InitOnceCtx, do_init);
  464. }
  465. /* Unset the context from the old driver if it's different from the new
  466. * current one.
  467. */
  468. if(idx < 0)
  469. {
  470. DriverIface *oldiface = GetThreadDriver();
  471. if(oldiface) oldiface->alcSetThreadContext(nullptr);
  472. oldiface = CurrentCtxDriver.exchange(nullptr);
  473. if(oldiface) oldiface->alcMakeContextCurrent(nullptr);
  474. }
  475. else
  476. {
  477. DriverIface *oldiface = GetThreadDriver();
  478. if(oldiface && oldiface != DriverList[idx].get())
  479. oldiface->alcSetThreadContext(nullptr);
  480. oldiface = CurrentCtxDriver.exchange(DriverList[idx].get());
  481. if(oldiface && oldiface != DriverList[idx].get())
  482. oldiface->alcMakeContextCurrent(nullptr);
  483. }
  484. SetThreadDriver(nullptr);
  485. return ALC_TRUE;
  486. }
  487. ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context)
  488. {
  489. if(context)
  490. {
  491. ALint idx = ContextIfaceMap.lookupByKey(context);
  492. if(idx >= 0)
  493. return DriverList[idx]->alcProcessContext(context);
  494. }
  495. LastError.store(ALC_INVALID_CONTEXT);
  496. }
  497. ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context)
  498. {
  499. if(context)
  500. {
  501. ALint idx = ContextIfaceMap.lookupByKey(context);
  502. if(idx >= 0)
  503. return DriverList[idx]->alcSuspendContext(context);
  504. }
  505. LastError.store(ALC_INVALID_CONTEXT);
  506. }
  507. ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context)
  508. {
  509. ALint idx;
  510. if(!context || (idx=ContextIfaceMap.lookupByKey(context)) < 0)
  511. {
  512. LastError.store(ALC_INVALID_CONTEXT);
  513. return;
  514. }
  515. DriverList[idx]->alcDestroyContext(context);
  516. ContextIfaceMap.removeByKey(context);
  517. }
  518. ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
  519. {
  520. DriverIface *iface = GetThreadDriver();
  521. if(!iface) iface = CurrentCtxDriver.load();
  522. return iface ? iface->alcGetCurrentContext() : nullptr;
  523. }
  524. ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context)
  525. {
  526. if(context)
  527. {
  528. ALint idx = ContextIfaceMap.lookupByKey(context);
  529. if(idx >= 0)
  530. return DriverList[idx]->alcGetContextsDevice(context);
  531. }
  532. LastError.store(ALC_INVALID_CONTEXT);
  533. return nullptr;
  534. }
  535. ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
  536. {
  537. if(device)
  538. {
  539. ALint idx = DeviceIfaceMap.lookupByKey(device);
  540. if(idx < 0) return ALC_INVALID_DEVICE;
  541. return DriverList[idx]->alcGetError(device);
  542. }
  543. return LastError.exchange(ALC_NO_ERROR);
  544. }
  545. ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname)
  546. {
  547. const char *ptr;
  548. size_t len;
  549. if(device)
  550. {
  551. ALint idx = DeviceIfaceMap.lookupByKey(device);
  552. if(idx < 0)
  553. {
  554. LastError.store(ALC_INVALID_DEVICE);
  555. return ALC_FALSE;
  556. }
  557. return DriverList[idx]->alcIsExtensionPresent(device, extname);
  558. }
  559. len = strlen(extname);
  560. ptr = alcExtensionList;
  561. while(ptr && *ptr)
  562. {
  563. if(al::strncasecmp(ptr, extname, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len])))
  564. return ALC_TRUE;
  565. if((ptr=strchr(ptr, ' ')) != nullptr)
  566. {
  567. do {
  568. ++ptr;
  569. } while(isspace(*ptr));
  570. }
  571. }
  572. return ALC_FALSE;
  573. }
  574. ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname)
  575. {
  576. if(device)
  577. {
  578. ALint idx = DeviceIfaceMap.lookupByKey(device);
  579. if(idx < 0)
  580. {
  581. LastError.store(ALC_INVALID_DEVICE);
  582. return nullptr;
  583. }
  584. return DriverList[idx]->alcGetProcAddress(device, funcname);
  585. }
  586. auto iter = std::find_if(alcFunctions.cbegin(), alcFunctions.cend(),
  587. [funcname](const FuncExportEntry &entry) -> bool
  588. { return strcmp(funcname, entry.funcName) == 0; }
  589. );
  590. return (iter != alcFunctions.cend()) ? iter->address : nullptr;
  591. }
  592. ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname)
  593. {
  594. if(device)
  595. {
  596. ALint idx = DeviceIfaceMap.lookupByKey(device);
  597. if(idx < 0)
  598. {
  599. LastError.store(ALC_INVALID_DEVICE);
  600. return 0;
  601. }
  602. return DriverList[idx]->alcGetEnumValue(device, enumname);
  603. }
  604. auto iter = std::find_if(alcEnumerations.cbegin(), alcEnumerations.cend(),
  605. [enumname](const EnumExportEntry &entry) -> bool
  606. { return strcmp(enumname, entry.enumName) == 0; }
  607. );
  608. return (iter != alcEnumerations.cend()) ? iter->value : 0;
  609. }
  610. ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param)
  611. {
  612. if(device)
  613. {
  614. ALint idx = DeviceIfaceMap.lookupByKey(device);
  615. if(idx < 0)
  616. {
  617. LastError.store(ALC_INVALID_DEVICE);
  618. return nullptr;
  619. }
  620. return DriverList[idx]->alcGetString(device, param);
  621. }
  622. switch(param)
  623. {
  624. case ALC_NO_ERROR:
  625. return alcNoError;
  626. case ALC_INVALID_ENUM:
  627. return alcErrInvalidEnum;
  628. case ALC_INVALID_VALUE:
  629. return alcErrInvalidValue;
  630. case ALC_INVALID_DEVICE:
  631. return alcErrInvalidDevice;
  632. case ALC_INVALID_CONTEXT:
  633. return alcErrInvalidContext;
  634. case ALC_OUT_OF_MEMORY:
  635. return alcErrOutOfMemory;
  636. case ALC_EXTENSIONS:
  637. return alcExtensionList;
  638. case ALC_DEVICE_SPECIFIER:
  639. {
  640. std::lock_guard<std::recursive_mutex> _{EnumerationLock};
  641. DevicesList.clear();
  642. ALint idx{0};
  643. for(const auto &drv : DriverList)
  644. {
  645. /* Only enumerate names from drivers that support it. */
  646. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  647. || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
  648. AppendDeviceList(&DevicesList,
  649. drv->alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx);
  650. ++idx;
  651. }
  652. /* Ensure the list is double-null termianted. */
  653. if(DevicesList.Names.empty())
  654. DevicesList.Names.emplace_back('\0');
  655. DevicesList.Names.emplace_back('\0');
  656. return DevicesList.Names.data();
  657. }
  658. case ALC_ALL_DEVICES_SPECIFIER:
  659. {
  660. std::lock_guard<std::recursive_mutex> _{EnumerationLock};
  661. AllDevicesList.clear();
  662. ALint idx{0};
  663. for(const auto &drv : DriverList)
  664. {
  665. /* If the driver doesn't support ALC_ENUMERATE_ALL_EXT, substitute
  666. * standard enumeration.
  667. */
  668. if(drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
  669. AppendDeviceList(&AllDevicesList,
  670. drv->alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER), idx);
  671. else if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  672. || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
  673. AppendDeviceList(&AllDevicesList,
  674. drv->alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx);
  675. ++idx;
  676. }
  677. /* Ensure the list is double-null termianted. */
  678. if(AllDevicesList.Names.empty())
  679. AllDevicesList.Names.emplace_back('\0');
  680. AllDevicesList.Names.emplace_back('\0');
  681. return AllDevicesList.Names.data();
  682. }
  683. case ALC_CAPTURE_DEVICE_SPECIFIER:
  684. {
  685. std::lock_guard<std::recursive_mutex> _{EnumerationLock};
  686. CaptureDevicesList.clear();
  687. ALint idx{0};
  688. for(const auto &drv : DriverList)
  689. {
  690. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  691. || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
  692. AppendDeviceList(&CaptureDevicesList,
  693. drv->alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER), idx);
  694. ++idx;
  695. }
  696. /* Ensure the list is double-null termianted. */
  697. if(CaptureDevicesList.Names.empty())
  698. CaptureDevicesList.Names.emplace_back('\0');
  699. CaptureDevicesList.Names.emplace_back('\0');
  700. return CaptureDevicesList.Names.data();
  701. }
  702. case ALC_DEFAULT_DEVICE_SPECIFIER:
  703. {
  704. for(const auto &drv : DriverList)
  705. {
  706. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  707. || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
  708. return drv->alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
  709. }
  710. return "";
  711. }
  712. case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
  713. {
  714. for(const auto &drv : DriverList)
  715. {
  716. if(drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") != ALC_FALSE)
  717. return drv->alcGetString(nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
  718. }
  719. return "";
  720. }
  721. case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
  722. {
  723. for(const auto &drv : DriverList)
  724. {
  725. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  726. || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
  727. return drv->alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
  728. }
  729. return "";
  730. }
  731. default:
  732. LastError.store(ALC_INVALID_ENUM);
  733. break;
  734. }
  735. return nullptr;
  736. }
  737. ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
  738. {
  739. if(device)
  740. {
  741. ALint idx = DeviceIfaceMap.lookupByKey(device);
  742. if(idx < 0)
  743. {
  744. LastError.store(ALC_INVALID_DEVICE);
  745. return;
  746. }
  747. return DriverList[idx]->alcGetIntegerv(device, param, size, values);
  748. }
  749. if(size <= 0 || values == nullptr)
  750. {
  751. LastError.store(ALC_INVALID_VALUE);
  752. return;
  753. }
  754. switch(param)
  755. {
  756. case ALC_MAJOR_VERSION:
  757. if(size >= 1)
  758. {
  759. values[0] = alcMajorVersion;
  760. return;
  761. }
  762. /*fall-through*/
  763. case ALC_MINOR_VERSION:
  764. if(size >= 1)
  765. {
  766. values[0] = alcMinorVersion;
  767. return;
  768. }
  769. LastError.store(ALC_INVALID_VALUE);
  770. return;
  771. case ALC_ATTRIBUTES_SIZE:
  772. case ALC_ALL_ATTRIBUTES:
  773. case ALC_FREQUENCY:
  774. case ALC_REFRESH:
  775. case ALC_SYNC:
  776. case ALC_MONO_SOURCES:
  777. case ALC_STEREO_SOURCES:
  778. case ALC_CAPTURE_SAMPLES:
  779. LastError.store(ALC_INVALID_DEVICE);
  780. return;
  781. default:
  782. LastError.store(ALC_INVALID_ENUM);
  783. return;
  784. }
  785. }
  786. ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize)
  787. {
  788. ALCdevice *device = nullptr;
  789. ALint idx = 0;
  790. if(devicename && devicename[0] == '\0')
  791. devicename = nullptr;
  792. if(devicename)
  793. {
  794. {
  795. std::lock_guard<std::recursive_mutex> _{EnumerationLock};
  796. if(CaptureDevicesList.Names.empty())
  797. (void)alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER);
  798. idx = GetDriverIndexForName(&CaptureDevicesList, devicename);
  799. }
  800. if(idx < 0)
  801. {
  802. LastError.store(ALC_INVALID_VALUE);
  803. TRACE("Failed to find driver for name \"%s\"\n", devicename);
  804. return nullptr;
  805. }
  806. TRACE("Found driver %d for name \"%s\"\n", idx, devicename);
  807. device = DriverList[idx]->alcCaptureOpenDevice(devicename, frequency, format, buffersize);
  808. }
  809. else
  810. {
  811. for(const auto &drv : DriverList)
  812. {
  813. if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
  814. || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
  815. {
  816. TRACE("Using default capture device from driver %d\n", idx);
  817. device = drv->alcCaptureOpenDevice(nullptr, frequency, format, buffersize);
  818. break;
  819. }
  820. ++idx;
  821. }
  822. }
  823. if(device)
  824. {
  825. if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR)
  826. {
  827. DriverList[idx]->alcCaptureCloseDevice(device);
  828. device = nullptr;
  829. }
  830. }
  831. return device;
  832. }
  833. ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
  834. {
  835. ALint idx;
  836. if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
  837. {
  838. LastError.store(ALC_INVALID_DEVICE);
  839. return ALC_FALSE;
  840. }
  841. if(!DriverList[idx]->alcCaptureCloseDevice(device))
  842. return ALC_FALSE;
  843. DeviceIfaceMap.removeByKey(device);
  844. return ALC_TRUE;
  845. }
  846. ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
  847. {
  848. if(device)
  849. {
  850. ALint idx = DeviceIfaceMap.lookupByKey(device);
  851. if(idx >= 0)
  852. return DriverList[idx]->alcCaptureStart(device);
  853. }
  854. LastError.store(ALC_INVALID_DEVICE);
  855. }
  856. ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
  857. {
  858. if(device)
  859. {
  860. ALint idx = DeviceIfaceMap.lookupByKey(device);
  861. if(idx >= 0)
  862. return DriverList[idx]->alcCaptureStop(device);
  863. }
  864. LastError.store(ALC_INVALID_DEVICE);
  865. }
  866. ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
  867. {
  868. if(device)
  869. {
  870. ALint idx = DeviceIfaceMap.lookupByKey(device);
  871. if(idx >= 0)
  872. return DriverList[idx]->alcCaptureSamples(device, buffer, samples);
  873. }
  874. LastError.store(ALC_INVALID_DEVICE);
  875. }
  876. ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
  877. {
  878. ALCenum err = ALC_INVALID_CONTEXT;
  879. ALint idx;
  880. if(!context)
  881. {
  882. DriverIface *oldiface = GetThreadDriver();
  883. if(oldiface && !oldiface->alcSetThreadContext(nullptr))
  884. return ALC_FALSE;
  885. SetThreadDriver(nullptr);
  886. return ALC_TRUE;
  887. }
  888. idx = ContextIfaceMap.lookupByKey(context);
  889. if(idx >= 0)
  890. {
  891. if(DriverList[idx]->alcSetThreadContext(context))
  892. {
  893. auto do_init = [idx]() { InitCtxFuncs(*DriverList[idx]); };
  894. std::call_once(DriverList[idx]->InitOnceCtx, do_init);
  895. DriverIface *oldiface = GetThreadDriver();
  896. if(oldiface != DriverList[idx].get())
  897. {
  898. SetThreadDriver(DriverList[idx].get());
  899. if(oldiface) oldiface->alcSetThreadContext(nullptr);
  900. }
  901. return ALC_TRUE;
  902. }
  903. err = DriverList[idx]->alcGetError(nullptr);
  904. }
  905. LastError.store(err);
  906. return ALC_FALSE;
  907. }
  908. ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
  909. {
  910. DriverIface *iface = GetThreadDriver();
  911. if(iface) return iface->alcGetThreadContext();
  912. return nullptr;
  913. }