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.

1977 lines
62KB

  1. /*
  2. * Carla Bridge Plugin
  3. * Copyright (C) 2011-2013 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 GPL.txt file
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #ifndef BUILD_BRIDGE
  19. #include "CarlaBridgeUtils.hpp"
  20. #include "CarlaShmUtils.hpp"
  21. #include "jackbridge/JackBridge.hpp"
  22. #include <cerrno>
  23. #include <cmath>
  24. #include <ctime>
  25. #include <QtCore/QDir>
  26. #include <QtCore/QFile>
  27. #include <QtCore/QStringList>
  28. #include <QtCore/QTextStream>
  29. #define CARLA_BRIDGE_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
  30. /* check argument count */ \
  31. if (argc != argcToCompare) \
  32. { \
  33. carla_stderr("BridgePlugin::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
  34. return 1; \
  35. } \
  36. if (argc > 0) \
  37. { \
  38. /* check for nullness */ \
  39. if (! (types && typesToCompare)) \
  40. { \
  41. carla_stderr("BridgePlugin::%s() - argument types are null", __FUNCTION__); \
  42. return 1; \
  43. } \
  44. /* check argument types */ \
  45. if (std::strcmp(types, typesToCompare) != 0) \
  46. { \
  47. carla_stderr("BridgePlugin::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
  48. return 1; \
  49. } \
  50. }
  51. CARLA_BACKEND_START_NAMESPACE
  52. // -------------------------------------------------------------------------------------------------------------------
  53. // Engine Helpers
  54. extern void registerEnginePlugin(CarlaEngine* const engine, const unsigned int id, CarlaPlugin* const plugin);
  55. // -------------------------------------------------------------------------------------------------------------------
  56. shm_t shm_mkstemp(char* const fileBase)
  57. {
  58. static const char charSet[] = "abcdefghijklmnopqrstuvwxyz"
  59. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  60. "0123456789";
  61. const size_t fileBaseLen((fileBase != nullptr) ? std::strlen(fileBase) : 0);
  62. shm_t fakeShm;
  63. carla_shm_init(fakeShm);
  64. if (fileBaseLen < 6)
  65. {
  66. errno = EINVAL;
  67. return fakeShm;
  68. }
  69. if (std::strcmp(fileBase + fileBaseLen - 6, "XXXXXX") != 0)
  70. {
  71. errno = EINVAL;
  72. return fakeShm;
  73. }
  74. for (;;)
  75. {
  76. for (size_t c = fileBaseLen - 6; c < fileBaseLen; ++c)
  77. {
  78. // Note the -1 to avoid the trailing '\0' in charSet.
  79. fileBase[c] = charSet[std::rand() % (sizeof(charSet) - 1)];
  80. }
  81. shm_t shm = carla_shm_create(fileBase);
  82. if (carla_is_shm_valid(shm) || errno != EEXIST)
  83. return shm;
  84. }
  85. }
  86. // -------------------------------------------------------------------------------------------------------------------
  87. struct BridgeAudioPool {
  88. CarlaString filename;
  89. float* data;
  90. size_t size;
  91. shm_t shm;
  92. BridgeAudioPool()
  93. : data(nullptr),
  94. size(0)
  95. {
  96. carla_shm_init(shm);
  97. }
  98. ~BridgeAudioPool()
  99. {
  100. // should be cleared by now
  101. CARLA_ASSERT(data == nullptr);
  102. clear();
  103. }
  104. void clear()
  105. {
  106. filename.clear();
  107. if (! carla_is_shm_valid(shm))
  108. return;
  109. if (data != nullptr)
  110. {
  111. carla_shm_unmap(shm, data, size);
  112. data = nullptr;
  113. }
  114. size = 0;
  115. carla_shm_close(shm);
  116. }
  117. void resize(const uint32_t bufferSize, const uint32_t portCount)
  118. {
  119. if (data != nullptr)
  120. carla_shm_unmap(shm, data, size);
  121. size = portCount*bufferSize*sizeof(float);
  122. if (size == 0)
  123. size = sizeof(float);
  124. data = (float*)carla_shm_map(shm, size);
  125. }
  126. };
  127. struct BridgeControl : public RingBufferControl {
  128. CarlaString filename;
  129. BridgeShmControl* data;
  130. shm_t shm;
  131. BridgeControl()
  132. : RingBufferControl(nullptr),
  133. data(nullptr)
  134. {
  135. carla_shm_init(shm);
  136. }
  137. ~BridgeControl()
  138. {
  139. // should be cleared by now
  140. CARLA_ASSERT(data == nullptr);
  141. clear();
  142. }
  143. void clear()
  144. {
  145. filename.clear();
  146. if (! carla_is_shm_valid(shm))
  147. return;
  148. if (data != nullptr)
  149. {
  150. carla_shm_unmap(shm, data, sizeof(BridgeShmControl));
  151. data = nullptr;
  152. }
  153. carla_shm_close(shm);
  154. }
  155. bool mapData()
  156. {
  157. CARLA_ASSERT(data == nullptr);
  158. if (carla_shm_map<BridgeShmControl>(shm, data))
  159. {
  160. setRingBuffer(&data->ringBuffer, true);
  161. return true;
  162. }
  163. return false;
  164. }
  165. void unmapData()
  166. {
  167. CARLA_ASSERT(data != nullptr);
  168. if (data == nullptr)
  169. return;
  170. carla_shm_unmap(shm, data, sizeof(BridgeShmControl));
  171. data = nullptr;
  172. setRingBuffer(nullptr, false);
  173. }
  174. bool waitForServer()
  175. {
  176. CARLA_ASSERT(data != nullptr);
  177. if (data == nullptr)
  178. return false;
  179. jackbridge_sem_post(&data->runServer);
  180. return jackbridge_sem_timedwait(&data->runClient, 5);
  181. }
  182. void writeOpcode(const PluginBridgeOpcode opcode)
  183. {
  184. writeInt(static_cast<int>(opcode));
  185. }
  186. };
  187. struct BridgeParamInfo {
  188. float value;
  189. CarlaString name;
  190. CarlaString unit;
  191. BridgeParamInfo()
  192. : value(0.0f) {}
  193. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(BridgeParamInfo)
  194. };
  195. // -------------------------------------------------------------------------------------------------------------------
  196. class BridgePlugin : public CarlaPlugin
  197. {
  198. public:
  199. BridgePlugin(CarlaEngine* const engine, const unsigned int id, const BinaryType btype, const PluginType ptype)
  200. : CarlaPlugin(engine, id),
  201. fBinaryType(btype),
  202. fPluginType(ptype),
  203. fInitiated(false),
  204. fInitError(false),
  205. fSaved(false),
  206. fNeedsSemDestroy(false),
  207. fParams(nullptr)
  208. {
  209. carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype));
  210. kData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_BRIDGE);
  211. fHints |= PLUGIN_IS_BRIDGE;
  212. }
  213. ~BridgePlugin() override
  214. {
  215. carla_debug("BridgePlugin::~BridgePlugin()");
  216. kData->singleMutex.lock();
  217. kData->masterMutex.lock();
  218. if (kData->client != nullptr && kData->client->isActive())
  219. kData->client->deactivate();
  220. if (kData->active)
  221. {
  222. deactivate();
  223. kData->active = false;
  224. }
  225. if (kData->osc.thread.isRunning())
  226. {
  227. fShmControl.writeOpcode(kPluginBridgeOpcodeQuit);
  228. fShmControl.commitWrite();
  229. fShmControl.waitForServer();
  230. }
  231. if (kData->osc.data.target != nullptr)
  232. {
  233. osc_send_hide(&kData->osc.data);
  234. osc_send_quit(&kData->osc.data);
  235. }
  236. kData->osc.data.free();
  237. // Wait a bit first, then force kill
  238. if (kData->osc.thread.isRunning() && ! kData->osc.thread.wait(kData->engine->getOptions().oscUiTimeout))
  239. {
  240. carla_stderr("Failed to properly stop Plugin Bridge thread");
  241. kData->osc.thread.terminate();
  242. }
  243. if (fNeedsSemDestroy)
  244. {
  245. jackbridge_sem_destroy(&fShmControl.data->runServer);
  246. jackbridge_sem_destroy(&fShmControl.data->runClient);
  247. }
  248. fShmAudioPool.clear();
  249. fShmControl.clear();
  250. clearBuffers();
  251. //info.chunk.clear();
  252. }
  253. // -------------------------------------------------------------------
  254. // Information (base)
  255. BinaryType binaryType() const
  256. {
  257. return fBinaryType;
  258. }
  259. PluginType type() const override
  260. {
  261. return fPluginType;
  262. }
  263. PluginCategory category() override
  264. {
  265. return fInfo.category;
  266. }
  267. long uniqueId() const override
  268. {
  269. return fInfo.uniqueId;
  270. }
  271. // -------------------------------------------------------------------
  272. // Information (count)
  273. uint32_t midiInCount() const override
  274. {
  275. return fInfo.mIns;
  276. }
  277. uint32_t midiOutCount() const override
  278. {
  279. return fInfo.mOuts;
  280. }
  281. // -------------------------------------------------------------------
  282. // Information (current data)
  283. int32_t chunkData(void** const dataPtr) override
  284. {
  285. CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS);
  286. CARLA_ASSERT(dataPtr != nullptr);
  287. #if 0
  288. if (! info.chunk.isEmpty())
  289. {
  290. *dataPtr = info.chunk.data();
  291. return info.chunk.size();
  292. }
  293. #endif
  294. return 0;
  295. }
  296. // -------------------------------------------------------------------
  297. // Information (per-plugin data)
  298. unsigned int availableOptions() override
  299. {
  300. unsigned int options = 0x0;
  301. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  302. options |= PLUGIN_OPTION_USE_CHUNKS;
  303. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  304. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  305. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  306. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  307. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  308. return options;
  309. }
  310. float getParameterValue(const uint32_t parameterId) override
  311. {
  312. CARLA_ASSERT(parameterId < kData->param.count);
  313. return fParams[parameterId].value;
  314. }
  315. void getLabel(char* const strBuf) override
  316. {
  317. std::strncpy(strBuf, (const char*)fInfo.label, STR_MAX);
  318. }
  319. void getMaker(char* const strBuf) override
  320. {
  321. std::strncpy(strBuf, (const char*)fInfo.maker, STR_MAX);
  322. }
  323. void getCopyright(char* const strBuf) override
  324. {
  325. std::strncpy(strBuf, (const char*)fInfo.copyright, STR_MAX);
  326. }
  327. void getRealName(char* const strBuf) override
  328. {
  329. std::strncpy(strBuf, (const char*)fInfo.name, STR_MAX);
  330. }
  331. void getParameterName(const uint32_t parameterId, char* const strBuf) override
  332. {
  333. CARLA_ASSERT(parameterId < kData->param.count);
  334. std::strncpy(strBuf, (const char*)fParams[parameterId].name, STR_MAX);
  335. }
  336. void getParameterUnit(const uint32_t parameterId, char* const strBuf) override
  337. {
  338. CARLA_ASSERT(parameterId < kData->param.count);
  339. std::strncpy(strBuf, (const char*)fParams[parameterId].unit, STR_MAX);
  340. }
  341. // -------------------------------------------------------------------
  342. // Set data (state)
  343. void prepareForSave() override
  344. {
  345. #if 0
  346. m_saved = false;
  347. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SAVE_NOW, "");
  348. for (int i=0; i < 200; ++i)
  349. {
  350. if (m_saved)
  351. break;
  352. carla_msleep(50);
  353. }
  354. if (! m_saved)
  355. carla_stderr("BridgePlugin::prepareForSave() - Timeout while requesting save state");
  356. else
  357. carla_debug("BridgePlugin::prepareForSave() - success!");
  358. #endif
  359. }
  360. // -------------------------------------------------------------------
  361. // Set data (internal stuff)
  362. // nothing
  363. // -------------------------------------------------------------------
  364. // Set data (plugin-specific stuff)
  365. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  366. {
  367. CARLA_ASSERT(parameterId < kData->param.count);
  368. const float fixedValue(kData->param.fixValue(parameterId, value));
  369. fParams[parameterId].value = fixedValue;
  370. const bool doLock(sendGui || sendOsc || sendCallback);
  371. if (doLock)
  372. kData->singleMutex.lock();
  373. fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
  374. fShmControl.writeInt(parameterId);
  375. fShmControl.writeFloat(value);
  376. if (doLock)
  377. {
  378. fShmControl.commitWrite();
  379. kData->singleMutex.unlock();
  380. }
  381. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  382. }
  383. void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  384. {
  385. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->prog.count));
  386. if (index < -1)
  387. index = -1;
  388. else if (index > static_cast<int32_t>(kData->prog.count))
  389. return;
  390. const bool doLock(sendGui || sendOsc || sendCallback);
  391. if (doLock)
  392. kData->singleMutex.lock();
  393. fShmControl.writeOpcode(kPluginBridgeOpcodeSetProgram);
  394. fShmControl.writeInt(index);
  395. if (doLock)
  396. {
  397. fShmControl.commitWrite();
  398. kData->singleMutex.unlock();
  399. }
  400. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback);
  401. }
  402. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  403. {
  404. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));
  405. if (index < -1)
  406. index = -1;
  407. else if (index > static_cast<int32_t>(kData->midiprog.count))
  408. return;
  409. const bool doLock(sendGui || sendOsc || sendCallback);
  410. if (doLock)
  411. kData->singleMutex.lock();
  412. fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram);
  413. fShmControl.writeInt(index);
  414. if (doLock)
  415. {
  416. fShmControl.commitWrite();
  417. kData->singleMutex.unlock();
  418. }
  419. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  420. }
  421. #if 0
  422. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  423. {
  424. CARLA_ASSERT(type);
  425. CARLA_ASSERT(key);
  426. CARLA_ASSERT(value);
  427. if (sendGui)
  428. {
  429. // TODO - if type is chunk|binary, store it in a file and send path instead
  430. QString cData;
  431. cData = type;
  432. cData += "·";
  433. cData += key;
  434. cData += "·";
  435. cData += value;
  436. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CUSTOM, cData.toUtf8().constData());
  437. }
  438. CarlaPlugin::setCustomData(type, key, value, sendGui);
  439. }
  440. void setChunkData(const char* const stringData) override
  441. {
  442. CARLA_ASSERT(m_hints & PLUGIN_USES_CHUNKS);
  443. CARLA_ASSERT(stringData);
  444. QString filePath;
  445. filePath = QDir::tempPath();
  446. filePath += "/.CarlaChunk_";
  447. filePath += m_name;
  448. filePath = QDir::toNativeSeparators(filePath);
  449. QFile file(filePath);
  450. if (file.open(QIODevice::WriteOnly | QIODevice::Text))
  451. {
  452. QTextStream out(&file);
  453. out << stringData;
  454. file.close();
  455. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CHUNK, filePath.toUtf8().constData());
  456. }
  457. }
  458. #endif
  459. // -------------------------------------------------------------------
  460. // Set gui stuff
  461. void showGui(const bool yesNo) override
  462. {
  463. if (yesNo)
  464. osc_send_show(&kData->osc.data);
  465. else
  466. osc_send_hide(&kData->osc.data);
  467. }
  468. void idleGui() override
  469. {
  470. if (! kData->osc.thread.isRunning())
  471. carla_stderr2("TESTING: Bridge has closed!");
  472. CarlaPlugin::idleGui();
  473. }
  474. // -------------------------------------------------------------------
  475. // Plugin state
  476. void reload() override
  477. {
  478. carla_debug("BridgePlugin::reload() - start");
  479. CARLA_ASSERT(kData->engine != nullptr);
  480. if (kData->engine == nullptr)
  481. return;
  482. const ProcessMode processMode(kData->engine->getProccessMode());
  483. // Safely disable plugin for reload
  484. const ScopedDisabler sd(this);
  485. bool needsCtrlIn, needsCtrlOut;
  486. needsCtrlIn = needsCtrlOut = false;
  487. if (fInfo.aIns > 0)
  488. {
  489. kData->audioIn.createNew(fInfo.aIns);
  490. }
  491. if (fInfo.aOuts > 0)
  492. {
  493. kData->audioOut.createNew(fInfo.aOuts);
  494. needsCtrlIn = true;
  495. }
  496. if (fInfo.mIns > 0)
  497. needsCtrlIn = true;
  498. if (fInfo.mOuts > 0)
  499. needsCtrlOut = true;
  500. const uint portNameSize(kData->engine->maxPortNameSize());
  501. CarlaString portName;
  502. // Audio Ins
  503. for (uint32_t j=0; j < fInfo.aIns; ++j)
  504. {
  505. portName.clear();
  506. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  507. {
  508. portName = fName;
  509. portName += ":";
  510. }
  511. if (fInfo.aIns > 1)
  512. {
  513. portName += "input_";
  514. portName += CarlaString(j+1);
  515. }
  516. else
  517. portName += "input";
  518. portName.truncate(portNameSize);
  519. kData->audioIn.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
  520. kData->audioIn.ports[j].rindex = j;
  521. }
  522. // Audio Outs
  523. for (uint32_t j=0; j < fInfo.aOuts; ++j)
  524. {
  525. portName.clear();
  526. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  527. {
  528. portName = fName;
  529. portName += ":";
  530. }
  531. if (fInfo.aOuts > 1)
  532. {
  533. portName += "output_";
  534. portName += CarlaString(j+1);
  535. }
  536. else
  537. portName += "output";
  538. portName.truncate(portNameSize);
  539. kData->audioOut.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  540. kData->audioOut.ports[j].rindex = j;
  541. }
  542. if (needsCtrlIn)
  543. {
  544. portName.clear();
  545. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  546. {
  547. portName = fName;
  548. portName += ":";
  549. }
  550. portName += "event-in";
  551. portName.truncate(portNameSize);
  552. kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
  553. }
  554. if (needsCtrlOut)
  555. {
  556. portName.clear();
  557. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  558. {
  559. portName = fName;
  560. portName += ":";
  561. }
  562. portName += "event-out";
  563. portName.truncate(portNameSize);
  564. kData->event.portOut = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);
  565. }
  566. bufferSizeChanged(kData->engine->getBufferSize());
  567. reloadPrograms(true);
  568. carla_debug("BridgePlugin::reload() - end");
  569. }
  570. // -------------------------------------------------------------------
  571. // Plugin processing
  572. void activate() override
  573. {
  574. // already locked before
  575. fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
  576. fShmControl.writeInt(PARAMETER_ACTIVE);
  577. fShmControl.writeFloat(1.0f);
  578. fShmControl.commitWrite();
  579. waitForServer();
  580. }
  581. void deactivate() override
  582. {
  583. // already locked before
  584. fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
  585. fShmControl.writeInt(PARAMETER_ACTIVE);
  586. fShmControl.writeFloat(0.0f);
  587. fShmControl.commitWrite();
  588. waitForServer();
  589. }
  590. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  591. {
  592. uint32_t i, k;
  593. // --------------------------------------------------------------------------------------------------------
  594. // Check if active
  595. if (! kData->active)
  596. {
  597. // disable any output sound
  598. for (i=0; i < kData->audioOut.count; ++i)
  599. carla_zeroFloat(outBuffer[i], frames);
  600. return;
  601. }
  602. // --------------------------------------------------------------------------------------------------------
  603. // Check if needs reset
  604. if (kData->needsReset)
  605. {
  606. // TODO
  607. kData->needsReset = false;
  608. }
  609. // --------------------------------------------------------------------------------------------------------
  610. // Event Input
  611. if (kData->event.portIn != nullptr)
  612. {
  613. // ----------------------------------------------------------------------------------------------------
  614. // MIDI Input (External)
  615. if (kData->extNotes.mutex.tryLock())
  616. {
  617. while (! kData->extNotes.data.isEmpty())
  618. {
  619. const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));
  620. CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  621. char data1, data2, data3;
  622. data1 = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF;
  623. data1 += note.channel;
  624. data2 = note.note;
  625. data3 = note.velo;
  626. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  627. fShmControl.writeLong(0);
  628. fShmControl.writeInt(3);
  629. fShmControl.writeChar(data1);
  630. fShmControl.writeChar(data2);
  631. fShmControl.writeChar(data3);
  632. }
  633. kData->extNotes.mutex.unlock();
  634. } // End of MIDI Input (External)
  635. // ----------------------------------------------------------------------------------------------------
  636. // Event Input (System)
  637. bool allNotesOffSent = false;
  638. uint32_t nEvents = kData->event.portIn->getEventCount();
  639. uint32_t nextBankId = 0;
  640. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  641. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  642. for (i=0; i < nEvents; ++i)
  643. {
  644. const EngineEvent& event(kData->event.portIn->getEvent(i));
  645. // Control change
  646. switch (event.type)
  647. {
  648. case kEngineEventTypeNull:
  649. break;
  650. case kEngineEventTypeControl:
  651. {
  652. const EngineControlEvent& ctrlEvent = event.ctrl;
  653. switch (ctrlEvent.type)
  654. {
  655. case kEngineControlEventTypeNull:
  656. break;
  657. case kEngineControlEventTypeParameter:
  658. {
  659. // Control backend stuff
  660. if (event.channel == kData->ctrlChannel)
  661. {
  662. float value;
  663. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
  664. {
  665. value = ctrlEvent.value;
  666. setDryWet(value, false, false);
  667. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  668. }
  669. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
  670. {
  671. value = ctrlEvent.value*127.0f/100.0f;
  672. setVolume(value, false, false);
  673. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  674. }
  675. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
  676. {
  677. float left, right;
  678. value = ctrlEvent.value/0.5f - 1.0f;
  679. if (value < 0.0f)
  680. {
  681. left = -1.0f;
  682. right = (value*2.0f)+1.0f;
  683. }
  684. else if (value > 0.0f)
  685. {
  686. left = (value*2.0f)-1.0f;
  687. right = 1.0f;
  688. }
  689. else
  690. {
  691. left = -1.0f;
  692. right = 1.0f;
  693. }
  694. setBalanceLeft(left, false, false);
  695. setBalanceRight(right, false, false);
  696. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  697. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  698. }
  699. }
  700. // Control plugin parameters
  701. for (k=0; k < kData->param.count; ++k)
  702. {
  703. if (kData->param.data[k].midiChannel != event.channel)
  704. continue;
  705. if (kData->param.data[k].midiCC != ctrlEvent.param)
  706. continue;
  707. if (kData->param.data[k].type != PARAMETER_INPUT)
  708. continue;
  709. if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  710. continue;
  711. float value;
  712. if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  713. {
  714. value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
  715. }
  716. else
  717. {
  718. value = kData->param.ranges[k].unnormalizeValue(ctrlEvent.value);
  719. if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
  720. value = std::rint(value);
  721. }
  722. setParameterValue(k, value, false, false, false);
  723. postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  724. }
  725. if ((fOptions & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  726. {
  727. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  728. fShmControl.writeLong(event.time);
  729. fShmControl.writeInt(3);
  730. fShmControl.writeChar(MIDI_STATUS_CONTROL_CHANGE + event.channel);
  731. fShmControl.writeChar(ctrlEvent.param);
  732. fShmControl.writeChar(ctrlEvent.value*127.0f);
  733. }
  734. break;
  735. }
  736. case kEngineControlEventTypeMidiBank:
  737. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  738. nextBankId = ctrlEvent.param;
  739. break;
  740. case kEngineControlEventTypeMidiProgram:
  741. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  742. {
  743. const uint32_t nextProgramId(ctrlEvent.param);
  744. if (kData->midiprog.count > 0)
  745. {
  746. for (k=0; k < kData->midiprog.count; ++k)
  747. {
  748. if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
  749. {
  750. setMidiProgram(k, false, false, false);
  751. postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
  752. break;
  753. }
  754. }
  755. }
  756. else
  757. {
  758. }
  759. }
  760. break;
  761. case kEngineControlEventTypeAllSoundOff:
  762. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  763. {
  764. // TODO
  765. }
  766. break;
  767. case kEngineControlEventTypeAllNotesOff:
  768. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  769. {
  770. if (event.channel == kData->ctrlChannel && ! allNotesOffSent)
  771. {
  772. allNotesOffSent = true;
  773. sendMidiAllNotesOffToCallback();
  774. }
  775. // TODO
  776. }
  777. break;
  778. }
  779. break;
  780. }
  781. case kEngineEventTypeMidi:
  782. {
  783. const EngineMidiEvent& midiEvent(event.midi);
  784. uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
  785. uint8_t channel = event.channel;
  786. if (MIDI_IS_STATUS_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  787. continue;
  788. if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fOptions & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  789. continue;
  790. if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  791. continue;
  792. if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (fOptions & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  793. continue;
  794. // Fix bad note-off
  795. if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
  796. status -= 0x10;
  797. char data[4];
  798. data[0] = status + channel;
  799. data[1] = midiEvent.data[1];
  800. data[2] = midiEvent.data[2];
  801. data[3] = midiEvent.data[3];
  802. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  803. fShmControl.writeLong(event.time);
  804. fShmControl.writeInt(midiEvent.size);
  805. for (uint8_t j=0; j < midiEvent.size && j < 4; ++j)
  806. fShmControl.writeChar(data[j]);
  807. if (status == MIDI_STATUS_NOTE_ON)
  808. postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
  809. else if (status == MIDI_STATUS_NOTE_OFF)
  810. postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
  811. break;
  812. }
  813. }
  814. }
  815. kData->postRtEvents.trySplice();
  816. } // End of Event Input
  817. processSingle(inBuffer, outBuffer, frames);
  818. }
  819. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  820. {
  821. CARLA_ASSERT(frames > 0);
  822. if (frames == 0)
  823. return false;
  824. if (kData->audioIn.count > 0)
  825. {
  826. CARLA_ASSERT(inBuffer != nullptr);
  827. if (inBuffer == nullptr)
  828. return false;
  829. }
  830. if (kData->audioOut.count > 0)
  831. {
  832. CARLA_ASSERT(outBuffer != nullptr);
  833. if (outBuffer == nullptr)
  834. return false;
  835. }
  836. uint32_t i, k;
  837. // --------------------------------------------------------------------------------------------------------
  838. // Try lock, silence otherwise
  839. if (kData->engine->isOffline())
  840. {
  841. kData->singleMutex.lock();
  842. }
  843. else if (! kData->singleMutex.tryLock())
  844. {
  845. for (i=0; i < kData->audioOut.count; ++i)
  846. carla_zeroFloat(outBuffer[i], frames);
  847. return false;
  848. }
  849. // --------------------------------------------------------------------------------------------------------
  850. // Reset audio buffers
  851. for (i=0; i < fInfo.aIns; ++i)
  852. carla_copyFloat(fShmAudioPool.data + (i * frames), inBuffer[i], frames);
  853. // --------------------------------------------------------------------------------------------------------
  854. // Run plugin
  855. fShmControl.writeOpcode(kPluginBridgeOpcodeProcess);
  856. fShmControl.commitWrite();
  857. if (! waitForServer())
  858. {
  859. kData->singleMutex.unlock();
  860. return true;
  861. }
  862. for (i=0; i < fInfo.aOuts; ++i)
  863. carla_copyFloat(outBuffer[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), frames);
  864. // --------------------------------------------------------------------------------------------------------
  865. // Post-processing (dry/wet, volume and balance)
  866. {
  867. const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) != 0 && kData->postProc.volume != 1.0f;
  868. const bool doDryWet = (fHints & PLUGIN_CAN_DRYWET) != 0 && kData->postProc.dryWet != 1.0f;
  869. const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) != 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);
  870. bool isPair;
  871. float bufValue, oldBufLeft[doBalance ? frames : 1];
  872. for (i=0; i < kData->audioOut.count; ++i)
  873. {
  874. // Dry/Wet
  875. if (doDryWet)
  876. {
  877. for (k=0; k < frames; ++k)
  878. {
  879. bufValue = inBuffer[(kData->audioIn.count == 1) ? 0 : i][k];
  880. outBuffer[i][k] = (outBuffer[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
  881. }
  882. }
  883. // Balance
  884. if (doBalance)
  885. {
  886. isPair = (i % 2 == 0);
  887. if (isPair)
  888. {
  889. CARLA_ASSERT(i+1 < kData->audioOut.count);
  890. carla_copyFloat(oldBufLeft, outBuffer[i], frames);
  891. }
  892. float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
  893. float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;
  894. for (k=0; k < frames; ++k)
  895. {
  896. if (isPair)
  897. {
  898. // left
  899. outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  900. outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
  901. }
  902. else
  903. {
  904. // right
  905. outBuffer[i][k] = outBuffer[i][k] * balRangeR;
  906. outBuffer[i][k] += oldBufLeft[k] * balRangeL;
  907. }
  908. }
  909. }
  910. // Volume
  911. if (doVolume)
  912. {
  913. for (k=0; k < frames; ++k)
  914. outBuffer[i][k] *= kData->postProc.volume;
  915. }
  916. }
  917. } // End of Post-processing
  918. // --------------------------------------------------------------------------------------------------------
  919. kData->singleMutex.unlock();
  920. return true;
  921. }
  922. void bufferSizeChanged(const uint32_t newBufferSize) override
  923. {
  924. resizeAudioPool(newBufferSize);
  925. fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize);
  926. fShmControl.writeInt(newBufferSize);
  927. fShmControl.commitWrite();
  928. }
  929. void sampleRateChanged(const double newSampleRate) override
  930. {
  931. fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate);
  932. fShmControl.writeFloat(newSampleRate);
  933. fShmControl.commitWrite();
  934. }
  935. // -------------------------------------------------------------------
  936. // Plugin buffers
  937. void clearBuffers() override
  938. {
  939. if (fParams != nullptr)
  940. {
  941. delete[] fParams;
  942. fParams = nullptr;
  943. }
  944. CarlaPlugin::clearBuffers();
  945. }
  946. // -------------------------------------------------------------------
  947. // Post-poned UI Stuff
  948. // nothing
  949. // -------------------------------------------------------------------
  950. int setOscPluginBridgeInfo(const PluginBridgeInfoType type, const int argc, const lo_arg* const* const argv, const char* const types)
  951. {
  952. carla_debug("setOscPluginBridgeInfo(%s, %i, %p, \"%s\")", PluginBridgeInfoType2str(type), argc, argv, types);
  953. switch (type)
  954. {
  955. case kPluginBridgeAudioCount:
  956. {
  957. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  958. const int32_t aIns = argv[0]->i;
  959. const int32_t aOuts = argv[1]->i;
  960. const int32_t aTotal = argv[2]->i;
  961. CARLA_ASSERT(aIns >= 0);
  962. CARLA_ASSERT(aOuts >= 0);
  963. CARLA_ASSERT(aIns + aOuts == aTotal);
  964. fInfo.aIns = aIns;
  965. fInfo.aOuts = aOuts;
  966. break;
  967. // unused
  968. (void)aTotal;
  969. }
  970. case kPluginBridgeMidiCount:
  971. {
  972. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  973. const int32_t mIns = argv[0]->i;
  974. const int32_t mOuts = argv[1]->i;
  975. const int32_t mTotal = argv[2]->i;
  976. CARLA_ASSERT(mIns >= 0);
  977. CARLA_ASSERT(mOuts >= 0);
  978. CARLA_ASSERT(mIns + mOuts == mTotal);
  979. fInfo.mIns = mIns;
  980. fInfo.mOuts = mOuts;
  981. break;
  982. // unused
  983. (void)mTotal;
  984. }
  985. case kPluginBridgeParameterCount:
  986. {
  987. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  988. const int32_t pIns = argv[0]->i;
  989. const int32_t pOuts = argv[1]->i;
  990. const int32_t pTotal = argv[2]->i;
  991. CARLA_ASSERT(pIns >= 0);
  992. CARLA_ASSERT(pOuts >= 0);
  993. CARLA_ASSERT(pIns + pOuts <= pTotal);
  994. // delete old data
  995. kData->param.clear();
  996. if (fParams != nullptr)
  997. {
  998. delete[] fParams;
  999. fParams = nullptr;
  1000. }
  1001. CARLA_SAFE_ASSERT_INT2(pTotal < static_cast<int32_t>(kData->engine->getOptions().maxParameters), pTotal, kData->engine->getOptions().maxParameters);
  1002. const int32_t count(carla_min<int32_t>(pTotal, kData->engine->getOptions().maxParameters, 0));
  1003. if (count > 0)
  1004. {
  1005. kData->param.createNew(count);
  1006. fParams = new BridgeParamInfo[count];
  1007. }
  1008. break;
  1009. // unused
  1010. (void)pIns;
  1011. (void)pOuts;
  1012. }
  1013. case kPluginBridgeProgramCount:
  1014. {
  1015. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1016. const int32_t count = argv[0]->i;
  1017. CARLA_ASSERT(count >= 0);
  1018. kData->prog.clear();
  1019. if (count > 0)
  1020. kData->prog.createNew(count);
  1021. break;
  1022. }
  1023. case kPluginBridgeMidiProgramCount:
  1024. {
  1025. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1026. const int32_t count = argv[0]->i;
  1027. CARLA_ASSERT(count >= 0);
  1028. kData->midiprog.clear();
  1029. if (count > 0)
  1030. kData->midiprog.createNew(count);
  1031. break;
  1032. }
  1033. case kPluginBridgePluginInfo:
  1034. {
  1035. CARLA_BRIDGE_CHECK_OSC_TYPES(7, "iissssh");
  1036. const int32_t category = argv[0]->i;
  1037. const int32_t hints = argv[1]->i;
  1038. const char* const name = (const char*)&argv[2]->s;
  1039. const char* const label = (const char*)&argv[3]->s;
  1040. const char* const maker = (const char*)&argv[4]->s;
  1041. const char* const copyright = (const char*)&argv[5]->s;
  1042. const int64_t uniqueId = argv[6]->h;
  1043. CARLA_ASSERT(category >= 0);
  1044. CARLA_ASSERT(hints >= 0);
  1045. CARLA_ASSERT(name != nullptr);
  1046. CARLA_ASSERT(label != nullptr);
  1047. CARLA_ASSERT(maker != nullptr);
  1048. CARLA_ASSERT(copyright != nullptr);
  1049. fHints = hints | PLUGIN_IS_BRIDGE;
  1050. fInfo.category = static_cast<PluginCategory>(category);
  1051. fInfo.uniqueId = uniqueId;
  1052. fInfo.name = name;
  1053. fInfo.label = label;
  1054. fInfo.maker = maker;
  1055. fInfo.copyright = copyright;
  1056. if (fName.isEmpty())
  1057. fName = name;
  1058. break;
  1059. }
  1060. case kPluginBridgeParameterInfo:
  1061. {
  1062. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iss");
  1063. const int32_t index = argv[0]->i;
  1064. const char* const name = (const char*)&argv[1]->s;
  1065. const char* const unit = (const char*)&argv[2]->s;
  1066. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->param.count), index, kData->param.count);
  1067. CARLA_ASSERT(name != nullptr);
  1068. CARLA_ASSERT(unit != nullptr);
  1069. if (index >= 0 && static_cast<int32_t>(kData->param.count))
  1070. {
  1071. fParams[index].name = name;
  1072. fParams[index].unit = unit;
  1073. }
  1074. break;
  1075. }
  1076. case kPluginBridgeParameterData:
  1077. {
  1078. CARLA_BRIDGE_CHECK_OSC_TYPES(6, "iiiiii");
  1079. const int32_t index = argv[0]->i;
  1080. const int32_t type = argv[1]->i;
  1081. const int32_t rindex = argv[2]->i;
  1082. const int32_t hints = argv[3]->i;
  1083. const int32_t channel = argv[4]->i;
  1084. const int32_t cc = argv[5]->i;
  1085. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->param.count), index, kData->param.count);
  1086. CARLA_ASSERT(type >= 0);
  1087. CARLA_ASSERT(rindex >= 0);
  1088. CARLA_ASSERT(hints >= 0);
  1089. CARLA_ASSERT(channel >= 0 && channel < 16);
  1090. CARLA_ASSERT(cc >= -1);
  1091. if (index >= 0 && static_cast<int32_t>(kData->param.count))
  1092. {
  1093. kData->param.data[index].type = static_cast<ParameterType>(type);
  1094. kData->param.data[index].index = index;
  1095. kData->param.data[index].rindex = rindex;
  1096. kData->param.data[index].hints = hints;
  1097. kData->param.data[index].midiChannel = channel;
  1098. kData->param.data[index].midiCC = cc;
  1099. }
  1100. break;
  1101. }
  1102. case kPluginBridgeParameterRanges:
  1103. {
  1104. CARLA_BRIDGE_CHECK_OSC_TYPES(7, "iffffff");
  1105. const int32_t index = argv[0]->i;
  1106. const float def = argv[1]->f;
  1107. const float min = argv[2]->f;
  1108. const float max = argv[3]->f;
  1109. const float step = argv[4]->f;
  1110. const float stepSmall = argv[5]->f;
  1111. const float stepLarge = argv[6]->f;
  1112. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->param.count), index, kData->param.count);
  1113. CARLA_ASSERT(min < max);
  1114. CARLA_ASSERT(def >= min);
  1115. CARLA_ASSERT(def <= max);
  1116. if (index >= 0 && static_cast<int32_t>(kData->param.count))
  1117. {
  1118. kData->param.ranges[index].def = def;
  1119. kData->param.ranges[index].min = min;
  1120. kData->param.ranges[index].max = max;
  1121. kData->param.ranges[index].step = step;
  1122. kData->param.ranges[index].stepSmall = stepSmall;
  1123. kData->param.ranges[index].stepLarge = stepLarge;
  1124. }
  1125. break;
  1126. }
  1127. case kPluginBridgeProgramInfo:
  1128. {
  1129. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "is");
  1130. const int32_t index = argv[0]->i;
  1131. const char* const name = (const char*)&argv[1]->s;
  1132. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->prog.count), index, kData->prog.count);
  1133. CARLA_ASSERT(name != nullptr);
  1134. if (index >= 0 && index < static_cast<int32_t>(kData->prog.count))
  1135. {
  1136. if (kData->prog.names[index] != nullptr)
  1137. delete[] kData->prog.names[index];
  1138. kData->prog.names[index] = carla_strdup(name);
  1139. }
  1140. break;
  1141. }
  1142. case kPluginBridgeMidiProgramInfo:
  1143. {
  1144. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "iiis");
  1145. const int32_t index = argv[0]->i;
  1146. const int32_t bank = argv[1]->i;
  1147. const int32_t program = argv[2]->i;
  1148. const char* const name = (const char*)&argv[3]->s;
  1149. CARLA_ASSERT_INT2(index < static_cast<int32_t>(kData->midiprog.count), index, kData->midiprog.count);
  1150. CARLA_ASSERT(bank >= 0);
  1151. CARLA_ASSERT(program >= 0 && program < 128);
  1152. CARLA_ASSERT(name != nullptr);
  1153. if (index >= 0 && index < static_cast<int32_t>(kData->midiprog.count))
  1154. {
  1155. if (kData->midiprog.data[index].name != nullptr)
  1156. delete[] kData->midiprog.data[index].name;
  1157. kData->midiprog.data[index].bank = bank;
  1158. kData->midiprog.data[index].program = program;
  1159. kData->midiprog.data[index].name = carla_strdup(name);
  1160. }
  1161. break;
  1162. }
  1163. case kPluginBridgeConfigure:
  1164. {
  1165. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ss");
  1166. const char* const key = (const char*)&argv[0]->s;
  1167. const char* const value = (const char*)&argv[1]->s;
  1168. CARLA_ASSERT(key != nullptr);
  1169. CARLA_ASSERT(value != nullptr);
  1170. if (key == nullptr || value == nullptr)
  1171. break;
  1172. if (std::strcmp(key, CARLA_BRIDGE_MSG_HIDE_GUI) == 0)
  1173. kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
  1174. else if (std::strcmp(key, CARLA_BRIDGE_MSG_SAVED) == 0)
  1175. fSaved = true;
  1176. break;
  1177. }
  1178. case kPluginBridgeSetParameterValue:
  1179. {
  1180. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "if");
  1181. const int32_t index = argv[0]->i;
  1182. const float value = argv[1]->f;
  1183. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->param.count), index, kData->param.count);
  1184. if (index >= 0 && static_cast<int32_t>(kData->param.count))
  1185. {
  1186. const float fixedValue(kData->param.fixValue(index, value));
  1187. fParams[index].value = fixedValue;
  1188. CarlaPlugin::setParameterValue(index, fixedValue, false, true, true);
  1189. }
  1190. break;
  1191. }
  1192. case kPluginBridgeSetDefaultValue:
  1193. {
  1194. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "if");
  1195. const int32_t index = argv[0]->i;
  1196. const float value = argv[1]->f;
  1197. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->param.count), index, kData->param.count);
  1198. if (index >= 0 && static_cast<int32_t>(kData->param.count))
  1199. kData->param.ranges[index].def = value;
  1200. break;
  1201. }
  1202. case kPluginBridgeSetProgram:
  1203. {
  1204. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1205. const int32_t index = argv[0]->i;
  1206. CARLA_ASSERT_INT2(index >= 0 && index < static_cast<int32_t>(kData->prog.count), index, kData->prog.count);
  1207. setProgram(index, false, true, true);
  1208. break;
  1209. }
  1210. case kPluginBridgeSetMidiProgram:
  1211. {
  1212. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1213. const int32_t index = argv[0]->i;
  1214. CARLA_ASSERT_INT2(index < static_cast<int32_t>(kData->midiprog.count), index, kData->midiprog.count);
  1215. setMidiProgram(index, false, true, true);
  1216. break;
  1217. }
  1218. case kPluginBridgeSetCustomData:
  1219. {
  1220. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "sss");
  1221. const char* const type = (const char*)&argv[0]->s;
  1222. const char* const key = (const char*)&argv[1]->s;
  1223. const char* const value = (const char*)&argv[2]->s;
  1224. CARLA_ASSERT(type != nullptr);
  1225. CARLA_ASSERT(key != nullptr);
  1226. CARLA_ASSERT(value != nullptr);
  1227. setCustomData(type, key, value, false);
  1228. break;
  1229. }
  1230. case kPluginBridgeSetChunkData:
  1231. {
  1232. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  1233. #if 0
  1234. const char* const chunkFileChar = (const char*)&argv[0]->s;
  1235. CARLA_ASSERT(chunkFileChar);
  1236. QString chunkFileStr(chunkFileChar);
  1237. #ifndef Q_OS_WIN
  1238. // Using Wine, fix temp dir
  1239. if (m_binary == BINARY_WIN32 || m_binary == BINARY_WIN64)
  1240. {
  1241. // Get WINEPREFIX
  1242. QString wineDir;
  1243. if (const char* const WINEPREFIX = getenv("WINEPREFIX"))
  1244. wineDir = QString(WINEPREFIX);
  1245. else
  1246. wineDir = QDir::homePath() + "/.wine";
  1247. QStringList chunkFileStrSplit1 = chunkFileStr.split(":/");
  1248. QStringList chunkFileStrSplit2 = chunkFileStrSplit1.at(1).split("\\");
  1249. QString wineDrive = chunkFileStrSplit1.at(0).toLower();
  1250. QString wineTMP = chunkFileStrSplit2.at(0);
  1251. QString baseName = chunkFileStrSplit2.at(1);
  1252. chunkFileStr = wineDir;
  1253. chunkFileStr += "/drive_";
  1254. chunkFileStr += wineDrive;
  1255. chunkFileStr += "/";
  1256. chunkFileStr += wineTMP;
  1257. chunkFileStr += "/";
  1258. chunkFileStr += baseName;
  1259. chunkFileStr = QDir::toNativeSeparators(chunkFileStr);
  1260. }
  1261. #endif
  1262. QFile chunkFile(chunkFileStr);
  1263. if (chunkFile.open(QIODevice::ReadOnly))
  1264. {
  1265. info.chunk = chunkFile.readAll();
  1266. chunkFile.close();
  1267. chunkFile.remove();
  1268. }
  1269. #endif
  1270. break;
  1271. }
  1272. case kPluginBridgeUpdateNow:
  1273. {
  1274. fInitiated = true;
  1275. break;
  1276. }
  1277. case kPluginBridgeError:
  1278. {
  1279. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  1280. const char* const error = (const char*)&argv[0]->s;
  1281. CARLA_ASSERT(error != nullptr);
  1282. kData->engine->setLastError(error);
  1283. fInitError = true;
  1284. fInitiated = true;
  1285. break;
  1286. }
  1287. }
  1288. return 0;
  1289. }
  1290. // -------------------------------------------------------------------
  1291. const void* getExtraStuff() const override
  1292. {
  1293. return fBridgeBinary.isNotEmpty() ? (const char*)fBridgeBinary : nullptr;
  1294. }
  1295. bool init(const char* const filename, const char* const name, const char* const label, const char* const bridgeBinary)
  1296. {
  1297. CARLA_ASSERT(kData->engine != nullptr);
  1298. CARLA_ASSERT(kData->client == nullptr);
  1299. // ---------------------------------------------------------------
  1300. // first checks
  1301. if (kData->engine == nullptr)
  1302. {
  1303. return false;
  1304. }
  1305. if (kData->client != nullptr)
  1306. {
  1307. kData->engine->setLastError("Plugin client is already registered");
  1308. return false;
  1309. }
  1310. // ---------------------------------------------------------------
  1311. // set info
  1312. if (name != nullptr)
  1313. fName = kData->engine->getUniquePluginName(name);
  1314. fFilename = filename;
  1315. fBridgeBinary = bridgeBinary;
  1316. // ---------------------------------------------------------------
  1317. // SHM Audio Pool
  1318. {
  1319. char tmpFileBase[60];
  1320. std::srand(std::time(NULL));
  1321. std::sprintf(tmpFileBase, "/carla-bridge_shm_XXXXXX");
  1322. fShmAudioPool.shm = shm_mkstemp(tmpFileBase);
  1323. if (! carla_is_shm_valid(fShmAudioPool.shm))
  1324. {
  1325. carla_stdout("Failed to open or create shared memory file #1");
  1326. return false;
  1327. }
  1328. fShmAudioPool.filename = tmpFileBase;
  1329. }
  1330. // ---------------------------------------------------------------
  1331. // SHM Control
  1332. {
  1333. char tmpFileBase[60];
  1334. std::sprintf(tmpFileBase, "/carla-bridge_shc_XXXXXX");
  1335. fShmControl.shm = shm_mkstemp(tmpFileBase);
  1336. if (! carla_is_shm_valid(fShmControl.shm))
  1337. {
  1338. carla_stdout("Failed to open or create shared memory file #2");
  1339. // clear
  1340. carla_shm_close(fShmAudioPool.shm);
  1341. return false;
  1342. }
  1343. fShmControl.filename = tmpFileBase;
  1344. if (! fShmControl.mapData())
  1345. {
  1346. carla_stdout("Failed to mmap shared memory file");
  1347. // clear
  1348. carla_shm_close(fShmControl.shm);
  1349. carla_shm_close(fShmAudioPool.shm);
  1350. return false;
  1351. }
  1352. CARLA_ASSERT(fShmControl.data != nullptr);
  1353. if (! jackbridge_sem_init(&fShmControl.data->runServer))
  1354. {
  1355. carla_stdout("Failed to initialize shared memory semaphore #1");
  1356. // clear
  1357. fShmControl.unmapData();
  1358. carla_shm_close(fShmControl.shm);
  1359. carla_shm_close(fShmAudioPool.shm);
  1360. return false;
  1361. }
  1362. if (! jackbridge_sem_init(&fShmControl.data->runClient))
  1363. {
  1364. carla_stdout("Failed to initialize shared memory semaphore #2");
  1365. // clear
  1366. jackbridge_sem_destroy(&fShmControl.data->runServer);
  1367. fShmControl.unmapData();
  1368. carla_shm_close(fShmControl.shm);
  1369. carla_shm_close(fShmAudioPool.shm);
  1370. return false;
  1371. }
  1372. fNeedsSemDestroy = true;
  1373. }
  1374. // initial values
  1375. fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize);
  1376. fShmControl.writeInt(kData->engine->getBufferSize());
  1377. fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate);
  1378. fShmControl.writeFloat(kData->engine->getSampleRate());
  1379. fShmControl.commitWrite();
  1380. // register plugin now so we can receive OSC (and wait for it)
  1381. fHints |= PLUGIN_IS_BRIDGE;
  1382. registerEnginePlugin(kData->engine, fId, this);
  1383. // init OSC
  1384. {
  1385. char shmIdStr[12+1] = { 0 };
  1386. std::strncpy(shmIdStr, &fShmAudioPool.filename[fShmAudioPool.filename.length()-6], 6);
  1387. std::strncat(shmIdStr, &fShmControl.filename[fShmControl.filename.length()-6], 6);
  1388. kData->osc.thread.setOscData(bridgeBinary, label, getPluginTypeAsString(fPluginType), shmIdStr);
  1389. kData->osc.thread.start();
  1390. }
  1391. for (int i=0; i < 200; ++i)
  1392. {
  1393. if (fInitiated || ! kData->osc.thread.isRunning())
  1394. break;
  1395. carla_msleep(50);
  1396. }
  1397. if (fInitError || ! fInitiated)
  1398. {
  1399. // unregister so it gets handled properly
  1400. registerEnginePlugin(kData->engine, fId, nullptr);
  1401. kData->osc.thread.quit();
  1402. if (kData->osc.thread.isRunning())
  1403. kData->osc.thread.terminate();
  1404. if (! fInitError)
  1405. kData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)");
  1406. return false;
  1407. }
  1408. // ---------------------------------------------------------------
  1409. // register client
  1410. if (fName.isEmpty())
  1411. {
  1412. if (name != nullptr)
  1413. fName = kData->engine->getUniquePluginName(name);
  1414. else if (label != nullptr)
  1415. fName = kData->engine->getUniquePluginName(label);
  1416. else
  1417. fName = kData->engine->getUniquePluginName("unknown");
  1418. }
  1419. kData->client = kData->engine->addClient(this);
  1420. if (kData->client == nullptr || ! kData->client->isOk())
  1421. {
  1422. kData->engine->setLastError("Failed to register plugin client");
  1423. return false;
  1424. }
  1425. return true;
  1426. }
  1427. private:
  1428. const BinaryType fBinaryType;
  1429. const PluginType fPluginType;
  1430. bool fInitiated;
  1431. bool fInitError;
  1432. bool fSaved;
  1433. bool fNeedsSemDestroy;
  1434. CarlaString fBridgeBinary;
  1435. BridgeAudioPool fShmAudioPool;
  1436. BridgeControl fShmControl;
  1437. struct Info {
  1438. uint32_t aIns, aOuts;
  1439. uint32_t mIns, mOuts;
  1440. PluginCategory category;
  1441. long uniqueId;
  1442. CarlaString name;
  1443. CarlaString label;
  1444. CarlaString maker;
  1445. CarlaString copyright;
  1446. //QByteArray chunk;
  1447. Info()
  1448. : aIns(0),
  1449. aOuts(0),
  1450. mIns(0),
  1451. mOuts(0),
  1452. category(PLUGIN_CATEGORY_NONE),
  1453. uniqueId(0) {}
  1454. } fInfo;
  1455. BridgeParamInfo* fParams;
  1456. void resizeAudioPool(const uint32_t bufferSize)
  1457. {
  1458. fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts);
  1459. fShmControl.writeOpcode(kPluginBridgeOpcodeSetAudioPool);
  1460. fShmControl.writeLong(fShmAudioPool.size);
  1461. fShmControl.commitWrite();
  1462. waitForServer();
  1463. }
  1464. bool waitForServer()
  1465. {
  1466. if (! fShmControl.waitForServer())
  1467. {
  1468. carla_stderr("waitForServer() timeout");
  1469. kData->active = false; // TODO
  1470. return false;
  1471. }
  1472. return true;
  1473. }
  1474. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BridgePlugin)
  1475. };
  1476. CARLA_BACKEND_END_NAMESPACE
  1477. #endif // ! BUILD_BRIDGE
  1478. CARLA_BACKEND_START_NAMESPACE
  1479. CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, PluginType ptype, const char* const bridgeBinary)
  1480. {
  1481. carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary);
  1482. #ifndef BUILD_BRIDGE
  1483. if (bridgeBinary == nullptr)
  1484. {
  1485. init.engine->setLastError("Bridge not possible, bridge-binary not found");
  1486. return nullptr;
  1487. }
  1488. BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, btype, ptype));
  1489. if (! plugin->init(init.filename, init.name, init.label, bridgeBinary))
  1490. {
  1491. delete plugin;
  1492. return nullptr;
  1493. }
  1494. plugin->reload();
  1495. if (init.engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK && ! CarlaPluginProtectedData::canRunInRack(plugin))
  1496. {
  1497. init.engine->setLastError("Carla's rack mode can only work with Stereo Bridged plugins, sorry!");
  1498. delete plugin;
  1499. return nullptr;
  1500. }
  1501. return plugin;
  1502. #else
  1503. init.engine->setLastError("Plugin bridge support not available");
  1504. return nullptr;
  1505. // unused
  1506. (void)bridgeBinary;
  1507. #endif
  1508. }
  1509. #ifndef BUILD_BRIDGE
  1510. // -------------------------------------------------------------------
  1511. // Bridge Helper
  1512. #define bridgePlugin ((BridgePlugin*)plugin)
  1513. int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeInfoType type,
  1514. const int argc, const lo_arg* const* const argv, const char* const types)
  1515. {
  1516. CARLA_ASSERT(plugin != nullptr && (plugin->hints() & PLUGIN_IS_BRIDGE) != 0);
  1517. return bridgePlugin->setOscPluginBridgeInfo(type, argc, argv, types);
  1518. }
  1519. BinaryType CarlaPluginGetBridgeBinaryType(CarlaPlugin* const plugin)
  1520. {
  1521. CARLA_ASSERT(plugin != nullptr && (plugin->hints() & PLUGIN_IS_BRIDGE) != 0);
  1522. return bridgePlugin->binaryType();
  1523. }
  1524. #undef bridgePlugin
  1525. #endif
  1526. CARLA_BACKEND_END_NAMESPACE