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.

1632 lines
59KB

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