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.

1257 lines
43KB

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