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.

1472 lines
54KB

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