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.

1322 lines
38KB

  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_core.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/VexSyntModule.h"
  25. #include "vex/PeggyViewComponent.h"
  26. // -----------------------------------------------------------------------
  27. class HelperWindow : public DocumentWindow
  28. {
  29. public:
  30. HelperWindow()
  31. : DocumentWindow("PlugWindow", Colour(0, 0, 0), DocumentWindow::closeButton, false),
  32. fClosed(false)
  33. {
  34. setDropShadowEnabled(false);
  35. setOpaque(true);
  36. setResizable(false, false);
  37. //setUsingNativeTitleBar(true);
  38. setVisible(false);
  39. }
  40. void show(Component* const comp)
  41. {
  42. fClosed = false;
  43. setContentNonOwned(comp, true);
  44. centreWithSize(comp->getWidth(), comp->getHeight());
  45. if (! isOnDesktop())
  46. addToDesktop();
  47. setVisible(true);
  48. }
  49. void hide()
  50. {
  51. setVisible(false);
  52. if (isOnDesktop())
  53. removeFromDesktop();
  54. clearContentComponent();
  55. }
  56. bool wasClosedByUser() const
  57. {
  58. return fClosed;
  59. }
  60. protected:
  61. void closeButtonPressed() override
  62. {
  63. fClosed = true;
  64. }
  65. private:
  66. bool fClosed;
  67. };
  68. // -----------------------------------------------------------------------
  69. class VexArpPlugin : public PluginClass,
  70. public PeggyViewComponent::Callback
  71. {
  72. public:
  73. enum Params {
  74. kParamOnOff = 0,
  75. kParamLength,
  76. kParamTimeMode,
  77. kParamSyncMode,
  78. kParamFailMode,
  79. kParamVelMode,
  80. kParamCount
  81. };
  82. VexArpPlugin(const HostDescriptor* const host)
  83. : PluginClass(host),
  84. fArp(&fSettings)
  85. {
  86. fArp.setSampleRate(getSampleRate());
  87. fMidiInBuffer.ensureSize(512*4);
  88. }
  89. protected:
  90. // -------------------------------------------------------------------
  91. // Plugin parameter calls
  92. uint32_t getParameterCount() const override
  93. {
  94. return kParamCount;
  95. }
  96. const Parameter* getParameterInfo(const uint32_t index) const override
  97. {
  98. static Parameter paramInfo;
  99. static ParameterScalePoint scalePoints[4];
  100. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE|PARAMETER_IS_INTEGER;
  101. paramInfo.name = nullptr;
  102. paramInfo.unit = nullptr;
  103. paramInfo.ranges.def = 0.0f;
  104. paramInfo.ranges.min = 0.0f;
  105. paramInfo.ranges.max = 1.0f;
  106. paramInfo.ranges.step = 1.0f;
  107. paramInfo.ranges.stepSmall = 1.0f;
  108. paramInfo.ranges.stepLarge = 1.0f;
  109. paramInfo.scalePointCount = 0;
  110. paramInfo.scalePoints = nullptr;
  111. switch (index)
  112. {
  113. case kParamOnOff:
  114. hints |= PARAMETER_IS_BOOLEAN;
  115. paramInfo.name = "On/Off";
  116. paramInfo.ranges.def = 0.0f;
  117. paramInfo.ranges.min = 0.0f;
  118. paramInfo.ranges.max = 1.0f;
  119. break;
  120. case kParamLength:
  121. paramInfo.name = "Length";
  122. paramInfo.ranges.def = 8.0f;
  123. paramInfo.ranges.min = 1.0f;
  124. paramInfo.ranges.max = 16.0f;
  125. break;
  126. case kParamTimeMode:
  127. hints |= PARAMETER_USES_SCALEPOINTS;
  128. paramInfo.name = "Time Signature";
  129. paramInfo.ranges.def = 2.0f;
  130. paramInfo.ranges.min = 1.0f;
  131. paramInfo.ranges.max = 3.0f;
  132. paramInfo.scalePointCount = 3;
  133. paramInfo.scalePoints = scalePoints;
  134. scalePoints[0].label = "8";
  135. scalePoints[1].label = "16";
  136. scalePoints[2].label = "32";
  137. scalePoints[0].value = 1.0f;
  138. scalePoints[1].value = 2.0f;
  139. scalePoints[2].value = 3.0f;
  140. break;
  141. case kParamSyncMode:
  142. hints |= PARAMETER_USES_SCALEPOINTS;
  143. paramInfo.name = "Sync Mode";
  144. paramInfo.ranges.def = 1.0f;
  145. paramInfo.ranges.min = 1.0f;
  146. paramInfo.ranges.max = 2.0f;
  147. paramInfo.scalePointCount = 2;
  148. paramInfo.scalePoints = scalePoints;
  149. scalePoints[0].label = "Key Sync";
  150. scalePoints[1].label = "Bar Sync";
  151. scalePoints[0].value = 1.0f;
  152. scalePoints[1].value = 2.0f;
  153. break;
  154. case kParamFailMode:
  155. hints |= PARAMETER_USES_SCALEPOINTS;
  156. paramInfo.name = "Fail Mode";
  157. paramInfo.ranges.def = 1.0f;
  158. paramInfo.ranges.min = 1.0f;
  159. paramInfo.ranges.max = 3.0f;
  160. paramInfo.scalePointCount = 3;
  161. paramInfo.scalePoints = scalePoints;
  162. scalePoints[0].label = "Silent Step";
  163. scalePoints[1].label = "Skip One";
  164. scalePoints[2].label = "Skip Two";
  165. scalePoints[0].value = 1.0f;
  166. scalePoints[1].value = 2.0f;
  167. scalePoints[2].value = 3.0f;
  168. break;
  169. case kParamVelMode:
  170. hints |= PARAMETER_USES_SCALEPOINTS;
  171. paramInfo.name = "Velocity Mode";
  172. paramInfo.ranges.def = 1.0f;
  173. paramInfo.ranges.min = 1.0f;
  174. paramInfo.ranges.max = 3.0f;
  175. paramInfo.scalePointCount = 3;
  176. paramInfo.scalePoints = scalePoints;
  177. scalePoints[0].label = "Pattern Velocity";
  178. scalePoints[1].label = "Input Velocity";
  179. scalePoints[2].label = "Sum Velocities";
  180. scalePoints[0].value = 1.0f;
  181. scalePoints[1].value = 2.0f;
  182. scalePoints[2].value = 3.0f;
  183. break;
  184. }
  185. paramInfo.hints = static_cast<ParameterHints>(hints);
  186. return &paramInfo;
  187. }
  188. float getParameterValue(const uint32_t index) const override
  189. {
  190. switch (index)
  191. {
  192. case kParamOnOff:
  193. return fSettings.on ? 1.0f : 0.0f;
  194. case kParamLength:
  195. return fSettings.length;
  196. case kParamTimeMode:
  197. return fSettings.timeMode;
  198. case kParamSyncMode:
  199. return fSettings.syncMode;
  200. case kParamFailMode:
  201. return fSettings.failMode;
  202. case kParamVelMode:
  203. return fSettings.velMode;
  204. default:
  205. return 0.0f;
  206. }
  207. }
  208. // -------------------------------------------------------------------
  209. // Plugin state calls
  210. void setParameterValue(const uint32_t index, const float value) override
  211. {
  212. switch (index)
  213. {
  214. case kParamOnOff:
  215. fSettings.on = (value >= 0.5f);
  216. break;
  217. case kParamLength:
  218. fSettings.length = value;
  219. break;
  220. case kParamTimeMode:
  221. fSettings.timeMode = value;
  222. break;
  223. case kParamSyncMode:
  224. fSettings.syncMode = value;
  225. break;
  226. case kParamFailMode:
  227. fSettings.failMode = value;
  228. break;
  229. case kParamVelMode:
  230. fSettings.velMode = value;
  231. break;
  232. }
  233. }
  234. // -------------------------------------------------------------------
  235. // Plugin process calls
  236. void process(float**, float**, const uint32_t frames, const MidiEvent* const midiEvents, const uint32_t midiEventCount) override
  237. {
  238. if (! fSettings.on)
  239. {
  240. for (uint32_t i=0; i < midiEventCount; ++i)
  241. writeMidiEvent(&midiEvents[i]);
  242. return;
  243. }
  244. const TimeInfo* const timeInfo(getTimeInfo());
  245. bool timePlaying = false;
  246. double ppqPos = 0.0;
  247. double barStartPos = 0.0;
  248. double bpm = 120.0;
  249. if (timeInfo != nullptr)
  250. {
  251. timePlaying = timeInfo->playing;
  252. if (timeInfo->bbt.valid)
  253. {
  254. double ppqBar = double(timeInfo->bbt.bar - 1) * timeInfo->bbt.beatsPerBar;
  255. double ppqBeat = double(timeInfo->bbt.beat - 1);
  256. double ppqTick = double(timeInfo->bbt.tick) / timeInfo->bbt.ticksPerBeat;
  257. ppqPos = ppqBar + ppqBeat + ppqTick;
  258. barStartPos = ppqBar;
  259. bpm = timeInfo->bbt.beatsPerMinute;
  260. }
  261. }
  262. fMidiInBuffer.clear();
  263. for (uint32_t i=0; i < midiEventCount; ++i)
  264. {
  265. const MidiEvent* const midiEvent(&midiEvents[i]);
  266. fMidiInBuffer.addEvent(MidiMessage(midiEvent->data, midiEvent->size), midiEvent->time);
  267. }
  268. const MidiBuffer& outMidiBuffer(fArp.processMidi(fMidiInBuffer, timePlaying, ppqPos, barStartPos, bpm, frames));
  269. MidiBuffer::Iterator outBufferIterator(outMidiBuffer);
  270. MidiMessage midiMessage(0xf4);
  271. int sampleNumber;
  272. MidiEvent tmpEvent;
  273. tmpEvent.port = 0;
  274. while (outBufferIterator.getNextEvent(midiMessage, sampleNumber))
  275. {
  276. tmpEvent.size = midiMessage.getRawDataSize();
  277. tmpEvent.time = sampleNumber;
  278. if (tmpEvent.size > 4)
  279. continue;
  280. std::memcpy(tmpEvent.data, midiMessage.getRawData(), sizeof(uint8_t)*tmpEvent.size);
  281. writeMidiEvent(&tmpEvent);
  282. }
  283. }
  284. // -------------------------------------------------------------------
  285. // Plugin UI calls
  286. void uiShow(const bool show) override
  287. {
  288. if (show)
  289. {
  290. if (fWindow == nullptr)
  291. {
  292. fWindow = new HelperWindow();
  293. fWindow->setName(getUiName());
  294. }
  295. if (fView == nullptr)
  296. {
  297. fView = new PeggyViewComponent(1, fSettings, this);
  298. fView->setSize(207, 280);
  299. }
  300. fWindow->show(fView);
  301. }
  302. else if (fWindow != nullptr)
  303. {
  304. fWindow->hide();
  305. fView = nullptr;
  306. fWindow = nullptr;
  307. }
  308. }
  309. void uiIdle() override
  310. {
  311. if (fWindow == nullptr)
  312. return;
  313. if (fWindow->wasClosedByUser())
  314. {
  315. uiShow(false);
  316. uiClosed();
  317. }
  318. }
  319. void uiSetParameterValue(const uint32_t, const float) override
  320. {
  321. if (fView == nullptr)
  322. return;
  323. fView->update();
  324. }
  325. // -------------------------------------------------------------------
  326. // Plugin dispatcher calls
  327. void sampleRateChanged(const double sampleRate) override
  328. {
  329. fArp.setSampleRate(sampleRate);
  330. }
  331. void uiNameChanged(const char* const uiName) override
  332. {
  333. if (fWindow == nullptr)
  334. return;
  335. fWindow->setName(uiName);
  336. }
  337. // -------------------------------------------------------------------
  338. // Peggy callback
  339. void somethingChanged(const uint32_t id) override
  340. {
  341. uiParameterChanged(id, getParameterValue(id));
  342. }
  343. private:
  344. VexArpSettings fSettings;
  345. VexArp fArp;
  346. MidiBuffer fMidiInBuffer;
  347. ScopedPointer<PeggyViewComponent> fView;
  348. ScopedPointer<HelperWindow> fWindow;
  349. PluginClassEND(VexArpPlugin)
  350. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexArpPlugin)
  351. };
  352. // -----------------------------------------------------------------------
  353. class VexChorusPlugin : public PluginClass
  354. {
  355. public:
  356. enum Params {
  357. kParamRate = 0,
  358. kParamDepth,
  359. kParamCount
  360. };
  361. VexChorusPlugin(const HostDescriptor* const host)
  362. : PluginClass(host),
  363. fChorus(fParameters)
  364. {
  365. std::memset(fParameters, 0, sizeof(float)*92);
  366. fParameters[76] = 0.3f;
  367. fParameters[77] = 0.6f;
  368. fChorus.setSampleRate(getSampleRate());
  369. }
  370. protected:
  371. // -------------------------------------------------------------------
  372. // Plugin parameter calls
  373. uint32_t getParameterCount() const override
  374. {
  375. return kParamCount;
  376. }
  377. const Parameter* getParameterInfo(const uint32_t index) const override
  378. {
  379. static Parameter paramInfo;
  380. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  381. paramInfo.name = nullptr;
  382. paramInfo.unit = nullptr;
  383. paramInfo.ranges.def = 0.0f;
  384. paramInfo.ranges.min = 0.0f;
  385. paramInfo.ranges.max = 1.0f;
  386. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  387. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  388. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  389. paramInfo.scalePointCount = 0;
  390. paramInfo.scalePoints = nullptr;
  391. switch (index)
  392. {
  393. case kParamRate:
  394. paramInfo.name = "Rate";
  395. paramInfo.ranges.def = 0.3f;
  396. paramInfo.ranges.min = 0.0f;
  397. paramInfo.ranges.max = 1.0f;
  398. break;
  399. case kParamDepth:
  400. paramInfo.name = "Depth";
  401. paramInfo.ranges.def = 0.6f;
  402. paramInfo.ranges.min = 0.0f;
  403. paramInfo.ranges.max = 1.0f;
  404. break;
  405. }
  406. paramInfo.hints = static_cast<ParameterHints>(hints);
  407. return &paramInfo;
  408. }
  409. float getParameterValue(const uint32_t index) const override
  410. {
  411. switch (index)
  412. {
  413. case kParamRate:
  414. return fParameters[76];
  415. case kParamDepth:
  416. return fParameters[77];
  417. default:
  418. return 0.0f;
  419. }
  420. }
  421. // -------------------------------------------------------------------
  422. // Plugin state calls
  423. void setParameterValue(const uint32_t index, const float value) override
  424. {
  425. switch (index)
  426. {
  427. case kParamRate:
  428. fParameters[76] = value;
  429. break;
  430. case kParamDepth:
  431. fParameters[77] = value;
  432. break;
  433. default:
  434. break;
  435. }
  436. }
  437. // -------------------------------------------------------------------
  438. // Plugin process calls
  439. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  440. {
  441. if (inBuffer[0] != outBuffer[0])
  442. carla_copyFloat(outBuffer[0], inBuffer[0], frames);
  443. if (inBuffer[1] != outBuffer[1])
  444. carla_copyFloat(outBuffer[1], inBuffer[1], frames);
  445. fChorus.processBlock(outBuffer[0], outBuffer[1], frames);
  446. }
  447. // -------------------------------------------------------------------
  448. // Plugin dispatcher calls
  449. void sampleRateChanged(const double sampleRate) override
  450. {
  451. fChorus.setSampleRate(sampleRate);
  452. }
  453. private:
  454. VexChorus fChorus;
  455. float fParameters[92];
  456. PluginClassEND(VexChorusPlugin)
  457. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexChorusPlugin)
  458. };
  459. // -----------------------------------------------------------------------
  460. class VexDelayPlugin : public PluginClass
  461. {
  462. public:
  463. enum Params {
  464. kParamTime = 0,
  465. kParamFeedback,
  466. kParamCount
  467. };
  468. VexDelayPlugin(const HostDescriptor* const host)
  469. : PluginClass(host),
  470. fDelay(fParameters)
  471. {
  472. std::memset(fParameters, 0, sizeof(float)*92);
  473. fParameters[73] = 0.5f * 8.0f;
  474. fParameters[74] = 0.4f * 100.0f;
  475. fDelay.setSampleRate(getSampleRate());
  476. }
  477. protected:
  478. // -------------------------------------------------------------------
  479. // Plugin parameter calls
  480. uint32_t getParameterCount() const override
  481. {
  482. return kParamCount;
  483. }
  484. const Parameter* getParameterInfo(const uint32_t index) const override
  485. {
  486. static Parameter paramInfo;
  487. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  488. paramInfo.name = nullptr;
  489. paramInfo.unit = nullptr;
  490. paramInfo.ranges.def = 0.0f;
  491. paramInfo.ranges.min = 0.0f;
  492. paramInfo.ranges.max = 1.0f;
  493. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  494. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  495. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  496. paramInfo.scalePointCount = 0;
  497. paramInfo.scalePoints = nullptr;
  498. switch (index)
  499. {
  500. case kParamTime:
  501. hints |= PARAMETER_IS_INTEGER;
  502. paramInfo.name = "Time";
  503. paramInfo.ranges.def = 4.0f;
  504. paramInfo.ranges.min = 0.0f;
  505. paramInfo.ranges.max = 8.0f;
  506. break;
  507. case kParamFeedback:
  508. paramInfo.name = "Feedback";
  509. paramInfo.unit = "%";
  510. paramInfo.ranges.def = 40.0f;
  511. paramInfo.ranges.min = 0.0f;
  512. paramInfo.ranges.max = 100.0f;
  513. break;
  514. }
  515. paramInfo.hints = static_cast<ParameterHints>(hints);
  516. return &paramInfo;
  517. }
  518. float getParameterValue(const uint32_t index) const override
  519. {
  520. switch (index)
  521. {
  522. case kParamTime:
  523. return fParameters[73] * 8.0f;
  524. case kParamFeedback:
  525. return fParameters[74] * 100.0f;
  526. default:
  527. return 0.0f;
  528. }
  529. }
  530. // -------------------------------------------------------------------
  531. // Plugin state calls
  532. void setParameterValue(const uint32_t index, const float value) override
  533. {
  534. switch (index)
  535. {
  536. case kParamTime:
  537. fParameters[73] = value/8.0f;
  538. break;
  539. case kParamFeedback:
  540. fParameters[74] = value/100.0f;
  541. break;
  542. default:
  543. break;
  544. }
  545. }
  546. // -------------------------------------------------------------------
  547. // Plugin process calls
  548. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  549. {
  550. if (inBuffer[0] != outBuffer[0])
  551. carla_copyFloat(outBuffer[0], inBuffer[0], frames);
  552. if (inBuffer[1] != outBuffer[1])
  553. carla_copyFloat(outBuffer[1], inBuffer[1], frames);
  554. const TimeInfo* const timeInfo(getTimeInfo());
  555. const double bpm((timeInfo != nullptr && timeInfo->bbt.valid) ? timeInfo->bbt.beatsPerMinute : 120.0);
  556. fDelay.processBlock(outBuffer[0], outBuffer[1], frames, bpm);
  557. }
  558. // -------------------------------------------------------------------
  559. // Plugin dispatcher calls
  560. void sampleRateChanged(const double sampleRate) override
  561. {
  562. fDelay.setSampleRate(sampleRate);
  563. }
  564. private:
  565. VexDelay fDelay;
  566. float fParameters[92];
  567. PluginClassEND(VexDelayPlugin)
  568. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexDelayPlugin)
  569. };
  570. // -----------------------------------------------------------------------
  571. class VexReverbPlugin : public PluginClass
  572. {
  573. public:
  574. enum Params {
  575. kParamSize = 0,
  576. kParamWidth,
  577. kParamDamp,
  578. kParamCount
  579. };
  580. VexReverbPlugin(const HostDescriptor* const host)
  581. : PluginClass(host),
  582. fReverb(fParameters)
  583. {
  584. std::memset(fParameters, 0, sizeof(float)*92);
  585. // FIXME?
  586. fParameters[79] = 0.6f;
  587. fParameters[80] = 0.6f;
  588. fParameters[81] = 0.7f;
  589. }
  590. protected:
  591. // -------------------------------------------------------------------
  592. // Plugin parameter calls
  593. uint32_t getParameterCount() const override
  594. {
  595. return kParamCount;
  596. }
  597. const Parameter* getParameterInfo(const uint32_t index) const override
  598. {
  599. static Parameter paramInfo;
  600. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  601. paramInfo.name = nullptr;
  602. paramInfo.unit = nullptr;
  603. paramInfo.ranges.def = 0.0f;
  604. paramInfo.ranges.min = 0.0f;
  605. paramInfo.ranges.max = 1.0f;
  606. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  607. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  608. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  609. paramInfo.scalePointCount = 0;
  610. paramInfo.scalePoints = nullptr;
  611. switch (index)
  612. {
  613. case kParamSize:
  614. paramInfo.name = "Size";
  615. paramInfo.ranges.def = 0.6f;
  616. paramInfo.ranges.min = 0.0f;
  617. paramInfo.ranges.max = 1.0f;
  618. break;
  619. case kParamWidth:
  620. paramInfo.name = "Width";
  621. paramInfo.ranges.def = 0.7f;
  622. paramInfo.ranges.min = 0.0f;
  623. paramInfo.ranges.max = 1.0f;
  624. break;
  625. case kParamDamp:
  626. paramInfo.name = "Damp";
  627. paramInfo.ranges.def = 0.6f;
  628. paramInfo.ranges.min = 0.0f;
  629. paramInfo.ranges.max = 1.0f;
  630. break;
  631. }
  632. paramInfo.hints = static_cast<ParameterHints>(hints);
  633. return &paramInfo;
  634. }
  635. float getParameterValue(const uint32_t index) const override
  636. {
  637. switch (index)
  638. {
  639. case kParamSize:
  640. return fParameters[79];
  641. case kParamWidth:
  642. return fParameters[80];
  643. case kParamDamp:
  644. return fParameters[81];
  645. default:
  646. return 0.0f;
  647. }
  648. }
  649. // -------------------------------------------------------------------
  650. // Plugin state calls
  651. void setParameterValue(const uint32_t index, const float value) override
  652. {
  653. switch (index)
  654. {
  655. case kParamSize:
  656. fParameters[79] = value;
  657. break;
  658. case kParamWidth:
  659. fParameters[80] = value;
  660. break;
  661. case kParamDamp:
  662. fParameters[81] = value;
  663. break;
  664. default:
  665. break;
  666. }
  667. }
  668. // -------------------------------------------------------------------
  669. // Plugin process calls
  670. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  671. {
  672. for (uint32_t i=0; i< frames; ++i)
  673. outBuffer[0][i] = inBuffer[0][i]/2.0f;
  674. for (uint32_t i=0; i< frames; ++i)
  675. outBuffer[1][i] = inBuffer[1][i]/2.0f;
  676. fReverb.processBlock(outBuffer[0], outBuffer[1], frames);
  677. }
  678. private:
  679. VexReverb fReverb;
  680. float fParameters[92];
  681. PluginClassEND(VexReverbPlugin)
  682. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexReverbPlugin)
  683. };
  684. // -----------------------------------------------------------------------
  685. class VexSynthPlugin : public PluginClass
  686. {
  687. public:
  688. static const unsigned int kParamCount = 92;
  689. VexSynthPlugin(const HostDescriptor* const host)
  690. : PluginClass(host),
  691. obf(nullptr),
  692. abf(nullptr),
  693. dbf1(nullptr),
  694. dbf2(nullptr),
  695. dbf3(nullptr),
  696. fChorus(fParameters),
  697. fDelay(fParameters),
  698. fReverb(fParameters),
  699. fSynth(fParameters)
  700. {
  701. std::memset(fParameters, 0, sizeof(float)*92);
  702. fParameters[0] = 1.0f; // main volume
  703. for (int i = 0; i < 3; ++i)
  704. {
  705. const int offset = i * 24;
  706. fParameters[offset + 1] = 0.5f;
  707. fParameters[offset + 2] = 0.5f;
  708. fParameters[offset + 3] = 0.5f;
  709. fParameters[offset + 4] = 0.5f;
  710. fParameters[offset + 5] = 0.9f;
  711. fParameters[offset + 6] = 0.0f;
  712. fParameters[offset + 7] = 1.0f;
  713. fParameters[offset + 8] = 0.5f;
  714. fParameters[offset + 9] = 0.0f;
  715. fParameters[offset + 10] = 0.2f;
  716. fParameters[offset + 11] = 0.0f;
  717. fParameters[offset + 12] = 0.5f;
  718. fParameters[offset + 13] = 0.5f;
  719. fParameters[offset + 14] = 0.0f;
  720. fParameters[offset + 15] = 0.3f;
  721. fParameters[offset + 16] = 0.7f;
  722. fParameters[offset + 17] = 0.1f;
  723. fParameters[offset + 18] = 0.5f;
  724. fParameters[offset + 19] = 0.5f;
  725. fParameters[offset + 20] = 0.0f;
  726. fParameters[offset + 21] = 0.0f;
  727. fParameters[offset + 22] = 0.5f;
  728. fParameters[offset + 23] = 0.5f;
  729. fParameters[offset + 24] = 0.5f;
  730. }
  731. // ^1 - 72
  732. fParameters[73] = 0.5f; // Delay Time
  733. fParameters[74] = 0.4f; // Delay Feedback
  734. fParameters[75] = 0.0f; // Delay Volume
  735. fParameters[76] = 0.3f; // Chorus Rate
  736. fParameters[77] = 0.6f; // Chorus Depth
  737. fParameters[78] = 0.5f; // Chorus Volume
  738. fParameters[79] = 0.6f; // Reverb Size
  739. fParameters[80] = 0.7f; // Reverb Width
  740. fParameters[81] = 0.6f; // Reverb Damp
  741. fParameters[82] = 0.0f; // Reverb Volume
  742. fParameters[83] = 0.5f; // wave1 panning
  743. fParameters[84] = 0.5f; // wave2 panning
  744. fParameters[85] = 0.5f; // wave3 panning
  745. fParameters[86] = 0.5f; // wave1 volume
  746. fParameters[87] = 0.5f; // wave2 volume
  747. fParameters[88] = 0.5f; // wave3 volume
  748. fParameters[89] = 1.0f; // wave1 on/off
  749. fParameters[90] = 1.0f; // wave2 on/off
  750. fParameters[91] = 1.0f; // wave3 on/off
  751. bufferSizeChanged(getBufferSize());
  752. sampleRateChanged(getSampleRate());
  753. }
  754. ~VexSynthPlugin()
  755. {
  756. delete obf;
  757. delete abf;
  758. delete dbf1;
  759. delete dbf2;
  760. delete dbf3;
  761. }
  762. protected:
  763. // -------------------------------------------------------------------
  764. // Plugin parameter calls
  765. uint32_t getParameterCount() const override
  766. {
  767. return kParamCount;
  768. }
  769. const Parameter* getParameterInfo(const uint32_t index) const override
  770. {
  771. static Parameter paramInfo;
  772. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  773. paramInfo.name = nullptr;
  774. paramInfo.unit = nullptr;
  775. paramInfo.ranges.def = 0.0f;
  776. paramInfo.ranges.min = 0.0f;
  777. paramInfo.ranges.max = 1.0f;
  778. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  779. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  780. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  781. paramInfo.scalePointCount = 0;
  782. paramInfo.scalePoints = nullptr;
  783. if (index >= 1 && index <= 72)
  784. {
  785. uint32_t ri = index % 24;
  786. switch (ri)
  787. {
  788. case 1:
  789. paramInfo.name = "oct";
  790. break;
  791. case 2:
  792. paramInfo.name = "cent";
  793. break;
  794. case 3:
  795. paramInfo.name = "phaseOffset";
  796. break;
  797. case 4:
  798. paramInfo.name = "phaseIncOffset";
  799. break;
  800. case 5:
  801. paramInfo.name = "filter";
  802. break;
  803. case 6:
  804. paramInfo.name = "filter";
  805. break;
  806. case 7:
  807. paramInfo.name = "filter";
  808. break;
  809. case 8:
  810. paramInfo.name = "filter";
  811. break;
  812. case 9:
  813. paramInfo.name = "F ADSR";
  814. break;
  815. case 10:
  816. paramInfo.name = "F ADSR";
  817. break;
  818. case 11:
  819. paramInfo.name = "F ADSR";
  820. break;
  821. case 12:
  822. paramInfo.name = "F ADSR";
  823. break;
  824. case 13:
  825. paramInfo.name = "F velocity";
  826. break;
  827. case 14:
  828. paramInfo.name = "A ADSR";
  829. break;
  830. case 15:
  831. paramInfo.name = "A ADSR";
  832. break;
  833. case 16:
  834. paramInfo.name = "A ADSR";
  835. break;
  836. case 17:
  837. paramInfo.name = "A ADSR";
  838. break;
  839. case 18:
  840. paramInfo.name = "A velocity";
  841. break;
  842. case 19:
  843. paramInfo.name = "lfoC";
  844. break;
  845. case 20:
  846. paramInfo.name = "lfoA";
  847. break;
  848. case 21:
  849. paramInfo.name = "lfoF";
  850. break;
  851. case 22:
  852. paramInfo.name = "fx vol D";
  853. break;
  854. case 23:
  855. paramInfo.name = "fx vol C";
  856. break;
  857. case 24:
  858. case 0:
  859. paramInfo.name = "fx vol R";
  860. break;
  861. default:
  862. paramInfo.name = "unknown2";
  863. break;
  864. }
  865. paramInfo.hints = static_cast<ParameterHints>(hints);
  866. return &paramInfo;
  867. }
  868. switch (index)
  869. {
  870. case 0:
  871. paramInfo.name = "Main volume";
  872. break;
  873. case 73:
  874. paramInfo.name = "Delay Time";
  875. break;
  876. case 74:
  877. paramInfo.name = "Delay Feedback";
  878. break;
  879. case 75:
  880. paramInfo.name = "Delay Volume";
  881. break;
  882. case 76:
  883. paramInfo.name = "Chorus Rate";
  884. break;
  885. case 77:
  886. paramInfo.name = "Chorus Depth";
  887. break;
  888. case 78:
  889. paramInfo.name = "Chorus Volume";
  890. break;
  891. case 79:
  892. paramInfo.name = "Reverb Size";
  893. break;
  894. case 80:
  895. paramInfo.name = "Reverb Width";
  896. break;
  897. case 81:
  898. paramInfo.name = "Reverb Damp";
  899. break;
  900. case 82:
  901. paramInfo.name = "Reverb Volume";
  902. break;
  903. case 83:
  904. paramInfo.name = "Wave1 Panning";
  905. break;
  906. case 84:
  907. paramInfo.name = "Wave2 Panning";
  908. break;
  909. case 85:
  910. paramInfo.name = "Wave3 Panning";
  911. break;
  912. case 86:
  913. paramInfo.name = "Wave1 Volume";
  914. break;
  915. case 87:
  916. paramInfo.name = "Wave2 Volume";
  917. break;
  918. case 88:
  919. paramInfo.name = "Wave3 Volume";
  920. break;
  921. case 89:
  922. paramInfo.name = "Wave1 on/off";
  923. break;
  924. case 90:
  925. paramInfo.name = "Wave2 on/off";
  926. break;
  927. case 91:
  928. paramInfo.name = "Wave3 on/off";
  929. break;
  930. default:
  931. paramInfo.name = "unknown";
  932. break;
  933. }
  934. paramInfo.hints = static_cast<ParameterHints>(hints);
  935. return &paramInfo;
  936. }
  937. float getParameterValue(const uint32_t index) const override
  938. {
  939. return (index < kParamCount) ? fParameters[index] : 0.0f;
  940. }
  941. // -------------------------------------------------------------------
  942. // Plugin state calls
  943. void setParameterValue(const uint32_t index, const float value) override
  944. {
  945. if (index < kParamCount)
  946. {
  947. fParameters[index] = value;
  948. fSynth.update(index);
  949. }
  950. }
  951. // -------------------------------------------------------------------
  952. // Plugin process calls
  953. void process(float**, float** outBuffer, const uint32_t frames, const MidiEvent* const midiEvents, const uint32_t midiEventCount) override
  954. {
  955. const TimeInfo* const timeInfo(getTimeInfo());
  956. const double bpm((timeInfo != nullptr && timeInfo->bbt.valid) ? timeInfo->bbt.beatsPerMinute : 120.0);
  957. for (uint32_t i=0; i < midiEventCount; ++i)
  958. {
  959. const MidiEvent* const midiEvent(&midiEvents[i]);
  960. const uint8_t status(MIDI_GET_STATUS_FROM_DATA(midiEvent->data));
  961. if (status == MIDI_STATUS_NOTE_ON)
  962. {
  963. fSynth.playNote(midiEvent->data[1], midiEvent->data[2], 0, 1);
  964. }
  965. else if (status == MIDI_STATUS_NOTE_OFF)
  966. {
  967. fSynth.releaseNote(midiEvent->data[1], 0, 1);
  968. }
  969. else if (status == MIDI_STATUS_CONTROL_CHANGE)
  970. {
  971. const uint8_t control(midiEvent->data[1]);
  972. if (control == MIDI_CONTROL_ALL_SOUND_OFF)
  973. fSynth.kill();
  974. else if (control == MIDI_CONTROL_ALL_NOTES_OFF)
  975. fSynth.releaseAll(1);
  976. }
  977. }
  978. if (obf->getNumSamples() != (int)frames)
  979. {
  980. obf->setSize(2, frames, 0, 0, 1);
  981. abf->setSize(2, frames, 0, 0, 1);
  982. dbf1->setSize(2, frames, 0, 0, 1);
  983. dbf2->setSize(2, frames, 0, 0, 1);
  984. dbf3->setSize(2, frames, 0, 0, 1);
  985. }
  986. obf ->clear();
  987. dbf1->clear();
  988. dbf2->clear();
  989. dbf3->clear();
  990. fSynth.doProcess(*obf, *abf, *dbf1, *dbf2, *dbf3);
  991. if (fParameters[75] > 0.001f) fDelay.processBlock(dbf1, bpm);
  992. if (fParameters[78] > 0.001f) fChorus.processBlock(dbf2);
  993. if (fParameters[82] > 0.001f) fReverb.processBlock(dbf3);
  994. AudioSampleBuffer output(outBuffer, 2, 0, frames);
  995. output.clear();
  996. obf->addFrom(0, 0, *dbf1, 0, 0, frames, fParameters[75]);
  997. obf->addFrom(1, 0, *dbf1, 1, 0, frames, fParameters[75]);
  998. obf->addFrom(0, 0, *dbf2, 0, 0, frames, fParameters[78]);
  999. obf->addFrom(1, 0, *dbf2, 1, 0, frames, fParameters[78]);
  1000. obf->addFrom(0, 0, *dbf3, 0, 0, frames, fParameters[82]);
  1001. obf->addFrom(1, 0, *dbf3, 1, 0, frames, fParameters[82]);
  1002. output.addFrom(0, 0, *obf, 0, 0, frames, fParameters[0]);
  1003. output.addFrom(1, 0, *obf, 1, 0, frames, fParameters[0]);
  1004. }
  1005. // -------------------------------------------------------------------
  1006. // Plugin dispatcher calls
  1007. void bufferSizeChanged(const uint32_t bufferSize) override
  1008. {
  1009. delete obf;
  1010. delete abf;
  1011. delete dbf1;
  1012. delete dbf2;
  1013. delete dbf3;
  1014. obf = new AudioSampleBuffer(2, bufferSize);
  1015. abf = new AudioSampleBuffer(2, bufferSize);
  1016. dbf1 = new AudioSampleBuffer(2, bufferSize);
  1017. dbf2 = new AudioSampleBuffer(2, bufferSize);
  1018. dbf3 = new AudioSampleBuffer(2, bufferSize);
  1019. }
  1020. void sampleRateChanged(const double sampleRate) override
  1021. {
  1022. fChorus.setSampleRate(sampleRate);
  1023. fDelay.setSampleRate(sampleRate);
  1024. fSynth.setSampleRate(sampleRate);
  1025. }
  1026. private:
  1027. float fParameters[92];
  1028. AudioSampleBuffer* obf;
  1029. AudioSampleBuffer* abf;
  1030. AudioSampleBuffer* dbf1; // delay
  1031. AudioSampleBuffer* dbf2; // chorus
  1032. AudioSampleBuffer* dbf3; // reverb
  1033. VexChorus fChorus;
  1034. VexDelay fDelay;
  1035. VexReverb fReverb;
  1036. VexSyntModule fSynth;
  1037. PluginClassEND(VexSynthPlugin)
  1038. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexSynthPlugin)
  1039. };
  1040. // -----------------------------------------------------------------------
  1041. static const PluginDescriptor vexArpDesc = {
  1042. /* category */ PLUGIN_CATEGORY_UTILITY,
  1043. /* hints */ static_cast<PluginHints>(PLUGIN_HAS_GUI|PLUGIN_NEEDS_SINGLE_THREAD|PLUGIN_USES_TIME),
  1044. /* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_EVERYTHING),
  1045. /* audioIns */ 0,
  1046. /* audioOuts */ 0,
  1047. /* midiIns */ 1,
  1048. /* midiOuts */ 1,
  1049. /* paramIns */ VexArpPlugin::kParamCount,
  1050. /* paramOuts */ 0,
  1051. /* name */ "VexArp",
  1052. /* label */ "vexArp",
  1053. /* maker */ "falkTX",
  1054. /* copyright */ "GNU GPL v2+",
  1055. PluginDescriptorFILL(VexArpPlugin)
  1056. };
  1057. static const PluginDescriptor vexChorusDesc = {
  1058. /* category */ PLUGIN_CATEGORY_MODULATOR,
  1059. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  1060. /* supports */ static_cast<PluginSupports>(0x0),
  1061. /* audioIns */ 2,
  1062. /* audioOuts */ 2,
  1063. /* midiIns */ 0,
  1064. /* midiOuts */ 0,
  1065. /* paramIns */ VexChorusPlugin::kParamCount,
  1066. /* paramOuts */ 0,
  1067. /* name */ "VexChorus",
  1068. /* label */ "vexChorus",
  1069. /* maker */ "falkTX",
  1070. /* copyright */ "GNU GPL v2+",
  1071. PluginDescriptorFILL(VexChorusPlugin)
  1072. };
  1073. static const PluginDescriptor vexDelayDesc = {
  1074. /* category */ PLUGIN_CATEGORY_DELAY,
  1075. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_TIME),
  1076. /* supports */ static_cast<PluginSupports>(0x0),
  1077. /* audioIns */ 2,
  1078. /* audioOuts */ 2,
  1079. /* midiIns */ 0,
  1080. /* midiOuts */ 0,
  1081. /* paramIns */ VexDelayPlugin::kParamCount,
  1082. /* paramOuts */ 0,
  1083. /* name */ "VexDelay",
  1084. /* label */ "vexDelay",
  1085. /* maker */ "falkTX",
  1086. /* copyright */ "GNU GPL v2+",
  1087. PluginDescriptorFILL(VexDelayPlugin)
  1088. };
  1089. static const PluginDescriptor vexReverbDesc = {
  1090. /* category */ PLUGIN_CATEGORY_DELAY,
  1091. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  1092. /* supports */ static_cast<PluginSupports>(0x0),
  1093. /* audioIns */ 2,
  1094. /* audioOuts */ 2,
  1095. /* midiIns */ 0,
  1096. /* midiOuts */ 0,
  1097. /* paramIns */ VexReverbPlugin::kParamCount,
  1098. /* paramOuts */ 0,
  1099. /* name */ "VexReverb",
  1100. /* label */ "vexReverb",
  1101. /* maker */ "falkTX",
  1102. /* copyright */ "GNU GPL v2+",
  1103. PluginDescriptorFILL(VexReverbPlugin)
  1104. };
  1105. static const PluginDescriptor vexSynthDesc = {
  1106. /* category */ PLUGIN_CATEGORY_SYNTH,
  1107. /* hints */ static_cast<PluginHints>(0x0),
  1108. /* supports */ static_cast<PluginSupports>(0x0),
  1109. /* audioIns */ 0,
  1110. /* audioOuts */ 2,
  1111. /* midiIns */ 1,
  1112. /* midiOuts */ 0,
  1113. /* paramIns */ VexSynthPlugin::kParamCount,
  1114. /* paramOuts */ 0,
  1115. /* name */ "VexSynth",
  1116. /* label */ "vexSynth",
  1117. /* maker */ "falkTX",
  1118. /* copyright */ "GNU GPL v2+",
  1119. PluginDescriptorFILL(VexSynthPlugin)
  1120. };
  1121. // -----------------------------------------------------------------------
  1122. CARLA_EXPORT
  1123. void carla_register_native_plugin_vex()
  1124. {
  1125. carla_register_native_plugin(&vexArpDesc);
  1126. carla_register_native_plugin(&vexChorusDesc);
  1127. carla_register_native_plugin(&vexDelayDesc);
  1128. carla_register_native_plugin(&vexReverbDesc);
  1129. carla_register_native_plugin(&vexSynthDesc);
  1130. }
  1131. // -----------------------------------------------------------------------