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.

944 lines
27KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 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 doc/GPL.txt file.
  16. */
  17. #include "CarlaNative.hpp"
  18. #include "juce_gui_basics.h"
  19. using namespace juce;
  20. #include "vex/VexArp.h"
  21. #include "vex/VexChorus.h"
  22. #include "vex/VexDelay.h"
  23. #include "vex/VexReverb.h"
  24. #include "vex/PeggyViewComponent.h"
  25. // -----------------------------------------------------------------------
  26. class HelperWindow : public DocumentWindow
  27. {
  28. public:
  29. HelperWindow()
  30. : DocumentWindow("PlugWindow", Colour(50, 50, 200), DocumentWindow::closeButton, false),
  31. fClosed(false)
  32. {
  33. setVisible(false);
  34. setAlwaysOnTop(true);
  35. setDropShadowEnabled(false);
  36. setOpaque(true);
  37. //setResizable(false, false);
  38. //setUsingNativeTitleBar(false);
  39. }
  40. void show(Component* const comp)
  41. {
  42. fClosed = false;
  43. const int width = comp->getWidth();
  44. const int height = comp->getHeight()+getTitleBarHeight();
  45. centreWithSize(width, height);
  46. setContentNonOwned(comp, false);
  47. setSize(width, height);
  48. if (! isOnDesktop())
  49. addToDesktop();
  50. setVisible(true);
  51. }
  52. void hide()
  53. {
  54. setVisible(false);
  55. if (isOnDesktop())
  56. removeFromDesktop();
  57. clearContentComponent();
  58. }
  59. bool wasClosedByUser() const noexcept
  60. {
  61. return fClosed;
  62. }
  63. protected:
  64. void closeButtonPressed() override
  65. {
  66. fClosed = true;
  67. }
  68. private:
  69. bool fClosed;
  70. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HelperWindow)
  71. };
  72. // -----------------------------------------------------------------------
  73. class VexArpPlugin : public PluginClass,
  74. public PeggyViewComponent::Callback
  75. {
  76. public:
  77. enum Params {
  78. kParamOnOff = 0,
  79. kParamLength,
  80. kParamTimeMode,
  81. kParamSyncMode,
  82. kParamFailMode,
  83. kParamVelMode,
  84. kParamLast,
  85. kParamCount = kParamLast + VexArpSettings::kVelocitiesSize + VexArpSettings::kGridSize
  86. };
  87. VexArpPlugin(const HostDescriptor* const host)
  88. : PluginClass(host),
  89. fArp(&fSettings)
  90. {
  91. fArp.setSampleRate(getSampleRate());
  92. fMidiInBuffer.ensureSize(512*4);
  93. }
  94. protected:
  95. // -------------------------------------------------------------------
  96. // Plugin parameter calls
  97. uint32_t getParameterCount() const override
  98. {
  99. return kParamCount;
  100. }
  101. const Parameter* getParameterInfo(const uint32_t index) const override
  102. {
  103. static Parameter paramInfo;
  104. static ParameterScalePoint scalePoints[4];
  105. static char bufName[24+1];
  106. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  107. paramInfo.name = nullptr;
  108. paramInfo.unit = nullptr;
  109. paramInfo.ranges.def = 0.0f;
  110. paramInfo.ranges.min = 0.0f;
  111. paramInfo.ranges.max = 1.0f;
  112. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  113. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  114. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  115. paramInfo.scalePointCount = 0;
  116. paramInfo.scalePoints = nullptr;
  117. if (index < kParamLast)
  118. {
  119. hints |= PARAMETER_IS_INTEGER;
  120. paramInfo.ranges.step = 1.0f;
  121. paramInfo.ranges.stepSmall = 1.0f;
  122. paramInfo.ranges.stepLarge = 1.0f;
  123. switch (index)
  124. {
  125. case kParamOnOff:
  126. hints |= PARAMETER_IS_BOOLEAN;
  127. paramInfo.name = "On/Off";
  128. paramInfo.ranges.def = 0.0f;
  129. paramInfo.ranges.min = 0.0f;
  130. paramInfo.ranges.max = 1.0f;
  131. break;
  132. case kParamLength:
  133. paramInfo.name = "Length";
  134. paramInfo.ranges.def = 8.0f;
  135. paramInfo.ranges.min = 1.0f;
  136. paramInfo.ranges.max = 16.0f;
  137. break;
  138. case kParamTimeMode:
  139. hints |= PARAMETER_USES_SCALEPOINTS;
  140. paramInfo.name = "Time Signature";
  141. paramInfo.ranges.def = 2.0f;
  142. paramInfo.ranges.min = 1.0f;
  143. paramInfo.ranges.max = 3.0f;
  144. paramInfo.scalePointCount = 3;
  145. paramInfo.scalePoints = scalePoints;
  146. scalePoints[0].label = "1/8";
  147. scalePoints[1].label = "1/16";
  148. scalePoints[2].label = "1/32";
  149. scalePoints[0].value = 1.0f;
  150. scalePoints[1].value = 2.0f;
  151. scalePoints[2].value = 3.0f;
  152. break;
  153. case kParamSyncMode:
  154. hints |= PARAMETER_USES_SCALEPOINTS;
  155. paramInfo.name = "Sync Mode";
  156. paramInfo.ranges.def = 1.0f;
  157. paramInfo.ranges.min = 1.0f;
  158. paramInfo.ranges.max = 2.0f;
  159. paramInfo.scalePointCount = 2;
  160. paramInfo.scalePoints = scalePoints;
  161. scalePoints[0].label = "Key Sync";
  162. scalePoints[1].label = "Bar Sync";
  163. scalePoints[0].value = 1.0f;
  164. scalePoints[1].value = 2.0f;
  165. break;
  166. case kParamFailMode:
  167. hints |= PARAMETER_USES_SCALEPOINTS;
  168. paramInfo.name = "Fail Mode";
  169. paramInfo.ranges.def = 1.0f;
  170. paramInfo.ranges.min = 1.0f;
  171. paramInfo.ranges.max = 3.0f;
  172. paramInfo.scalePointCount = 3;
  173. paramInfo.scalePoints = scalePoints;
  174. scalePoints[0].label = "Silent Step";
  175. scalePoints[1].label = "Skip One";
  176. scalePoints[2].label = "Skip Two";
  177. scalePoints[0].value = 1.0f;
  178. scalePoints[1].value = 2.0f;
  179. scalePoints[2].value = 3.0f;
  180. break;
  181. case kParamVelMode:
  182. hints |= PARAMETER_USES_SCALEPOINTS;
  183. paramInfo.name = "Velocity Mode";
  184. paramInfo.ranges.def = 1.0f;
  185. paramInfo.ranges.min = 1.0f;
  186. paramInfo.ranges.max = 3.0f;
  187. paramInfo.scalePointCount = 3;
  188. paramInfo.scalePoints = scalePoints;
  189. scalePoints[0].label = "Pattern Velocity";
  190. scalePoints[1].label = "Input Velocity";
  191. scalePoints[2].label = "Sum Velocities";
  192. scalePoints[0].value = 1.0f;
  193. scalePoints[1].value = 2.0f;
  194. scalePoints[2].value = 3.0f;
  195. break;
  196. }
  197. }
  198. else if (index < kParamLast + VexArpSettings::kVelocitiesSize)
  199. {
  200. carla_zeroChar(bufName, 24+1);
  201. std::snprintf(bufName, 24, "Grid Velocity %i", index - kParamLast);
  202. paramInfo.name = bufName;
  203. }
  204. else
  205. {
  206. carla_zeroChar(bufName, 24+1);
  207. hints |= PARAMETER_IS_BOOLEAN|PARAMETER_IS_INTEGER;
  208. paramInfo.ranges.step = 1.0f;
  209. paramInfo.ranges.stepSmall = 1.0f;
  210. paramInfo.ranges.stepLarge = 1.0f;
  211. carla_zeroChar(bufName, 24+1);
  212. std::snprintf(bufName, 24, "Grid on/off %i", index - (kParamLast + VexArpSettings::kVelocitiesSize));
  213. paramInfo.name = bufName;
  214. }
  215. paramInfo.hints = static_cast<ParameterHints>(hints);
  216. return &paramInfo;
  217. }
  218. float getParameterValue(const uint32_t index) const override
  219. {
  220. if (index < kParamLast)
  221. {
  222. switch (index)
  223. {
  224. case kParamOnOff:
  225. return fSettings.on ? 1.0f : 0.0f;
  226. case kParamLength:
  227. return fSettings.length;
  228. case kParamTimeMode:
  229. return fSettings.timeMode;
  230. case kParamSyncMode:
  231. return fSettings.syncMode;
  232. case kParamFailMode:
  233. return fSettings.failMode;
  234. case kParamVelMode:
  235. return fSettings.velMode;
  236. default:
  237. return 0.0f;
  238. }
  239. }
  240. else if (index < kParamLast + VexArpSettings::kVelocitiesSize)
  241. {
  242. return fSettings.velocities[index-kParamLast];
  243. }
  244. else
  245. {
  246. return fSettings.grid[index-(kParamLast+VexArpSettings::kVelocitiesSize)] ? 1.0f : 0.0f;
  247. }
  248. }
  249. // -------------------------------------------------------------------
  250. // Plugin state calls
  251. void setParameterValue(const uint32_t index, const float value) override
  252. {
  253. if (index < kParamLast)
  254. {
  255. switch (index)
  256. {
  257. case kParamOnOff:
  258. fSettings.on = (value >= 0.5f);
  259. break;
  260. case kParamLength:
  261. fSettings.length = value;
  262. break;
  263. case kParamTimeMode:
  264. fSettings.timeMode = value;
  265. break;
  266. case kParamSyncMode:
  267. fSettings.syncMode = value;
  268. break;
  269. case kParamFailMode:
  270. fSettings.failMode = value;
  271. break;
  272. case kParamVelMode:
  273. fSettings.velMode = value;
  274. break;
  275. }
  276. }
  277. else if (index < kParamLast + VexArpSettings::kVelocitiesSize)
  278. {
  279. fSettings.velocities[index-kParamLast] = value;
  280. }
  281. else
  282. {
  283. fSettings.grid[index-(kParamLast+VexArpSettings::kVelocitiesSize)] = (value >= 0.5f);
  284. }
  285. }
  286. // -------------------------------------------------------------------
  287. // Plugin process calls
  288. void process(float**, float**, const uint32_t frames, const MidiEvent* const midiEvents, const uint32_t midiEventCount) override
  289. {
  290. if (! fSettings.on)
  291. {
  292. for (uint32_t i=0; i < midiEventCount; ++i)
  293. writeMidiEvent(&midiEvents[i]);
  294. return;
  295. }
  296. const TimeInfo* const timeInfo(getTimeInfo());
  297. bool timePlaying = false;
  298. double ppqPos = 0.0;
  299. double barStartPos = 0.0;
  300. double bpm = 120.0;
  301. if (timeInfo != nullptr)
  302. {
  303. timePlaying = timeInfo->playing;
  304. if (timeInfo->bbt.valid)
  305. {
  306. double ppqBar = double(timeInfo->bbt.bar - 1) * timeInfo->bbt.beatsPerBar;
  307. double ppqBeat = double(timeInfo->bbt.beat - 1);
  308. double ppqTick = double(timeInfo->bbt.tick) / timeInfo->bbt.ticksPerBeat;
  309. ppqPos = ppqBar + ppqBeat + ppqTick;
  310. barStartPos = ppqBar;
  311. bpm = timeInfo->bbt.beatsPerMinute;
  312. }
  313. }
  314. fMidiInBuffer.clear();
  315. for (uint32_t i=0; i < midiEventCount; ++i)
  316. {
  317. const MidiEvent* const midiEvent(&midiEvents[i]);
  318. fMidiInBuffer.addEvent(MidiMessage(midiEvent->data, midiEvent->size), midiEvent->time);
  319. }
  320. const MidiBuffer& outMidiBuffer(fArp.processMidi(fMidiInBuffer, timePlaying, ppqPos, barStartPos, bpm, frames));
  321. MidiBuffer::Iterator outBufferIterator(outMidiBuffer);
  322. MidiMessage midiMessage(0xf4);
  323. int sampleNumber;
  324. MidiEvent tmpEvent;
  325. tmpEvent.port = 0;
  326. while (outBufferIterator.getNextEvent(midiMessage, sampleNumber))
  327. {
  328. tmpEvent.size = midiMessage.getRawDataSize();
  329. tmpEvent.time = sampleNumber;
  330. if (tmpEvent.size > 4)
  331. continue;
  332. std::memcpy(tmpEvent.data, midiMessage.getRawData(), sizeof(uint8_t)*tmpEvent.size);
  333. writeMidiEvent(&tmpEvent);
  334. }
  335. }
  336. // -------------------------------------------------------------------
  337. // Plugin UI calls
  338. void uiShow(const bool show) override
  339. {
  340. if (show)
  341. {
  342. if (fWindow == nullptr)
  343. {
  344. fWindow = new HelperWindow();
  345. fWindow->setName(getUiName());
  346. }
  347. if (fView == nullptr)
  348. {
  349. fView = new PeggyViewComponent(1, fSettings, this);
  350. fView->setSize(207, 320);
  351. }
  352. fWindow->show(fView);
  353. }
  354. else if (fWindow != nullptr)
  355. {
  356. fWindow->hide();
  357. fView = nullptr;
  358. fWindow = nullptr;
  359. }
  360. }
  361. void uiIdle() override
  362. {
  363. if (fWindow == nullptr)
  364. return;
  365. if (fWindow->wasClosedByUser())
  366. {
  367. uiShow(false);
  368. uiClosed();
  369. }
  370. }
  371. void uiSetParameterValue(const uint32_t, const float) override
  372. {
  373. if (fView == nullptr)
  374. return;
  375. fView->update();
  376. }
  377. // -------------------------------------------------------------------
  378. // Plugin dispatcher calls
  379. void sampleRateChanged(const double sampleRate) override
  380. {
  381. fArp.setSampleRate(sampleRate);
  382. }
  383. void uiNameChanged(const char* const uiName) override
  384. {
  385. if (fWindow == nullptr)
  386. return;
  387. fWindow->setName(uiName);
  388. }
  389. // -------------------------------------------------------------------
  390. // Peggy callback
  391. void arpParameterChanged(const uint32_t id) override
  392. {
  393. uiParameterChanged(id, getParameterValue(id));
  394. }
  395. private:
  396. VexArpSettings fSettings;
  397. VexArp fArp;
  398. MidiBuffer fMidiInBuffer;
  399. ScopedPointer<PeggyViewComponent> fView;
  400. ScopedPointer<HelperWindow> fWindow;
  401. PluginClassEND(VexArpPlugin)
  402. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexArpPlugin)
  403. };
  404. // -----------------------------------------------------------------------
  405. class VexChorusPlugin : public PluginClass
  406. {
  407. public:
  408. enum Params {
  409. kParamRate = 0,
  410. kParamDepth,
  411. kParamCount
  412. };
  413. VexChorusPlugin(const HostDescriptor* const host)
  414. : PluginClass(host),
  415. fChorus(fParameters)
  416. {
  417. std::memset(fParameters, 0, sizeof(float)*92);
  418. fParameters[76] = 0.3f;
  419. fParameters[77] = 0.6f;
  420. fChorus.setSampleRate(getSampleRate());
  421. }
  422. protected:
  423. // -------------------------------------------------------------------
  424. // Plugin parameter calls
  425. uint32_t getParameterCount() const override
  426. {
  427. return kParamCount;
  428. }
  429. const Parameter* getParameterInfo(const uint32_t index) const override
  430. {
  431. static Parameter paramInfo;
  432. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  433. paramInfo.name = nullptr;
  434. paramInfo.unit = nullptr;
  435. paramInfo.ranges.def = 0.0f;
  436. paramInfo.ranges.min = 0.0f;
  437. paramInfo.ranges.max = 1.0f;
  438. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  439. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  440. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  441. paramInfo.scalePointCount = 0;
  442. paramInfo.scalePoints = nullptr;
  443. switch (index)
  444. {
  445. case kParamRate:
  446. paramInfo.name = "Rate";
  447. paramInfo.ranges.def = 0.3f;
  448. break;
  449. case kParamDepth:
  450. paramInfo.name = "Depth";
  451. paramInfo.ranges.def = 0.6f;
  452. break;
  453. }
  454. paramInfo.hints = static_cast<ParameterHints>(hints);
  455. return &paramInfo;
  456. }
  457. float getParameterValue(const uint32_t index) const override
  458. {
  459. switch (index)
  460. {
  461. case kParamRate:
  462. return fParameters[76];
  463. case kParamDepth:
  464. return fParameters[77];
  465. default:
  466. return 0.0f;
  467. }
  468. }
  469. // -------------------------------------------------------------------
  470. // Plugin state calls
  471. void setParameterValue(const uint32_t index, const float value) override
  472. {
  473. switch (index)
  474. {
  475. case kParamRate:
  476. fParameters[76] = value;
  477. break;
  478. case kParamDepth:
  479. fParameters[77] = value;
  480. break;
  481. default:
  482. break;
  483. }
  484. }
  485. // -------------------------------------------------------------------
  486. // Plugin process calls
  487. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  488. {
  489. if (inBuffer[0] != outBuffer[0])
  490. FloatVectorOperations::copy(outBuffer[0], inBuffer[0], frames);
  491. if (inBuffer[1] != outBuffer[1])
  492. FloatVectorOperations::copy(outBuffer[1], inBuffer[1], frames);
  493. fChorus.processBlock(outBuffer[0], outBuffer[1], frames);
  494. }
  495. // -------------------------------------------------------------------
  496. // Plugin dispatcher calls
  497. void sampleRateChanged(const double sampleRate) override
  498. {
  499. fChorus.setSampleRate(sampleRate);
  500. }
  501. private:
  502. VexChorus fChorus;
  503. float fParameters[92];
  504. PluginClassEND(VexChorusPlugin)
  505. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexChorusPlugin)
  506. };
  507. // -----------------------------------------------------------------------
  508. class VexDelayPlugin : public PluginClass
  509. {
  510. public:
  511. enum Params {
  512. kParamTime = 0,
  513. kParamFeedback,
  514. kParamCount
  515. };
  516. VexDelayPlugin(const HostDescriptor* const host)
  517. : PluginClass(host),
  518. fDelay(fParameters)
  519. {
  520. std::memset(fParameters, 0, sizeof(float)*92);
  521. fParameters[73] = 0.5f;
  522. fParameters[74] = 0.4f;
  523. fDelay.setSampleRate(getSampleRate());
  524. }
  525. protected:
  526. // -------------------------------------------------------------------
  527. // Plugin parameter calls
  528. uint32_t getParameterCount() const override
  529. {
  530. return kParamCount;
  531. }
  532. const Parameter* getParameterInfo(const uint32_t index) const override
  533. {
  534. static Parameter paramInfo;
  535. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  536. paramInfo.name = nullptr;
  537. paramInfo.unit = nullptr;
  538. paramInfo.ranges.def = 0.0f;
  539. paramInfo.ranges.min = 0.0f;
  540. paramInfo.ranges.max = 1.0f;
  541. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  542. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  543. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  544. paramInfo.scalePointCount = 0;
  545. paramInfo.scalePoints = nullptr;
  546. switch (index)
  547. {
  548. case kParamTime:
  549. hints |= PARAMETER_IS_INTEGER;
  550. paramInfo.name = "Time";
  551. paramInfo.unit = "steps";
  552. paramInfo.ranges.def = 4.0f;
  553. paramInfo.ranges.min = 0.0f;
  554. paramInfo.ranges.max = 8.0f;
  555. break;
  556. case kParamFeedback:
  557. paramInfo.name = "Feedback";
  558. paramInfo.unit = "%";
  559. paramInfo.ranges.def = 40.0f;
  560. paramInfo.ranges.min = 0.0f;
  561. paramInfo.ranges.max = 100.0f;
  562. break;
  563. }
  564. paramInfo.hints = static_cast<ParameterHints>(hints);
  565. return &paramInfo;
  566. }
  567. float getParameterValue(const uint32_t index) const override
  568. {
  569. switch (index)
  570. {
  571. case kParamTime:
  572. return fParameters[73] * 8.0f;
  573. case kParamFeedback:
  574. return fParameters[74] * 100.0f;
  575. default:
  576. return 0.0f;
  577. }
  578. }
  579. // -------------------------------------------------------------------
  580. // Plugin state calls
  581. void setParameterValue(const uint32_t index, const float value) override
  582. {
  583. switch (index)
  584. {
  585. case kParamTime:
  586. fParameters[73] = value/8.0f;
  587. break;
  588. case kParamFeedback:
  589. fParameters[74] = value/100.0f;
  590. break;
  591. default:
  592. break;
  593. }
  594. }
  595. // -------------------------------------------------------------------
  596. // Plugin process calls
  597. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  598. {
  599. if (inBuffer[0] != outBuffer[0])
  600. FloatVectorOperations::copy(outBuffer[0], inBuffer[0], frames);
  601. if (inBuffer[1] != outBuffer[1])
  602. FloatVectorOperations::copy(outBuffer[1], inBuffer[1], frames);
  603. const TimeInfo* const timeInfo(getTimeInfo());
  604. const double bpm((timeInfo != nullptr && timeInfo->bbt.valid) ? timeInfo->bbt.beatsPerMinute : 120.0);
  605. fDelay.processBlock(outBuffer[0], outBuffer[1], frames, bpm);
  606. }
  607. // -------------------------------------------------------------------
  608. // Plugin dispatcher calls
  609. void sampleRateChanged(const double sampleRate) override
  610. {
  611. fDelay.setSampleRate(sampleRate);
  612. }
  613. private:
  614. VexDelay fDelay;
  615. float fParameters[92];
  616. PluginClassEND(VexDelayPlugin)
  617. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexDelayPlugin)
  618. };
  619. // -----------------------------------------------------------------------
  620. class VexReverbPlugin : public PluginClass
  621. {
  622. public:
  623. enum Params {
  624. kParamSize = 0,
  625. kParamWidth,
  626. kParamDamp,
  627. kParamCount
  628. };
  629. VexReverbPlugin(const HostDescriptor* const host)
  630. : PluginClass(host),
  631. fReverb(fParameters)
  632. {
  633. std::memset(fParameters, 0, sizeof(float)*92);
  634. fParameters[79] = 0.6f;
  635. fParameters[80] = 0.7f;
  636. fParameters[81] = 0.6f;
  637. }
  638. protected:
  639. // -------------------------------------------------------------------
  640. // Plugin parameter calls
  641. uint32_t getParameterCount() const override
  642. {
  643. return kParamCount;
  644. }
  645. const Parameter* getParameterInfo(const uint32_t index) const override
  646. {
  647. static Parameter paramInfo;
  648. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  649. paramInfo.name = nullptr;
  650. paramInfo.unit = nullptr;
  651. paramInfo.ranges.def = 0.0f;
  652. paramInfo.ranges.min = 0.0f;
  653. paramInfo.ranges.max = 1.0f;
  654. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  655. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  656. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  657. paramInfo.scalePointCount = 0;
  658. paramInfo.scalePoints = nullptr;
  659. switch (index)
  660. {
  661. case kParamSize:
  662. paramInfo.name = "Size";
  663. paramInfo.ranges.def = 0.6f;
  664. break;
  665. case kParamWidth:
  666. paramInfo.name = "Width";
  667. paramInfo.ranges.def = 0.7f;
  668. break;
  669. case kParamDamp:
  670. paramInfo.name = "Damp";
  671. paramInfo.ranges.def = 0.6f;
  672. break;
  673. }
  674. paramInfo.hints = static_cast<ParameterHints>(hints);
  675. return &paramInfo;
  676. }
  677. float getParameterValue(const uint32_t index) const override
  678. {
  679. switch (index)
  680. {
  681. case kParamSize:
  682. return fParameters[79];
  683. case kParamWidth:
  684. return fParameters[80];
  685. case kParamDamp:
  686. return fParameters[81];
  687. default:
  688. return 0.0f;
  689. }
  690. }
  691. // -------------------------------------------------------------------
  692. // Plugin state calls
  693. void setParameterValue(const uint32_t index, const float value) override
  694. {
  695. switch (index)
  696. {
  697. case kParamSize:
  698. fParameters[79] = value;
  699. break;
  700. case kParamWidth:
  701. fParameters[80] = value;
  702. break;
  703. case kParamDamp:
  704. fParameters[81] = value;
  705. break;
  706. default:
  707. break;
  708. }
  709. }
  710. // -------------------------------------------------------------------
  711. // Plugin process calls
  712. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  713. {
  714. for (uint32_t i=0; i< frames; ++i)
  715. FloatVectorOperations::copyWithMultiply(outBuffer[0], inBuffer[0], 0.5f, frames);
  716. for (uint32_t i=0; i< frames; ++i)
  717. FloatVectorOperations::copyWithMultiply(outBuffer[1], inBuffer[1], 0.5f, frames);
  718. fReverb.processBlock(outBuffer[0], outBuffer[1], frames);
  719. }
  720. private:
  721. VexReverb fReverb;
  722. float fParameters[92];
  723. PluginClassEND(VexReverbPlugin)
  724. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexReverbPlugin)
  725. };
  726. // -----------------------------------------------------------------------
  727. static const PluginDescriptor vexArpDesc = {
  728. /* category */ PLUGIN_CATEGORY_UTILITY,
  729. /* hints */ static_cast<PluginHints>(PLUGIN_HAS_GUI|PLUGIN_NEEDS_UI_JUCE|PLUGIN_USES_TIME),
  730. /* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_EVERYTHING),
  731. /* audioIns */ 0,
  732. /* audioOuts */ 0,
  733. /* midiIns */ 1,
  734. /* midiOuts */ 1,
  735. /* paramIns */ VexArpPlugin::kParamCount,
  736. /* paramOuts */ 0,
  737. /* name */ "VexArp",
  738. /* label */ "vexArp",
  739. /* maker */ "falkTX",
  740. /* copyright */ "GNU GPL v2+",
  741. PluginDescriptorFILL(VexArpPlugin)
  742. };
  743. static const PluginDescriptor vexChorusDesc = {
  744. /* category */ PLUGIN_CATEGORY_MODULATOR,
  745. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  746. /* supports */ static_cast<PluginSupports>(0x0),
  747. /* audioIns */ 2,
  748. /* audioOuts */ 2,
  749. /* midiIns */ 0,
  750. /* midiOuts */ 0,
  751. /* paramIns */ VexChorusPlugin::kParamCount,
  752. /* paramOuts */ 0,
  753. /* name */ "VexChorus",
  754. /* label */ "vexChorus",
  755. /* maker */ "falkTX",
  756. /* copyright */ "GNU GPL v2+",
  757. PluginDescriptorFILL(VexChorusPlugin)
  758. };
  759. static const PluginDescriptor vexDelayDesc = {
  760. /* category */ PLUGIN_CATEGORY_DELAY,
  761. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_TIME),
  762. /* supports */ static_cast<PluginSupports>(0x0),
  763. /* audioIns */ 2,
  764. /* audioOuts */ 2,
  765. /* midiIns */ 0,
  766. /* midiOuts */ 0,
  767. /* paramIns */ VexDelayPlugin::kParamCount,
  768. /* paramOuts */ 0,
  769. /* name */ "VexDelay",
  770. /* label */ "vexDelay",
  771. /* maker */ "falkTX",
  772. /* copyright */ "GNU GPL v2+",
  773. PluginDescriptorFILL(VexDelayPlugin)
  774. };
  775. static const PluginDescriptor vexReverbDesc = {
  776. /* category */ PLUGIN_CATEGORY_DELAY,
  777. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  778. /* supports */ static_cast<PluginSupports>(0x0),
  779. /* audioIns */ 2,
  780. /* audioOuts */ 2,
  781. /* midiIns */ 0,
  782. /* midiOuts */ 0,
  783. /* paramIns */ VexReverbPlugin::kParamCount,
  784. /* paramOuts */ 0,
  785. /* name */ "VexReverb",
  786. /* label */ "vexReverb",
  787. /* maker */ "falkTX",
  788. /* copyright */ "GNU GPL v2+",
  789. PluginDescriptorFILL(VexReverbPlugin)
  790. };
  791. // -----------------------------------------------------------------------
  792. CARLA_EXPORT
  793. void carla_register_native_plugin_vex_fx()
  794. {
  795. carla_register_native_plugin(&vexArpDesc);
  796. carla_register_native_plugin(&vexChorusDesc);
  797. carla_register_native_plugin(&vexDelayDesc);
  798. carla_register_native_plugin(&vexReverbDesc);
  799. }
  800. // -----------------------------------------------------------------------