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.

1533 lines
58KB

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