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

563 lines
16 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 "backends/jack.h"
  22. #include <cstdlib>
  23. #include <cstdio>
  24. #include <memory.h>
  25. #include <thread>
  26. #include <functional>
  27. #include "alMain.h"
  28. #include "alu.h"
  29. #include "alconfig.h"
  30. #include "ringbuffer.h"
  31. #include "threads.h"
  32. #include "compat.h"
  33. #include <jack/jack.h>
  34. #include <jack/ringbuffer.h>
  35. namespace {
  36. constexpr ALCchar jackDevice[] = "JACK Default";
  37. #ifdef HAVE_DYNLOAD
  38. #define JACK_FUNCS(MAGIC) \
  39. MAGIC(jack_client_open); \
  40. MAGIC(jack_client_close); \
  41. MAGIC(jack_client_name_size); \
  42. MAGIC(jack_get_client_name); \
  43. MAGIC(jack_connect); \
  44. MAGIC(jack_activate); \
  45. MAGIC(jack_deactivate); \
  46. MAGIC(jack_port_register); \
  47. MAGIC(jack_port_unregister); \
  48. MAGIC(jack_port_get_buffer); \
  49. MAGIC(jack_port_name); \
  50. MAGIC(jack_get_ports); \
  51. MAGIC(jack_free); \
  52. MAGIC(jack_get_sample_rate); \
  53. MAGIC(jack_set_error_function); \
  54. MAGIC(jack_set_process_callback); \
  55. MAGIC(jack_set_buffer_size_callback); \
  56. MAGIC(jack_set_buffer_size); \
  57. MAGIC(jack_get_buffer_size);
  58. void *jack_handle;
  59. #define MAKE_FUNC(f) decltype(f) * p##f
  60. JACK_FUNCS(MAKE_FUNC);
  61. decltype(jack_error_callback) * pjack_error_callback;
  62. #undef MAKE_FUNC
  63. #ifndef IN_IDE_PARSER
  64. #define jack_client_open pjack_client_open
  65. #define jack_client_close pjack_client_close
  66. #define jack_client_name_size pjack_client_name_size
  67. #define jack_get_client_name pjack_get_client_name
  68. #define jack_connect pjack_connect
  69. #define jack_activate pjack_activate
  70. #define jack_deactivate pjack_deactivate
  71. #define jack_port_register pjack_port_register
  72. #define jack_port_unregister pjack_port_unregister
  73. #define jack_port_get_buffer pjack_port_get_buffer
  74. #define jack_port_name pjack_port_name
  75. #define jack_get_ports pjack_get_ports
  76. #define jack_free pjack_free
  77. #define jack_get_sample_rate pjack_get_sample_rate
  78. #define jack_set_error_function pjack_set_error_function
  79. #define jack_set_process_callback pjack_set_process_callback
  80. #define jack_set_buffer_size_callback pjack_set_buffer_size_callback
  81. #define jack_set_buffer_size pjack_set_buffer_size
  82. #define jack_get_buffer_size pjack_get_buffer_size
  83. #define jack_error_callback (*pjack_error_callback)
  84. #endif
  85. #endif
  86. jack_options_t ClientOptions = JackNullOption;
  87. ALCboolean jack_load()
  88. {
  89. ALCboolean error = ALC_FALSE;
  90. #ifdef HAVE_DYNLOAD
  91. if(!jack_handle)
  92. {
  93. std::string missing_funcs;
  94. #ifdef _WIN32
  95. #define JACKLIB "libjack.dll"
  96. #else
  97. #define JACKLIB "libjack.so.0"
  98. #endif
  99. jack_handle = LoadLib(JACKLIB);
  100. if(!jack_handle)
  101. {
  102. WARN("Failed to load %s\n", JACKLIB);
  103. return ALC_FALSE;
  104. }
  105. error = ALC_FALSE;
  106. #define LOAD_FUNC(f) do { \
  107. p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f)); \
  108. if(p##f == nullptr) { \
  109. error = ALC_TRUE; \
  110. missing_funcs += "\n" #f; \
  111. } \
  112. } while(0)
  113. JACK_FUNCS(LOAD_FUNC);
  114. #undef LOAD_FUNC
  115. /* Optional symbols. These don't exist in all versions of JACK. */
  116. #define LOAD_SYM(f) p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f))
  117. LOAD_SYM(jack_error_callback);
  118. #undef LOAD_SYM
  119. if(error)
  120. {
  121. WARN("Missing expected functions:%s\n", missing_funcs.c_str());
  122. CloseLib(jack_handle);
  123. jack_handle = nullptr;
  124. }
  125. }
  126. #endif
  127. return !error;
  128. }
  129. struct JackPlayback final : public BackendBase {
  130. JackPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
  131. ~JackPlayback() override;
  132. static int bufferSizeNotifyC(jack_nframes_t numframes, void *arg);
  133. int bufferSizeNotify(jack_nframes_t numframes);
  134. static int processC(jack_nframes_t numframes, void *arg);
  135. int process(jack_nframes_t numframes);
  136. int mixerProc();
  137. ALCenum open(const ALCchar *name) override;
  138. ALCboolean reset() override;
  139. ALCboolean start() override;
  140. void stop() override;
  141. ClockLatency getClockLatency() override;
  142. jack_client_t *mClient{nullptr};
  143. jack_port_t *mPort[MAX_OUTPUT_CHANNELS]{};
  144. RingBufferPtr mRing;
  145. al::semaphore mSem;
  146. std::atomic<bool> mKillNow{true};
  147. std::thread mThread;
  148. static constexpr inline const char *CurrentPrefix() noexcept { return "JackPlayback::"; }
  149. DEF_NEWDEL(JackPlayback)
  150. };
  151. JackPlayback::~JackPlayback()
  152. {
  153. if(!mClient)
  154. return;
  155. std::for_each(std::begin(mPort), std::end(mPort),
  156. [this](jack_port_t *port) -> void
  157. { if(port) jack_port_unregister(mClient, port); }
  158. );
  159. std::fill(std::begin(mPort), std::end(mPort), nullptr);
  160. jack_client_close(mClient);
  161. mClient = nullptr;
  162. }
  163. int JackPlayback::bufferSizeNotifyC(jack_nframes_t numframes, void *arg)
  164. { return static_cast<JackPlayback*>(arg)->bufferSizeNotify(numframes); }
  165. int JackPlayback::bufferSizeNotify(jack_nframes_t numframes)
  166. {
  167. std::lock_guard<std::mutex> _{mDevice->StateLock};
  168. mDevice->UpdateSize = numframes;
  169. mDevice->BufferSize = numframes*2;
  170. ALuint bufsize{mDevice->UpdateSize};
  171. if(ConfigValueUInt(mDevice->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
  172. bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
  173. mDevice->BufferSize = bufsize + mDevice->UpdateSize;
  174. TRACE("%u / %u buffer\n", mDevice->UpdateSize, mDevice->BufferSize);
  175. mRing = nullptr;
  176. mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
  177. if(!mRing)
  178. {
  179. ERR("Failed to reallocate ringbuffer\n");
  180. aluHandleDisconnect(mDevice, "Failed to reallocate %u-sample buffer", bufsize);
  181. }
  182. return 0;
  183. }
  184. int JackPlayback::processC(jack_nframes_t numframes, void *arg)
  185. { return static_cast<JackPlayback*>(arg)->process(numframes); }
  186. int JackPlayback::process(jack_nframes_t numframes)
  187. {
  188. jack_default_audio_sample_t *out[MAX_OUTPUT_CHANNELS];
  189. ALsizei numchans{0};
  190. for(auto port : mPort)
  191. {
  192. if(!port) break;
  193. out[numchans++] = static_cast<float*>(jack_port_get_buffer(port, numframes));
  194. }
  195. auto data = mRing->getReadVector();
  196. jack_nframes_t todo{minu(numframes, data.first.len)};
  197. std::transform(out, out+numchans, out,
  198. [&data,numchans,todo](ALfloat *outbuf) -> ALfloat*
  199. {
  200. const ALfloat *RESTRICT in = reinterpret_cast<ALfloat*>(data.first.buf);
  201. std::generate_n(outbuf, todo,
  202. [&in,numchans]() noexcept -> ALfloat
  203. {
  204. ALfloat ret{*in};
  205. in += numchans;
  206. return ret;
  207. }
  208. );
  209. data.first.buf += sizeof(ALfloat);
  210. return outbuf + todo;
  211. }
  212. );
  213. jack_nframes_t total{todo};
  214. todo = minu(numframes-total, data.second.len);
  215. if(todo > 0)
  216. {
  217. std::transform(out, out+numchans, out,
  218. [&data,numchans,todo](ALfloat *outbuf) -> ALfloat*
  219. {
  220. const ALfloat *RESTRICT in = reinterpret_cast<ALfloat*>(data.second.buf);
  221. std::generate_n(outbuf, todo,
  222. [&in,numchans]() noexcept -> ALfloat
  223. {
  224. ALfloat ret{*in};
  225. in += numchans;
  226. return ret;
  227. }
  228. );
  229. data.second.buf += sizeof(ALfloat);
  230. return outbuf + todo;
  231. }
  232. );
  233. total += todo;
  234. }
  235. mRing->readAdvance(total);
  236. mSem.post();
  237. if(numframes > total)
  238. {
  239. todo = numframes-total;
  240. std::transform(out, out+numchans, out,
  241. [todo](ALfloat *outbuf) -> ALfloat*
  242. {
  243. std::fill_n(outbuf, todo, 0.0f);
  244. return outbuf + todo;
  245. }
  246. );
  247. }
  248. return 0;
  249. }
  250. int JackPlayback::mixerProc()
  251. {
  252. SetRTPriority();
  253. althrd_setname(MIXER_THREAD_NAME);
  254. lock();
  255. while(!mKillNow.load(std::memory_order_acquire) &&
  256. mDevice->Connected.load(std::memory_order_acquire))
  257. {
  258. if(mRing->writeSpace() < mDevice->UpdateSize)
  259. {
  260. unlock();
  261. mSem.wait();
  262. lock();
  263. continue;
  264. }
  265. auto data = mRing->getWriteVector();
  266. auto todo = static_cast<ALuint>(data.first.len + data.second.len);
  267. todo -= todo%mDevice->UpdateSize;
  268. ALuint len1{minu(data.first.len, todo)};
  269. ALuint len2{minu(data.second.len, todo-len1)};
  270. aluMixData(mDevice, data.first.buf, len1);
  271. if(len2 > 0)
  272. aluMixData(mDevice, data.second.buf, len2);
  273. mRing->writeAdvance(todo);
  274. }
  275. unlock();
  276. return 0;
  277. }
  278. ALCenum JackPlayback::open(const ALCchar *name)
  279. {
  280. if(!name)
  281. name = jackDevice;
  282. else if(strcmp(name, jackDevice) != 0)
  283. return ALC_INVALID_VALUE;
  284. const char *client_name{"alsoft"};
  285. jack_status_t status;
  286. mClient = jack_client_open(client_name, ClientOptions, &status, nullptr);
  287. if(mClient == nullptr)
  288. {
  289. ERR("jack_client_open() failed, status = 0x%02x\n", status);
  290. return ALC_INVALID_VALUE;
  291. }
  292. if((status&JackServerStarted))
  293. TRACE("JACK server started\n");
  294. if((status&JackNameNotUnique))
  295. {
  296. client_name = jack_get_client_name(mClient);
  297. TRACE("Client name not unique, got `%s' instead\n", client_name);
  298. }
  299. jack_set_process_callback(mClient, &JackPlayback::processC, this);
  300. jack_set_buffer_size_callback(mClient, &JackPlayback::bufferSizeNotifyC, this);
  301. mDevice->DeviceName = name;
  302. return ALC_NO_ERROR;
  303. }
  304. ALCboolean JackPlayback::reset()
  305. {
  306. std::for_each(std::begin(mPort), std::end(mPort),
  307. [this](jack_port_t *port) -> void
  308. { if(port) jack_port_unregister(mClient, port); }
  309. );
  310. std::fill(std::begin(mPort), std::end(mPort), nullptr);
  311. /* Ignore the requested buffer metrics and just keep one JACK-sized buffer
  312. * ready for when requested.
  313. */
  314. mDevice->Frequency = jack_get_sample_rate(mClient);
  315. mDevice->UpdateSize = jack_get_buffer_size(mClient);
  316. mDevice->BufferSize = mDevice->UpdateSize * 2;
  317. ALuint bufsize{mDevice->UpdateSize};
  318. if(ConfigValueUInt(mDevice->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
  319. bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
  320. mDevice->BufferSize = bufsize + mDevice->UpdateSize;
  321. /* Force 32-bit float output. */
  322. mDevice->FmtType = DevFmtFloat;
  323. ALsizei numchans{mDevice->channelsFromFmt()};
  324. auto ports_end = std::begin(mPort) + numchans;
  325. auto bad_port = std::find_if_not(std::begin(mPort), ports_end,
  326. [this](jack_port_t *&port) -> bool
  327. {
  328. std::string name{"channel_" + std::to_string(&port - mPort + 1)};
  329. port = jack_port_register(mClient, name.c_str(), JACK_DEFAULT_AUDIO_TYPE,
  330. JackPortIsOutput, 0);
  331. return port != nullptr;
  332. }
  333. );
  334. if(bad_port != ports_end)
  335. {
  336. ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(mDevice->FmtChans));
  337. if(bad_port == std::begin(mPort)) return ALC_FALSE;
  338. if(bad_port == std::begin(mPort)+1)
  339. mDevice->FmtChans = DevFmtMono;
  340. else
  341. {
  342. ports_end = mPort+2;
  343. while(bad_port != ports_end)
  344. {
  345. jack_port_unregister(mClient, *(--bad_port));
  346. *bad_port = nullptr;
  347. }
  348. mDevice->FmtChans = DevFmtStereo;
  349. }
  350. numchans = std::distance(std::begin(mPort), bad_port);
  351. }
  352. mRing = nullptr;
  353. mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
  354. if(!mRing)
  355. {
  356. ERR("Failed to allocate ringbuffer\n");
  357. return ALC_FALSE;
  358. }
  359. SetDefaultChannelOrder(mDevice);
  360. return ALC_TRUE;
  361. }
  362. ALCboolean JackPlayback::start()
  363. {
  364. if(jack_activate(mClient))
  365. {
  366. ERR("Failed to activate client\n");
  367. return ALC_FALSE;
  368. }
  369. const char **ports{jack_get_ports(mClient, nullptr, nullptr,
  370. JackPortIsPhysical|JackPortIsInput)};
  371. if(ports == nullptr)
  372. {
  373. ERR("No physical playback ports found\n");
  374. jack_deactivate(mClient);
  375. return ALC_FALSE;
  376. }
  377. std::mismatch(std::begin(mPort), std::end(mPort), ports,
  378. [this](const jack_port_t *port, const char *pname) -> bool
  379. {
  380. if(!port) return false;
  381. if(!pname)
  382. {
  383. ERR("No physical playback port for \"%s\"\n", jack_port_name(port));
  384. return false;
  385. }
  386. if(jack_connect(mClient, jack_port_name(port), pname))
  387. ERR("Failed to connect output port \"%s\" to \"%s\"\n", jack_port_name(port),
  388. pname);
  389. return true;
  390. }
  391. );
  392. jack_free(ports);
  393. try {
  394. mKillNow.store(false, std::memory_order_release);
  395. mThread = std::thread{std::mem_fn(&JackPlayback::mixerProc), this};
  396. return ALC_TRUE;
  397. }
  398. catch(std::exception& e) {
  399. ERR("Could not create playback thread: %s\n", e.what());
  400. }
  401. catch(...) {
  402. }
  403. jack_deactivate(mClient);
  404. return ALC_FALSE;
  405. }
  406. void JackPlayback::stop()
  407. {
  408. if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
  409. return;
  410. mSem.post();
  411. mThread.join();
  412. jack_deactivate(mClient);
  413. }
  414. ClockLatency JackPlayback::getClockLatency()
  415. {
  416. ClockLatency ret;
  417. lock();
  418. ret.ClockTime = GetDeviceClockTime(mDevice);
  419. ret.Latency = std::chrono::seconds{mRing->readSpace()};
  420. ret.Latency /= mDevice->Frequency;
  421. unlock();
  422. return ret;
  423. }
  424. void jack_msg_handler(const char *message)
  425. {
  426. WARN("%s\n", message);
  427. }
  428. } // namespace
  429. bool JackBackendFactory::init()
  430. {
  431. if(!jack_load())
  432. return false;
  433. if(!GetConfigValueBool(nullptr, "jack", "spawn-server", 0))
  434. ClientOptions = static_cast<jack_options_t>(ClientOptions | JackNoStartServer);
  435. void (*old_error_cb)(const char*){&jack_error_callback ? jack_error_callback : nullptr};
  436. jack_set_error_function(jack_msg_handler);
  437. jack_status_t status;
  438. jack_client_t *client{jack_client_open("alsoft", ClientOptions, &status, nullptr)};
  439. jack_set_error_function(old_error_cb);
  440. if(!client)
  441. {
  442. WARN("jack_client_open() failed, 0x%02x\n", status);
  443. if((status&JackServerFailed) && !(ClientOptions&JackNoStartServer))
  444. ERR("Unable to connect to JACK server\n");
  445. return false;
  446. }
  447. jack_client_close(client);
  448. return true;
  449. }
  450. bool JackBackendFactory::querySupport(BackendType type)
  451. { return (type == BackendType::Playback); }
  452. void JackBackendFactory::probe(DevProbe type, std::string *outnames)
  453. {
  454. switch(type)
  455. {
  456. case DevProbe::Playback:
  457. /* Includes null char. */
  458. outnames->append(jackDevice, sizeof(jackDevice));
  459. break;
  460. case DevProbe::Capture:
  461. break;
  462. }
  463. }
  464. BackendPtr JackBackendFactory::createBackend(ALCdevice *device, BackendType type)
  465. {
  466. if(type == BackendType::Playback)
  467. return BackendPtr{new JackPlayback{device}};
  468. return nullptr;
  469. }
  470. BackendFactory &JackBackendFactory::getFactory()
  471. {
  472. static JackBackendFactory factory{};
  473. return factory;
  474. }