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.

1227 lines
42KB

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