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.

1121 lines
38KB

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