jack.cpp 16 KB

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