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.

1179 lines
39KB

  1. /*
  2. * Carla Juce Plugin
  3. * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #ifdef HAVE_JUCE_UI
  20. #if defined(CARLA_OS_MAC)
  21. /*
  22. * Missing functions in OSX.
  23. */
  24. namespace std {
  25. inline float
  26. fmin(float __x, float __y)
  27. { return __builtin_fminf(__x, __y); }
  28. inline float
  29. fmax(float __x, float __y)
  30. { return __builtin_fmaxf(__x, __y); }
  31. inline float
  32. rint(float __x)
  33. { return __builtin_rintf(__x); }
  34. }
  35. #endif
  36. #include "CarlaBackendUtils.hpp"
  37. #include "JucePluginWindow.hpp"
  38. #include "juce_audio_processors.h"
  39. using namespace juce;
  40. CARLA_BACKEND_START_NAMESPACE
  41. class JucePlugin : public CarlaPlugin,
  42. public AudioPlayHead,
  43. public AudioProcessorListener
  44. {
  45. public:
  46. JucePlugin(CarlaEngine* const engine, const uint id)
  47. : CarlaPlugin(engine, id),
  48. fInstance(nullptr),
  49. fAudioBuffer(1, 0)
  50. {
  51. carla_debug("JucePlugin::JucePlugin(%p, %i)", engine, id);
  52. fMidiBuffer.ensureSize(2048);
  53. fMidiBuffer.clear();
  54. fPosInfo.resetToDefault();
  55. }
  56. ~JucePlugin() override
  57. {
  58. carla_debug("JucePlugin::~JucePlugin()");
  59. // close UI
  60. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  61. showCustomUI(false);
  62. pData->singleMutex.lock();
  63. pData->masterMutex.lock();
  64. if (pData->client != nullptr && pData->client->isActive())
  65. pData->client->deactivate();
  66. if (pData->active)
  67. {
  68. deactivate();
  69. pData->active = false;
  70. }
  71. if (fInstance != nullptr)
  72. {
  73. delete fInstance;
  74. fInstance = nullptr;
  75. }
  76. clearBuffers();
  77. }
  78. // -------------------------------------------------------------------
  79. // Information (base)
  80. PluginType getType() const noexcept override
  81. {
  82. PluginType type = PLUGIN_NONE;
  83. try {
  84. type = getPluginTypeFromString(fDesc.pluginFormatName.toRawUTF8());
  85. } catch(...) {}
  86. return type;
  87. }
  88. PluginCategory getCategory() const noexcept override
  89. {
  90. PluginCategory category = PLUGIN_CATEGORY_NONE;
  91. try {
  92. category = getPluginCategoryFromName(fDesc.category.toRawUTF8());
  93. } catch(...) {}
  94. return category;
  95. }
  96. int64_t getUniqueId() const noexcept override
  97. {
  98. return fDesc.uid;
  99. }
  100. // -------------------------------------------------------------------
  101. // Information (count)
  102. // nothing
  103. // -------------------------------------------------------------------
  104. // Information (current data)
  105. // nothing
  106. // -------------------------------------------------------------------
  107. // Information (per-plugin data)
  108. uint getOptionsAvailable() const noexcept override
  109. {
  110. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0x0);
  111. uint options = 0x0;
  112. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  113. //options |= PLUGIN_OPTION_USE_CHUNKS;
  114. if (fInstance->acceptsMidi())
  115. {
  116. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  117. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  118. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  119. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  120. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  121. }
  122. return options;
  123. }
  124. float getParameterValue(const uint32_t parameterId) const noexcept override
  125. {
  126. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  127. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0.0f);
  128. return fInstance->getParameter(static_cast<int>(parameterId));
  129. }
  130. void getLabel(char* const strBuf) const noexcept override
  131. {
  132. std::strncpy(strBuf, fDesc.name.toRawUTF8(), STR_MAX);
  133. }
  134. void getMaker(char* const strBuf) const noexcept override
  135. {
  136. std::strncpy(strBuf, fDesc.manufacturerName.toRawUTF8(), STR_MAX);
  137. }
  138. void getCopyright(char* const strBuf) const noexcept override
  139. {
  140. getMaker(strBuf);
  141. }
  142. void getRealName(char* const strBuf) const noexcept override
  143. {
  144. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  145. std::strncpy(strBuf, fInstance->getName().toRawUTF8(), STR_MAX);
  146. }
  147. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  148. {
  149. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  150. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  151. std::strncpy(strBuf, fInstance->getParameterName(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  152. }
  153. void getParameterText(const uint32_t parameterId, char* const strBuf) const noexcept override
  154. {
  155. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  156. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  157. std::strncpy(strBuf, fInstance->getParameterText(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  158. }
  159. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  162. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  163. std::strncpy(strBuf, fInstance->getParameterLabel(static_cast<int>(parameterId)).toRawUTF8(), STR_MAX);
  164. }
  165. // -------------------------------------------------------------------
  166. // Set data (state)
  167. // nothing
  168. // -------------------------------------------------------------------
  169. // Set data (internal stuff)
  170. void setName(const char* const newName) override
  171. {
  172. CarlaPlugin::setName(newName);
  173. if (fWindow != nullptr)
  174. {
  175. String uiName(pData->name);
  176. uiName += " (GUI)";
  177. fWindow->setName(uiName);
  178. }
  179. }
  180. // -------------------------------------------------------------------
  181. // Set data (plugin-specific stuff)
  182. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  183. {
  184. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  185. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  186. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  187. fInstance->setParameter(static_cast<int>(parameterId), value);
  188. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  189. }
  190. // -------------------------------------------------------------------
  191. // Set ui stuff
  192. void showCustomUI(const bool yesNo) override
  193. {
  194. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  195. #ifdef CARLA_OS_LINUX
  196. const MessageManagerLock mmLock;
  197. #endif
  198. if (yesNo)
  199. {
  200. if (fWindow == nullptr)
  201. {
  202. String uiName(pData->name);
  203. uiName += " (GUI)";
  204. fWindow = new JucePluginWindow();
  205. fWindow->setName(uiName);
  206. }
  207. if (AudioProcessorEditor* const editor = fInstance->createEditorIfNeeded())
  208. fWindow->show(editor);
  209. }
  210. else
  211. {
  212. if (fWindow != nullptr)
  213. fWindow->hide();
  214. if (AudioProcessorEditor* const editor = fInstance->getActiveEditor())
  215. delete editor;
  216. fWindow = nullptr;
  217. }
  218. }
  219. void idle() override
  220. {
  221. if (fWindow != nullptr)
  222. {
  223. if (fWindow->wasClosedByUser())
  224. {
  225. showCustomUI(false);
  226. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  227. }
  228. }
  229. CarlaPlugin::idle();
  230. }
  231. // -------------------------------------------------------------------
  232. // Plugin state
  233. void reload() override
  234. {
  235. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  236. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  237. carla_debug("VstPlugin::reload() - start");
  238. const EngineProcessMode processMode(pData->engine->getProccessMode());
  239. // Safely disable plugin for reload
  240. const ScopedDisabler sd(this);
  241. if (pData->active)
  242. deactivate();
  243. clearBuffers();
  244. fInstance->refreshParameterList();
  245. uint32_t aIns, aOuts, mIns, mOuts, params;
  246. mIns = mOuts = 0;
  247. bool needsCtrlIn, needsCtrlOut;
  248. needsCtrlIn = needsCtrlOut = false;
  249. aIns = (fInstance->getNumInputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumInputChannels()) : 0;
  250. aOuts = (fInstance->getNumOutputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumOutputChannels()) : 0;
  251. params = (fInstance->getNumParameters() > 0) ? static_cast<uint32_t>(fInstance->getNumParameters()) : 0;
  252. if (fInstance->acceptsMidi())
  253. {
  254. mIns = 1;
  255. needsCtrlIn = true;
  256. }
  257. if (fInstance->producesMidi())
  258. {
  259. mOuts = 1;
  260. needsCtrlOut = true;
  261. }
  262. if (aIns > 0)
  263. {
  264. pData->audioIn.createNew(aIns);
  265. }
  266. if (aOuts > 0)
  267. {
  268. pData->audioOut.createNew(aOuts);
  269. needsCtrlIn = true;
  270. }
  271. if (params > 0)
  272. {
  273. pData->param.createNew(params, false);
  274. needsCtrlIn = true;
  275. }
  276. const uint portNameSize(pData->engine->getMaxPortNameSize());
  277. CarlaString portName;
  278. // Audio Ins
  279. for (uint32_t j=0; j < aIns; ++j)
  280. {
  281. portName.clear();
  282. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  283. {
  284. portName = pData->name;
  285. portName += ":";
  286. }
  287. if (aIns > 1)
  288. {
  289. portName += "input_";
  290. portName += CarlaString(j+1);
  291. }
  292. else
  293. portName += "input";
  294. portName.truncate(portNameSize);
  295. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true);
  296. pData->audioIn.ports[j].rindex = j;
  297. }
  298. // Audio Outs
  299. for (uint32_t j=0; j < aOuts; ++j)
  300. {
  301. portName.clear();
  302. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  303. {
  304. portName = pData->name;
  305. portName += ":";
  306. }
  307. if (aOuts > 1)
  308. {
  309. portName += "output_";
  310. portName += CarlaString(j+1);
  311. }
  312. else
  313. portName += "output";
  314. portName.truncate(portNameSize);
  315. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  316. pData->audioOut.ports[j].rindex = j;
  317. }
  318. for (uint32_t j=0; j < params; ++j)
  319. {
  320. pData->param.data[j].type = PARAMETER_INPUT;
  321. pData->param.data[j].index = static_cast<int32_t>(j);
  322. pData->param.data[j].rindex = static_cast<int32_t>(j);
  323. float min, max, def, step, stepSmall, stepLarge;
  324. // TODO
  325. //const int numSteps(fInstance->getParameterNumSteps(static_cast<int>(j)));
  326. {
  327. min = 0.0f;
  328. max = 1.0f;
  329. step = 0.001f;
  330. stepSmall = 0.0001f;
  331. stepLarge = 0.1f;
  332. }
  333. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  334. #ifndef BUILD_BRIDGE
  335. pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  336. #endif
  337. if (fInstance->isParameterAutomatable(static_cast<int>(j)))
  338. pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  339. // FIXME?
  340. def = fInstance->getParameterDefaultValue(static_cast<int>(j));
  341. if (def < min)
  342. def = min;
  343. else if (def > max)
  344. def = max;
  345. pData->param.ranges[j].min = min;
  346. pData->param.ranges[j].max = max;
  347. pData->param.ranges[j].def = def;
  348. pData->param.ranges[j].step = step;
  349. pData->param.ranges[j].stepSmall = stepSmall;
  350. pData->param.ranges[j].stepLarge = stepLarge;
  351. }
  352. if (needsCtrlIn)
  353. {
  354. portName.clear();
  355. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  356. {
  357. portName = pData->name;
  358. portName += ":";
  359. }
  360. portName += "events-in";
  361. portName.truncate(portNameSize);
  362. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  363. }
  364. if (needsCtrlOut)
  365. {
  366. portName.clear();
  367. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  368. {
  369. portName = pData->name;
  370. portName += ":";
  371. }
  372. portName += "events-out";
  373. portName.truncate(portNameSize);
  374. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false);
  375. }
  376. // plugin hints
  377. pData->hints = 0x0;
  378. if (fDesc.isInstrument)
  379. pData->hints |= PLUGIN_IS_SYNTH;
  380. if (fInstance->hasEditor())
  381. {
  382. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  383. pData->hints |= PLUGIN_NEEDS_SINGLE_THREAD;
  384. }
  385. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  386. pData->hints |= PLUGIN_CAN_DRYWET;
  387. if (aOuts > 0)
  388. pData->hints |= PLUGIN_CAN_VOLUME;
  389. if (aOuts >= 2 && aOuts % 2 == 0)
  390. pData->hints |= PLUGIN_CAN_BALANCE;
  391. // extra plugin hints
  392. pData->extraHints = 0x0;
  393. if (mIns > 0)
  394. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  395. if (mOuts > 0)
  396. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  397. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  398. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  399. fInstance->setPlayConfigDetails(static_cast<int>(aIns), static_cast<int>(aOuts), pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  400. bufferSizeChanged(pData->engine->getBufferSize());
  401. //reloadPrograms(true);
  402. if (pData->active)
  403. activate();
  404. carla_debug("VstPlugin::reload() - end");
  405. }
  406. // -------------------------------------------------------------------
  407. // Plugin processing
  408. void activate() noexcept override
  409. {
  410. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  411. try {
  412. fInstance->prepareToPlay(pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  413. } catch(...) {}
  414. }
  415. void deactivate() noexcept override
  416. {
  417. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  418. try {
  419. fInstance->releaseResources();
  420. } catch(...) {}
  421. }
  422. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  423. {
  424. // --------------------------------------------------------------------------------------------------------
  425. // Check if active
  426. if (! pData->active)
  427. {
  428. // disable any output sound
  429. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  430. FloatVectorOperations::clear(outBuffer[i], static_cast<int>(frames));
  431. return;
  432. }
  433. // --------------------------------------------------------------------------------------------------------
  434. // Check if needs reset
  435. if (pData->needsReset)
  436. {
  437. fInstance->reset();
  438. pData->needsReset = false;
  439. }
  440. // --------------------------------------------------------------------------------------------------------
  441. // TimeInfo
  442. // TODO
  443. // --------------------------------------------------------------------------------------------------------
  444. // Event Input
  445. fMidiBuffer.clear();
  446. if (pData->event.portIn != nullptr)
  447. {
  448. // ----------------------------------------------------------------------------------------------------
  449. // MIDI Input (External)
  450. if (pData->extNotes.mutex.tryLock())
  451. {
  452. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next())
  453. {
  454. const ExternalMidiNote& note(it.getValue());
  455. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  456. uint8_t midiEvent[3];
  457. midiEvent[0] = static_cast<uint8_t>((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  458. midiEvent[1] = note.note;
  459. midiEvent[2] = note.velo;
  460. fMidiBuffer.addEvent(midiEvent, 3, 0);
  461. }
  462. pData->extNotes.data.clear();
  463. pData->extNotes.mutex.unlock();
  464. } // End of MIDI Input (External)
  465. // ----------------------------------------------------------------------------------------------------
  466. // Event Input (System)
  467. bool allNotesOffSent = false;
  468. uint32_t numEvents = pData->event.portIn->getEventCount();
  469. uint32_t nextBankId;
  470. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  471. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  472. else
  473. nextBankId = 0;
  474. for (uint32_t i=0; i < numEvents; ++i)
  475. {
  476. const EngineEvent& event(pData->event.portIn->getEvent(i));
  477. if (event.time >= frames)
  478. continue;
  479. switch (event.type)
  480. {
  481. case kEngineEventTypeNull:
  482. break;
  483. case kEngineEventTypeControl: {
  484. const EngineControlEvent& ctrlEvent(event.ctrl);
  485. switch (ctrlEvent.type)
  486. {
  487. case kEngineControlEventTypeNull:
  488. break;
  489. case kEngineControlEventTypeParameter: {
  490. #ifndef BUILD_BRIDGE
  491. // Control backend stuff
  492. if (event.channel == pData->ctrlChannel)
  493. {
  494. float value;
  495. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  496. {
  497. value = ctrlEvent.value;
  498. setDryWet(value, false, false);
  499. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  500. break;
  501. }
  502. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  503. {
  504. value = ctrlEvent.value*127.0f/100.0f;
  505. setVolume(value, false, false);
  506. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  507. break;
  508. }
  509. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  510. {
  511. float left, right;
  512. value = ctrlEvent.value/0.5f - 1.0f;
  513. if (value < 0.0f)
  514. {
  515. left = -1.0f;
  516. right = (value*2.0f)+1.0f;
  517. }
  518. else if (value > 0.0f)
  519. {
  520. left = (value*2.0f)-1.0f;
  521. right = 1.0f;
  522. }
  523. else
  524. {
  525. left = -1.0f;
  526. right = 1.0f;
  527. }
  528. setBalanceLeft(left, false, false);
  529. setBalanceRight(right, false, false);
  530. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  531. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  532. break;
  533. }
  534. }
  535. #endif
  536. // Control plugin parameters
  537. uint32_t k;
  538. for (k=0; k < pData->param.count; ++k)
  539. {
  540. if (pData->param.data[k].midiChannel != event.channel)
  541. continue;
  542. if (pData->param.data[k].midiCC != ctrlEvent.param)
  543. continue;
  544. if (pData->param.data[k].type != PARAMETER_INPUT)
  545. continue;
  546. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  547. continue;
  548. float value;
  549. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  550. {
  551. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  552. }
  553. else
  554. {
  555. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  556. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  557. value = std::rint(value);
  558. }
  559. setParameterValue(k, value, false, false, false);
  560. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  561. break;
  562. }
  563. // check if event is already handled
  564. if (k != pData->param.count)
  565. break;
  566. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  567. {
  568. uint8_t midiData[3];
  569. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  570. midiData[1] = static_cast<uint8_t>(ctrlEvent.param);
  571. midiData[2] = uint8_t(ctrlEvent.value*127.0f);
  572. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  573. }
  574. break;
  575. } // case kEngineControlEventTypeParameter
  576. case kEngineControlEventTypeMidiBank:
  577. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  578. nextBankId = ctrlEvent.param;
  579. break;
  580. case kEngineControlEventTypeMidiProgram:
  581. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  582. {
  583. const uint32_t nextProgramId = ctrlEvent.param;
  584. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  585. {
  586. if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
  587. {
  588. const int32_t index(static_cast<int32_t>(k));
  589. setMidiProgram(index, false, false, false);
  590. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f);
  591. break;
  592. }
  593. }
  594. }
  595. break;
  596. case kEngineControlEventTypeAllSoundOff:
  597. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  598. {
  599. uint8_t midiData[3];
  600. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  601. midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  602. midiData[2] = 0;
  603. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  604. }
  605. break;
  606. case kEngineControlEventTypeAllNotesOff:
  607. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  608. {
  609. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  610. {
  611. allNotesOffSent = true;
  612. sendMidiAllNotesOffToCallback();
  613. }
  614. uint8_t midiData[3];
  615. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  616. midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  617. midiData[2] = 0;
  618. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  619. }
  620. break;
  621. } // switch (ctrlEvent.type)
  622. break;
  623. } // case kEngineEventTypeControl
  624. case kEngineEventTypeMidi:
  625. {
  626. const EngineMidiEvent& midiEvent(event.midi);
  627. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  628. uint8_t channel = event.channel;
  629. // Fix bad note-off
  630. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  631. status = MIDI_STATUS_NOTE_OFF;
  632. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  633. continue;
  634. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  635. continue;
  636. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  637. continue;
  638. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  639. continue;
  640. fMidiBuffer.addEvent(midiEvent.data, midiEvent.size, static_cast<int>(event.time));
  641. if (status == MIDI_STATUS_NOTE_ON)
  642. pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
  643. else if (status == MIDI_STATUS_NOTE_OFF)
  644. pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
  645. break;
  646. } // case kEngineEventTypeMidi
  647. } // switch (event.type)
  648. }
  649. pData->postRtEvents.trySplice();
  650. } // End of Event Input
  651. // --------------------------------------------------------------------------------------------------------
  652. // Set TimeInfo
  653. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  654. fPosInfo.isPlaying = timeInfo.playing;
  655. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  656. {
  657. const double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar;
  658. const double ppqBeat = double(timeInfo.bbt.beat - 1);
  659. const double ppqTick = double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat;
  660. fPosInfo.bpm = timeInfo.bbt.beatsPerMinute;
  661. fPosInfo.timeSigNumerator = static_cast<int>(timeInfo.bbt.beatsPerBar);
  662. fPosInfo.timeSigDenominator = static_cast<int>(timeInfo.bbt.beatType);
  663. fPosInfo.timeInSamples = static_cast<int64_t>(timeInfo.frame);
  664. fPosInfo.timeInSeconds = static_cast<double>(fPosInfo.timeInSamples)/pData->engine->getSampleRate();
  665. fPosInfo.ppqPosition = ppqBar + ppqBeat + ppqTick;
  666. fPosInfo.ppqPositionOfLastBarStart = ppqBar;
  667. }
  668. // --------------------------------------------------------------------------------------------------------
  669. // Process
  670. processSingle(inBuffer, outBuffer, frames);
  671. // --------------------------------------------------------------------------------------------------------
  672. // MIDI Output
  673. if (pData->event.portOut != nullptr)
  674. {
  675. // TODO
  676. }
  677. }
  678. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  679. {
  680. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  681. if (pData->audioIn.count > 0)
  682. {
  683. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  684. }
  685. if (pData->audioOut.count > 0)
  686. {
  687. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  688. }
  689. // --------------------------------------------------------------------------------------------------------
  690. // Try lock, silence otherwise
  691. if (pData->engine->isOffline())
  692. {
  693. pData->singleMutex.lock();
  694. }
  695. else if (! pData->singleMutex.tryLock())
  696. {
  697. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  698. FloatVectorOperations::clear(outBuffer[i], static_cast<int>(frames));
  699. return false;
  700. }
  701. // --------------------------------------------------------------------------------------------------------
  702. // Set audio in buffers
  703. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  704. fAudioBuffer.copyFrom(static_cast<int>(i), 0, inBuffer[i], static_cast<int>(frames));
  705. // --------------------------------------------------------------------------------------------------------
  706. // Run plugin
  707. fInstance->processBlock(fAudioBuffer, fMidiBuffer);
  708. // --------------------------------------------------------------------------------------------------------
  709. // Set audio out buffers
  710. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  711. FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getReadPointer(static_cast<int>(i)), static_cast<int>(frames));
  712. // --------------------------------------------------------------------------------------------------------
  713. // Midi out
  714. if (! fMidiBuffer.isEmpty())
  715. {
  716. if (pData->event.portOut != nullptr)
  717. {
  718. const uint8* midiEventData;
  719. int midiEventSize, midiEventPosition;
  720. for (MidiBuffer::Iterator i(fMidiBuffer); i.getNextEvent(midiEventData, midiEventSize, midiEventPosition);)
  721. {
  722. CARLA_SAFE_ASSERT_BREAK(midiEventPosition >= 0 && midiEventPosition < static_cast<int>(frames));
  723. CARLA_SAFE_ASSERT_BREAK(midiEventSize > 0);
  724. if (! pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(midiEventPosition), static_cast<uint8_t>(midiEventSize), midiEventData))
  725. break;
  726. }
  727. }
  728. fMidiBuffer.clear();
  729. }
  730. // --------------------------------------------------------------------------------------------------------
  731. pData->singleMutex.unlock();
  732. return true;
  733. }
  734. void bufferSizeChanged(const uint32_t newBufferSize) override
  735. {
  736. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  737. carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
  738. fAudioBuffer.setSize(static_cast<int>(std::max<uint32_t>(pData->audioIn.count, pData->audioOut.count)), static_cast<int>(newBufferSize));
  739. if (pData->active)
  740. {
  741. deactivate();
  742. activate();
  743. }
  744. }
  745. void sampleRateChanged(const double newSampleRate) override
  746. {
  747. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  748. carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
  749. if (pData->active)
  750. {
  751. deactivate();
  752. activate();
  753. }
  754. }
  755. // -------------------------------------------------------------------
  756. // Plugin buffers
  757. // nothing
  758. // -------------------------------------------------------------------
  759. // Post-poned UI Stuff
  760. // nothing
  761. // -------------------------------------------------------------------
  762. protected:
  763. void audioProcessorParameterChanged(AudioProcessor*, int index, float value) override
  764. {
  765. CARLA_SAFE_ASSERT_RETURN(index >= 0,);
  766. const uint32_t uindex(static_cast<uint32_t>(index));
  767. const float fixedValue(pData->param.getFixedValue(uindex, value));
  768. CarlaPlugin::setParameterValue(static_cast<uint32_t>(index), fixedValue, false, true, true);
  769. }
  770. void audioProcessorChanged(AudioProcessor*) override
  771. {
  772. pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0.0f, nullptr);
  773. }
  774. void audioProcessorParameterChangeGestureBegin(AudioProcessor*, int) {}
  775. void audioProcessorParameterChangeGestureEnd(AudioProcessor*, int) {}
  776. bool getCurrentPosition(CurrentPositionInfo& result) override
  777. {
  778. carla_copyStruct<CurrentPositionInfo>(result, fPosInfo);
  779. return true;
  780. }
  781. // -------------------------------------------------------------------
  782. public:
  783. bool init(const char* const filename, const char* const name, /*const char* const label, */const int64_t uniqueId, const char* const format)
  784. {
  785. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  786. // ---------------------------------------------------------------
  787. // first checks
  788. if (pData->client != nullptr)
  789. {
  790. pData->engine->setLastError("Plugin client is already registered");
  791. return false;
  792. }
  793. if (filename == nullptr || filename[0] == '\0')
  794. {
  795. pData->engine->setLastError("null filename");
  796. return false;
  797. }
  798. #if 0
  799. if (label == nullptr || label[0] == '\0')
  800. {
  801. pData->engine->setLastError("null label");
  802. return false;
  803. }
  804. #endif
  805. if (format == nullptr || format[0] == '\0')
  806. {
  807. pData->engine->setLastError("null format");
  808. return false;
  809. }
  810. #ifdef CARLA_OS_LINUX
  811. const MessageManagerLock mmLock;
  812. #endif
  813. // ---------------------------------------------------------------
  814. // fix path for wine usage
  815. String jfilename(filename);
  816. #ifdef CARLA_OS_WIN
  817. if (jfilename.startsWith("/"))
  818. {
  819. jfilename.replace("/", "\\");
  820. jfilename = "Z:" + jfilename;
  821. }
  822. #endif
  823. //fDesc.name = fDesc.descriptiveName = label;
  824. fDesc.uid = static_cast<int>(uniqueId);
  825. fDesc.fileOrIdentifier = jfilename;
  826. fDesc.pluginFormatName = format;
  827. fFormatManager.addDefaultFormats();
  828. String error;
  829. fInstance = fFormatManager.createPluginInstance(fDesc, 44100, 512, error);
  830. if (fInstance == nullptr)
  831. {
  832. pData->engine->setLastError(error.toRawUTF8());
  833. return false;
  834. }
  835. fInstance->fillInPluginDescription(fDesc);
  836. fInstance->setPlayHead(this);
  837. fInstance->addListener(this);
  838. // ---------------------------------------------------------------
  839. // get info
  840. if (name != nullptr && name[0] != '\0')
  841. pData->name = pData->engine->getUniquePluginName(name);
  842. else
  843. pData->name = pData->engine->getUniquePluginName(fInstance->getName().toRawUTF8());
  844. pData->filename = carla_strdup(filename);
  845. // ---------------------------------------------------------------
  846. // register client
  847. pData->client = pData->engine->addClient(this);
  848. if (pData->client == nullptr || ! pData->client->isOk())
  849. {
  850. pData->engine->setLastError("Failed to register plugin client");
  851. return false;
  852. }
  853. // ---------------------------------------------------------------
  854. // set default options
  855. pData->options = 0x0;
  856. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  857. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  858. //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  859. if (fInstance->acceptsMidi())
  860. {
  861. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  862. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  863. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  864. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  865. }
  866. return true;
  867. }
  868. private:
  869. PluginDescription fDesc;
  870. AudioPluginInstance* fInstance;
  871. AudioPluginFormatManager fFormatManager;
  872. AudioSampleBuffer fAudioBuffer;
  873. MidiBuffer fMidiBuffer;
  874. CurrentPositionInfo fPosInfo;
  875. const char* fUniqueId;
  876. ScopedPointer<JucePluginWindow> fWindow;
  877. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePlugin)
  878. };
  879. CARLA_BACKEND_END_NAMESPACE
  880. #endif // HAVE_JUCE_UI
  881. // -------------------------------------------------------------------------------------------------------------------
  882. CARLA_BACKEND_START_NAMESPACE
  883. CarlaPlugin* CarlaPlugin::newJuce(const Initializer& init, const char* const format)
  884. {
  885. carla_debug("CarlaPlugin::newJuce({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "}, %s)", init.engine, init.filename, init.name, init.label, init.uniqueId, format);
  886. #ifdef HAVE_JUCE_UI
  887. JucePlugin* const plugin(new JucePlugin(init.engine, init.id));
  888. if (! plugin->init(init.filename, init.name, /*init.label,*/ init.uniqueId, format))
  889. {
  890. delete plugin;
  891. return nullptr;
  892. }
  893. plugin->reload();
  894. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  895. {
  896. init.engine->setLastError("Carla's rack mode can only work with Stereo VST3 plugins, sorry!");
  897. delete plugin;
  898. return nullptr;
  899. }
  900. return plugin;
  901. #else
  902. init.engine->setLastError("Juce plugin not available");
  903. return nullptr;
  904. (void)format;
  905. #endif
  906. }
  907. CARLA_BACKEND_END_NAMESPACE
  908. // -------------------------------------------------------------------------------------------------------------------