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.

1545 lines
55KB

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