Audio plugin host https://kx.studio/carla
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.

1530 lines
54KB

  1. /*
  2. * Carla JACK API for external applications
  3. * Copyright (C) 2016-2019 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "libjack.hpp"
  18. #include "CarlaThread.hpp"
  19. #include "CarlaJuceUtils.hpp"
  20. #include <signal.h>
  21. #include <sys/prctl.h>
  22. #include <sys/time.h>
  23. // ---------------------------------------------------------------------------------------------------------------------
  24. CARLA_EXPORT
  25. int jack_carla_interposed_action(uint, uint, void*)
  26. {
  27. static bool printWarning = true;
  28. if (printWarning)
  29. {
  30. printWarning = false;
  31. carla_stderr2("Non-exported jack_carla_interposed_action called, this should not happen!!");
  32. carla_stderr("Printing some info:");
  33. carla_stderr("\tLD_LIBRARY_PATH: '%s'", std::getenv("LD_LIBRARY_PATH"));
  34. carla_stderr("\tLD_PRELOAD: '%s'", std::getenv("LD_PRELOAD"));
  35. std::fflush(stderr);
  36. }
  37. // ::kill(::getpid(), SIGKILL);
  38. return 1337;
  39. }
  40. // ---------------------------------------------------------------------------------------------------------------------
  41. CARLA_BACKEND_START_NAMESPACE
  42. // ---------------------------------------------------------------------------------------------------------------------
  43. static int64_t getCurrentTimeMilliseconds() noexcept
  44. {
  45. struct timeval tv;
  46. gettimeofday (&tv, nullptr);
  47. return ((int64_t) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
  48. }
  49. static int carla_interposed_callback(int, void*);
  50. // ---------------------------------------------------------------------------------------------------------------------
  51. class CarlaJackRealtimeThread : public CarlaThread
  52. {
  53. public:
  54. struct Callback {
  55. Callback() {}
  56. virtual ~Callback() {};
  57. virtual void runRealtimeThread() = 0;
  58. };
  59. CarlaJackRealtimeThread(Callback* const callback)
  60. : CarlaThread("CarlaJackRealtimeThread"),
  61. fCallback(callback) {}
  62. protected:
  63. void run() override
  64. {
  65. fCallback->runRealtimeThread();
  66. }
  67. private:
  68. Callback* const fCallback;
  69. CARLA_DECLARE_NON_COPY_CLASS(CarlaJackRealtimeThread)
  70. };
  71. // --------------------------------------------------------------------------------------------------------------------
  72. class CarlaJackNonRealtimeThread : public CarlaThread
  73. {
  74. public:
  75. struct Callback {
  76. Callback() {}
  77. virtual ~Callback() {};
  78. virtual void runNonRealtimeThread() = 0;
  79. };
  80. CarlaJackNonRealtimeThread(Callback* const callback)
  81. : CarlaThread("CarlaJackNonRealtimeThread"),
  82. fCallback(callback) {}
  83. protected:
  84. void run() override
  85. {
  86. fCallback->runNonRealtimeThread();
  87. }
  88. private:
  89. Callback* const fCallback;
  90. CARLA_DECLARE_NON_COPY_CLASS(CarlaJackNonRealtimeThread)
  91. };
  92. // ---------------------------------------------------------------------------------------------------------------------
  93. class CarlaJackAppClient : public CarlaJackRealtimeThread::Callback,
  94. public CarlaJackNonRealtimeThread::Callback
  95. {
  96. public:
  97. JackServerState fServer;
  98. LinkedList<JackClientState*> fClients;
  99. LinkedList<JackClientState*> fNewClients;
  100. CarlaJackAppClient()
  101. : fServer(this),
  102. fClients(),
  103. fNewClients(),
  104. fShmAudioPool(),
  105. fShmRtClientControl(),
  106. fShmNonRtClientControl(),
  107. fShmNonRtServerControl(),
  108. fAudioPoolCopy(nullptr),
  109. fAudioTmpBuf(nullptr),
  110. fDummyMidiInBuffer(true),
  111. fDummyMidiOutBuffer(false),
  112. fMidiInBuffers(nullptr),
  113. fMidiOutBuffers(nullptr),
  114. fIsOffline(false),
  115. fIsReady(false),
  116. fLastPingTime(-1),
  117. fSessionManager(0),
  118. fSetupHints(0),
  119. fRealtimeThread(this),
  120. fNonRealtimeThread(this),
  121. fRealtimeThreadMutex()
  122. #ifdef DEBUG
  123. ,leakDetector_CarlaJackAppClient()
  124. #endif
  125. {
  126. carla_debug("CarlaJackAppClient::CarlaJackAppClient()");
  127. const char* const shmIds(std::getenv("CARLA_SHM_IDS"));
  128. CARLA_SAFE_ASSERT_INT2_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4, std::strlen(shmIds), 6*4,);
  129. const char* const libjackSetup(std::getenv("CARLA_LIBJACK_SETUP"));
  130. CARLA_SAFE_ASSERT_RETURN(libjackSetup != nullptr && std::strlen(libjackSetup) >= 6,);
  131. // make sure we don't get loaded again
  132. carla_unsetenv("CARLA_SHM_IDS");
  133. // kill ourselves if main carla dies
  134. carla_terminateProcessOnParentExit(true);
  135. for (int i=4; --i >= 0;) {
  136. CARLA_SAFE_ASSERT_RETURN(libjackSetup[i] >= '0' && libjackSetup[i] <= '0'+64,);
  137. }
  138. CARLA_SAFE_ASSERT_RETURN(libjackSetup[4] >= '0' && libjackSetup[4] <= '0' + LIBJACK_SESSION_MANAGER_NSM,);
  139. CARLA_SAFE_ASSERT_RETURN(libjackSetup[5] >= '0' && libjackSetup[5] < '0'+0x4f,);
  140. std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6);
  141. std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6);
  142. std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6);
  143. std::memcpy(fBaseNameNonRtServerControl, shmIds+6*3, 6);
  144. fBaseNameAudioPool[6] = '\0';
  145. fBaseNameRtClientControl[6] = '\0';
  146. fBaseNameNonRtClientControl[6] = '\0';
  147. fBaseNameNonRtServerControl[6] = '\0';
  148. fServer.numAudioIns = static_cast<uint8_t>(libjackSetup[0] - '0');
  149. fServer.numAudioOuts = static_cast<uint8_t>(libjackSetup[1] - '0');
  150. fServer.numMidiIns = static_cast<uint8_t>(libjackSetup[2] - '0');
  151. fServer.numMidiOuts = static_cast<uint8_t>(libjackSetup[3] - '0');
  152. fSessionManager = static_cast<uint>(libjackSetup[4] - '0');
  153. fSetupHints = static_cast<uint>(libjackSetup[5] - '0');
  154. if (fSetupHints & LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN)
  155. fServer.numMidiOuts = 16;
  156. jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_HINTS_AND_CALLBACK,
  157. fSetupHints,
  158. (void*)carla_interposed_callback);
  159. jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_SESSION_MANAGER,
  160. fSessionManager,
  161. nullptr);
  162. fNonRealtimeThread.startThread(false);
  163. }
  164. ~CarlaJackAppClient() noexcept override
  165. {
  166. carla_debug("CarlaJackAppClient::~CarlaJackAppClient()");
  167. fLastPingTime = -1;
  168. fNonRealtimeThread.stopThread(5000);
  169. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  170. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  171. {
  172. JackClientState* const jclient(it.getValue(nullptr));
  173. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  174. delete jclient;
  175. }
  176. fClients.clear();
  177. }
  178. JackClientState* createClient(const char* const name)
  179. {
  180. while (fNonRealtimeThread.isThreadRunning() && ! fIsReady)
  181. carla_sleep(1);
  182. return new JackClientState(fServer, name);
  183. }
  184. void destroyClient(JackClientState* const jclient)
  185. {
  186. {
  187. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  188. fClients.removeOne(jclient);
  189. }
  190. delete jclient;
  191. }
  192. bool activateClient(JackClientState* const jclient)
  193. {
  194. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  195. if (! fClients.append(jclient))
  196. return false;
  197. if (! fNewClients.append(jclient))
  198. {
  199. fClients.removeOne(jclient);
  200. return false;
  201. }
  202. jclient->activated = true;
  203. jclient->deactivated = false;
  204. return true;
  205. }
  206. bool deactivateClient(JackClientState* const jclient)
  207. {
  208. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  209. if (! fClients.removeOne(jclient))
  210. return false;
  211. jclient->activated = false;
  212. jclient->deactivated = true;
  213. return true;
  214. }
  215. const char* getClientNameFromUUID(const jack_uuid_t uuid) const noexcept
  216. {
  217. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  218. {
  219. JackClientState* const jclient(it.getValue(nullptr));
  220. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  221. if (jclient->uuid == uuid)
  222. return jclient->name;
  223. }
  224. return nullptr;
  225. }
  226. jack_uuid_t getUUIDForClientName(const char* const name) const noexcept
  227. {
  228. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  229. {
  230. JackClientState* const jclient(it.getValue(nullptr));
  231. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  232. if (std::strcmp(jclient->name, name) == 0)
  233. return jclient->uuid;
  234. }
  235. return JACK_UUID_EMPTY_INITIALIZER;
  236. }
  237. pthread_t getRealtimeThreadId() const noexcept
  238. {
  239. return (pthread_t)fRealtimeThread.getThreadId();
  240. }
  241. int handleInterposerCallback(const int cb_action, void* const ptr)
  242. {
  243. carla_debug("handleInterposerCallback(%o, %p)", cb_action, ptr);
  244. switch (cb_action)
  245. {
  246. case LIBJACK_INTERPOSER_CALLBACK_UI_HIDE: {
  247. const CarlaMutexLocker cml(fShmNonRtServerControl.mutex);
  248. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
  249. fShmNonRtServerControl.commitWrite();
  250. break;
  251. }
  252. }
  253. return 0;
  254. // maybe unused
  255. (void)ptr;
  256. }
  257. // -------------------------------------------------------------------
  258. protected:
  259. void runRealtimeThread() override;
  260. void runNonRealtimeThread() override;
  261. private:
  262. bool initSharedMemmory();
  263. void clearSharedMemory() noexcept;
  264. bool handleRtData();
  265. bool handleNonRtData();
  266. BridgeAudioPool fShmAudioPool;
  267. BridgeRtClientControl fShmRtClientControl;
  268. BridgeNonRtClientControl fShmNonRtClientControl;
  269. BridgeNonRtServerControl fShmNonRtServerControl;
  270. float* fAudioPoolCopy;
  271. float* fAudioTmpBuf;
  272. JackMidiPortBufferDummy fDummyMidiInBuffer;
  273. JackMidiPortBufferDummy fDummyMidiOutBuffer;
  274. JackMidiPortBufferOnStack* fMidiInBuffers;
  275. JackMidiPortBufferOnStack* fMidiOutBuffers;
  276. char fBaseNameAudioPool[6+1];
  277. char fBaseNameRtClientControl[6+1];
  278. char fBaseNameNonRtClientControl[6+1];
  279. char fBaseNameNonRtServerControl[6+1];
  280. bool fIsOffline;
  281. volatile bool fIsReady;
  282. int64_t fLastPingTime;
  283. uint fSessionManager;
  284. uint fSetupHints;
  285. CarlaJackRealtimeThread fRealtimeThread;
  286. CarlaJackNonRealtimeThread fNonRealtimeThread;
  287. CarlaMutex fRealtimeThreadMutex;
  288. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaJackAppClient)
  289. };
  290. // ---------------------------------------------------------------------------------------------------------------------
  291. bool CarlaJackAppClient::initSharedMemmory()
  292. {
  293. if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
  294. {
  295. carla_stderr("Failed to attach to audio pool shared memory");
  296. return false;
  297. }
  298. if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
  299. {
  300. clearSharedMemory();
  301. carla_stderr("Failed to attach to rt client control shared memory");
  302. return false;
  303. }
  304. if (! fShmRtClientControl.mapData())
  305. {
  306. clearSharedMemory();
  307. carla_stderr("Failed to map rt client control shared memory");
  308. return false;
  309. }
  310. if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
  311. {
  312. clearSharedMemory();
  313. carla_stderr("Failed to attach to non-rt client control shared memory");
  314. return false;
  315. }
  316. if (! fShmNonRtClientControl.mapData())
  317. {
  318. clearSharedMemory();
  319. carla_stderr("Failed to map non-rt control client shared memory");
  320. return false;
  321. }
  322. if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
  323. {
  324. clearSharedMemory();
  325. carla_stderr("Failed to attach to non-rt server control shared memory");
  326. return false;
  327. }
  328. if (! fShmNonRtServerControl.mapData())
  329. {
  330. clearSharedMemory();
  331. carla_stderr("Failed to map non-rt control server shared memory");
  332. return false;
  333. }
  334. PluginBridgeNonRtClientOpcode opcode;
  335. opcode = fShmNonRtClientControl.readOpcode();
  336. CARLA_SAFE_ASSERT_RETURN(opcode == kPluginBridgeNonRtClientVersion, false);
  337. const uint32_t apiVersion = fShmNonRtClientControl.readUInt();
  338. CARLA_SAFE_ASSERT_RETURN(apiVersion == CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT, false);
  339. const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
  340. CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));
  341. const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
  342. CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));
  343. const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
  344. CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));
  345. if (shmRtClientDataSize != sizeof(BridgeRtClientData) ||
  346. shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) ||
  347. shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
  348. {
  349. carla_stderr2("CarlaJackAppClient: data size mismatch");
  350. return false;
  351. }
  352. opcode = fShmNonRtClientControl.readOpcode();
  353. CARLA_SAFE_ASSERT_RETURN(opcode == kPluginBridgeNonRtClientInitialSetup, false);
  354. fServer.bufferSize = fShmNonRtClientControl.readUInt();
  355. fServer.sampleRate = fShmNonRtClientControl.readDouble();
  356. if (fServer.bufferSize == 0 || carla_isZero(fServer.sampleRate))
  357. {
  358. carla_stderr2("CarlaJackAppClient: invalid empty state");
  359. return false;
  360. }
  361. fAudioTmpBuf = new float[fServer.bufferSize];
  362. carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
  363. fLastPingTime = getCurrentTimeMilliseconds();
  364. CARLA_SAFE_ASSERT(fLastPingTime > 0);
  365. {
  366. // tell backend we're live
  367. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  368. // ready!
  369. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
  370. fShmNonRtServerControl.commitWrite();
  371. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  372. }
  373. fIsReady = true;
  374. return true;
  375. }
  376. void CarlaJackAppClient::clearSharedMemory() noexcept
  377. {
  378. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  379. if (fAudioPoolCopy != nullptr)
  380. {
  381. delete[] fAudioPoolCopy;
  382. fAudioPoolCopy = nullptr;
  383. }
  384. if (fAudioTmpBuf != nullptr)
  385. {
  386. delete[] fAudioTmpBuf;
  387. fAudioTmpBuf = nullptr;
  388. }
  389. if (fMidiInBuffers != nullptr)
  390. {
  391. delete[] fMidiInBuffers;
  392. fMidiInBuffers = nullptr;
  393. }
  394. if (fMidiOutBuffers != nullptr)
  395. {
  396. delete[] fMidiOutBuffers;
  397. fMidiOutBuffers = nullptr;
  398. }
  399. fShmAudioPool.clear();
  400. fShmRtClientControl.clear();
  401. fShmNonRtClientControl.clear();
  402. fShmNonRtServerControl.clear();
  403. }
  404. bool CarlaJackAppClient::handleRtData()
  405. {
  406. if (fNewClients.count() != 0)
  407. {
  408. for (LinkedList<JackClientState*>::Itenerator it = fNewClients.begin2(); it.valid(); it.next())
  409. {
  410. JackClientState* const jclient(it.getValue(nullptr));
  411. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  412. if (jclient->threadInitCb != nullptr)
  413. jclient->threadInitCb(jclient->threadInitCbPtr);
  414. }
  415. fNewClients.clear();
  416. }
  417. const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);
  418. if (! helper.ok)
  419. return false;
  420. bool ret = false;
  421. for (; fShmRtClientControl.isDataAvailableForReading();)
  422. {
  423. const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
  424. #ifdef DEBUG
  425. if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
  426. carla_debug("CarlaJackAppClientRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
  427. }
  428. #endif
  429. switch (opcode)
  430. {
  431. case kPluginBridgeRtClientNull:
  432. break;
  433. case kPluginBridgeRtClientSetAudioPool: {
  434. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  435. if (fShmAudioPool.data != nullptr)
  436. {
  437. jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
  438. fShmAudioPool.data = nullptr;
  439. }
  440. if (fAudioPoolCopy != nullptr)
  441. {
  442. delete[] fAudioPoolCopy;
  443. fAudioPoolCopy = nullptr;
  444. }
  445. const uint64_t poolSize(fShmRtClientControl.readULong());
  446. CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
  447. fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
  448. fAudioPoolCopy = new float[poolSize];
  449. break;
  450. }
  451. case kPluginBridgeRtClientSetBufferSize:
  452. if (const uint32_t newBufferSize = fShmRtClientControl.readUInt())
  453. {
  454. if (fServer.bufferSize != newBufferSize)
  455. {
  456. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  457. fServer.bufferSize = newBufferSize;
  458. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  459. {
  460. JackClientState* const jclient(it.getValue(nullptr));
  461. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  462. if (jclient->bufferSizeCb != nullptr)
  463. jclient->bufferSizeCb(fServer.bufferSize, jclient->bufferSizeCbPtr);
  464. }
  465. delete[] fAudioTmpBuf;
  466. fAudioTmpBuf = new float[fServer.bufferSize];
  467. carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
  468. }
  469. }
  470. break;
  471. case kPluginBridgeRtClientSetSampleRate: {
  472. const double newSampleRate = fShmRtClientControl.readDouble();
  473. if (carla_isNotZero(newSampleRate) && carla_isNotEqual(fServer.sampleRate, newSampleRate))
  474. {
  475. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  476. fServer.sampleRate = newSampleRate;
  477. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  478. {
  479. JackClientState* const jclient(it.getValue(nullptr));
  480. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  481. if (jclient->sampleRateCb != nullptr)
  482. jclient->sampleRateCb(static_cast<uint32_t>(fServer.sampleRate), jclient->sampleRateCbPtr);
  483. }
  484. }
  485. } break;
  486. case kPluginBridgeRtClientSetOnline: {
  487. const bool offline = fShmRtClientControl.readBool();
  488. if (fIsOffline != offline)
  489. {
  490. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  491. fIsOffline = offline;
  492. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  493. {
  494. JackClientState* const jclient(it.getValue(nullptr));
  495. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  496. if (jclient->freewheelCb != nullptr)
  497. jclient->freewheelCb(offline ? 1 : 0, jclient->freewheelCbPtr);
  498. }
  499. }
  500. } break;
  501. case kPluginBridgeRtClientControlEventParameter:
  502. case kPluginBridgeRtClientControlEventMidiBank:
  503. case kPluginBridgeRtClientControlEventMidiProgram:
  504. case kPluginBridgeRtClientControlEventAllSoundOff:
  505. case kPluginBridgeRtClientControlEventAllNotesOff:
  506. break;
  507. case kPluginBridgeRtClientMidiEvent: {
  508. const uint32_t time(fShmRtClientControl.readUInt());
  509. const uint8_t port(fShmRtClientControl.readByte());
  510. const uint8_t size(fShmRtClientControl.readByte());
  511. CARLA_SAFE_ASSERT_BREAK(size > 0);
  512. if (port >= fServer.numMidiIns || size > JackMidiPortBufferBase::kMaxEventSize || ! fRealtimeThreadMutex.tryLock())
  513. {
  514. for (uint8_t i=0; i<size; ++i)
  515. fShmRtClientControl.readByte();
  516. break;
  517. }
  518. JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[port]);
  519. if (midiPortBuf.count < JackMidiPortBufferBase::kMaxEventCount &&
  520. midiPortBuf.bufferPoolPos + size < JackMidiPortBufferBase::kBufferPoolSize)
  521. {
  522. jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
  523. ev.time = time;
  524. ev.size = size;
  525. ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
  526. midiPortBuf.bufferPoolPos += size;
  527. for (uint8_t i=0; i<size; ++i)
  528. ev.buffer[i] = fShmRtClientControl.readByte();
  529. }
  530. fRealtimeThreadMutex.unlock(true);
  531. break;
  532. }
  533. case kPluginBridgeRtClientProcess: {
  534. const uint32_t frames(fShmRtClientControl.readUInt());
  535. CARLA_SAFE_ASSERT_UINT2_BREAK(frames == fServer.bufferSize, frames, fServer.bufferSize);
  536. // TODO tell client of xrun in case buffersize does not match
  537. const CarlaMutexTryLocker cmtl(fRealtimeThreadMutex, fIsOffline);
  538. if (cmtl.wasLocked())
  539. {
  540. CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);
  541. // mixdown is default, do buffer addition (for multiple clients) if requested
  542. const bool doBufferAddition = fSetupHints & LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION;
  543. // mixdown midi outputs based on channel if requested
  544. const bool doMidiChanMixdown = fSetupHints & LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN;
  545. // location to start of audio outputs (shm buffer)
  546. float* const fdataRealOuts = fShmAudioPool.data+(fServer.bufferSize*fServer.numAudioIns);
  547. if (doBufferAddition && fServer.numAudioOuts > 0)
  548. carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
  549. if (! fClients.isEmpty())
  550. {
  551. // save transport for all clients
  552. const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
  553. const bool transportChanged = fServer.playing != bridgeTimeInfo.playing ||
  554. (bridgeTimeInfo.playing && fServer.position.frame + frames != bridgeTimeInfo.frame);
  555. fServer.playing = bridgeTimeInfo.playing;
  556. fServer.position.frame = static_cast<jack_nframes_t>(bridgeTimeInfo.frame);
  557. fServer.position.usecs = bridgeTimeInfo.usecs;
  558. fServer.position.frame_rate = static_cast<jack_nframes_t>(fServer.sampleRate);
  559. if (bridgeTimeInfo.validFlags & kPluginBridgeTimeInfoValidBBT)
  560. {
  561. fServer.position.valid = JackPositionBBT;
  562. fServer.position.bar = bridgeTimeInfo.bar;
  563. fServer.position.beat = bridgeTimeInfo.beat;
  564. fServer.position.tick = static_cast<int32_t>(bridgeTimeInfo.tick + 0.5);
  565. fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
  566. fServer.position.beat_type = bridgeTimeInfo.beatType;
  567. fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
  568. fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
  569. fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
  570. }
  571. else
  572. {
  573. fServer.position.valid = static_cast<jack_position_bits_t>(0x0);
  574. }
  575. int numClientOutputsProcessed = 0;
  576. // now go through each client
  577. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  578. {
  579. JackClientState* const jclient(it.getValue(nullptr));
  580. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  581. const CarlaMutexTryLocker cmtl2(jclient->mutex, fIsOffline);
  582. // check if we can process
  583. if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
  584. {
  585. if (fServer.numAudioOuts > 0)
  586. carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
  587. if (jclient->deactivated)
  588. fShmRtClientControl.data->procFlags = 1;
  589. }
  590. else
  591. {
  592. // report transport sync changes if needed
  593. if (transportChanged && jclient->syncCb != nullptr)
  594. {
  595. jclient->syncCb(fServer.playing ? JackTransportRolling : JackTransportStopped,
  596. &fServer.position,
  597. jclient->syncCbPtr);
  598. }
  599. uint8_t i;
  600. // direct access to shm buffer, used only for inputs
  601. float* fdataReal = fShmAudioPool.data;
  602. // safe temp location for output, mixed down to shm buffer later on
  603. float* fdataCopy = fAudioPoolCopy;
  604. // wherever we're using fAudioTmpBuf
  605. bool needsTmpBufClear = false;
  606. // set audio inputs
  607. i = 0;
  608. for (LinkedList<JackPortState*>::Itenerator it2 = jclient->audioIns.begin2(); it2.valid(); it2.next())
  609. {
  610. JackPortState* const jport = it2.getValue(nullptr);
  611. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  612. if (i++ < fServer.numAudioIns)
  613. {
  614. if (numClientOutputsProcessed == 0 || ! doBufferAddition)
  615. jport->buffer = fdataReal;
  616. else
  617. jport->buffer = fdataRealOuts + (i*fServer.bufferSize);
  618. fdataReal += fServer.bufferSize;
  619. fdataCopy += fServer.bufferSize;
  620. }
  621. else
  622. {
  623. jport->buffer = fAudioTmpBuf;
  624. needsTmpBufClear = true;
  625. }
  626. }
  627. if (i < fServer.numAudioIns)
  628. {
  629. const std::size_t remainingBufferSize = fServer.bufferSize * static_cast<uint8_t>(fServer.numAudioIns - i);
  630. //fdataReal += remainingBufferSize;
  631. fdataCopy += remainingBufferSize;
  632. }
  633. // location to start of audio outputs
  634. float* const fdataCopyOuts = fdataCopy;
  635. // set audio outputs
  636. i = 0;
  637. for (LinkedList<JackPortState*>::Itenerator it2 = jclient->audioOuts.begin2(); it2.valid(); it2.next())
  638. {
  639. JackPortState* const jport = it2.getValue(nullptr);
  640. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  641. if (i++ < fServer.numAudioOuts)
  642. {
  643. jport->buffer = fdataCopy;
  644. fdataCopy += fServer.bufferSize;
  645. }
  646. else
  647. {
  648. jport->buffer = fAudioTmpBuf;
  649. needsTmpBufClear = true;
  650. }
  651. }
  652. if (i < fServer.numAudioOuts)
  653. {
  654. const std::size_t remainingBufferSize = fServer.bufferSize * static_cast<uint8_t>(fServer.numAudioOuts - i);
  655. carla_zeroFloats(fdataCopy, remainingBufferSize);
  656. //fdataCopy += remainingBufferSize;
  657. }
  658. // set midi inputs
  659. i = 0;
  660. for (LinkedList<JackPortState*>::Itenerator it2 = jclient->midiIns.begin2(); it2.valid(); it2.next())
  661. {
  662. JackPortState* const jport = it2.getValue(nullptr);
  663. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  664. if (i++ < fServer.numMidiIns)
  665. jport->buffer = &fMidiInBuffers[i-1];
  666. else
  667. jport->buffer = &fDummyMidiInBuffer;
  668. }
  669. // set midi outputs
  670. i = 0;
  671. for (LinkedList<JackPortState*>::Itenerator it2 = jclient->midiOuts.begin2(); it2.valid(); it2.next())
  672. {
  673. JackPortState* const jport = it2.getValue(nullptr);
  674. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  675. if (i++ < fServer.numMidiOuts)
  676. jport->buffer = &fMidiOutBuffers[i-1];
  677. else
  678. jport->buffer = &fDummyMidiOutBuffer;
  679. }
  680. if (needsTmpBufClear)
  681. carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
  682. jclient->processCb(fServer.bufferSize, jclient->processCbPtr);
  683. if (fServer.numAudioOuts > 0)
  684. {
  685. if (++numClientOutputsProcessed == 1)
  686. {
  687. // first client, we can copy stuff over
  688. carla_copyFloats(fdataRealOuts, fdataCopyOuts,
  689. fServer.bufferSize*fServer.numAudioOuts);
  690. }
  691. else
  692. {
  693. // subsequent clients, add data (then divide by number of clients later on)
  694. carla_add(fdataRealOuts, fdataCopyOuts,
  695. fServer.bufferSize*fServer.numAudioOuts);
  696. if (doBufferAddition)
  697. {
  698. // for more than 1 client addition, we need to divide buffers now
  699. carla_multiply(fdataRealOuts,
  700. 1.0f/static_cast<float>(numClientOutputsProcessed),
  701. fServer.bufferSize*fServer.numAudioOuts);
  702. }
  703. }
  704. if (jclient->audioOuts.count() == 1 && fServer.numAudioOuts > 1)
  705. {
  706. for (uint8_t j=1; j<fServer.numAudioOuts; ++j)
  707. {
  708. carla_copyFloats(fdataRealOuts+(fServer.bufferSize*j),
  709. fdataCopyOuts,
  710. fServer.bufferSize);
  711. }
  712. }
  713. }
  714. }
  715. }
  716. if (numClientOutputsProcessed > 1 && ! doBufferAddition)
  717. {
  718. // more than 1 client active, need to divide buffers
  719. carla_multiply(fdataRealOuts,
  720. 1.0f/static_cast<float>(numClientOutputsProcessed),
  721. fServer.bufferSize*fServer.numAudioOuts);
  722. }
  723. }
  724. // fClients.isEmpty()
  725. else if (fServer.numAudioOuts > 0)
  726. {
  727. carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
  728. }
  729. for (uint8_t i=0; i<fServer.numMidiIns; ++i)
  730. {
  731. fMidiInBuffers[i].count = 0;
  732. fMidiInBuffers[i].bufferPoolPos = 0;
  733. }
  734. if (fServer.numMidiOuts > 0)
  735. {
  736. uint8_t* midiData = fShmRtClientControl.data->midiOut;
  737. carla_zeroBytes(midiData, kBridgeBaseMidiOutHeaderSize);
  738. std::size_t curMidiDataPos = 0;
  739. for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
  740. {
  741. JackMidiPortBufferOnStack& midiPortBuf(fMidiOutBuffers[i]);
  742. for (uint16_t j=0; j<midiPortBuf.count; ++j)
  743. {
  744. jack_midi_event_t& jmevent(midiPortBuf.events[j]);
  745. if (curMidiDataPos + kBridgeBaseMidiOutHeaderSize + jmevent.size >= kBridgeRtClientDataMidiOutSize)
  746. break;
  747. if (doMidiChanMixdown && MIDI_IS_CHANNEL_MESSAGE(jmevent.buffer[0]))
  748. jmevent.buffer[0] = static_cast<jack_midi_data_t>(
  749. (jmevent.buffer[0] & MIDI_STATUS_BIT) | (i & MIDI_CHANNEL_BIT));
  750. // set time
  751. *(uint32_t*)midiData = jmevent.time;
  752. midiData += 4;
  753. // set port
  754. *midiData++ = doMidiChanMixdown ? 0 : i;
  755. // set size
  756. *midiData++ = static_cast<uint8_t>(jmevent.size);
  757. // set data
  758. std::memcpy(midiData, jmevent.buffer, jmevent.size);
  759. midiData += jmevent.size;
  760. curMidiDataPos += kBridgeBaseMidiOutHeaderSize + jmevent.size;
  761. }
  762. }
  763. // make last event null, so server stops when reaching it
  764. if (curMidiDataPos != 0 &&
  765. curMidiDataPos + kBridgeBaseMidiOutHeaderSize < kBridgeRtClientDataMidiOutSize)
  766. {
  767. carla_zeroBytes(midiData, kBridgeBaseMidiOutHeaderSize);
  768. // sort events in case of mixdown
  769. if (doMidiChanMixdown)
  770. {
  771. uint32_t time;
  772. uint8_t size, *midiDataPtr;
  773. uint8_t tmp[kBridgeBaseMidiOutHeaderSize + JackMidiPortBufferBase::kMaxEventSize];
  774. bool wasSorted = true;
  775. for (; wasSorted;)
  776. {
  777. midiDataPtr = fShmRtClientControl.data->midiOut;
  778. uint8_t* prevData = midiDataPtr;
  779. uint32_t prevTime = *(uint32_t*)midiDataPtr;
  780. uint8_t prevSize = *(midiDataPtr + 5);
  781. wasSorted = false;
  782. for (;;)
  783. {
  784. time = *(uint32_t*)midiDataPtr;
  785. size = *(midiDataPtr + 5); // time and port
  786. if (size == 0)
  787. break;
  788. if (prevTime > time)
  789. {
  790. // copy previous data to a temporary place
  791. std::memcpy(tmp, prevData, kBridgeBaseMidiOutHeaderSize + prevSize);
  792. // override previous data with new one (shifting left)
  793. std::memcpy(prevData, midiDataPtr, kBridgeBaseMidiOutHeaderSize + size);
  794. // override new data with old one
  795. std::memcpy(midiDataPtr, tmp, kBridgeBaseMidiOutHeaderSize + prevSize);
  796. // done swapping, flag it
  797. wasSorted = true;
  798. }
  799. prevTime = time;
  800. prevSize = size;
  801. prevData = midiDataPtr;
  802. midiDataPtr += 6 + size;
  803. }
  804. }
  805. }
  806. }
  807. }
  808. }
  809. else
  810. {
  811. carla_stderr2("CarlaJackAppClient: fRealtimeThreadMutex tryLock failed");
  812. }
  813. fServer.monotonic_frame += frames;
  814. break;
  815. }
  816. case kPluginBridgeRtClientQuit:
  817. ret = true;
  818. break;
  819. }
  820. #ifdef DEBUG
  821. if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
  822. carla_debug("CarlaJackAppClientRtThread::run() - opcode %s done", PluginBridgeRtClientOpcode2str(opcode));
  823. }
  824. #endif
  825. }
  826. return ret;
  827. }
  828. bool CarlaJackAppClient::handleNonRtData()
  829. {
  830. bool ret = false;
  831. for (; fShmNonRtClientControl.isDataAvailableForReading();)
  832. {
  833. const PluginBridgeNonRtClientOpcode opcode(fShmNonRtClientControl.readOpcode());
  834. #ifdef DEBUG
  835. if (opcode != kPluginBridgeNonRtClientPing) {
  836. carla_debug("CarlaJackAppClient::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode));
  837. }
  838. #endif
  839. if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0)
  840. fLastPingTime = getCurrentTimeMilliseconds();
  841. switch (opcode)
  842. {
  843. case kPluginBridgeNonRtClientNull:
  844. break;
  845. case kPluginBridgeNonRtClientVersion: {
  846. const uint apiVersion = fShmNonRtServerControl.readUInt();
  847. CARLA_SAFE_ASSERT_UINT2(apiVersion == CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT,
  848. apiVersion, CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT);
  849. } break;
  850. case kPluginBridgeNonRtClientPing: {
  851. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  852. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
  853. fShmNonRtServerControl.commitWrite();
  854. } break;
  855. case kPluginBridgeNonRtClientPingOnOff: {
  856. const uint32_t onOff(fShmNonRtClientControl.readBool());
  857. fLastPingTime = onOff ? getCurrentTimeMilliseconds() : -1;
  858. } break;
  859. case kPluginBridgeNonRtClientActivate:
  860. case kPluginBridgeNonRtClientDeactivate:
  861. break;
  862. case kPluginBridgeNonRtClientInitialSetup:
  863. // should never happen!!
  864. fShmNonRtServerControl.readUInt();
  865. fShmNonRtServerControl.readDouble();
  866. break;
  867. case kPluginBridgeNonRtClientSetParameterValue:
  868. case kPluginBridgeNonRtClientSetParameterMidiChannel:
  869. case kPluginBridgeNonRtClientSetParameterMappedControlIndex:
  870. case kPluginBridgeNonRtClientSetParameterMappedRange:
  871. case kPluginBridgeNonRtClientSetProgram:
  872. case kPluginBridgeNonRtClientSetMidiProgram:
  873. case kPluginBridgeNonRtClientSetCustomData:
  874. case kPluginBridgeNonRtClientSetChunkDataFile:
  875. break;
  876. case kPluginBridgeNonRtClientSetOption:
  877. fShmNonRtClientControl.readUInt();
  878. fShmNonRtClientControl.readBool();
  879. break;
  880. case kPluginBridgeNonRtClientSetOptions:
  881. fShmNonRtClientControl.readUInt();
  882. break;
  883. case kPluginBridgeNonRtClientSetCtrlChannel:
  884. fShmNonRtClientControl.readShort();
  885. break;
  886. case kPluginBridgeNonRtClientGetParameterText:
  887. fShmNonRtClientControl.readUInt();
  888. break;
  889. case kPluginBridgeNonRtClientPrepareForSave:
  890. {
  891. if (fSessionManager == LIBJACK_SESSION_MANAGER_AUTO && std::getenv("NSM_URL") == nullptr)
  892. {
  893. struct sigaction sig;
  894. carla_zeroStruct(sig);
  895. sigaction(SIGUSR1, nullptr, &sig);
  896. if (sig.sa_handler != nullptr)
  897. fSessionManager = LIBJACK_SESSION_MANAGER_LADISH;
  898. }
  899. if (fSessionManager == LIBJACK_SESSION_MANAGER_LADISH)
  900. ::kill(::getpid(), SIGUSR1);
  901. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  902. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSaved);
  903. fShmNonRtServerControl.commitWrite();
  904. }
  905. break;
  906. case kPluginBridgeNonRtClientRestoreLV2State:
  907. break;
  908. case kPluginBridgeNonRtClientShowUI:
  909. if (jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SHOW_HIDE_GUI, 1, nullptr) == 1337)
  910. {
  911. // failed, LD_PRELOAD did not work?
  912. const char* const message("Cannot show UI, LD_PRELOAD not working?");
  913. const std::size_t messageSize(std::strlen(message));
  914. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  915. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
  916. fShmNonRtServerControl.commitWrite();
  917. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
  918. fShmNonRtServerControl.writeUInt(messageSize);
  919. fShmNonRtServerControl.writeCustomData(message, messageSize);
  920. fShmNonRtServerControl.commitWrite();
  921. }
  922. break;
  923. case kPluginBridgeNonRtClientHideUI:
  924. jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SHOW_HIDE_GUI, 0, nullptr);
  925. break;
  926. case kPluginBridgeNonRtClientUiParameterChange:
  927. case kPluginBridgeNonRtClientUiProgramChange:
  928. case kPluginBridgeNonRtClientUiMidiProgramChange:
  929. case kPluginBridgeNonRtClientUiNoteOn:
  930. case kPluginBridgeNonRtClientUiNoteOff:
  931. break;
  932. case kPluginBridgeNonRtClientQuit:
  933. ret = true;
  934. break;
  935. }
  936. #ifdef DEBUG
  937. if (opcode != kPluginBridgeNonRtClientPing) {
  938. carla_debug("CarlaJackAppClient::handleNonRtData() - opcode %s handled", PluginBridgeNonRtClientOpcode2str(opcode));
  939. }
  940. #endif
  941. }
  942. return ret;
  943. }
  944. void CarlaJackAppClient::runRealtimeThread()
  945. {
  946. carla_debug("CarlaJackAppClient runRealtimeThread START");
  947. #ifdef __SSE2_MATH__
  948. // Set FTZ and DAZ flags
  949. _mm_setcsr(_mm_getcsr() | 0x8040);
  950. #endif
  951. bool quitReceived = false;
  952. for (; ! fRealtimeThread.shouldThreadExit();)
  953. {
  954. if (handleRtData())
  955. {
  956. quitReceived = true;
  957. break;
  958. }
  959. }
  960. fNonRealtimeThread.signalThreadShouldExit();
  961. carla_debug("CarlaJackAppClient runRealtimeThread FINISHED");
  962. // TODO
  963. return; (void)quitReceived;
  964. }
  965. void CarlaJackAppClient::runNonRealtimeThread()
  966. {
  967. carla_debug("CarlaJackAppClient runNonRealtimeThread START");
  968. CARLA_SAFE_ASSERT_RETURN(initSharedMemmory(),);
  969. if (fServer.numMidiIns > 0)
  970. {
  971. fMidiInBuffers = new JackMidiPortBufferOnStack[fServer.numMidiIns];
  972. for (uint8_t i=0; i<fServer.numMidiIns; ++i)
  973. fMidiInBuffers[i].isInput = true;
  974. }
  975. if (fServer.numMidiOuts > 0)
  976. {
  977. fMidiOutBuffers = new JackMidiPortBufferOnStack[fServer.numMidiOuts];
  978. for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
  979. fMidiOutBuffers[i].isInput = false;
  980. }
  981. fRealtimeThread.startThread(true);
  982. fLastPingTime = getCurrentTimeMilliseconds();
  983. carla_stdout("Carla Jack Client Ready!");
  984. bool quitReceived = false,
  985. timedOut = false;
  986. for (; ! fNonRealtimeThread.shouldThreadExit();)
  987. {
  988. carla_msleep(50);
  989. try {
  990. quitReceived = handleNonRtData();
  991. } CARLA_SAFE_EXCEPTION("handleNonRtData");
  992. if (quitReceived)
  993. break;
  994. /*
  995. if (fLastPingTime > 0 && getCurrentTimeMilliseconds() > fLastPingTime + 30000)
  996. {
  997. carla_stderr("Did not receive ping message from server for 30 secs, closing...");
  998. timedOut = true;
  999. fRealtimeThread.signalThreadShouldExit();
  1000. break;
  1001. }
  1002. */
  1003. }
  1004. //callback(true, true, ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
  1005. if (quitReceived)
  1006. {
  1007. ::kill(::getpid(), SIGTERM);
  1008. }
  1009. else if (timedOut)
  1010. {
  1011. // TODO send shutdown?
  1012. carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended with time out");
  1013. ::kill(::getpid(), SIGTERM);
  1014. }
  1015. else
  1016. {
  1017. bool activated;
  1018. {
  1019. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  1020. if (fClients.isEmpty())
  1021. {
  1022. activated = false;
  1023. }
  1024. else if (JackClientState* const jclient = fClients.getLast(nullptr))
  1025. {
  1026. const CarlaMutexLocker cms2(jclient->mutex);
  1027. activated = jclient->activated;
  1028. }
  1029. else
  1030. {
  1031. activated = true;
  1032. }
  1033. }
  1034. if (activated)
  1035. {
  1036. carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended while client is activated");
  1037. const char* const message("Plugin bridge error, process thread has stopped");
  1038. const std::size_t messageSize(std::strlen(message));
  1039. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  1040. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
  1041. fShmNonRtServerControl.writeUInt(messageSize);
  1042. fShmNonRtServerControl.writeCustomData(message, messageSize);
  1043. fShmNonRtServerControl.commitWrite();
  1044. }
  1045. }
  1046. if (fRealtimeThread.isThreadRunning())
  1047. {
  1048. fRealtimeThread.signalThreadShouldExit();
  1049. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  1050. if (fShmRtClientControl.data != nullptr)
  1051. fShmRtClientControl.data->procFlags = 1;
  1052. }
  1053. clearSharedMemory();
  1054. fRealtimeThread.stopThread(5000);
  1055. carla_debug("CarlaJackAppClient runNonRealtimeThread FINISHED");
  1056. }
  1057. CARLA_BACKEND_END_NAMESPACE
  1058. // ---------------------------------------------------------------------------------------------------------------------
  1059. using CarlaBackend::CarlaJackAppClient;
  1060. using CarlaBackend::JackClientState;
  1061. static CarlaJackAppClient gClient;
  1062. CARLA_BACKEND_START_NAMESPACE
  1063. static int carla_interposed_callback(int cb_action, void* ptr)
  1064. {
  1065. return gClient.handleInterposerCallback(cb_action, ptr);
  1066. }
  1067. CARLA_BACKEND_END_NAMESPACE
  1068. // ---------------------------------------------------------------------------------------------------------------------
  1069. CARLA_EXPORT
  1070. jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...)
  1071. {
  1072. carla_debug("%s(%s, 0x%x, %p)", __FUNCTION__, client_name, options, status);
  1073. if (JackClientState* const client = gClient.createClient(client_name))
  1074. {
  1075. if (status != nullptr)
  1076. *status = static_cast<JackStatus>(0x0);
  1077. return (jack_client_t*)client;
  1078. }
  1079. if (status != nullptr)
  1080. *status = JackServerError;
  1081. return nullptr;
  1082. // unused
  1083. (void)options;
  1084. }
  1085. CARLA_EXPORT
  1086. jack_client_t* jack_client_new(const char* client_name)
  1087. {
  1088. return jack_client_open(client_name, JackNullOption, nullptr);
  1089. }
  1090. CARLA_EXPORT
  1091. int jack_client_close(jack_client_t* client)
  1092. {
  1093. carla_debug("%s(%p)", __FUNCTION__, client);
  1094. JackClientState* const jclient = (JackClientState*)client;
  1095. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  1096. gClient.destroyClient(jclient);
  1097. return 0;
  1098. }
  1099. CARLA_EXPORT
  1100. int jack_activate(jack_client_t* client)
  1101. {
  1102. carla_debug("%s(%p)", __FUNCTION__, client);
  1103. JackClientState* const jclient = (JackClientState*)client;
  1104. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  1105. return gClient.activateClient(jclient) ? 0 : 1;
  1106. }
  1107. CARLA_EXPORT
  1108. int jack_deactivate(jack_client_t* client)
  1109. {
  1110. carla_debug("%s(%p)", __FUNCTION__, client);
  1111. JackClientState* const jclient = (JackClientState*)client;
  1112. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  1113. return gClient.deactivateClient(jclient) ? 0 : 1;
  1114. }
  1115. // ---------------------------------------------------------------------------------------------------------------------
  1116. CARLA_EXPORT
  1117. char* jack_get_client_name_by_uuid(jack_client_t* const client, const char* const uuidstr)
  1118. {
  1119. carla_debug("%s(%p, %s)", __FUNCTION__, client, uuidstr);
  1120. jack_uuid_t uuid = JACK_UUID_EMPTY_INITIALIZER;
  1121. CARLA_SAFE_ASSERT_RETURN(jack_uuid_parse(uuidstr, &uuid) == 0, nullptr);
  1122. JackClientState* const jclient = (JackClientState*)client;
  1123. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr);
  1124. const char* clientName;
  1125. if (jclient->server.uuid == uuid)
  1126. return strdup("system");
  1127. if (jclient->uuid == uuid)
  1128. {
  1129. clientName = jclient->name;
  1130. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr, nullptr);
  1131. }
  1132. else
  1133. {
  1134. CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
  1135. CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, nullptr);
  1136. clientName = jackAppPtr->getClientNameFromUUID(uuid);
  1137. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr, nullptr);
  1138. }
  1139. return strdup(clientName);
  1140. }
  1141. CARLA_EXPORT
  1142. char* jack_get_uuid_for_client_name(jack_client_t* client, const char* name)
  1143. {
  1144. carla_debug("%s(%p, %s)", __FUNCTION__, client, name);
  1145. JackClientState* const jclient = (JackClientState*)client;
  1146. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr);
  1147. if (std::strcmp(name, "system") == 0)
  1148. {
  1149. char* const uuidstr = static_cast<char*>(std::malloc(JACK_UUID_STRING_SIZE));
  1150. CARLA_SAFE_ASSERT_RETURN(uuidstr != nullptr, nullptr);
  1151. jack_uuid_unparse(jclient->server.uuid, uuidstr);
  1152. return uuidstr;
  1153. }
  1154. else
  1155. {
  1156. CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
  1157. CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, nullptr);
  1158. const jack_uuid_t uuid = jackAppPtr->getUUIDForClientName(name);
  1159. CARLA_SAFE_ASSERT_RETURN(uuid != JACK_UUID_EMPTY_INITIALIZER, nullptr);
  1160. char* const uuidstr = static_cast<char*>(std::malloc(JACK_UUID_STRING_SIZE));
  1161. CARLA_SAFE_ASSERT_RETURN(uuidstr != nullptr, nullptr);
  1162. jack_uuid_unparse(jclient->uuid, uuidstr);
  1163. return uuidstr;
  1164. }
  1165. }
  1166. // ---------------------------------------------------------------------------------------------------------------------
  1167. CARLA_EXPORT
  1168. pthread_t jack_client_thread_id(jack_client_t* client)
  1169. {
  1170. carla_debug("%s(%p)", __FUNCTION__, client);
  1171. JackClientState* const jclient = (JackClientState*)client;
  1172. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 0);
  1173. CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
  1174. CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, 0);
  1175. return jackAppPtr->getRealtimeThreadId();
  1176. }
  1177. // ---------------------------------------------------------------------------------------------------------------------
  1178. #include "jackbridge/JackBridge2.cpp"
  1179. #include "CarlaBridgeUtils.cpp"
  1180. // ---------------------------------------------------------------------------------------------------------------------
  1181. // TODO
  1182. CARLA_BACKEND_USE_NAMESPACE
  1183. CARLA_EXPORT
  1184. int jack_client_real_time_priority(jack_client_t* client)
  1185. {
  1186. carla_debug("%s(%p)", __FUNCTION__, client);
  1187. // code as used by water
  1188. const int minPriority = sched_get_priority_min(SCHED_RR);
  1189. const int maxPriority = sched_get_priority_max(SCHED_RR);
  1190. return ((maxPriority - minPriority) * 9) / 10 + minPriority;
  1191. // unused
  1192. (void)client;
  1193. }
  1194. int jack_client_create_thread(jack_client_t* client, pthread_t* thread, int priority,
  1195. int realtime, void *(*start_routine)(void*), void* arg)
  1196. {
  1197. carla_stderr2("%s(%p, %p, %i, %i, %p, %p)", __FUNCTION__, client, thread, priority, realtime, start_routine, arg);
  1198. return ENOSYS;
  1199. }
  1200. typedef void (*JackSessionCallback)(jack_session_event_t*, void*);
  1201. CARLA_EXPORT
  1202. int jack_set_session_callback(jack_client_t* client, JackSessionCallback callback, void* arg)
  1203. {
  1204. carla_stderr2("%s(%p, %p, %p)", __FUNCTION__, client, callback, arg);
  1205. return 0;
  1206. }
  1207. // ---------------------------------------------------------------------------------------------------------------------