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.

libjack.cpp 59KB

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