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.

904 lines
27KB

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