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.

1205 lines
41KB

  1. /*
  2. * Carla JACK API for external applications
  3. * Copyright (C) 2016-2017 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 <sys/prctl.h>
  19. #include "CarlaThread.hpp"
  20. using juce::FloatVectorOperations;
  21. using juce::Thread;
  22. using juce::Time;
  23. typedef int (*CarlaInterposedCallback)(int, void*);
  24. CARLA_EXPORT
  25. int jack_carla_interposed_action(int, int, void*)
  26. {
  27. carla_stderr2("Non-export jack_carla_interposed_action called, this should not happen!!");
  28. return 1337;
  29. }
  30. CARLA_BACKEND_START_NAMESPACE
  31. // ---------------------------------------------------------------------------------------------------------------------
  32. class CarlaJackRealtimeThread : public Thread
  33. {
  34. public:
  35. struct Callback {
  36. Callback() {}
  37. virtual ~Callback() {};
  38. virtual void runRealtimeThread() = 0;
  39. };
  40. CarlaJackRealtimeThread(Callback* const callback)
  41. : Thread("CarlaJackRealtimeThread"),
  42. fCallback(callback) {}
  43. protected:
  44. void run() override
  45. {
  46. fCallback->runRealtimeThread();
  47. }
  48. private:
  49. Callback* const fCallback;
  50. };
  51. // --------------------------------------------------------------------------------------------------------------------
  52. class CarlaJackNonRealtimeThread : public Thread
  53. {
  54. public:
  55. struct Callback {
  56. Callback() {}
  57. virtual ~Callback() {};
  58. virtual void runNonRealtimeThread() = 0;
  59. };
  60. CarlaJackNonRealtimeThread(Callback* const callback)
  61. : Thread("CarlaJackNonRealtimeThread"),
  62. fCallback(callback) {}
  63. protected:
  64. void run() override
  65. {
  66. fCallback->runNonRealtimeThread();
  67. }
  68. private:
  69. Callback* const fCallback;
  70. };
  71. static int carla_interposed_callback(int, void*);
  72. // ---------------------------------------------------------------------------------------------------------------------
  73. class CarlaJackAppClient : public CarlaJackRealtimeThread::Callback,
  74. public CarlaJackNonRealtimeThread::Callback
  75. {
  76. public:
  77. JackServerState fServer;
  78. LinkedList<JackClientState*> fClients;
  79. CarlaJackAppClient()
  80. : fServer(this),
  81. fAudioPoolCopy(nullptr),
  82. fAudioTmpBuf(nullptr),
  83. fDummyMidiInBuffer(true, "ignored"),
  84. fDummyMidiOutBuffer(false, "ignored"),
  85. fMidiInBuffers(nullptr),
  86. fMidiOutBuffers(nullptr),
  87. fIsOffline(false),
  88. fLastPingTime(-1),
  89. fSessionManager(0),
  90. fSetupHints(0),
  91. fRealtimeThread(this),
  92. fNonRealtimeThread(this)
  93. {
  94. carla_debug("CarlaJackAppClient::CarlaJackAppClient()");
  95. const char* const shmIds(std::getenv("CARLA_SHM_IDS"));
  96. CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4,);
  97. const char* const libjackSetup(std::getenv("CARLA_LIBJACK_SETUP"));
  98. CARLA_SAFE_ASSERT_RETURN(libjackSetup != nullptr && std::strlen(libjackSetup) == 6,);
  99. // make sure we don't get loaded again
  100. carla_unsetenv("CARLA_SHM_IDS");
  101. // kill ourselves if main carla dies
  102. ::prctl(PR_SET_PDEATHSIG, SIGKILL);
  103. for (int i=4; --i >= 0;) {
  104. CARLA_SAFE_ASSERT_RETURN(libjackSetup[i] >= '0' && libjackSetup[i] <= '0'+64,);
  105. }
  106. for (int i=6; --i >= 4;) {
  107. CARLA_SAFE_ASSERT_RETURN(libjackSetup[i] >= '0' && libjackSetup[i] < '0'+0x4f,);
  108. }
  109. std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6);
  110. std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6);
  111. std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6);
  112. std::memcpy(fBaseNameNonRtServerControl, shmIds+6*3, 6);
  113. fBaseNameAudioPool[6] = '\0';
  114. fBaseNameRtClientControl[6] = '\0';
  115. fBaseNameNonRtClientControl[6] = '\0';
  116. fBaseNameNonRtServerControl[6] = '\0';
  117. fServer.numAudioIns = libjackSetup[0] - '0';
  118. fServer.numAudioOuts = libjackSetup[1] - '0';
  119. fServer.numMidiIns = libjackSetup[2] - '0';
  120. fServer.numMidiOuts = libjackSetup[3] - '0';
  121. fSessionManager = libjackSetup[4] - '0';
  122. fSetupHints = libjackSetup[5] - '0';
  123. jack_carla_interposed_action(1, fSetupHints, (void*)carla_interposed_callback);
  124. jack_carla_interposed_action(2, fSessionManager, nullptr);
  125. fNonRealtimeThread.startThread();
  126. }
  127. ~CarlaJackAppClient() noexcept override
  128. {
  129. carla_debug("CarlaJackAppClient::~CarlaJackAppClient()");
  130. fLastPingTime = -1;
  131. fNonRealtimeThread.stopThread(5000);
  132. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  133. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  134. {
  135. JackClientState* const jclient(it.getValue(nullptr));
  136. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  137. delete jclient;
  138. }
  139. fClients.clear();
  140. }
  141. JackClientState* createClient(const char* const name)
  142. {
  143. return new JackClientState(fServer, name);
  144. }
  145. void destroyClient(JackClientState* const jclient)
  146. {
  147. {
  148. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  149. fClients.removeOne(jclient);
  150. }
  151. delete jclient;
  152. }
  153. bool activateClient(JackClientState* const jclient)
  154. {
  155. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  156. if (! fClients.append(jclient))
  157. return false;
  158. jclient->activated = true;
  159. jclient->deactivated = false;
  160. return true;
  161. }
  162. bool deactivateClient(JackClientState* const jclient)
  163. {
  164. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  165. if (! fClients.removeOne(jclient))
  166. return false;
  167. jclient->activated = false;
  168. jclient->deactivated = true;
  169. return true;
  170. }
  171. pthread_t getRealtimeThreadId() const noexcept
  172. {
  173. return (pthread_t)fRealtimeThread.getThreadId();
  174. }
  175. int handleInterposerCallback(const int cb_action, void* const ptr)
  176. {
  177. carla_stdout("handleInterposerCallback(%o, %p)", cb_action, ptr);
  178. switch (cb_action)
  179. {
  180. case 1: {
  181. const CarlaMutexLocker cml(fShmNonRtServerControl.mutex);
  182. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
  183. fShmNonRtServerControl.commitWrite();
  184. break;
  185. }
  186. }
  187. return 0;
  188. }
  189. // -------------------------------------------------------------------
  190. protected:
  191. void runRealtimeThread() override;
  192. void runNonRealtimeThread() override;
  193. private:
  194. bool initSharedMemmory();
  195. void clearSharedMemory() noexcept;
  196. bool handleRtData();
  197. bool handleNonRtData();
  198. BridgeAudioPool fShmAudioPool;
  199. BridgeRtClientControl fShmRtClientControl;
  200. BridgeNonRtClientControl fShmNonRtClientControl;
  201. BridgeNonRtServerControl fShmNonRtServerControl;
  202. float* fAudioPoolCopy;
  203. float* fAudioTmpBuf;
  204. JackMidiPortBuffer fDummyMidiInBuffer;
  205. JackMidiPortBuffer fDummyMidiOutBuffer;
  206. JackMidiPortBuffer* fMidiInBuffers;
  207. JackMidiPortBuffer* fMidiOutBuffers;
  208. char fBaseNameAudioPool[6+1];
  209. char fBaseNameRtClientControl[6+1];
  210. char fBaseNameNonRtClientControl[6+1];
  211. char fBaseNameNonRtServerControl[6+1];
  212. bool fIsOffline;
  213. int64_t fLastPingTime;
  214. int fSessionManager;
  215. int fSetupHints;
  216. CarlaJackRealtimeThread fRealtimeThread;
  217. CarlaJackNonRealtimeThread fNonRealtimeThread;
  218. CarlaMutex fRealtimeThreadMutex;
  219. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaJackAppClient)
  220. };
  221. // ---------------------------------------------------------------------------------------------------------------------
  222. bool CarlaJackAppClient::initSharedMemmory()
  223. {
  224. if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
  225. {
  226. carla_stderr("Failed to attach to audio pool shared memory");
  227. return false;
  228. }
  229. if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
  230. {
  231. clearSharedMemory();
  232. carla_stderr("Failed to attach to rt client control shared memory");
  233. return false;
  234. }
  235. if (! fShmRtClientControl.mapData())
  236. {
  237. clearSharedMemory();
  238. carla_stderr("Failed to map rt client control shared memory");
  239. return false;
  240. }
  241. if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
  242. {
  243. clearSharedMemory();
  244. carla_stderr("Failed to attach to non-rt client control shared memory");
  245. return false;
  246. }
  247. if (! fShmNonRtClientControl.mapData())
  248. {
  249. clearSharedMemory();
  250. carla_stderr("Failed to map non-rt control client shared memory");
  251. return false;
  252. }
  253. if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
  254. {
  255. clearSharedMemory();
  256. carla_stderr("Failed to attach to non-rt server control shared memory");
  257. return false;
  258. }
  259. if (! fShmNonRtServerControl.mapData())
  260. {
  261. clearSharedMemory();
  262. carla_stderr("Failed to map non-rt control server shared memory");
  263. return false;
  264. }
  265. PluginBridgeNonRtClientOpcode opcode;
  266. opcode = fShmNonRtClientControl.readOpcode();
  267. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);
  268. const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
  269. CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));
  270. const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
  271. CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));
  272. const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
  273. CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));
  274. if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
  275. {
  276. carla_stderr2("CarlaJackAppClient: data size mismatch");
  277. return false;
  278. }
  279. opcode = fShmNonRtClientControl.readOpcode();
  280. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientInitialSetup, opcode);
  281. fServer.bufferSize = fShmNonRtClientControl.readUInt();
  282. fServer.sampleRate = fShmNonRtClientControl.readDouble();
  283. if (fServer.bufferSize == 0 || carla_isZero(fServer.sampleRate))
  284. {
  285. carla_stderr2("CarlaJackAppClient: invalid empty state");
  286. return false;
  287. }
  288. fAudioTmpBuf = new float[fServer.bufferSize];
  289. FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);
  290. // tell backend we're live
  291. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  292. fLastPingTime = Time::currentTimeMillis();
  293. CARLA_SAFE_ASSERT(fLastPingTime > 0);
  294. // ready!
  295. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
  296. fShmNonRtServerControl.commitWrite();
  297. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  298. return true;
  299. }
  300. void CarlaJackAppClient::clearSharedMemory() noexcept
  301. {
  302. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  303. if (fAudioPoolCopy != nullptr)
  304. {
  305. delete[] fAudioPoolCopy;
  306. fAudioPoolCopy = nullptr;
  307. }
  308. if (fAudioTmpBuf != nullptr)
  309. {
  310. delete[] fAudioTmpBuf;
  311. fAudioTmpBuf = nullptr;
  312. }
  313. if (fMidiInBuffers != nullptr)
  314. {
  315. delete[] fMidiInBuffers;
  316. fMidiInBuffers = nullptr;
  317. }
  318. if (fMidiOutBuffers != nullptr)
  319. {
  320. delete[] fMidiOutBuffers;
  321. fMidiOutBuffers = nullptr;
  322. }
  323. fShmAudioPool.clear();
  324. fShmRtClientControl.clear();
  325. fShmNonRtClientControl.clear();
  326. fShmNonRtServerControl.clear();
  327. }
  328. bool CarlaJackAppClient::handleRtData()
  329. {
  330. const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);
  331. if (! helper.ok)
  332. return false;
  333. bool ret = false;
  334. for (; fShmRtClientControl.isDataAvailableForReading();)
  335. {
  336. const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
  337. #ifdef DEBUG
  338. if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
  339. carla_debug("CarlaJackAppClientRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
  340. }
  341. #endif
  342. switch (opcode)
  343. {
  344. case kPluginBridgeRtClientNull:
  345. break;
  346. case kPluginBridgeRtClientSetAudioPool: {
  347. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  348. if (fShmAudioPool.data != nullptr)
  349. {
  350. jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
  351. fShmAudioPool.data = nullptr;
  352. }
  353. if (fAudioPoolCopy != nullptr)
  354. {
  355. delete[] fAudioPoolCopy;
  356. fAudioPoolCopy = nullptr;
  357. }
  358. const uint64_t poolSize(fShmRtClientControl.readULong());
  359. CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
  360. fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
  361. fAudioPoolCopy = new float[poolSize];
  362. break;
  363. }
  364. case kPluginBridgeRtClientSetBufferSize:
  365. if (const uint32_t newBufferSize = fShmRtClientControl.readUInt())
  366. {
  367. if (fServer.bufferSize != newBufferSize)
  368. {
  369. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  370. fServer.bufferSize = newBufferSize;
  371. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  372. {
  373. JackClientState* const jclient(it.getValue(nullptr));
  374. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  375. jclient->bufferSizeCb(fServer.bufferSize, jclient->bufferSizeCbPtr);
  376. }
  377. delete[] fAudioTmpBuf;
  378. fAudioTmpBuf = new float[fServer.bufferSize];
  379. FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);
  380. }
  381. }
  382. break;
  383. case kPluginBridgeRtClientSetSampleRate:
  384. if (const double newSampleRate = fShmRtClientControl.readDouble())
  385. {
  386. if (fServer.sampleRate != newSampleRate)
  387. {
  388. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  389. fServer.sampleRate = newSampleRate;
  390. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  391. {
  392. JackClientState* const jclient(it.getValue(nullptr));
  393. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  394. jclient->sampleRateCb(fServer.sampleRate, jclient->sampleRateCbPtr);
  395. }
  396. }
  397. }
  398. break;
  399. case kPluginBridgeRtClientSetOnline:
  400. // TODO inform changes
  401. fIsOffline = fShmRtClientControl.readBool();
  402. //offlineModeChanged(fIsOffline);
  403. break;
  404. case kPluginBridgeRtClientControlEventParameter:
  405. case kPluginBridgeRtClientControlEventMidiBank:
  406. case kPluginBridgeRtClientControlEventMidiProgram:
  407. case kPluginBridgeRtClientControlEventAllSoundOff:
  408. case kPluginBridgeRtClientControlEventAllNotesOff:
  409. break;
  410. case kPluginBridgeRtClientMidiEvent: {
  411. const uint32_t time(fShmRtClientControl.readUInt());
  412. const uint8_t port(fShmRtClientControl.readByte());
  413. const uint8_t size(fShmRtClientControl.readByte());
  414. CARLA_SAFE_ASSERT_BREAK(size > 0);
  415. if (port >= fServer.numMidiIns || size > JackMidiPortBuffer::kMaxEventSize || ! fRealtimeThreadMutex.tryLock())
  416. {
  417. for (uint8_t i=0; i<size; ++i)
  418. fShmRtClientControl.readByte();
  419. break;
  420. }
  421. JackMidiPortBuffer& midiPortBuf(fMidiInBuffers[port]);
  422. if (midiPortBuf.count < JackMidiPortBuffer::kMaxEventCount &&
  423. midiPortBuf.bufferPoolPos + size < JackMidiPortBuffer::kBufferPoolSize)
  424. {
  425. jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
  426. ev.time = time;
  427. ev.size = size;
  428. ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
  429. midiPortBuf.bufferPoolPos += size;
  430. for (uint8_t i=0; i<size; ++i)
  431. ev.buffer[i] = fShmRtClientControl.readByte();
  432. }
  433. fRealtimeThreadMutex.unlock(true);
  434. break;
  435. }
  436. case kPluginBridgeRtClientProcess: {
  437. // FIXME - lock if offline
  438. const CarlaMutexTryLocker cmtl(fRealtimeThreadMutex);
  439. if (cmtl.wasLocked())
  440. {
  441. CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);
  442. // location to start of audio outputs (shm buffer)
  443. float* const fdataRealOuts = fShmAudioPool.data+(fServer.bufferSize*fServer.numAudioIns);
  444. if (! fClients.isEmpty())
  445. {
  446. // save tranport for all clients
  447. const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
  448. fServer.playing = bridgeTimeInfo.playing;
  449. fServer.position.frame = bridgeTimeInfo.frame;
  450. fServer.position.usecs = bridgeTimeInfo.usecs;
  451. if (bridgeTimeInfo.valid & 0x1 /* kValidBBT */)
  452. {
  453. fServer.position.valid = JackPositionBBT;
  454. fServer.position.bar = bridgeTimeInfo.bar;
  455. fServer.position.beat = bridgeTimeInfo.beat;
  456. fServer.position.tick = bridgeTimeInfo.tick;
  457. fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
  458. fServer.position.beat_type = bridgeTimeInfo.beatType;
  459. fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
  460. fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
  461. fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
  462. }
  463. else
  464. {
  465. fServer.position.valid = static_cast<jack_position_bits_t>(0);
  466. }
  467. int numClientOutputsProcessed = 0;
  468. // now go through each client
  469. for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
  470. {
  471. JackClientState* const jclient(it.getValue(nullptr));
  472. CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
  473. // FIXME - lock if offline
  474. const CarlaMutexTryLocker cmtl2(jclient->mutex);
  475. // check if we can process
  476. if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
  477. {
  478. if (fServer.numAudioOuts > 0)
  479. FloatVectorOperations::clear(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
  480. if (jclient->deactivated)
  481. fShmRtClientControl.data->procFlags = 1;
  482. }
  483. else
  484. {
  485. uint8_t i;
  486. // direct access to shm buffer, used only for inputs
  487. float* fdataReal = fShmAudioPool.data;
  488. // safe temp location for output, mixed down to shm buffer later on
  489. float* fdataCopy = fAudioPoolCopy;
  490. // wherever we're using fAudioTmpBuf
  491. bool needsTmpBufClear = false;
  492. // set audio inputs
  493. i = 0;
  494. for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next())
  495. {
  496. JackPortState* const jport = it.getValue(nullptr);
  497. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  498. if (i++ < fServer.numAudioIns)
  499. {
  500. jport->buffer = fdataReal;
  501. fdataReal += fServer.bufferSize;
  502. fdataCopy += fServer.bufferSize;
  503. }
  504. else
  505. {
  506. jport->buffer = fAudioTmpBuf;
  507. needsTmpBufClear = true;
  508. }
  509. }
  510. // FIXME one single "if"
  511. for (; i++ < fServer.numAudioIns;)
  512. {
  513. fdataReal += fServer.bufferSize;
  514. fdataCopy += fServer.bufferSize;
  515. }
  516. // location to start of audio outputs
  517. float* const fdataCopyOuts = fdataCopy;
  518. // set audio ouputs
  519. i = 0;
  520. for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next())
  521. {
  522. JackPortState* const jport = it.getValue(nullptr);
  523. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  524. if (i++ < fServer.numAudioOuts)
  525. {
  526. jport->buffer = fdataCopy;
  527. fdataCopy += fServer.bufferSize;
  528. }
  529. else
  530. {
  531. jport->buffer = fAudioTmpBuf;
  532. needsTmpBufClear = true;
  533. }
  534. }
  535. // FIXME one single "if"
  536. for (; i++ < fServer.numAudioOuts;)
  537. {
  538. FloatVectorOperations::clear(fdataCopy, fServer.bufferSize);
  539. fdataCopy += fServer.bufferSize;
  540. }
  541. // set midi inputs
  542. i = 0;
  543. for (LinkedList<JackPortState*>::Itenerator it = jclient->midiIns.begin2(); it.valid(); it.next())
  544. {
  545. JackPortState* const jport = it.getValue(nullptr);
  546. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  547. if (i++ < fServer.numMidiIns)
  548. jport->buffer = &fMidiInBuffers[i-1];
  549. else
  550. jport->buffer = &fDummyMidiInBuffer;
  551. }
  552. // set midi outputs
  553. i = 0;
  554. for (LinkedList<JackPortState*>::Itenerator it = jclient->midiOuts.begin2(); it.valid(); it.next())
  555. {
  556. JackPortState* const jport = it.getValue(nullptr);
  557. CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
  558. if (i++ < fServer.numMidiOuts)
  559. jport->buffer = &fMidiOutBuffers[i-1];
  560. else
  561. jport->buffer = &fDummyMidiOutBuffer;
  562. }
  563. if (needsTmpBufClear)
  564. FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);
  565. jclient->processCb(fServer.bufferSize, jclient->processCbPtr);
  566. if (fServer.numAudioOuts > 0)
  567. {
  568. if (++numClientOutputsProcessed == 1)
  569. {
  570. // first client, we can copy stuff over
  571. FloatVectorOperations::copy(fdataRealOuts, fdataCopyOuts,
  572. fServer.bufferSize*fServer.numAudioOuts);
  573. }
  574. else
  575. {
  576. // subsequent clients, add data (then divide by number of clients later on)
  577. FloatVectorOperations::add(fdataRealOuts, fdataCopyOuts,
  578. fServer.bufferSize*fServer.numAudioOuts);
  579. }
  580. if (jclient->audioOuts.count() == 1 && fServer.numAudioOuts > 1)
  581. {
  582. for (uint8_t i=1; i<fServer.numAudioOuts; ++i)
  583. {
  584. FloatVectorOperations::copy(fdataRealOuts+(fServer.bufferSize*i),
  585. fdataCopyOuts,
  586. fServer.bufferSize);
  587. }
  588. }
  589. }
  590. }
  591. }
  592. if (numClientOutputsProcessed > 1)
  593. {
  594. // more than 1 client active, need to divide buffers
  595. FloatVectorOperations::multiply(fdataRealOuts,
  596. 1.0f/static_cast<float>(numClientOutputsProcessed),
  597. fServer.bufferSize*fServer.numAudioOuts);
  598. }
  599. }
  600. // fClients.isEmpty()
  601. else if (fServer.numAudioOuts > 0)
  602. {
  603. FloatVectorOperations::clear(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
  604. }
  605. for (uint8_t i=0; i<fServer.numMidiIns; ++i)
  606. {
  607. fMidiInBuffers[i].count = 0;
  608. fMidiInBuffers[i].bufferPoolPos = 0;
  609. }
  610. if (fServer.numMidiOuts > 0)
  611. {
  612. uint8_t* midiData(fShmRtClientControl.data->midiOut);
  613. carla_zeroBytes(midiData, kBridgeBaseMidiOutHeaderSize);
  614. std::size_t curMidiDataPos = 0;
  615. for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
  616. {
  617. JackMidiPortBuffer& midiPortBuf(fMidiOutBuffers[i]);
  618. for (uint16_t j=0; j<midiPortBuf.count; ++j)
  619. {
  620. jack_midi_event_t& jmevent(midiPortBuf.events[j]);
  621. if (curMidiDataPos + kBridgeBaseMidiOutHeaderSize + jmevent.size >= kBridgeRtClientDataMidiOutSize)
  622. break;
  623. // set time
  624. *(uint32_t*)midiData = jmevent.time;
  625. midiData += 4;
  626. // set port
  627. *midiData++ = i;
  628. // set size
  629. *midiData++ = static_cast<uint8_t>(jmevent.size);
  630. // set data
  631. std::memcpy(midiData, jmevent.buffer, jmevent.size);
  632. midiData += jmevent.size;
  633. curMidiDataPos += kBridgeBaseMidiOutHeaderSize + jmevent.size;
  634. }
  635. }
  636. }
  637. }
  638. else
  639. {
  640. carla_stderr2("CarlaJackAppClient: fRealtimeThreadMutex tryLock failed");
  641. }
  642. break;
  643. }
  644. case kPluginBridgeRtClientQuit:
  645. ret = true;
  646. break;
  647. }
  648. #ifdef DEBUG
  649. if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
  650. carla_debug("CarlaJackAppClientRtThread::run() - opcode %s done", PluginBridgeRtClientOpcode2str(opcode));
  651. }
  652. #endif
  653. }
  654. return ret;
  655. }
  656. bool CarlaJackAppClient::handleNonRtData()
  657. {
  658. bool ret = false;
  659. for (; fShmNonRtClientControl.isDataAvailableForReading();)
  660. {
  661. const PluginBridgeNonRtClientOpcode opcode(fShmNonRtClientControl.readOpcode());
  662. #ifdef DEBUG
  663. if (opcode != kPluginBridgeNonRtClientPing) {
  664. carla_debug("CarlaJackAppClient::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode));
  665. }
  666. #endif
  667. if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0)
  668. fLastPingTime = Time::currentTimeMillis();
  669. switch (opcode)
  670. {
  671. case kPluginBridgeNonRtClientNull:
  672. break;
  673. case kPluginBridgeNonRtClientPing: {
  674. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  675. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
  676. fShmNonRtServerControl.commitWrite();
  677. } break;
  678. case kPluginBridgeNonRtClientPingOnOff: {
  679. const uint32_t onOff(fShmNonRtClientControl.readBool());
  680. fLastPingTime = onOff ? Time::currentTimeMillis() : -1;
  681. } break;
  682. case kPluginBridgeNonRtClientActivate:
  683. case kPluginBridgeNonRtClientDeactivate:
  684. break;
  685. case kPluginBridgeNonRtClientInitialSetup:
  686. // should never happen!!
  687. fShmNonRtServerControl.readUInt();
  688. fShmNonRtServerControl.readDouble();
  689. break;
  690. case kPluginBridgeNonRtClientSetParameterValue:
  691. case kPluginBridgeNonRtClientSetParameterMidiChannel:
  692. case kPluginBridgeNonRtClientSetParameterMidiCC:
  693. case kPluginBridgeNonRtClientSetProgram:
  694. case kPluginBridgeNonRtClientSetMidiProgram:
  695. case kPluginBridgeNonRtClientSetCustomData:
  696. case kPluginBridgeNonRtClientSetChunkDataFile:
  697. break;
  698. case kPluginBridgeNonRtClientSetOption:
  699. fShmNonRtClientControl.readUInt();
  700. fShmNonRtClientControl.readBool();
  701. break;
  702. case kPluginBridgeNonRtClientSetCtrlChannel:
  703. fShmNonRtClientControl.readShort();
  704. break;
  705. case kPluginBridgeNonRtClientPrepareForSave:
  706. {
  707. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  708. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSaved);
  709. fShmNonRtServerControl.commitWrite();
  710. }
  711. break;
  712. case kPluginBridgeNonRtClientShowUI:
  713. if (jack_carla_interposed_action(3, 1, nullptr) == 1337)
  714. {
  715. // failed, LD_PRELOAD did not work?
  716. const char* const message("Cannot show UI, LD_PRELOAD not working?");
  717. const std::size_t messageSize(std::strlen(message));
  718. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  719. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
  720. fShmNonRtServerControl.commitWrite();
  721. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
  722. fShmNonRtServerControl.writeUInt(messageSize);
  723. fShmNonRtServerControl.writeCustomData(message, messageSize);
  724. fShmNonRtServerControl.commitWrite();
  725. }
  726. break;
  727. case kPluginBridgeNonRtClientHideUI:
  728. jack_carla_interposed_action(3, 0, nullptr);
  729. break;
  730. case kPluginBridgeNonRtClientUiParameterChange:
  731. case kPluginBridgeNonRtClientUiProgramChange:
  732. case kPluginBridgeNonRtClientUiMidiProgramChange:
  733. case kPluginBridgeNonRtClientUiNoteOn:
  734. case kPluginBridgeNonRtClientUiNoteOff:
  735. break;
  736. case kPluginBridgeNonRtClientQuit:
  737. ret = true;
  738. break;
  739. }
  740. #ifdef DEBUG
  741. if (opcode != kPluginBridgeNonRtClientPing) {
  742. carla_debug("CarlaJackAppClient::handleNonRtData() - opcode %s handled", PluginBridgeNonRtClientOpcode2str(opcode));
  743. }
  744. #endif
  745. }
  746. return ret;
  747. }
  748. void CarlaJackAppClient::runRealtimeThread()
  749. {
  750. carla_debug("CarlaJackAppClient runRealtimeThread START");
  751. #ifdef __SSE2_MATH__
  752. // Set FTZ and DAZ flags
  753. _mm_setcsr(_mm_getcsr() | 0x8040);
  754. #endif
  755. bool quitReceived = false;
  756. for (; ! fRealtimeThread.threadShouldExit();)
  757. {
  758. if (handleRtData())
  759. {
  760. quitReceived = true;
  761. break;
  762. }
  763. }
  764. fNonRealtimeThread.signalThreadShouldExit();
  765. carla_debug("CarlaJackAppClient runRealtimeThread FINISHED");
  766. }
  767. void CarlaJackAppClient::runNonRealtimeThread()
  768. {
  769. carla_debug("CarlaJackAppClient runNonRealtimeThread START");
  770. CARLA_SAFE_ASSERT_RETURN(initSharedMemmory(),);
  771. if (fServer.numMidiIns > 0)
  772. {
  773. fMidiInBuffers = new JackMidiPortBuffer[fServer.numMidiIns];
  774. for (uint8_t i=0; i<fServer.numMidiIns; ++i)
  775. fMidiInBuffers[i].isInput = true;
  776. }
  777. if (fServer.numMidiOuts > 0)
  778. {
  779. fMidiOutBuffers = new JackMidiPortBuffer[fServer.numMidiOuts];
  780. for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
  781. fMidiOutBuffers[i].isInput = false;
  782. }
  783. fRealtimeThread.startThread(Thread::realtimeAudioPriority);
  784. fLastPingTime = Time::currentTimeMillis();
  785. carla_stdout("Carla Jack Client Ready!");
  786. bool quitReceived = false,
  787. timedOut = false;
  788. for (; ! fNonRealtimeThread.threadShouldExit();)
  789. {
  790. carla_msleep(50);
  791. try {
  792. quitReceived = handleNonRtData();
  793. } CARLA_SAFE_EXCEPTION("handleNonRtData");
  794. if (quitReceived)
  795. break;
  796. /*
  797. if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000)
  798. {
  799. carla_stderr("Did not receive ping message from server for 30 secs, closing...");
  800. timedOut = true;
  801. fRealtimeThread.signalThreadShouldExit();
  802. break;
  803. }
  804. */
  805. }
  806. //callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
  807. if (quitReceived)
  808. {
  809. ::kill(::getpid(), SIGTERM);
  810. }
  811. else if (timedOut)
  812. {
  813. // TODO send shutdown?
  814. carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended with time out");
  815. ::kill(::getpid(), SIGTERM);
  816. }
  817. else
  818. {
  819. bool activated;
  820. {
  821. const CarlaMutexLocker cms(fRealtimeThreadMutex);
  822. if (fClients.isEmpty())
  823. {
  824. activated = false;
  825. }
  826. else if (JackClientState* const jclient = fClients.getLast(nullptr))
  827. {
  828. const CarlaMutexLocker cms(jclient->mutex);
  829. activated = jclient->activated;
  830. }
  831. else
  832. {
  833. activated = true;
  834. }
  835. }
  836. if (activated)
  837. {
  838. carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended while client is activated");
  839. const char* const message("Plugin bridge error, process thread has stopped");
  840. const std::size_t messageSize(std::strlen(message));
  841. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  842. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
  843. fShmNonRtServerControl.writeUInt(messageSize);
  844. fShmNonRtServerControl.writeCustomData(message, messageSize);
  845. fShmNonRtServerControl.commitWrite();
  846. }
  847. }
  848. if (fRealtimeThread.isThreadRunning())
  849. {
  850. fRealtimeThread.signalThreadShouldExit();
  851. const CarlaMutexLocker cml(fRealtimeThreadMutex);
  852. if (fShmRtClientControl.data != nullptr)
  853. fShmRtClientControl.data->procFlags = 1;
  854. }
  855. clearSharedMemory();
  856. fRealtimeThread.stopThread(5000);
  857. carla_debug("CarlaJackAppClient runNonRealtimeThread FINISHED");
  858. }
  859. // ---------------------------------------------------------------------------------------------------------------------
  860. static CarlaJackAppClient gClient;
  861. static int carla_interposed_callback(int cb_action, void* ptr)
  862. {
  863. return gClient.handleInterposerCallback(cb_action, ptr);
  864. }
  865. // ---------------------------------------------------------------------------------------------------------------------
  866. CARLA_EXPORT
  867. jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...)
  868. {
  869. carla_debug("%s(%s, 0x%x, %p)", __FUNCTION__, client_name, options, status);
  870. if (JackClientState* const client = gClient.createClient(client_name))
  871. {
  872. if (status != nullptr)
  873. *status = static_cast<JackStatus>(0x0);
  874. return (jack_client_t*)client;
  875. }
  876. if (status != nullptr)
  877. *status = JackServerError;
  878. return nullptr;
  879. // unused
  880. (void)options;
  881. }
  882. CARLA_EXPORT
  883. jack_client_t* jack_client_new(const char* client_name)
  884. {
  885. return jack_client_open(client_name, JackNullOption, nullptr);
  886. }
  887. CARLA_EXPORT
  888. int jack_client_close(jack_client_t* client)
  889. {
  890. carla_debug("%s(%p)", __FUNCTION__, client);
  891. JackClientState* const jclient = (JackClientState*)client;
  892. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  893. gClient.destroyClient(jclient);
  894. return 0;
  895. }
  896. CARLA_EXPORT
  897. int jack_activate(jack_client_t* client)
  898. {
  899. carla_debug("%s(%p)", __FUNCTION__, client);
  900. JackClientState* const jclient = (JackClientState*)client;
  901. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  902. return gClient.activateClient(jclient) ? 0 : 1;
  903. }
  904. CARLA_EXPORT
  905. int jack_deactivate(jack_client_t* client)
  906. {
  907. carla_debug("%s(%p)", __FUNCTION__, client);
  908. JackClientState* const jclient = (JackClientState*)client;
  909. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
  910. return gClient.deactivateClient(jclient) ? 0 : 1;
  911. }
  912. // ---------------------------------------------------------------------------------------------------------------------
  913. CARLA_EXPORT
  914. pthread_t jack_client_thread_id(jack_client_t* client)
  915. {
  916. carla_debug("%s(%p)", __FUNCTION__, client);
  917. JackClientState* const jclient = (JackClientState*)client;
  918. CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 0);
  919. CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
  920. CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, 0);
  921. return jackAppPtr->getRealtimeThreadId();
  922. }
  923. CARLA_BACKEND_END_NAMESPACE
  924. // ---------------------------------------------------------------------------------------------------------------------
  925. #include "jackbridge/JackBridge2.cpp"
  926. #include "CarlaBridgeUtils.cpp"
  927. // ---------------------------------------------------------------------------------------------------------------------
  928. // TODO
  929. CARLA_BACKEND_USE_NAMESPACE
  930. CARLA_EXPORT
  931. int jack_client_real_time_priority(jack_client_t* client)
  932. {
  933. carla_debug("%s(%p)", __FUNCTION__, client);
  934. // code as used by juce
  935. const int minPriority = sched_get_priority_min(SCHED_RR);
  936. const int maxPriority = sched_get_priority_max(SCHED_RR);
  937. return ((maxPriority - minPriority) * 9) / 10 + minPriority;
  938. // unused
  939. (void)client;
  940. }
  941. int jack_client_create_thread(jack_client_t* client, pthread_t* thread, int priority,
  942. int realtime, void *(*start_routine)(void*), void* arg)
  943. {
  944. carla_stderr2("%s(%p, %p, %i, %i, %p, %p)", __FUNCTION__, client, thread, priority, realtime, start_routine, arg);
  945. return ENOSYS;
  946. }
  947. typedef void (*JackSessionCallback)(jack_session_event_t*, void*);
  948. CARLA_EXPORT
  949. int jack_set_session_callback(jack_client_t* client, JackSessionCallback callback, void* arg)
  950. {
  951. carla_stderr2("%s(%p, %p, %p)", __FUNCTION__, client, callback, arg);
  952. return 0;
  953. }
  954. // ---------------------------------------------------------------------------------------------------------------------