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.

1110 lines
37KB

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