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

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