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.

1696 lines
58KB

  1. /*
  2. * Carla Plugin JACK
  3. * Copyright (C) 2016-2017 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifdef BUILD_BRIDGE
  18. # error This file should not be used under bridge mode
  19. #endif
  20. #include "CarlaPluginInternal.hpp"
  21. #include "CarlaEngine.hpp"
  22. #ifdef CARLA_OS_LINUX
  23. #include "CarlaBackendUtils.hpp"
  24. #include "CarlaBridgeUtils.hpp"
  25. #include "CarlaEngineUtils.hpp"
  26. #include "CarlaMathUtils.hpp"
  27. #include "CarlaPipeUtils.hpp"
  28. #include "CarlaShmUtils.hpp"
  29. #include "CarlaThread.hpp"
  30. #include "jackbridge/JackBridge.hpp"
  31. #include <ctime>
  32. // -------------------------------------------------------------------------------------------------------------------
  33. using juce::ChildProcess;
  34. using juce::File;
  35. using juce::ScopedPointer;
  36. using juce::String;
  37. using juce::StringArray;
  38. using juce::Time;
  39. CARLA_BACKEND_START_NAMESPACE
  40. // -------------------------------------------------------------------------------------------------------------------
  41. // Fallback data
  42. static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
  43. // -------------------------------------------------------------------------------------------------------------------
  44. class CarlaPluginJackThread : public CarlaThread
  45. {
  46. public:
  47. CarlaPluginJackThread(CarlaEngine* const engine, CarlaPlugin* const plugin) noexcept
  48. : CarlaThread("CarlaPluginJackThread"),
  49. kEngine(engine),
  50. kPlugin(plugin),
  51. fShmIds(),
  52. fProcess() {}
  53. void setData(const char* const shmIds) noexcept
  54. {
  55. CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',);
  56. CARLA_SAFE_ASSERT(! isThreadRunning());
  57. fShmIds = shmIds;
  58. }
  59. uintptr_t getProcessID() const noexcept
  60. {
  61. CARLA_SAFE_ASSERT_RETURN(fProcess != nullptr, 0);
  62. return (uintptr_t)fProcess->getPID();
  63. }
  64. protected:
  65. void run()
  66. {
  67. if (fProcess == nullptr)
  68. {
  69. fProcess = new ChildProcess();
  70. }
  71. else if (fProcess->isRunning())
  72. {
  73. carla_stderr("CarlaPluginJackThread::run() - already running");
  74. }
  75. String name(kPlugin->getName());
  76. String filename(kPlugin->getFilename());
  77. if (name.isEmpty())
  78. name = "(none)";
  79. CARLA_SAFE_ASSERT_RETURN(filename.isNotEmpty(),);
  80. StringArray arguments;
  81. // binary
  82. arguments.addTokens(filename, true);
  83. bool started;
  84. {
  85. const EngineOptions& options(kEngine->getOptions());
  86. char strBuf[STR_MAX+1];
  87. std::snprintf(strBuf, STR_MAX, P_UINTPTR, options.frontendWinId);
  88. strBuf[STR_MAX] = '\0';
  89. CarlaString libjackdir(options.binaryDir);
  90. libjackdir += "/jack";
  91. const ScopedEngineEnvironmentLocker _seel(kEngine);
  92. const ScopedEnvVar sev1("LD_PRELOAD", nullptr);
  93. const ScopedEnvVar sev2("LD_LIBRARY_PATH", libjackdir.buffer());
  94. carla_setenv("CARLA_FRONTEND_WIN_ID", strBuf);
  95. carla_setenv("CARLA_SHM_IDS", fShmIds.toRawUTF8());
  96. started = fProcess->start(arguments);
  97. }
  98. if (! started)
  99. {
  100. carla_stdout("failed!");
  101. fProcess = nullptr;
  102. return;
  103. }
  104. for (; fProcess->isRunning() && ! shouldThreadExit();)
  105. carla_msleep(50);
  106. // we only get here if bridge crashed or thread asked to exit
  107. if (fProcess->isRunning() && shouldThreadExit())
  108. {
  109. fProcess->waitForProcessToFinish(2000);
  110. if (fProcess->isRunning())
  111. {
  112. carla_stdout("CarlaPluginJackThread::run() - bridge refused to close, force kill now");
  113. fProcess->kill();
  114. }
  115. else
  116. {
  117. carla_stdout("CarlaPluginJackThread::run() - bridge auto-closed successfully");
  118. }
  119. }
  120. else
  121. {
  122. // forced quit, may have crashed
  123. if (fProcess->getExitCode() != 0 /*|| fProcess->exitStatus() == QProcess::CrashExit*/)
  124. {
  125. carla_stderr("CarlaPluginJackThread::run() - bridge crashed");
  126. CarlaString errorString("Plugin '" + CarlaString(kPlugin->getName()) + "' has crashed!\n"
  127. "Saving now will lose its current settings.\n"
  128. "Please remove this plugin, and not rely on it from this point.");
  129. kEngine->callback(CarlaBackend::ENGINE_CALLBACK_ERROR, kPlugin->getId(), 0, 0, 0.0f, errorString);
  130. }
  131. else
  132. {
  133. carla_stderr("CarlaPluginJackThread::run() - bridge closed itself");
  134. }
  135. }
  136. fProcess = nullptr;
  137. }
  138. private:
  139. CarlaEngine* const kEngine;
  140. CarlaPlugin* const kPlugin;
  141. String fShmIds;
  142. ScopedPointer<ChildProcess> fProcess;
  143. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginJackThread)
  144. };
  145. // -------------------------------------------------------------------------------------------------------------------
  146. class CarlaPluginJack : public CarlaPlugin
  147. {
  148. public:
  149. CarlaPluginJack(CarlaEngine* const engine, const uint id)
  150. : CarlaPlugin(engine, id),
  151. fInitiated(false),
  152. fInitError(false),
  153. fTimedOut(false),
  154. fTimedError(false),
  155. fProcCanceled(false),
  156. fProcWaitTime(0),
  157. fLastPongTime(-1),
  158. fBridgeThread(engine, this),
  159. fShmAudioPool(),
  160. fShmRtClientControl(),
  161. fShmNonRtClientControl(),
  162. fShmNonRtServerControl(),
  163. fInfo()
  164. {
  165. carla_debug("CarlaPluginJack::CarlaPluginJack(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype));
  166. pData->hints |= PLUGIN_IS_BRIDGE;
  167. }
  168. ~CarlaPluginJack() override
  169. {
  170. carla_debug("CarlaPluginJack::~CarlaPluginJack()");
  171. // close UI
  172. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  173. pData->transientTryCounter = 0;
  174. pData->singleMutex.lock();
  175. pData->masterMutex.lock();
  176. if (pData->client != nullptr && pData->client->isActive())
  177. pData->client->deactivate();
  178. if (pData->active)
  179. {
  180. deactivate();
  181. pData->active = false;
  182. }
  183. if (fBridgeThread.isThreadRunning())
  184. {
  185. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientQuit);
  186. fShmRtClientControl.commitWrite();
  187. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientQuit);
  188. fShmNonRtClientControl.commitWrite();
  189. if (! fTimedOut)
  190. waitForClient("stopping", 3000);
  191. }
  192. fBridgeThread.stopThread(3000);
  193. fShmNonRtServerControl.clear();
  194. fShmNonRtClientControl.clear();
  195. fShmRtClientControl.clear();
  196. fShmAudioPool.clear();
  197. clearBuffers();
  198. fInfo.chunk.clear();
  199. }
  200. // -------------------------------------------------------------------
  201. // Information (base)
  202. PluginType getType() const noexcept override
  203. {
  204. return PLUGIN_JACK;
  205. }
  206. PluginCategory getCategory() const noexcept override
  207. {
  208. return fInfo.category;
  209. }
  210. // -------------------------------------------------------------------
  211. // Information (count)
  212. uint32_t getMidiInCount() const noexcept override
  213. {
  214. return fInfo.mIns;
  215. }
  216. uint32_t getMidiOutCount() const noexcept override
  217. {
  218. return fInfo.mOuts;
  219. }
  220. // -------------------------------------------------------------------
  221. // Information (current data)
  222. // -------------------------------------------------------------------
  223. // Information (per-plugin data)
  224. uint getOptionsAvailable() const noexcept override
  225. {
  226. return fInfo.optionsAvailable;
  227. }
  228. void getLabel(char* const strBuf) const noexcept override
  229. {
  230. std::strncpy(strBuf, fInfo.label, STR_MAX);
  231. }
  232. void getMaker(char* const strBuf) const noexcept override
  233. {
  234. nullStrBuf(strBuf);
  235. }
  236. void getCopyright(char* const strBuf) const noexcept override
  237. {
  238. nullStrBuf(strBuf);
  239. }
  240. void getRealName(char* const strBuf) const noexcept override
  241. {
  242. std::strncpy(strBuf, fInfo.name, STR_MAX);
  243. }
  244. // -------------------------------------------------------------------
  245. // Set data (state)
  246. // -------------------------------------------------------------------
  247. // Set data (internal stuff)
  248. void setOption(const uint option, const bool yesNo, const bool sendCallback) override
  249. {
  250. {
  251. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  252. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetOption);
  253. fShmNonRtClientControl.writeUInt(option);
  254. fShmNonRtClientControl.writeBool(yesNo);
  255. fShmNonRtClientControl.commitWrite();
  256. }
  257. CarlaPlugin::setOption(option, yesNo, sendCallback);
  258. }
  259. void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override
  260. {
  261. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  262. {
  263. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  264. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetCtrlChannel);
  265. fShmNonRtClientControl.writeShort(channel);
  266. fShmNonRtClientControl.commitWrite();
  267. }
  268. CarlaPlugin::setCtrlChannel(channel, sendOsc, sendCallback);
  269. }
  270. // -------------------------------------------------------------------
  271. // Set data (plugin-specific stuff)
  272. // -------------------------------------------------------------------
  273. // Set ui stuff
  274. void idle() override
  275. {
  276. if (fBridgeThread.isThreadRunning())
  277. {
  278. if (fInitiated && fTimedOut && pData->active)
  279. setActive(false, true, true);
  280. {
  281. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  282. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPing);
  283. fShmNonRtClientControl.commitWrite();
  284. }
  285. try {
  286. handleNonRtData();
  287. } CARLA_SAFE_EXCEPTION("handleNonRtData");
  288. }
  289. else if (fInitiated)
  290. {
  291. fTimedOut = true;
  292. fTimedError = true;
  293. fInitiated = false;
  294. carla_stderr2("Plugin bridge has been stopped or crashed");
  295. pData->engine->callback(ENGINE_CALLBACK_PLUGIN_UNAVAILABLE, pData->id, 0, 0, 0.0f,
  296. "Plugin bridge has been stopped or crashed");
  297. }
  298. CarlaPlugin::idle();
  299. }
  300. // -------------------------------------------------------------------
  301. // Plugin state
  302. void reload() override
  303. {
  304. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  305. carla_debug("CarlaPluginJack::reload() - start");
  306. const EngineProcessMode processMode(pData->engine->getProccessMode());
  307. // Safely disable plugin for reload
  308. const ScopedDisabler sd(this);
  309. // cleanup of previous data
  310. pData->audioIn.clear();
  311. pData->audioOut.clear();
  312. pData->cvIn.clear();
  313. pData->cvOut.clear();
  314. pData->event.clear();
  315. bool needsCtrlIn, needsCtrlOut;
  316. needsCtrlIn = needsCtrlOut = false;
  317. if (fInfo.aIns > 0)
  318. {
  319. pData->audioIn.createNew(fInfo.aIns);
  320. }
  321. if (fInfo.aOuts > 0)
  322. {
  323. pData->audioOut.createNew(fInfo.aOuts);
  324. needsCtrlIn = true;
  325. }
  326. if (fInfo.cvIns > 0)
  327. {
  328. pData->cvIn.createNew(fInfo.cvIns);
  329. }
  330. if (fInfo.cvOuts > 0)
  331. {
  332. pData->cvOut.createNew(fInfo.cvOuts);
  333. }
  334. if (fInfo.mIns > 0)
  335. needsCtrlIn = true;
  336. if (fInfo.mOuts > 0)
  337. needsCtrlOut = true;
  338. const uint portNameSize(pData->engine->getMaxPortNameSize());
  339. CarlaString portName;
  340. // Audio Ins
  341. for (uint32_t j=0; j < fInfo.aIns; ++j)
  342. {
  343. portName.clear();
  344. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  345. {
  346. portName = pData->name;
  347. portName += ":";
  348. }
  349. if (fInfo.aInNames != nullptr && fInfo.aInNames[j] != nullptr)
  350. {
  351. portName += fInfo.aInNames[j];
  352. }
  353. else if (fInfo.aIns > 1)
  354. {
  355. portName += "input_";
  356. portName += CarlaString(j+1);
  357. }
  358. else
  359. portName += "input";
  360. portName.truncate(portNameSize);
  361. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  362. pData->audioIn.ports[j].rindex = j;
  363. }
  364. // Audio Outs
  365. for (uint32_t j=0; j < fInfo.aOuts; ++j)
  366. {
  367. portName.clear();
  368. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  369. {
  370. portName = pData->name;
  371. portName += ":";
  372. }
  373. if (fInfo.aOutNames != nullptr && fInfo.aOutNames[j] != nullptr)
  374. {
  375. portName += fInfo.aOutNames[j];
  376. }
  377. else if (fInfo.aOuts > 1)
  378. {
  379. portName += "output_";
  380. portName += CarlaString(j+1);
  381. }
  382. else
  383. portName += "output";
  384. portName.truncate(portNameSize);
  385. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  386. pData->audioOut.ports[j].rindex = j;
  387. }
  388. // TODO - MIDI
  389. // TODO - CV
  390. if (needsCtrlIn)
  391. {
  392. portName.clear();
  393. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  394. {
  395. portName = pData->name;
  396. portName += ":";
  397. }
  398. portName += "event-in";
  399. portName.truncate(portNameSize);
  400. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  401. }
  402. if (needsCtrlOut)
  403. {
  404. portName.clear();
  405. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  406. {
  407. portName = pData->name;
  408. portName += ":";
  409. }
  410. portName += "event-out";
  411. portName.truncate(portNameSize);
  412. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  413. }
  414. // extra plugin hints
  415. pData->extraHints = 0x0;
  416. if (fInfo.mIns > 0)
  417. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  418. if (fInfo.mOuts > 0)
  419. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  420. if (fInfo.aIns <= 2 && fInfo.aOuts <= 2 && (fInfo.aIns == fInfo.aOuts || fInfo.aIns == 0 || fInfo.aOuts == 0))
  421. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  422. bufferSizeChanged(pData->engine->getBufferSize());
  423. reloadPrograms(true);
  424. carla_debug("CarlaPluginJack::reload() - end");
  425. }
  426. // -------------------------------------------------------------------
  427. // Plugin processing
  428. void activate() noexcept override
  429. {
  430. if (! fBridgeThread.isThreadRunning())
  431. {
  432. CARLA_SAFE_ASSERT_RETURN(restartBridgeThread(),);
  433. }
  434. CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
  435. {
  436. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  437. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientActivate);
  438. fShmNonRtClientControl.commitWrite();
  439. }
  440. fTimedOut = false;
  441. try {
  442. waitForClient("activate", 2000);
  443. } CARLA_SAFE_EXCEPTION("activate - waitForClient");
  444. }
  445. void deactivate() noexcept override
  446. {
  447. if (! fBridgeThread.isThreadRunning())
  448. return;
  449. CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
  450. {
  451. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  452. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientDeactivate);
  453. fShmNonRtClientControl.commitWrite();
  454. }
  455. fTimedOut = false;
  456. try {
  457. waitForClient("deactivate", 2000);
  458. } CARLA_SAFE_EXCEPTION("deactivate - waitForClient");
  459. }
  460. void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override
  461. {
  462. // --------------------------------------------------------------------------------------------------------
  463. // Check if active
  464. if (fProcCanceled || fTimedOut || fTimedError || ! pData->active)
  465. {
  466. // disable any output sound
  467. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  468. FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
  469. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  470. FloatVectorOperations::clear(cvOut[i], static_cast<int>(frames));
  471. return;
  472. }
  473. // --------------------------------------------------------------------------------------------------------
  474. // Check if needs reset
  475. if (pData->needsReset)
  476. {
  477. // TODO
  478. pData->needsReset = false;
  479. }
  480. // --------------------------------------------------------------------------------------------------------
  481. // Event Input
  482. if (pData->event.portIn != nullptr)
  483. {
  484. // ----------------------------------------------------------------------------------------------------
  485. // MIDI Input (External)
  486. if (pData->extNotes.mutex.tryLock())
  487. {
  488. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
  489. {
  490. const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
  491. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  492. uint8_t data1, data2, data3;
  493. data1 = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  494. data2 = note.note;
  495. data3 = note.velo;
  496. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent);
  497. fShmRtClientControl.writeUInt(0); // time
  498. fShmRtClientControl.writeByte(0); // port
  499. fShmRtClientControl.writeByte(3); // size
  500. fShmRtClientControl.writeByte(data1);
  501. fShmRtClientControl.writeByte(data2);
  502. fShmRtClientControl.writeByte(data3);
  503. fShmRtClientControl.commitWrite();
  504. }
  505. pData->extNotes.data.clear();
  506. pData->extNotes.mutex.unlock();
  507. } // End of MIDI Input (External)
  508. // ----------------------------------------------------------------------------------------------------
  509. // Event Input (System)
  510. bool allNotesOffSent = false;
  511. for (uint32_t i=0, numEvents=pData->event.portIn->getEventCount(); i < numEvents; ++i)
  512. {
  513. const EngineEvent& event(pData->event.portIn->getEvent(i));
  514. // Control change
  515. switch (event.type)
  516. {
  517. case kEngineEventTypeNull:
  518. break;
  519. case kEngineEventTypeControl: {
  520. const EngineControlEvent& ctrlEvent = event.ctrl;
  521. switch (ctrlEvent.type)
  522. {
  523. case kEngineControlEventTypeNull:
  524. break;
  525. case kEngineControlEventTypeParameter:
  526. // Control backend stuff
  527. if (event.channel == pData->ctrlChannel)
  528. {
  529. float value;
  530. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  531. {
  532. value = ctrlEvent.value;
  533. setDryWet(value, false, false);
  534. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  535. }
  536. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  537. {
  538. value = ctrlEvent.value*127.0f/100.0f;
  539. setVolume(value, false, false);
  540. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  541. }
  542. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  543. {
  544. float left, right;
  545. value = ctrlEvent.value/0.5f - 1.0f;
  546. if (value < 0.0f)
  547. {
  548. left = -1.0f;
  549. right = (value*2.0f)+1.0f;
  550. }
  551. else if (value > 0.0f)
  552. {
  553. left = (value*2.0f)-1.0f;
  554. right = 1.0f;
  555. }
  556. else
  557. {
  558. left = -1.0f;
  559. right = 1.0f;
  560. }
  561. setBalanceLeft(left, false, false);
  562. setBalanceRight(right, false, false);
  563. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  564. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  565. }
  566. }
  567. break;
  568. case kEngineControlEventTypeMidiBank:
  569. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  570. {
  571. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiBank);
  572. fShmRtClientControl.writeUInt(event.time);
  573. fShmRtClientControl.writeByte(event.channel);
  574. fShmRtClientControl.writeUShort(event.ctrl.param);
  575. fShmRtClientControl.commitWrite();
  576. }
  577. break;
  578. case kEngineControlEventTypeMidiProgram:
  579. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  580. {
  581. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiProgram);
  582. fShmRtClientControl.writeUInt(event.time);
  583. fShmRtClientControl.writeByte(event.channel);
  584. fShmRtClientControl.writeUShort(event.ctrl.param);
  585. fShmRtClientControl.commitWrite();
  586. }
  587. break;
  588. case kEngineControlEventTypeAllSoundOff:
  589. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  590. {
  591. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventAllSoundOff);
  592. fShmRtClientControl.writeUInt(event.time);
  593. fShmRtClientControl.writeByte(event.channel);
  594. fShmRtClientControl.commitWrite();
  595. }
  596. break;
  597. case kEngineControlEventTypeAllNotesOff:
  598. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  599. {
  600. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  601. {
  602. allNotesOffSent = true;
  603. sendMidiAllNotesOffToCallback();
  604. }
  605. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventAllNotesOff);
  606. fShmRtClientControl.writeUInt(event.time);
  607. fShmRtClientControl.writeByte(event.channel);
  608. fShmRtClientControl.commitWrite();
  609. }
  610. break;
  611. } // switch (ctrlEvent.type)
  612. break;
  613. } // case kEngineEventTypeControl
  614. case kEngineEventTypeMidi: {
  615. const EngineMidiEvent& midiEvent(event.midi);
  616. if (midiEvent.size == 0 || midiEvent.size >= MAX_MIDI_VALUE)
  617. continue;
  618. const uint8_t* const midiData(midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data);
  619. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
  620. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  621. continue;
  622. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  623. continue;
  624. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  625. continue;
  626. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  627. continue;
  628. // Fix bad note-off
  629. if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
  630. status = MIDI_STATUS_NOTE_OFF;
  631. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent);
  632. fShmRtClientControl.writeUInt(event.time);
  633. fShmRtClientControl.writeByte(midiEvent.port);
  634. fShmRtClientControl.writeByte(midiEvent.size);
  635. fShmRtClientControl.writeByte(uint8_t(midiData[0] | (event.channel & MIDI_CHANNEL_BIT)));
  636. for (uint8_t j=1; j < midiEvent.size; ++j)
  637. fShmRtClientControl.writeByte(midiData[j]);
  638. fShmRtClientControl.commitWrite();
  639. if (status == MIDI_STATUS_NOTE_ON)
  640. pData->postponeRtEvent(kPluginPostRtEventNoteOn, event.channel, midiData[1], midiData[2]);
  641. else if (status == MIDI_STATUS_NOTE_OFF)
  642. pData->postponeRtEvent(kPluginPostRtEventNoteOff, event.channel, midiData[1], 0.0f);
  643. } break;
  644. }
  645. }
  646. pData->postRtEvents.trySplice();
  647. } // End of Event Input
  648. if (! processSingle(audioIn, audioOut, cvIn, cvOut, frames))
  649. return;
  650. // --------------------------------------------------------------------------------------------------------
  651. // MIDI Output
  652. if (pData->event.portOut != nullptr)
  653. {
  654. uint8_t size;
  655. uint32_t time;
  656. const uint8_t* midiData(fShmRtClientControl.data->midiOut);
  657. for (std::size_t read=0; read<kBridgeRtClientDataMidiOutSize;)
  658. {
  659. size = *midiData;
  660. if (size == 0)
  661. break;
  662. // advance 8 bits (1 byte)
  663. midiData = midiData + 1;
  664. // get time as 32bit
  665. time = *(const uint32_t*)midiData;
  666. // advance 32 bits (4 bytes)
  667. midiData = midiData + 4;
  668. // store midi data advancing as needed
  669. uint8_t data[size];
  670. for (uint8_t j=0; j<size; ++j)
  671. data[j] = *midiData++;
  672. pData->event.portOut->writeMidiEvent(time, size, data);
  673. read += 1U /* size*/ + 4U /* time */ + size;
  674. }
  675. } // End of Control and MIDI Output
  676. }
  677. bool processSingle(const float** const audioIn, float** const audioOut,
  678. const float** const cvIn, float** const cvOut, const uint32_t frames)
  679. {
  680. CARLA_SAFE_ASSERT_RETURN(! fTimedError, false);
  681. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  682. if (pData->audioIn.count > 0)
  683. {
  684. CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
  685. }
  686. if (pData->audioOut.count > 0)
  687. {
  688. CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false);
  689. }
  690. if (pData->cvIn.count > 0)
  691. {
  692. CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false);
  693. }
  694. if (pData->cvOut.count > 0)
  695. {
  696. CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false);
  697. }
  698. const int iframes(static_cast<int>(frames));
  699. // --------------------------------------------------------------------------------------------------------
  700. // Try lock, silence otherwise
  701. if (pData->engine->isOffline())
  702. {
  703. pData->singleMutex.lock();
  704. }
  705. else if (! pData->singleMutex.tryLock())
  706. {
  707. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  708. FloatVectorOperations::clear(audioOut[i], iframes);
  709. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  710. FloatVectorOperations::clear(cvOut[i], iframes);
  711. return false;
  712. }
  713. // --------------------------------------------------------------------------------------------------------
  714. // Reset audio buffers
  715. for (uint32_t i=0; i < fInfo.aIns; ++i)
  716. FloatVectorOperations::copy(fShmAudioPool.data + (i * frames), audioIn[i], iframes);
  717. // --------------------------------------------------------------------------------------------------------
  718. // TimeInfo
  719. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  720. BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
  721. bridgeTimeInfo.playing = timeInfo.playing;
  722. bridgeTimeInfo.frame = timeInfo.frame;
  723. bridgeTimeInfo.usecs = timeInfo.usecs;
  724. bridgeTimeInfo.valid = timeInfo.valid;
  725. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  726. {
  727. bridgeTimeInfo.bar = timeInfo.bbt.bar;
  728. bridgeTimeInfo.beat = timeInfo.bbt.beat;
  729. bridgeTimeInfo.tick = timeInfo.bbt.tick;
  730. bridgeTimeInfo.beatsPerBar = timeInfo.bbt.beatsPerBar;
  731. bridgeTimeInfo.beatType = timeInfo.bbt.beatType;
  732. bridgeTimeInfo.ticksPerBeat = timeInfo.bbt.ticksPerBeat;
  733. bridgeTimeInfo.beatsPerMinute = timeInfo.bbt.beatsPerMinute;
  734. bridgeTimeInfo.barStartTick = timeInfo.bbt.barStartTick;
  735. }
  736. // --------------------------------------------------------------------------------------------------------
  737. // Run plugin
  738. {
  739. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientProcess);
  740. fShmRtClientControl.commitWrite();
  741. }
  742. waitForClient("process", fProcWaitTime);
  743. if (fTimedOut)
  744. {
  745. pData->singleMutex.unlock();
  746. return false;
  747. }
  748. if (fShmRtClientControl.data->procFlags)
  749. {
  750. carla_stdout("PROC Flags active, disabling plugin");
  751. fInitiated = false;
  752. fProcCanceled = true;
  753. }
  754. for (uint32_t i=0; i < fInfo.aOuts; ++i)
  755. FloatVectorOperations::copy(audioOut[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), iframes);
  756. // --------------------------------------------------------------------------------------------------------
  757. // Post-processing (dry/wet, volume and balance)
  758. {
  759. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && carla_isNotEqual(pData->postProc.volume, 1.0f);
  760. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
  761. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  762. const bool isMono = (pData->audioIn.count == 1);
  763. bool isPair;
  764. float bufValue, oldBufLeft[doBalance ? frames : 1];
  765. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  766. {
  767. // Dry/Wet
  768. if (doDryWet)
  769. {
  770. const uint32_t c = isMono ? 0 : i;
  771. for (uint32_t k=0; k < frames; ++k)
  772. {
  773. bufValue = audioIn[c][k];
  774. audioOut[i][k] = (audioOut[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  775. }
  776. }
  777. // Balance
  778. if (doBalance)
  779. {
  780. isPair = (i % 2 == 0);
  781. if (isPair)
  782. {
  783. CARLA_ASSERT(i+1 < pData->audioOut.count);
  784. FloatVectorOperations::copy(oldBufLeft, audioOut[i], iframes);
  785. }
  786. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  787. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  788. for (uint32_t k=0; k < frames; ++k)
  789. {
  790. if (isPair)
  791. {
  792. // left
  793. audioOut[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  794. audioOut[i][k] += audioOut[i+1][k] * (1.0f - balRangeR);
  795. }
  796. else
  797. {
  798. // right
  799. audioOut[i][k] = audioOut[i][k] * balRangeR;
  800. audioOut[i][k] += oldBufLeft[k] * balRangeL;
  801. }
  802. }
  803. }
  804. // Volume (and buffer copy)
  805. if (doVolume)
  806. {
  807. for (uint32_t k=0; k < frames; ++k)
  808. audioOut[i][k] *= pData->postProc.volume;
  809. }
  810. }
  811. } // End of Post-processing
  812. // --------------------------------------------------------------------------------------------------------
  813. pData->singleMutex.unlock();
  814. return true;
  815. }
  816. void bufferSizeChanged(const uint32_t newBufferSize) override
  817. {
  818. resizeAudioPool(newBufferSize);
  819. {
  820. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  821. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetBufferSize);
  822. fShmNonRtClientControl.writeUInt(newBufferSize);
  823. fShmNonRtClientControl.commitWrite();
  824. }
  825. //fProcWaitTime = newBufferSize*1000/pData->engine->getSampleRate();
  826. fProcWaitTime = 1000;
  827. waitForClient("buffersize", 1000);
  828. }
  829. void sampleRateChanged(const double newSampleRate) override
  830. {
  831. {
  832. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  833. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetSampleRate);
  834. fShmNonRtClientControl.writeDouble(newSampleRate);
  835. fShmNonRtClientControl.commitWrite();
  836. }
  837. //fProcWaitTime = pData->engine->getBufferSize()*1000/newSampleRate;
  838. fProcWaitTime = 1000;
  839. waitForClient("samplerate", 1000);
  840. }
  841. void offlineModeChanged(const bool isOffline) override
  842. {
  843. {
  844. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  845. fShmNonRtClientControl.writeOpcode(isOffline ? kPluginBridgeNonRtClientSetOffline : kPluginBridgeNonRtClientSetOnline);
  846. fShmNonRtClientControl.commitWrite();
  847. }
  848. waitForClient("offline", 1000);
  849. }
  850. // -------------------------------------------------------------------
  851. // Post-poned UI Stuff
  852. // -------------------------------------------------------------------
  853. void handleNonRtData()
  854. {
  855. for (; fShmNonRtServerControl.isDataAvailableForReading();)
  856. {
  857. const PluginBridgeNonRtServerOpcode opcode(fShmNonRtServerControl.readOpcode());
  858. //#ifdef DEBUG
  859. if (opcode != kPluginBridgeNonRtServerPong)
  860. {
  861. carla_debug("CarlaPluginJack::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode));
  862. }
  863. //#endif
  864. if (opcode != kPluginBridgeNonRtServerNull && fLastPongTime > 0)
  865. fLastPongTime = Time::currentTimeMillis();
  866. switch (opcode)
  867. {
  868. case kPluginBridgeNonRtServerNull:
  869. case kPluginBridgeNonRtServerPong:
  870. break;
  871. case kPluginBridgeNonRtServerPluginInfo1:
  872. // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId
  873. fShmNonRtServerControl.readUInt();
  874. fShmNonRtServerControl.readUInt();
  875. fShmNonRtServerControl.readUInt();
  876. fShmNonRtServerControl.readUInt();
  877. fShmNonRtServerControl.readLong();
  878. break;
  879. case kPluginBridgeNonRtServerPluginInfo2: {
  880. // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright)
  881. // realName
  882. const uint32_t realNameSize(fShmNonRtServerControl.readUInt());
  883. char realName[realNameSize+1];
  884. carla_zeroChars(realName, realNameSize+1);
  885. fShmNonRtServerControl.readCustomData(realName, realNameSize);
  886. // label
  887. const uint32_t labelSize(fShmNonRtServerControl.readUInt());
  888. char label[labelSize+1];
  889. carla_zeroChars(label, labelSize+1);
  890. fShmNonRtServerControl.readCustomData(label, labelSize);
  891. // maker
  892. const uint32_t makerSize(fShmNonRtServerControl.readUInt());
  893. char maker[makerSize+1];
  894. carla_zeroChars(maker, makerSize+1);
  895. fShmNonRtServerControl.readCustomData(maker, makerSize);
  896. // copyright
  897. const uint32_t copyrightSize(fShmNonRtServerControl.readUInt());
  898. char copyright[copyrightSize+1];
  899. carla_zeroChars(copyright, copyrightSize+1);
  900. fShmNonRtServerControl.readCustomData(copyright, copyrightSize);
  901. fInfo.name = realName;
  902. fInfo.label = label;
  903. if (pData->name == nullptr)
  904. pData->name = pData->engine->getUniquePluginName(realName);
  905. } break;
  906. case kPluginBridgeNonRtServerAudioCount:
  907. // uint/ins, uint/outs
  908. fInfo.aIns = fShmNonRtServerControl.readUInt();
  909. fInfo.aOuts = fShmNonRtServerControl.readUInt();
  910. CARLA_SAFE_ASSERT(fInfo.aInNames == nullptr);
  911. CARLA_SAFE_ASSERT(fInfo.aOutNames == nullptr);
  912. if (fInfo.aIns > 0)
  913. {
  914. fInfo.aInNames = new const char*[fInfo.aIns];
  915. carla_zeroPointers(fInfo.aInNames, fInfo.aIns);
  916. }
  917. if (fInfo.aOuts > 0)
  918. {
  919. fInfo.aOutNames = new const char*[fInfo.aOuts];
  920. carla_zeroPointers(fInfo.aOutNames, fInfo.aOuts);
  921. }
  922. break;
  923. case kPluginBridgeNonRtServerMidiCount:
  924. // uint/ins, uint/outs
  925. fInfo.mIns = fShmNonRtServerControl.readUInt();
  926. fInfo.mOuts = fShmNonRtServerControl.readUInt();
  927. break;
  928. case kPluginBridgeNonRtServerCvCount:
  929. // uint/ins, uint/outs
  930. fInfo.cvIns = fShmNonRtServerControl.readUInt();
  931. fInfo.cvOuts = fShmNonRtServerControl.readUInt();
  932. break;
  933. case kPluginBridgeNonRtServerParameterCount:
  934. // uint/count
  935. fShmNonRtServerControl.readUInt();
  936. break;
  937. case kPluginBridgeNonRtServerProgramCount:
  938. // uint/count
  939. fShmNonRtServerControl.readUInt();
  940. break;
  941. case kPluginBridgeNonRtServerMidiProgramCount:
  942. // uint/count
  943. fShmNonRtServerControl.readUInt();
  944. break;
  945. case kPluginBridgeNonRtServerPortName: {
  946. // byte/type, uint/index, uint/size, str[] (name)
  947. const uint8_t portType = fShmNonRtServerControl.readByte();
  948. const uint32_t index = fShmNonRtServerControl.readUInt();
  949. // name
  950. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  951. char* const name = new char[nameSize+1];
  952. carla_zeroChars(name, nameSize+1);
  953. fShmNonRtServerControl.readCustomData(name, nameSize);
  954. CARLA_SAFE_ASSERT_BREAK(portType > kPluginBridgePortNull && portType < kPluginBridgePortTypeCount);
  955. switch (portType)
  956. {
  957. case kPluginBridgePortAudioInput:
  958. CARLA_SAFE_ASSERT_BREAK(index < fInfo.aIns);
  959. fInfo.aInNames[index] = name;
  960. break;
  961. case kPluginBridgePortAudioOutput:
  962. CARLA_SAFE_ASSERT_BREAK(index < fInfo.aOuts);
  963. fInfo.aOutNames[index] = name;
  964. break;
  965. }
  966. } break;
  967. case kPluginBridgeNonRtServerParameterData1:
  968. // uint/index, int/rindex, uint/type, uint/hints, int/cc
  969. fShmNonRtServerControl.readUInt();
  970. fShmNonRtServerControl.readInt();
  971. fShmNonRtServerControl.readUInt();
  972. fShmNonRtServerControl.readUInt();
  973. fShmNonRtServerControl.readShort();
  974. break;
  975. case kPluginBridgeNonRtServerParameterData2:
  976. // uint/index, uint/size, str[] (name), uint/size, str[] (unit)
  977. fShmNonRtServerControl.readUInt();
  978. if (const uint32_t size = fShmNonRtServerControl.readUInt())
  979. {
  980. char name[size];
  981. fShmNonRtServerControl.readCustomData(name, size);
  982. }
  983. if (const uint32_t size = fShmNonRtServerControl.readUInt())
  984. {
  985. char symbol[size];
  986. fShmNonRtServerControl.readCustomData(symbol, size);
  987. }
  988. if (const uint32_t size = fShmNonRtServerControl.readUInt())
  989. {
  990. char unit[size];
  991. fShmNonRtServerControl.readCustomData(unit, size);
  992. }
  993. break;
  994. case kPluginBridgeNonRtServerParameterRanges:
  995. // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
  996. fShmNonRtServerControl.readUInt();
  997. fShmNonRtServerControl.readFloat();
  998. fShmNonRtServerControl.readFloat();
  999. fShmNonRtServerControl.readFloat();
  1000. fShmNonRtServerControl.readFloat();
  1001. fShmNonRtServerControl.readFloat();
  1002. fShmNonRtServerControl.readFloat();
  1003. break;
  1004. case kPluginBridgeNonRtServerParameterValue:
  1005. // uint/index, float/value
  1006. fShmNonRtServerControl.readUInt();
  1007. fShmNonRtServerControl.readFloat();
  1008. break;
  1009. case kPluginBridgeNonRtServerParameterValue2:
  1010. // uint/index, float/value
  1011. fShmNonRtServerControl.readUInt();
  1012. fShmNonRtServerControl.readFloat();
  1013. break;
  1014. case kPluginBridgeNonRtServerDefaultValue:
  1015. // uint/index, float/value
  1016. fShmNonRtServerControl.readUInt();
  1017. fShmNonRtServerControl.readFloat();
  1018. break;
  1019. case kPluginBridgeNonRtServerCurrentProgram:
  1020. // int/index
  1021. fShmNonRtServerControl.readInt();
  1022. break;
  1023. case kPluginBridgeNonRtServerCurrentMidiProgram: {
  1024. // int/index
  1025. fShmNonRtServerControl.readInt();
  1026. } break;
  1027. case kPluginBridgeNonRtServerProgramName: {
  1028. // uint/index, uint/size, str[] (name)
  1029. fShmNonRtServerControl.readUInt();
  1030. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1031. char name[nameSize];
  1032. fShmNonRtServerControl.readCustomData(name, nameSize);
  1033. } break;
  1034. case kPluginBridgeNonRtServerMidiProgramData: {
  1035. // uint/index, uint/bank, uint/program, uint/size, str[] (name)
  1036. fShmNonRtServerControl.readUInt();
  1037. fShmNonRtServerControl.readUInt();
  1038. fShmNonRtServerControl.readUInt();
  1039. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1040. char name[nameSize];
  1041. fShmNonRtServerControl.readCustomData(name, nameSize);
  1042. } break;
  1043. case kPluginBridgeNonRtServerSetCustomData: {
  1044. // uint/size, str[], uint/size, str[], uint/size, str[]
  1045. // type
  1046. const uint32_t typeSize(fShmNonRtServerControl.readUInt());
  1047. char type[typeSize];
  1048. fShmNonRtServerControl.readCustomData(type, typeSize);
  1049. // key
  1050. const uint32_t keySize(fShmNonRtServerControl.readUInt());
  1051. char key[keySize];
  1052. fShmNonRtServerControl.readCustomData(key, keySize);
  1053. // value
  1054. const uint32_t valueSize(fShmNonRtServerControl.readUInt());
  1055. char value[valueSize];
  1056. fShmNonRtServerControl.readCustomData(value, valueSize);
  1057. } break;
  1058. case kPluginBridgeNonRtServerSetChunkDataFile: {
  1059. // uint/size, str[] (filename)
  1060. const uint32_t chunkFilePathSize(fShmNonRtServerControl.readUInt());
  1061. char chunkFilePath[chunkFilePathSize];
  1062. fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize);
  1063. } break;
  1064. case kPluginBridgeNonRtServerSetLatency:
  1065. // uint
  1066. fShmNonRtServerControl.readUInt();
  1067. break;
  1068. case kPluginBridgeNonRtServerReady:
  1069. fInitiated = true;
  1070. break;
  1071. case kPluginBridgeNonRtServerSaved:
  1072. break;
  1073. case kPluginBridgeNonRtServerUiClosed:
  1074. carla_stdout("bridge closed cleanly?");
  1075. pData->active = false;
  1076. #ifdef HAVE_LIBLO
  1077. if (pData->engine->isOscControlRegistered())
  1078. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, 0.0f);
  1079. #endif
  1080. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_ACTIVE, 0, 0.0f, nullptr);
  1081. fBridgeThread.stopThread(1000);
  1082. break;
  1083. case kPluginBridgeNonRtServerError: {
  1084. // error
  1085. const uint32_t errorSize(fShmNonRtServerControl.readUInt());
  1086. char error[errorSize+1];
  1087. carla_zeroChars(error, errorSize+1);
  1088. fShmNonRtServerControl.readCustomData(error, errorSize);
  1089. if (fInitiated)
  1090. {
  1091. pData->engine->callback(ENGINE_CALLBACK_ERROR, pData->id, 0, 0, 0.0f, error);
  1092. // just in case
  1093. pData->engine->setLastError(error);
  1094. fInitError = true;
  1095. }
  1096. else
  1097. {
  1098. pData->engine->setLastError(error);
  1099. fInitError = true;
  1100. fInitiated = true;
  1101. }
  1102. } break;
  1103. }
  1104. }
  1105. }
  1106. // -------------------------------------------------------------------
  1107. uintptr_t getUiBridgeProcessId() const noexcept override
  1108. {
  1109. return fBridgeThread.getProcessID();
  1110. }
  1111. // -------------------------------------------------------------------
  1112. bool init(const char* const filename, const char* const name)
  1113. {
  1114. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1115. // ---------------------------------------------------------------
  1116. // first checks
  1117. if (pData->client != nullptr)
  1118. {
  1119. pData->engine->setLastError("Plugin client is already registered");
  1120. return false;
  1121. }
  1122. // ---------------------------------------------------------------
  1123. // set info
  1124. if (name != nullptr && name[0] != '\0')
  1125. pData->name = pData->engine->getUniquePluginName(name);
  1126. if (filename != nullptr && filename[0] != '\0')
  1127. pData->filename = carla_strdup(filename);
  1128. else
  1129. pData->filename = carla_strdup("");
  1130. std::srand(static_cast<uint>(std::time(nullptr)));
  1131. // ---------------------------------------------------------------
  1132. // init sem/shm
  1133. if (! fShmAudioPool.initializeServer())
  1134. {
  1135. carla_stderr("Failed to initialize shared memory audio pool");
  1136. return false;
  1137. }
  1138. if (! fShmRtClientControl.initializeServer())
  1139. {
  1140. carla_stderr("Failed to initialize RT client control");
  1141. fShmAudioPool.clear();
  1142. return false;
  1143. }
  1144. if (! fShmNonRtClientControl.initializeServer())
  1145. {
  1146. carla_stderr("Failed to initialize Non-RT client control");
  1147. fShmRtClientControl.clear();
  1148. fShmAudioPool.clear();
  1149. return false;
  1150. }
  1151. if (! fShmNonRtServerControl.initializeServer())
  1152. {
  1153. carla_stderr("Failed to initialize Non-RT server control");
  1154. fShmNonRtClientControl.clear();
  1155. fShmRtClientControl.clear();
  1156. fShmAudioPool.clear();
  1157. return false;
  1158. }
  1159. // ---------------------------------------------------------------
  1160. // init bridge thread
  1161. {
  1162. char shmIdsStr[6*4+1];
  1163. carla_zeroChars(shmIdsStr, 6*4+1);
  1164. std::strncpy(shmIdsStr+6*0, &fShmAudioPool.filename[fShmAudioPool.filename.length()-6], 6);
  1165. std::strncpy(shmIdsStr+6*1, &fShmRtClientControl.filename[fShmRtClientControl.filename.length()-6], 6);
  1166. std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6);
  1167. std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6);
  1168. fBridgeThread.setData(shmIdsStr);
  1169. }
  1170. if (! restartBridgeThread())
  1171. return false;
  1172. // ---------------------------------------------------------------
  1173. // register client
  1174. if (pData->name == nullptr)
  1175. pData->name = pData->engine->getUniquePluginName("unknown");
  1176. pData->client = pData->engine->addClient(this);
  1177. if (pData->client == nullptr || ! pData->client->isOk())
  1178. {
  1179. pData->engine->setLastError("Failed to register plugin client");
  1180. return false;
  1181. }
  1182. return true;
  1183. }
  1184. private:
  1185. bool fInitiated;
  1186. bool fInitError;
  1187. bool fTimedOut;
  1188. bool fTimedError;
  1189. bool fProcCanceled;
  1190. uint fProcWaitTime;
  1191. int64_t fLastPongTime;
  1192. CarlaPluginJackThread fBridgeThread;
  1193. BridgeAudioPool fShmAudioPool;
  1194. BridgeRtClientControl fShmRtClientControl;
  1195. BridgeNonRtClientControl fShmNonRtClientControl;
  1196. BridgeNonRtServerControl fShmNonRtServerControl;
  1197. struct Info {
  1198. uint32_t aIns, aOuts;
  1199. uint32_t cvIns, cvOuts;
  1200. uint32_t mIns, mOuts;
  1201. PluginCategory category;
  1202. uint optionsAvailable;
  1203. CarlaString name;
  1204. CarlaString label;
  1205. const char** aInNames;
  1206. const char** aOutNames;
  1207. std::vector<uint8_t> chunk;
  1208. Info()
  1209. : aIns(0),
  1210. aOuts(0),
  1211. cvIns(0),
  1212. cvOuts(0),
  1213. mIns(0),
  1214. mOuts(0),
  1215. category(PLUGIN_CATEGORY_NONE),
  1216. optionsAvailable(0),
  1217. name(),
  1218. label(),
  1219. aInNames(nullptr),
  1220. aOutNames(nullptr),
  1221. chunk() {}
  1222. CARLA_DECLARE_NON_COPY_STRUCT(Info)
  1223. } fInfo;
  1224. void resizeAudioPool(const uint32_t bufferSize)
  1225. {
  1226. fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts, fInfo.cvIns+fInfo.cvOuts);
  1227. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
  1228. fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.dataSize));
  1229. fShmRtClientControl.commitWrite();
  1230. waitForClient("resize-pool", 5000);
  1231. }
  1232. void waitForClient(const char* const action, const uint msecs)
  1233. {
  1234. CARLA_SAFE_ASSERT_RETURN(! fTimedOut,);
  1235. CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
  1236. if (fShmRtClientControl.waitForClient(msecs))
  1237. return;
  1238. fTimedOut = true;
  1239. carla_stderr("waitForClient(%s) timed out", action);
  1240. }
  1241. bool restartBridgeThread()
  1242. {
  1243. fInitiated = false;
  1244. fInitError = false;
  1245. fTimedError = false;
  1246. // cleanup of previous data
  1247. delete[] fInfo.aInNames;
  1248. fInfo.aInNames = nullptr;
  1249. delete[] fInfo.aOutNames;
  1250. fInfo.aOutNames = nullptr;
  1251. // reset memory
  1252. fProcCanceled = false;
  1253. fShmRtClientControl.data->procFlags = 0;
  1254. carla_zeroStruct(fShmRtClientControl.data->timeInfo);
  1255. carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
  1256. fShmRtClientControl.clearData();
  1257. fShmNonRtClientControl.clearData();
  1258. fShmNonRtServerControl.clearData();
  1259. // initial values
  1260. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientNull);
  1261. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeRtClientData)));
  1262. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtClientData)));
  1263. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtServerData)));
  1264. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetBufferSize);
  1265. fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize());
  1266. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetSampleRate);
  1267. fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate());
  1268. fShmNonRtClientControl.commitWrite();
  1269. if (fShmAudioPool.dataSize != 0)
  1270. {
  1271. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
  1272. fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.dataSize));
  1273. fShmRtClientControl.commitWrite();
  1274. }
  1275. else
  1276. {
  1277. // testing dummy message
  1278. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull);
  1279. fShmRtClientControl.commitWrite();
  1280. }
  1281. fBridgeThread.startThread();
  1282. fLastPongTime = Time::currentTimeMillis();
  1283. CARLA_SAFE_ASSERT(fLastPongTime > 0);
  1284. static bool sFirstInit = true;
  1285. int64_t timeoutEnd = 5000;
  1286. if (sFirstInit)
  1287. timeoutEnd *= 2;
  1288. sFirstInit = false;
  1289. const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;
  1290. for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();)
  1291. {
  1292. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1293. if (needsEngineIdle)
  1294. pData->engine->idle();
  1295. idle();
  1296. if (fInitiated)
  1297. break;
  1298. if (pData->engine->isAboutToClose())
  1299. break;
  1300. carla_msleep(20);
  1301. }
  1302. fLastPongTime = -1;
  1303. if (fInitError || ! fInitiated)
  1304. {
  1305. fBridgeThread.stopThread(6000);
  1306. if (! fInitError)
  1307. pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n"
  1308. "(or the plugin crashed on initialization?)");
  1309. return false;
  1310. }
  1311. return true;
  1312. }
  1313. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginJack)
  1314. };
  1315. CARLA_BACKEND_END_NAMESPACE
  1316. #endif // CARLA_OS_LINUX
  1317. // -------------------------------------------------------------------------------------------------------------------
  1318. CARLA_BACKEND_START_NAMESPACE
  1319. CarlaPlugin* CarlaPlugin::newJackApp(const Initializer& init)
  1320. {
  1321. carla_debug("CarlaPlugin::newJackApp({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label);
  1322. #ifdef CARLA_OS_LINUX
  1323. CarlaPluginJack* const plugin(new CarlaPluginJack(init.engine, init.id));
  1324. if (! plugin->init(init.filename, init.name))
  1325. {
  1326. delete plugin;
  1327. return nullptr;
  1328. }
  1329. return plugin;
  1330. #else
  1331. init.engine->setLastError("JACK Application support not available");
  1332. return nullptr;
  1333. #endif
  1334. }
  1335. CARLA_BACKEND_END_NAMESPACE
  1336. // -------------------------------------------------------------------------------------------------------------------