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.

1630 lines
61KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-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. #ifndef BUILD_BRIDGE
  18. # error This file should not be compiled if not building bridge
  19. #endif
  20. #include "CarlaEngineInternal.hpp"
  21. #include "CarlaPlugin.hpp"
  22. #include "CarlaBackendUtils.hpp"
  23. #include "CarlaBase64Utils.hpp"
  24. #include "CarlaBridgeUtils.hpp"
  25. #include "CarlaMIDI.h"
  26. #ifdef __SSE2_MATH__
  27. # include <xmmintrin.h>
  28. #endif
  29. // must be last
  30. #include "jackbridge/JackBridge.hpp"
  31. using juce::File;
  32. using juce::MemoryBlock;
  33. using juce::String;
  34. using juce::Time;
  35. using juce::Thread;
  36. template<typename T>
  37. bool jackbridge_shm_map2(void* shm, T*& value) noexcept
  38. {
  39. value = (T*)jackbridge_shm_map(shm, sizeof(T));
  40. return (value != nullptr);
  41. }
  42. CARLA_BACKEND_START_NAMESPACE
  43. // -------------------------------------------------------------------
  44. struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
  45. CarlaString filename;
  46. BridgeRtClientData* data;
  47. char shm[64];
  48. BridgeRtClientControl() noexcept
  49. : filename(),
  50. data(nullptr)
  51. {
  52. carla_zeroChars(shm, 64);
  53. jackbridge_shm_init(shm);
  54. }
  55. ~BridgeRtClientControl() noexcept override
  56. {
  57. // should be cleared by now
  58. CARLA_SAFE_ASSERT(data == nullptr);
  59. clear();
  60. }
  61. void clear() noexcept
  62. {
  63. filename.clear();
  64. if (data != nullptr)
  65. unmapData();
  66. if (! jackbridge_shm_is_valid(shm))
  67. return;
  68. jackbridge_shm_close(shm);
  69. jackbridge_shm_init(shm);
  70. }
  71. bool attach() noexcept
  72. {
  73. // must be invalid right now
  74. CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);
  75. jackbridge_shm_attach(shm, filename);
  76. return jackbridge_shm_is_valid(shm);
  77. }
  78. bool mapData() noexcept
  79. {
  80. CARLA_SAFE_ASSERT(data == nullptr);
  81. if (jackbridge_shm_map2<BridgeRtClientData>(shm, data))
  82. {
  83. CARLA_SAFE_ASSERT(data->midiOut[0] == 0);
  84. setRingBuffer(&data->ringBuffer, false);
  85. CARLA_SAFE_ASSERT_RETURN(jackbridge_sem_connect(&data->sem.server), false);
  86. CARLA_SAFE_ASSERT_RETURN(jackbridge_sem_connect(&data->sem.client), false);
  87. return true;
  88. }
  89. return false;
  90. }
  91. void unmapData() noexcept
  92. {
  93. data = nullptr;
  94. setRingBuffer(nullptr, false);
  95. }
  96. PluginBridgeRtClientOpcode readOpcode() noexcept
  97. {
  98. return static_cast<PluginBridgeRtClientOpcode>(readUInt());
  99. }
  100. // helper class that automatically posts semaphore on destructor
  101. struct WaitHelper {
  102. BridgeRtClientData* const data;
  103. const bool ok;
  104. WaitHelper(BridgeRtClientControl& c) noexcept
  105. : data(c.data),
  106. ok(jackbridge_sem_timedwait(&data->sem.server, 5000, false)) {}
  107. ~WaitHelper() noexcept
  108. {
  109. if (ok)
  110. jackbridge_sem_post(&data->sem.client, false);
  111. }
  112. CARLA_DECLARE_NON_COPY_STRUCT(WaitHelper)
  113. };
  114. CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtClientControl)
  115. };
  116. // -------------------------------------------------------------------
  117. struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
  118. CarlaString filename;
  119. BridgeNonRtClientData* data;
  120. char shm[64];
  121. BridgeNonRtClientControl() noexcept
  122. : filename(),
  123. data(nullptr)
  124. {
  125. carla_zeroChars(shm, 64);
  126. jackbridge_shm_init(shm);
  127. }
  128. ~BridgeNonRtClientControl() noexcept override
  129. {
  130. // should be cleared by now
  131. CARLA_SAFE_ASSERT(data == nullptr);
  132. clear();
  133. }
  134. void clear() noexcept
  135. {
  136. filename.clear();
  137. if (data != nullptr)
  138. unmapData();
  139. if (! jackbridge_shm_is_valid(shm))
  140. {
  141. CARLA_SAFE_ASSERT(data == nullptr);
  142. return;
  143. }
  144. jackbridge_shm_close(shm);
  145. jackbridge_shm_init(shm);
  146. }
  147. bool attach() noexcept
  148. {
  149. // must be invalid right now
  150. CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);
  151. jackbridge_shm_attach(shm, filename);
  152. return jackbridge_shm_is_valid(shm);
  153. }
  154. bool mapData() noexcept
  155. {
  156. CARLA_SAFE_ASSERT(data == nullptr);
  157. if (jackbridge_shm_map2<BridgeNonRtClientData>(shm, data))
  158. {
  159. setRingBuffer(&data->ringBuffer, false);
  160. return true;
  161. }
  162. return false;
  163. }
  164. void unmapData() noexcept
  165. {
  166. data = nullptr;
  167. setRingBuffer(nullptr, false);
  168. }
  169. PluginBridgeNonRtClientOpcode readOpcode() noexcept
  170. {
  171. return static_cast<PluginBridgeNonRtClientOpcode>(readUInt());
  172. }
  173. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
  174. };
  175. // -------------------------------------------------------------------
  176. struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
  177. CarlaMutex mutex;
  178. CarlaString filename;
  179. BridgeNonRtServerData* data;
  180. char shm[64];
  181. BridgeNonRtServerControl() noexcept
  182. : mutex(),
  183. filename(),
  184. data(nullptr)
  185. {
  186. carla_zeroChars(shm, 64);
  187. jackbridge_shm_init(shm);
  188. }
  189. ~BridgeNonRtServerControl() noexcept override
  190. {
  191. // should be cleared by now
  192. CARLA_SAFE_ASSERT(data == nullptr);
  193. clear();
  194. }
  195. void clear() noexcept
  196. {
  197. filename.clear();
  198. if (data != nullptr)
  199. unmapData();
  200. if (! jackbridge_shm_is_valid(shm))
  201. {
  202. CARLA_SAFE_ASSERT(data == nullptr);
  203. return;
  204. }
  205. jackbridge_shm_close(shm);
  206. jackbridge_shm_init(shm);
  207. }
  208. bool attach() noexcept
  209. {
  210. // must be invalid right now
  211. CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);
  212. jackbridge_shm_attach(shm, filename);
  213. return jackbridge_shm_is_valid(shm);
  214. }
  215. bool mapData() noexcept
  216. {
  217. CARLA_SAFE_ASSERT(data == nullptr);
  218. if (jackbridge_shm_map2<BridgeNonRtServerData>(shm, data))
  219. {
  220. setRingBuffer(&data->ringBuffer, false);
  221. return true;
  222. }
  223. return false;
  224. }
  225. void unmapData() noexcept
  226. {
  227. data = nullptr;
  228. setRingBuffer(nullptr, false);
  229. }
  230. void writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept
  231. {
  232. writeUInt(static_cast<uint32_t>(opcode));
  233. }
  234. void waitIfDataIsReachingLimit() noexcept
  235. {
  236. if (getAvailableDataSize() < HugeStackBuffer::size/4)
  237. return;
  238. for (int i=50; --i >= 0;)
  239. {
  240. if (getAvailableDataSize() >= HugeStackBuffer::size*3/4)
  241. {
  242. writeOpcode(kPluginBridgeNonRtServerPong);
  243. commitWrite();
  244. return;
  245. }
  246. carla_msleep(20);
  247. }
  248. carla_stderr("Client waitIfDataIsReachingLimit() reached and failed");
  249. }
  250. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
  251. };
  252. // -----------------------------------------------------------------------
  253. // Bridge Engine client
  254. struct LatencyChangedCallback {
  255. virtual ~LatencyChangedCallback() noexcept {}
  256. virtual void latencyChanged(const uint32_t samples) noexcept = 0;
  257. };
  258. class CarlaEngineBridgeClient : public CarlaEngineClient
  259. {
  260. public:
  261. CarlaEngineBridgeClient(const CarlaEngine& engine, LatencyChangedCallback* const cb)
  262. : CarlaEngineClient(engine),
  263. fLatencyCallback(cb) {}
  264. protected:
  265. void setLatency(const uint32_t samples) noexcept
  266. {
  267. if (getLatency() == samples)
  268. return;
  269. fLatencyCallback->latencyChanged(samples);
  270. CarlaEngineClient::setLatency(samples);
  271. }
  272. private:
  273. LatencyChangedCallback* const fLatencyCallback;
  274. CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineBridgeClient)
  275. };
  276. // -------------------------------------------------------------------
  277. class CarlaEngineBridge : public CarlaEngine,
  278. private Thread,
  279. private LatencyChangedCallback
  280. {
  281. public:
  282. CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName)
  283. : CarlaEngine(),
  284. Thread("CarlaEngineBridge"),
  285. fShmAudioPool(),
  286. fShmRtClientControl(),
  287. fShmNonRtClientControl(),
  288. fShmNonRtServerControl(),
  289. fBaseNameAudioPool(audioPoolBaseName),
  290. fIsOffline(false),
  291. fFirstIdle(true),
  292. fLastPingTime(-1)
  293. {
  294. carla_debug("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);
  295. fShmRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT;
  296. fShmRtClientControl.filename += rtClientBaseName;
  297. fShmNonRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT;
  298. fShmNonRtClientControl.filename += nonRtClientBaseName;
  299. fShmNonRtServerControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER;
  300. fShmNonRtServerControl.filename += nonRtServerBaseName;
  301. }
  302. ~CarlaEngineBridge() noexcept override
  303. {
  304. carla_debug("CarlaEngineBridge::~CarlaEngineBridge()");
  305. clear();
  306. }
  307. // -------------------------------------
  308. // CarlaEngine virtual calls
  309. bool init(const char* const clientName) override
  310. {
  311. carla_debug("CarlaEngineBridge::init(\"%s\")", clientName);
  312. if (! pData->init(clientName))
  313. {
  314. setLastError("Failed to init internal data");
  315. return false;
  316. }
  317. if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
  318. {
  319. carla_stderr("Failed to attach to audio pool shared memory");
  320. return false;
  321. }
  322. if (! fShmRtClientControl.attach())
  323. {
  324. clear();
  325. carla_stderr("Failed to attach to rt client control shared memory");
  326. return false;
  327. }
  328. if (! fShmRtClientControl.mapData())
  329. {
  330. clear();
  331. carla_stderr("Failed to map rt client control shared memory");
  332. return false;
  333. }
  334. if (! fShmNonRtClientControl.attach())
  335. {
  336. clear();
  337. carla_stderr("Failed to attach to non-rt client control shared memory");
  338. return false;
  339. }
  340. if (! fShmNonRtClientControl.mapData())
  341. {
  342. clear();
  343. carla_stderr("Failed to map non-rt control client shared memory");
  344. return false;
  345. }
  346. if (! fShmNonRtServerControl.attach())
  347. {
  348. clear();
  349. carla_stderr("Failed to attach to non-rt server control shared memory");
  350. return false;
  351. }
  352. if (! fShmNonRtServerControl.mapData())
  353. {
  354. clear();
  355. carla_stderr("Failed to map non-rt control server shared memory");
  356. return false;
  357. }
  358. PluginBridgeNonRtClientOpcode opcode;
  359. opcode = fShmNonRtClientControl.readOpcode();
  360. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);
  361. const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
  362. CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));
  363. const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
  364. CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));
  365. const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
  366. CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));
  367. opcode = fShmNonRtClientControl.readOpcode();
  368. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
  369. pData->bufferSize = fShmNonRtClientControl.readUInt();
  370. opcode = fShmNonRtClientControl.readOpcode();
  371. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
  372. pData->sampleRate = fShmNonRtClientControl.readDouble();
  373. pData->initTime(nullptr);
  374. if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
  375. return false;
  376. // tell backend we're live
  377. {
  378. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  379. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
  380. fShmNonRtServerControl.commitWrite();
  381. }
  382. startThread(10);
  383. return true;
  384. }
  385. bool close() override
  386. {
  387. carla_debug("CarlaEnginePlugin::close()");
  388. fLastPingTime = -1;
  389. CarlaEngine::close();
  390. stopThread(5000);
  391. clear();
  392. return true;
  393. }
  394. bool isRunning() const noexcept override
  395. {
  396. return isThreadRunning() || ! fFirstIdle;
  397. }
  398. bool isOffline() const noexcept override
  399. {
  400. return fIsOffline;
  401. }
  402. EngineType getType() const noexcept override
  403. {
  404. return kEngineTypeBridge;
  405. }
  406. const char* getCurrentDriverName() const noexcept override
  407. {
  408. return "Bridge";
  409. }
  410. CarlaEngineClient* addClient(CarlaPlugin* const) override
  411. {
  412. return new CarlaEngineBridgeClient(*this, this);
  413. }
  414. void idle() noexcept override
  415. {
  416. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  417. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  418. const bool wasFirstIdle(fFirstIdle);
  419. if (wasFirstIdle)
  420. {
  421. fFirstIdle = false;
  422. fLastPingTime = Time::currentTimeMillis();
  423. CARLA_SAFE_ASSERT(fLastPingTime > 0);
  424. char bufStr[STR_MAX+1];
  425. uint32_t bufStrSize;
  426. const CarlaEngineClient* const client(plugin->getEngineClient());
  427. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  428. // kPluginBridgeNonRtServerPluginInfo1
  429. {
  430. // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId
  431. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo1);
  432. fShmNonRtServerControl.writeUInt(plugin->getCategory());
  433. fShmNonRtServerControl.writeUInt(plugin->getHints());
  434. fShmNonRtServerControl.writeUInt(plugin->getOptionsAvailable());
  435. fShmNonRtServerControl.writeUInt(plugin->getOptionsEnabled());
  436. fShmNonRtServerControl.writeLong(plugin->getUniqueId());
  437. fShmNonRtServerControl.commitWrite();
  438. }
  439. // kPluginBridgeNonRtServerPluginInfo2
  440. {
  441. // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright)
  442. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo2);
  443. carla_zeroChars(bufStr, STR_MAX);
  444. plugin->getRealName(bufStr);
  445. bufStrSize = carla_fixedValue(1U, 64U, static_cast<uint32_t>(std::strlen(bufStr)));
  446. fShmNonRtServerControl.writeUInt(bufStrSize);
  447. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  448. carla_zeroChars(bufStr, STR_MAX);
  449. plugin->getLabel(bufStr);
  450. bufStrSize = carla_fixedValue(1U, 256U, static_cast<uint32_t>(std::strlen(bufStr)));
  451. fShmNonRtServerControl.writeUInt(bufStrSize);
  452. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  453. carla_zeroChars(bufStr, STR_MAX);
  454. plugin->getMaker(bufStr);
  455. bufStrSize = carla_fixedValue(1U, 64U, static_cast<uint32_t>(std::strlen(bufStr)));
  456. fShmNonRtServerControl.writeUInt(bufStrSize);
  457. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  458. carla_zeroChars(bufStr, STR_MAX);
  459. plugin->getCopyright(bufStr);
  460. bufStrSize = carla_fixedValue(1U, 64U, static_cast<uint32_t>(std::strlen(bufStr)));
  461. fShmNonRtServerControl.writeUInt(bufStrSize);
  462. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  463. fShmNonRtServerControl.commitWrite();
  464. }
  465. // kPluginBridgeNonRtServerAudioCount
  466. {
  467. const uint32_t aIns = plugin->getAudioInCount();
  468. const uint32_t aOuts = plugin->getAudioOutCount();
  469. // uint/ins, uint/outs
  470. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount);
  471. fShmNonRtServerControl.writeUInt(aIns);
  472. fShmNonRtServerControl.writeUInt(aOuts);
  473. fShmNonRtServerControl.commitWrite();
  474. // kPluginBridgeNonRtServerPortName
  475. for (uint32_t i=0; i<aIns; ++i)
  476. {
  477. const char* const portName(client->getAudioPortName(true, i));
  478. CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0');
  479. // byte/type, uint/index, uint/size, str[] (name)
  480. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName);
  481. fShmNonRtServerControl.writeByte(kPluginBridgePortAudioInput);
  482. fShmNonRtServerControl.writeUInt(i);
  483. bufStrSize = static_cast<uint32_t>(std::strlen(portName));
  484. fShmNonRtServerControl.writeUInt(bufStrSize);
  485. fShmNonRtServerControl.writeCustomData(portName, bufStrSize);
  486. }
  487. // kPluginBridgeNonRtServerPortName
  488. for (uint32_t i=0; i<aOuts; ++i)
  489. {
  490. const char* const portName(client->getAudioPortName(false, i));
  491. CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0');
  492. // byte/type, uint/index, uint/size, str[] (name)
  493. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName);
  494. fShmNonRtServerControl.writeByte(kPluginBridgePortAudioOutput);
  495. fShmNonRtServerControl.writeUInt(i);
  496. bufStrSize = static_cast<uint32_t>(std::strlen(portName));
  497. fShmNonRtServerControl.writeUInt(bufStrSize);
  498. fShmNonRtServerControl.writeCustomData(portName, bufStrSize);
  499. }
  500. }
  501. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  502. // kPluginBridgeNonRtServerMidiCount
  503. {
  504. // uint/ins, uint/outs
  505. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiCount);
  506. fShmNonRtServerControl.writeUInt(plugin->getMidiInCount());
  507. fShmNonRtServerControl.writeUInt(plugin->getMidiOutCount());
  508. fShmNonRtServerControl.commitWrite();
  509. }
  510. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  511. // kPluginBridgeNonRtServerCvCount
  512. {
  513. // uint/ins, uint/outs
  514. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerCvCount);
  515. fShmNonRtServerControl.writeUInt(plugin->getCVInCount());
  516. fShmNonRtServerControl.writeUInt(plugin->getCVOutCount());
  517. fShmNonRtServerControl.commitWrite();
  518. }
  519. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  520. // kPluginBridgeNonRtServerParameter*
  521. if (const uint32_t count = plugin->getParameterCount())
  522. {
  523. // uint/count
  524. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterCount);
  525. fShmNonRtServerControl.writeUInt(count);
  526. fShmNonRtServerControl.commitWrite();
  527. for (uint32_t i=0; i<count; ++i)
  528. {
  529. const ParameterData& paramData(plugin->getParameterData(i));
  530. if (paramData.type != PARAMETER_INPUT && paramData.type != PARAMETER_OUTPUT)
  531. continue;
  532. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  533. continue;
  534. // kPluginBridgeNonRtServerParameterData1
  535. {
  536. // uint/index, int/rindex, uint/type, uint/hints, short/cc
  537. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterData1);
  538. fShmNonRtServerControl.writeUInt(i);
  539. fShmNonRtServerControl.writeInt(paramData.rindex);
  540. fShmNonRtServerControl.writeUInt(paramData.type);
  541. fShmNonRtServerControl.writeUInt(paramData.hints);
  542. fShmNonRtServerControl.writeShort(paramData.midiCC);
  543. fShmNonRtServerControl.commitWrite();
  544. }
  545. // kPluginBridgeNonRtServerParameterData2
  546. {
  547. // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit)
  548. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterData2);
  549. fShmNonRtServerControl.writeUInt(i);
  550. carla_zeroChars(bufStr, STR_MAX);
  551. plugin->getParameterName(i, bufStr);
  552. bufStrSize = carla_fixedValue(1U, 32U, static_cast<uint32_t>(std::strlen(bufStr)));
  553. fShmNonRtServerControl.writeUInt(bufStrSize);
  554. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  555. carla_zeroChars(bufStr, STR_MAX);
  556. plugin->getParameterSymbol(i, bufStr);
  557. bufStrSize = carla_fixedValue(1U, 64U, static_cast<uint32_t>(std::strlen(bufStr)));
  558. fShmNonRtServerControl.writeUInt(bufStrSize);
  559. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  560. carla_zeroChars(bufStr, STR_MAX);
  561. plugin->getParameterUnit(i, bufStr);
  562. bufStrSize = carla_fixedValue(1U, 32U, static_cast<uint32_t>(std::strlen(bufStr)));
  563. fShmNonRtServerControl.writeUInt(bufStrSize);
  564. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  565. fShmNonRtServerControl.commitWrite();
  566. }
  567. // kPluginBridgeNonRtServerParameterRanges
  568. {
  569. const ParameterRanges& paramRanges(plugin->getParameterRanges(i));
  570. // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
  571. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterRanges);
  572. fShmNonRtServerControl.writeUInt(i);
  573. fShmNonRtServerControl.writeFloat(paramRanges.def);
  574. fShmNonRtServerControl.writeFloat(paramRanges.min);
  575. fShmNonRtServerControl.writeFloat(paramRanges.max);
  576. fShmNonRtServerControl.writeFloat(paramRanges.step);
  577. fShmNonRtServerControl.writeFloat(paramRanges.stepSmall);
  578. fShmNonRtServerControl.writeFloat(paramRanges.stepLarge);
  579. fShmNonRtServerControl.commitWrite();
  580. }
  581. // kPluginBridgeNonRtServerParameterValue2
  582. {
  583. // uint/index float/value (used for init/output parameters only, don't resend values)
  584. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterValue2);
  585. fShmNonRtServerControl.writeUInt(i);
  586. fShmNonRtServerControl.writeFloat(plugin->getParameterValue(i));
  587. fShmNonRtServerControl.commitWrite();
  588. }
  589. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  590. }
  591. }
  592. // kPluginBridgeNonRtServerProgram*
  593. if (const uint32_t count = plugin->getProgramCount())
  594. {
  595. // uint/count
  596. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerProgramCount);
  597. fShmNonRtServerControl.writeUInt(count);
  598. fShmNonRtServerControl.commitWrite();
  599. for (uint32_t i=0; i < count; ++i)
  600. {
  601. // uint/index, uint/size, str[] (name)
  602. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerProgramName);
  603. fShmNonRtServerControl.writeUInt(i);
  604. carla_zeroChars(bufStr, STR_MAX);
  605. plugin->getProgramName(i, bufStr);
  606. bufStrSize = carla_fixedValue(1U, 32U, static_cast<uint32_t>(std::strlen(bufStr)));
  607. fShmNonRtServerControl.writeUInt(bufStrSize);
  608. fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize);
  609. fShmNonRtServerControl.commitWrite();
  610. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  611. }
  612. }
  613. // kPluginBridgeNonRtServerMidiProgram*
  614. if (const uint32_t count = plugin->getMidiProgramCount())
  615. {
  616. // uint/count
  617. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiProgramCount);
  618. fShmNonRtServerControl.writeUInt(count);
  619. fShmNonRtServerControl.commitWrite();
  620. for (uint32_t i=0; i < count; ++i)
  621. {
  622. const MidiProgramData& mpData(plugin->getMidiProgramData(i));
  623. CARLA_SAFE_ASSERT_CONTINUE(mpData.name != nullptr);
  624. // uint/index, uint/bank, uint/program, uint/size, str[] (name)
  625. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiProgramData);
  626. fShmNonRtServerControl.writeUInt(i);
  627. fShmNonRtServerControl.writeUInt(mpData.bank);
  628. fShmNonRtServerControl.writeUInt(mpData.program);
  629. bufStrSize = carla_fixedValue(1U, 32U, static_cast<uint32_t>(std::strlen(mpData.name)));
  630. fShmNonRtServerControl.writeUInt(bufStrSize);
  631. fShmNonRtServerControl.writeCustomData(mpData.name, bufStrSize);
  632. fShmNonRtServerControl.commitWrite();
  633. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  634. }
  635. }
  636. if (const uint32_t latency = plugin->getLatencyInFrames())
  637. {
  638. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSetLatency);
  639. fShmNonRtServerControl.writeUInt(latency);
  640. fShmNonRtServerControl.commitWrite();
  641. }
  642. // ready!
  643. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
  644. fShmNonRtServerControl.commitWrite();
  645. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  646. carla_stdout("Carla Bridge Ready!");
  647. fLastPingTime = Time::currentTimeMillis();
  648. }
  649. // send parameter outputs
  650. if (const uint32_t count = plugin->getParameterCount())
  651. {
  652. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  653. for (uint32_t i=0; i < count; ++i)
  654. {
  655. if (! plugin->isParameterOutput(i))
  656. continue;
  657. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterValue2);
  658. fShmNonRtServerControl.writeUInt(i);
  659. fShmNonRtServerControl.writeFloat(plugin->getParameterValue(i));
  660. // parameter outputs are not that important, we can skip some
  661. if (! fShmNonRtServerControl.commitWrite())
  662. break;
  663. }
  664. }
  665. CarlaEngine::idle();
  666. try {
  667. handleNonRtData();
  668. } CARLA_SAFE_EXCEPTION("handleNonRtData");
  669. if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000 && ! wasFirstIdle)
  670. {
  671. carla_stderr("Did not receive ping message from server for 30 secs, closing...");
  672. threadShouldExit();
  673. callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
  674. }
  675. }
  676. void callback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr) noexcept override
  677. {
  678. CarlaEngine::callback(action, pluginId, value1, value2, value3, valueStr);
  679. if (fLastPingTime < 0)
  680. return;
  681. switch (action)
  682. {
  683. // uint/index float/value
  684. case ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED: {
  685. CARLA_SAFE_ASSERT_BREAK(value1 >= 0);
  686. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  687. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterValue);
  688. fShmNonRtServerControl.writeUInt(static_cast<uint>(value1));
  689. fShmNonRtServerControl.writeFloat(value3);
  690. fShmNonRtServerControl.commitWrite();
  691. } break;
  692. // uint/index float/value
  693. case ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED: {
  694. CARLA_SAFE_ASSERT_BREAK(value1 >= 0);
  695. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  696. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerDefaultValue);
  697. fShmNonRtServerControl.writeUInt(static_cast<uint>(value1));
  698. fShmNonRtServerControl.writeFloat(value3);
  699. fShmNonRtServerControl.commitWrite();
  700. } break;
  701. // int/index
  702. case ENGINE_CALLBACK_PROGRAM_CHANGED: {
  703. CARLA_SAFE_ASSERT_BREAK(value1 >= -1);
  704. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  705. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerCurrentProgram);
  706. fShmNonRtServerControl.writeInt(value1);
  707. fShmNonRtServerControl.commitWrite();
  708. } break;
  709. // int/index
  710. case ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED: {
  711. CARLA_SAFE_ASSERT_BREAK(value1 >= -1);
  712. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  713. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerCurrentMidiProgram);
  714. fShmNonRtServerControl.writeInt(value1);
  715. fShmNonRtServerControl.commitWrite();
  716. } break;
  717. case ENGINE_CALLBACK_UI_STATE_CHANGED:
  718. if (value1 != 1)
  719. {
  720. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  721. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
  722. fShmNonRtServerControl.commitWrite();
  723. }
  724. break;
  725. default:
  726. break;
  727. }
  728. }
  729. // -------------------------------------------------------------------
  730. void clear() noexcept
  731. {
  732. fShmAudioPool.clear();
  733. fShmRtClientControl.clear();
  734. fShmNonRtClientControl.clear();
  735. fShmNonRtServerControl.clear();
  736. }
  737. void handleNonRtData()
  738. {
  739. for (; fShmNonRtClientControl.isDataAvailableForReading();)
  740. {
  741. const PluginBridgeNonRtClientOpcode opcode(fShmNonRtClientControl.readOpcode());
  742. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  743. #ifdef DEBUG
  744. if (opcode != kPluginBridgeNonRtClientPing) {
  745. carla_debug("CarlaEngineBridge::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode));
  746. }
  747. #endif
  748. if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0)
  749. fLastPingTime = Time::currentTimeMillis();
  750. switch (opcode)
  751. {
  752. case kPluginBridgeNonRtClientNull:
  753. break;
  754. case kPluginBridgeNonRtClientPing: {
  755. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  756. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
  757. fShmNonRtServerControl.commitWrite();
  758. } break;
  759. case kPluginBridgeNonRtClientPingOnOff: {
  760. const uint32_t onOff(fShmNonRtClientControl.readBool());
  761. fLastPingTime = onOff ? Time::currentTimeMillis() : -1;
  762. } break;
  763. case kPluginBridgeNonRtClientActivate:
  764. if (plugin != nullptr && plugin->isEnabled())
  765. plugin->setActive(true, false, false);
  766. break;
  767. case kPluginBridgeNonRtClientDeactivate:
  768. if (plugin != nullptr && plugin->isEnabled())
  769. plugin->setActive(false, false, false);
  770. break;
  771. case kPluginBridgeNonRtClientSetBufferSize: {
  772. const uint32_t bufferSize(fShmNonRtClientControl.readUInt());
  773. pData->bufferSize = bufferSize;
  774. bufferSizeChanged(bufferSize);
  775. break;
  776. }
  777. case kPluginBridgeNonRtClientSetSampleRate: {
  778. const double sampleRate(fShmNonRtClientControl.readDouble());
  779. pData->sampleRate = sampleRate;
  780. sampleRateChanged(sampleRate);
  781. break;
  782. }
  783. case kPluginBridgeNonRtClientSetOffline:
  784. fIsOffline = true;
  785. offlineModeChanged(true);
  786. break;
  787. case kPluginBridgeNonRtClientSetOnline:
  788. fIsOffline = false;
  789. offlineModeChanged(false);
  790. break;
  791. case kPluginBridgeNonRtClientSetParameterValue: {
  792. const uint32_t index(fShmNonRtClientControl.readUInt());
  793. const float value(fShmNonRtClientControl.readFloat());
  794. if (plugin != nullptr && plugin->isEnabled())
  795. plugin->setParameterValue(index, value, false, false, false);
  796. break;
  797. }
  798. case kPluginBridgeNonRtClientSetParameterMidiChannel: {
  799. const uint32_t index(fShmNonRtClientControl.readUInt());
  800. const uint8_t channel(fShmNonRtClientControl.readByte());
  801. if (plugin != nullptr && plugin->isEnabled())
  802. plugin->setParameterMidiChannel(index, channel, false, false);
  803. break;
  804. }
  805. case kPluginBridgeNonRtClientSetParameterMidiCC: {
  806. const uint32_t index(fShmNonRtClientControl.readUInt());
  807. const int16_t cc(fShmNonRtClientControl.readShort());
  808. if (plugin != nullptr && plugin->isEnabled())
  809. plugin->setParameterMidiCC(index, cc, false, false);
  810. break;
  811. }
  812. case kPluginBridgeNonRtClientSetProgram: {
  813. const int32_t index(fShmNonRtClientControl.readInt());
  814. if (plugin != nullptr && plugin->isEnabled())
  815. plugin->setProgram(index, false, false, false);
  816. break;
  817. }
  818. case kPluginBridgeNonRtClientSetMidiProgram: {
  819. const int32_t index(fShmNonRtClientControl.readInt());
  820. if (plugin != nullptr && plugin->isEnabled())
  821. plugin->setMidiProgram(index, false, false, false);
  822. break;
  823. }
  824. case kPluginBridgeNonRtClientSetCustomData: {
  825. // type
  826. const uint32_t typeSize(fShmNonRtClientControl.readUInt());
  827. char typeStr[typeSize+1];
  828. carla_zeroChars(typeStr, typeSize+1);
  829. fShmNonRtClientControl.readCustomData(typeStr, typeSize);
  830. // key
  831. const uint32_t keySize(fShmNonRtClientControl.readUInt());
  832. char keyStr[keySize+1];
  833. carla_zeroChars(keyStr, keySize+1);
  834. fShmNonRtClientControl.readCustomData(keyStr, keySize);
  835. // value
  836. const uint32_t valueSize(fShmNonRtClientControl.readUInt());
  837. char valueStr[valueSize+1];
  838. carla_zeroChars(valueStr, valueSize+1);
  839. fShmNonRtClientControl.readCustomData(valueStr, valueSize);
  840. if (plugin != nullptr && plugin->isEnabled())
  841. plugin->setCustomData(typeStr, keyStr, valueStr, true);
  842. break;
  843. }
  844. case kPluginBridgeNonRtClientSetChunkDataFile: {
  845. const uint32_t size(fShmNonRtClientControl.readUInt());
  846. CARLA_SAFE_ASSERT_BREAK(size > 0);
  847. char chunkFilePathTry[size+1];
  848. carla_zeroChars(chunkFilePathTry, size+1);
  849. fShmNonRtClientControl.readCustomData(chunkFilePathTry, size);
  850. CARLA_SAFE_ASSERT_BREAK(chunkFilePathTry[0] != '\0');
  851. if (plugin == nullptr || ! plugin->isEnabled()) break;
  852. String chunkFilePath(chunkFilePathTry);
  853. #ifdef CARLA_OS_WIN
  854. // check if running under Wine
  855. if (chunkFilePath.startsWith("/"))
  856. chunkFilePath = chunkFilePath.replaceSection(0, 1, "Z:\\").replace("/", "\\");
  857. #endif
  858. File chunkFile(chunkFilePath);
  859. CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile());
  860. String chunkDataBase64(chunkFile.loadFileAsString());
  861. chunkFile.deleteFile();
  862. CARLA_SAFE_ASSERT_BREAK(chunkDataBase64.isNotEmpty());
  863. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(chunkDataBase64.toRawUTF8()));
  864. plugin->setChunkData(chunk.data(), chunk.size());
  865. break;
  866. }
  867. case kPluginBridgeNonRtClientSetCtrlChannel: {
  868. const int16_t channel(fShmNonRtClientControl.readShort());
  869. CARLA_SAFE_ASSERT_BREAK(channel >= -1 && channel < MAX_MIDI_CHANNELS);
  870. if (plugin != nullptr && plugin->isEnabled())
  871. plugin->setCtrlChannel(static_cast<int8_t>(channel), false, false);
  872. break;
  873. }
  874. case kPluginBridgeNonRtClientSetOption: {
  875. const uint32_t option(fShmNonRtClientControl.readUInt());
  876. const bool yesNo(fShmNonRtClientControl.readBool());
  877. if (plugin != nullptr && plugin->isEnabled())
  878. plugin->setOption(option, yesNo, false);
  879. break;
  880. }
  881. case kPluginBridgeNonRtClientPrepareForSave: {
  882. if (plugin == nullptr || ! plugin->isEnabled()) break;
  883. plugin->prepareForSave();
  884. for (uint32_t i=0, count=plugin->getCustomDataCount(); i<count; ++i)
  885. {
  886. const CustomData& cdata(plugin->getCustomData(i));
  887. if (std::strcmp(cdata.type, CUSTOM_DATA_TYPE_STRING) == 0 && std::strcmp(cdata.key, "CarlaLoadLv2StateNow") == 0 && std::strcmp(cdata.value, "true") == 0)
  888. continue;
  889. const uint32_t typeLen(static_cast<uint32_t>(std::strlen(cdata.type)));
  890. const uint32_t keyLen(static_cast<uint32_t>(std::strlen(cdata.key)));
  891. const uint32_t valueLen(static_cast<uint32_t>(std::strlen(cdata.value)));
  892. {
  893. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  894. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSetCustomData);
  895. fShmNonRtServerControl.writeUInt(typeLen);
  896. fShmNonRtServerControl.writeCustomData(cdata.type, typeLen);
  897. fShmNonRtServerControl.writeUInt(keyLen);
  898. fShmNonRtServerControl.writeCustomData(cdata.key, keyLen);
  899. fShmNonRtServerControl.writeUInt(valueLen);
  900. fShmNonRtServerControl.writeCustomData(cdata.value, valueLen);
  901. fShmNonRtServerControl.commitWrite();
  902. fShmNonRtServerControl.waitIfDataIsReachingLimit();
  903. }
  904. }
  905. if (plugin->getOptionsEnabled() & PLUGIN_OPTION_USE_CHUNKS)
  906. {
  907. void* data = nullptr;
  908. if (const std::size_t dataSize = plugin->getChunkData(&data))
  909. {
  910. CARLA_SAFE_ASSERT_BREAK(data != nullptr);
  911. CarlaString dataBase64 = CarlaString::asBase64(data, dataSize);
  912. CARLA_SAFE_ASSERT_BREAK(dataBase64.length() > 0);
  913. String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName());
  914. filePath += CARLA_OS_SEP_STR;
  915. filePath += ".CarlaChunk_";
  916. filePath += fShmNonRtClientControl.filename.buffer() + 24;
  917. if (File(filePath).replaceWithText(dataBase64.buffer()))
  918. {
  919. const uint32_t ulength(static_cast<uint32_t>(filePath.length()));
  920. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  921. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSetChunkDataFile);
  922. fShmNonRtServerControl.writeUInt(ulength);
  923. fShmNonRtServerControl.writeCustomData(filePath.toRawUTF8(), ulength);
  924. fShmNonRtServerControl.commitWrite();
  925. }
  926. }
  927. }
  928. {
  929. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  930. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSaved);
  931. fShmNonRtServerControl.commitWrite();
  932. }
  933. break;
  934. }
  935. case kPluginBridgeNonRtClientShowUI:
  936. if (plugin != nullptr && plugin->isEnabled())
  937. plugin->showCustomUI(true);
  938. break;
  939. case kPluginBridgeNonRtClientHideUI:
  940. if (plugin != nullptr && plugin->isEnabled())
  941. plugin->showCustomUI(false);
  942. break;
  943. case kPluginBridgeNonRtClientUiParameterChange: {
  944. const uint32_t index(fShmNonRtClientControl.readUInt());
  945. const float value(fShmNonRtClientControl.readFloat());
  946. if (plugin != nullptr && plugin->isEnabled())
  947. plugin->uiParameterChange(index, value);
  948. break;
  949. }
  950. case kPluginBridgeNonRtClientUiProgramChange: {
  951. const uint32_t index(fShmNonRtClientControl.readUInt());
  952. if (plugin != nullptr && plugin->isEnabled())
  953. plugin->uiProgramChange(index);
  954. break;
  955. }
  956. case kPluginBridgeNonRtClientUiMidiProgramChange: {
  957. const uint32_t index(fShmNonRtClientControl.readUInt());
  958. if (plugin != nullptr && plugin->isEnabled())
  959. plugin->uiMidiProgramChange(index);
  960. break;
  961. }
  962. case kPluginBridgeNonRtClientUiNoteOn: {
  963. const uint8_t chnl(fShmNonRtClientControl.readByte());
  964. const uint8_t note(fShmNonRtClientControl.readByte());
  965. const uint8_t velo(fShmNonRtClientControl.readByte());
  966. if (plugin != nullptr && plugin->isEnabled())
  967. plugin->uiNoteOn(chnl, note, velo);
  968. break;
  969. }
  970. case kPluginBridgeNonRtClientUiNoteOff: {
  971. const uint8_t chnl(fShmNonRtClientControl.readByte());
  972. const uint8_t note(fShmNonRtClientControl.readByte());
  973. if (plugin != nullptr && plugin->isEnabled())
  974. plugin->uiNoteOff(chnl, note);
  975. break;
  976. }
  977. case kPluginBridgeNonRtClientQuit:
  978. signalThreadShouldExit();
  979. callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
  980. break;
  981. }
  982. }
  983. }
  984. // -------------------------------------------------------------------
  985. protected:
  986. void run() override
  987. {
  988. #ifdef __SSE2_MATH__
  989. // Set FTZ and DAZ flags
  990. _mm_setcsr(_mm_getcsr() | 0x8040);
  991. #endif
  992. bool quitReceived = false;
  993. for (; ! threadShouldExit();)
  994. {
  995. const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);
  996. if (! helper.ok)
  997. continue;
  998. for (; fShmRtClientControl.isDataAvailableForReading();)
  999. {
  1000. const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
  1001. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  1002. #ifdef DEBUG
  1003. if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
  1004. carla_debug("CarlaEngineBridgeRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
  1005. }
  1006. #endif
  1007. switch (opcode)
  1008. {
  1009. case kPluginBridgeRtClientNull:
  1010. break;
  1011. case kPluginBridgeRtClientSetAudioPool: {
  1012. if (fShmAudioPool.data != nullptr)
  1013. {
  1014. jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
  1015. fShmAudioPool.data = nullptr;
  1016. }
  1017. const uint64_t poolSize(fShmRtClientControl.readULong());
  1018. CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
  1019. fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
  1020. break;
  1021. }
  1022. case kPluginBridgeRtClientControlEventParameter: {
  1023. const uint32_t time(fShmRtClientControl.readUInt());
  1024. const uint8_t channel(fShmRtClientControl.readByte());
  1025. const uint16_t param(fShmRtClientControl.readUShort());
  1026. const float value(fShmRtClientControl.readFloat());
  1027. if (EngineEvent* const event = getNextFreeInputEvent())
  1028. {
  1029. event->type = kEngineEventTypeControl;
  1030. event->time = time;
  1031. event->channel = channel;
  1032. event->ctrl.type = kEngineControlEventTypeParameter;
  1033. event->ctrl.param = param;
  1034. event->ctrl.value = value;
  1035. }
  1036. break;
  1037. }
  1038. case kPluginBridgeRtClientControlEventMidiBank: {
  1039. const uint32_t time(fShmRtClientControl.readUInt());
  1040. const uint8_t channel(fShmRtClientControl.readByte());
  1041. const uint16_t index(fShmRtClientControl.readUShort());
  1042. if (EngineEvent* const event = getNextFreeInputEvent())
  1043. {
  1044. event->type = kEngineEventTypeControl;
  1045. event->time = time;
  1046. event->channel = channel;
  1047. event->ctrl.type = kEngineControlEventTypeMidiBank;
  1048. event->ctrl.param = index;
  1049. event->ctrl.value = 0.0f;
  1050. }
  1051. break;
  1052. }
  1053. case kPluginBridgeRtClientControlEventMidiProgram: {
  1054. const uint32_t time(fShmRtClientControl.readUInt());
  1055. const uint8_t channel(fShmRtClientControl.readByte());
  1056. const uint16_t index(fShmRtClientControl.readUShort());
  1057. if (EngineEvent* const event = getNextFreeInputEvent())
  1058. {
  1059. event->type = kEngineEventTypeControl;
  1060. event->time = time;
  1061. event->channel = channel;
  1062. event->ctrl.type = kEngineControlEventTypeMidiProgram;
  1063. event->ctrl.param = index;
  1064. event->ctrl.value = 0.0f;
  1065. }
  1066. break;
  1067. }
  1068. case kPluginBridgeRtClientControlEventAllSoundOff: {
  1069. const uint32_t time(fShmRtClientControl.readUInt());
  1070. const uint8_t channel(fShmRtClientControl.readByte());
  1071. if (EngineEvent* const event = getNextFreeInputEvent())
  1072. {
  1073. event->type = kEngineEventTypeControl;
  1074. event->time = time;
  1075. event->channel = channel;
  1076. event->ctrl.type = kEngineControlEventTypeAllSoundOff;
  1077. event->ctrl.param = 0;
  1078. event->ctrl.value = 0.0f;
  1079. }
  1080. } break;
  1081. case kPluginBridgeRtClientControlEventAllNotesOff: {
  1082. const uint32_t time(fShmRtClientControl.readUInt());
  1083. const uint8_t channel(fShmRtClientControl.readByte());
  1084. if (EngineEvent* const event = getNextFreeInputEvent())
  1085. {
  1086. event->type = kEngineEventTypeControl;
  1087. event->time = time;
  1088. event->channel = channel;
  1089. event->ctrl.type = kEngineControlEventTypeAllNotesOff;
  1090. event->ctrl.param = 0;
  1091. event->ctrl.value = 0.0f;
  1092. }
  1093. } break;
  1094. case kPluginBridgeRtClientMidiEvent: {
  1095. const uint32_t time(fShmRtClientControl.readUInt());
  1096. const uint8_t port(fShmRtClientControl.readByte());
  1097. const uint8_t size(fShmRtClientControl.readByte());
  1098. CARLA_SAFE_ASSERT_BREAK(size > 0);
  1099. uint8_t data[size];
  1100. for (uint8_t i=0; i<size; ++i)
  1101. data[i] = fShmRtClientControl.readByte();
  1102. if (EngineEvent* const event = getNextFreeInputEvent())
  1103. {
  1104. event->type = kEngineEventTypeMidi;
  1105. event->time = time;
  1106. event->channel = MIDI_GET_CHANNEL_FROM_DATA(data);
  1107. event->midi.port = port;
  1108. event->midi.size = size;
  1109. if (size > EngineMidiEvent::kDataSize)
  1110. {
  1111. event->midi.dataExt = data;
  1112. std::memset(event->midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize);
  1113. }
  1114. else
  1115. {
  1116. event->midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data);
  1117. uint8_t i=1;
  1118. for (; i < size; ++i)
  1119. event->midi.data[i] = data[i];
  1120. for (; i < EngineMidiEvent::kDataSize; ++i)
  1121. event->midi.data[i] = 0;
  1122. event->midi.dataExt = nullptr;
  1123. }
  1124. }
  1125. break;
  1126. }
  1127. case kPluginBridgeRtClientProcess: {
  1128. CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);
  1129. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(false))
  1130. {
  1131. const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
  1132. const uint32_t audioInCount(plugin->getAudioInCount());
  1133. const uint32_t audioOutCount(plugin->getAudioOutCount());
  1134. const uint32_t cvInCount(plugin->getCVInCount());
  1135. const uint32_t cvOutCount(plugin->getCVOutCount());
  1136. const float* audioIn[audioInCount];
  1137. /* */ float* audioOut[audioOutCount];
  1138. const float* cvIn[cvInCount];
  1139. /* */ float* cvOut[cvOutCount];
  1140. float* fdata = fShmAudioPool.data;
  1141. for (uint32_t i=0; i < audioInCount; ++i, fdata += pData->bufferSize)
  1142. audioIn[i] = fdata;
  1143. for (uint32_t i=0; i < audioOutCount; ++i, fdata += pData->bufferSize)
  1144. audioOut[i] = fdata;
  1145. for (uint32_t i=0; i < cvInCount; ++i, fdata += pData->bufferSize)
  1146. cvIn[i] = fdata;
  1147. for (uint32_t i=0; i < cvOutCount; ++i, fdata += pData->bufferSize)
  1148. cvOut[i] = fdata;
  1149. EngineTimeInfo& timeInfo(pData->timeInfo);
  1150. timeInfo.playing = bridgeTimeInfo.playing;
  1151. timeInfo.frame = bridgeTimeInfo.frame;
  1152. timeInfo.usecs = bridgeTimeInfo.usecs;
  1153. timeInfo.valid = bridgeTimeInfo.valid;
  1154. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  1155. {
  1156. timeInfo.bbt.bar = bridgeTimeInfo.bar;
  1157. timeInfo.bbt.beat = bridgeTimeInfo.beat;
  1158. timeInfo.bbt.tick = bridgeTimeInfo.tick;
  1159. timeInfo.bbt.beatsPerBar = bridgeTimeInfo.beatsPerBar;
  1160. timeInfo.bbt.beatType = bridgeTimeInfo.beatType;
  1161. timeInfo.bbt.ticksPerBeat = bridgeTimeInfo.ticksPerBeat;
  1162. timeInfo.bbt.beatsPerMinute = bridgeTimeInfo.beatsPerMinute;
  1163. timeInfo.bbt.barStartTick = bridgeTimeInfo.barStartTick;
  1164. }
  1165. plugin->initBuffers();
  1166. plugin->process(audioIn, audioOut, cvIn, cvOut, pData->bufferSize);
  1167. plugin->unlock();
  1168. }
  1169. uint8_t* midiData(fShmRtClientControl.data->midiOut);
  1170. carla_zeroBytes(midiData, kBridgeRtClientDataMidiOutSize);
  1171. std::size_t curMidiDataPos = 0;
  1172. if (pData->events.in[0].type != kEngineEventTypeNull)
  1173. carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
  1174. if (pData->events.out[0].type != kEngineEventTypeNull)
  1175. {
  1176. for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
  1177. {
  1178. const EngineEvent& event(pData->events.out[i]);
  1179. if (event.type == kEngineEventTypeNull)
  1180. break;
  1181. if (event.type == kEngineEventTypeControl)
  1182. {
  1183. uint8_t size;
  1184. uint8_t data[3];
  1185. event.ctrl.convertToMidiData(event.channel, size, data);
  1186. CARLA_SAFE_ASSERT_CONTINUE(size > 0 && size <= 3);
  1187. if (curMidiDataPos + 1U /* size*/ + 4U /* time */ + size >= kBridgeRtClientDataMidiOutSize)
  1188. break;
  1189. // set size
  1190. *midiData++ = size;
  1191. // set time
  1192. *(uint32_t*)midiData = event.time;
  1193. midiData = midiData + 4;
  1194. // set data
  1195. for (uint8_t j=0; j<size; ++j)
  1196. *midiData++ = data[j];
  1197. curMidiDataPos += 1U /* size*/ + 4U /* time */ + size;
  1198. }
  1199. else if (event.type == kEngineEventTypeMidi)
  1200. {
  1201. const EngineMidiEvent& _midiEvent(event.midi);
  1202. if (curMidiDataPos + 1 /* size*/ + 4 /* time */ + _midiEvent.size >= kBridgeRtClientDataMidiOutSize)
  1203. break;
  1204. const uint8_t* const _midiData(_midiEvent.dataExt != nullptr ? _midiEvent.dataExt : _midiEvent.data);
  1205. // set size
  1206. *midiData++ = _midiEvent.size;
  1207. // set time
  1208. *(uint32_t*)midiData = event.time;
  1209. midiData = midiData + 4;
  1210. // set data
  1211. *midiData++ = uint8_t(_midiData[0] | (event.channel & MIDI_CHANNEL_BIT));
  1212. for (uint8_t j=1; j<_midiEvent.size; ++j)
  1213. *midiData++ = _midiData[j];
  1214. curMidiDataPos += 1U /* size*/ + 4U /* time */ + _midiEvent.size;
  1215. }
  1216. }
  1217. carla_zeroStructs(pData->events.out, kMaxEngineEventInternalCount);
  1218. }
  1219. } break;
  1220. case kPluginBridgeRtClientQuit: {
  1221. quitReceived = true;
  1222. signalThreadShouldExit();
  1223. } break;
  1224. }
  1225. }
  1226. }
  1227. callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
  1228. if (! quitReceived)
  1229. {
  1230. const char* const message("Plugin bridge error, process thread has stopped");
  1231. const std::size_t messageSize(std::strlen(message));
  1232. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  1233. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
  1234. fShmNonRtServerControl.writeUInt(messageSize);
  1235. fShmNonRtServerControl.writeCustomData(message, messageSize);
  1236. fShmNonRtServerControl.commitWrite();
  1237. }
  1238. }
  1239. // called from process thread above
  1240. EngineEvent* getNextFreeInputEvent() const noexcept
  1241. {
  1242. for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
  1243. {
  1244. EngineEvent* const event(&pData->events.in[i]);
  1245. if (event->type == kEngineEventTypeNull)
  1246. return event;
  1247. }
  1248. return nullptr;
  1249. }
  1250. void latencyChanged(const uint32_t samples) noexcept
  1251. {
  1252. const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
  1253. fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSetLatency);
  1254. fShmNonRtServerControl.writeUInt(samples);
  1255. fShmNonRtServerControl.commitWrite();
  1256. }
  1257. // -------------------------------------------------------------------
  1258. private:
  1259. BridgeAudioPool fShmAudioPool;
  1260. BridgeRtClientControl fShmRtClientControl;
  1261. BridgeNonRtClientControl fShmNonRtClientControl;
  1262. BridgeNonRtServerControl fShmNonRtServerControl;
  1263. CarlaString fBaseNameAudioPool;
  1264. bool fIsOffline;
  1265. bool fFirstIdle;
  1266. int64_t fLastPingTime;
  1267. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineBridge)
  1268. };
  1269. // -----------------------------------------------------------------------
  1270. CarlaEngine* CarlaEngine::newBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName)
  1271. {
  1272. return new CarlaEngineBridge(audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);
  1273. }
  1274. // -----------------------------------------------------------------------
  1275. #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1276. CarlaPlugin* CarlaPlugin::newNative(const CarlaPlugin::Initializer&) { return nullptr; }
  1277. CarlaPlugin* CarlaPlugin::newFileGIG(const CarlaPlugin::Initializer&, const bool) { return nullptr; }
  1278. CarlaPlugin* CarlaPlugin::newFileSF2(const CarlaPlugin::Initializer&, const bool) { return nullptr; }
  1279. CarlaPlugin* CarlaPlugin::newFileSFZ(const CarlaPlugin::Initializer&) { return nullptr; }
  1280. #endif
  1281. CARLA_BACKEND_END_NAMESPACE
  1282. // -----------------------------------------------------------------------
  1283. #if defined(CARLA_OS_WIN) && ! defined(__WINE__)
  1284. extern "C" __declspec (dllexport)
  1285. #else
  1286. extern "C" __attribute__ ((visibility("default")))
  1287. #endif
  1288. void carla_register_native_plugin_carla();
  1289. void carla_register_native_plugin_carla(){}
  1290. #include "CarlaBridgeUtils.cpp"
  1291. // -----------------------------------------------------------------------