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.

vex-fx.cpp 26KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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 "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 PluginClass,
  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 HostDescriptor* const host)
  41. : PluginClass(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 Parameter* getParameterInfo(const uint32_t index) const override
  56. {
  57. static Parameter paramInfo;
  58. static ParameterScalePoint 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<ParameterHints>(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 MidiEvent* 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 TimeInfo* 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 MidiEvent* 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. MidiEvent tmpEvent;
  280. tmpEvent.port = 0;
  281. while (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. 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. }
  310. else if (fWindow != nullptr)
  311. {
  312. fWindow->hide();
  313. fView = nullptr;
  314. fWindow = nullptr;
  315. }
  316. }
  317. void uiIdle() override
  318. {
  319. if (fWindow == nullptr)
  320. return;
  321. if (fNeedsUpdate)
  322. {
  323. if (fView != nullptr)
  324. {
  325. MessageManagerLock mmLock;
  326. fView->update();
  327. }
  328. fNeedsUpdate = false;
  329. }
  330. if (fWindow->wasClosedByUser())
  331. {
  332. uiShow(false);
  333. uiClosed();
  334. }
  335. }
  336. void uiSetParameterValue(const uint32_t, const float) override
  337. {
  338. if (fView == nullptr)
  339. return;
  340. fNeedsUpdate = true;
  341. }
  342. // -------------------------------------------------------------------
  343. // Plugin dispatcher calls
  344. void sampleRateChanged(const double sampleRate) override
  345. {
  346. fArp.setSampleRate(sampleRate);
  347. }
  348. void uiNameChanged(const char* const uiName) override
  349. {
  350. if (fWindow == nullptr)
  351. return;
  352. MessageManagerLock mmLock;
  353. fWindow->setName(uiName);
  354. }
  355. // -------------------------------------------------------------------
  356. // Peggy callback
  357. void arpParameterChanged(const uint32_t id) override
  358. {
  359. uiParameterChanged(id, getParameterValue(id));
  360. }
  361. private:
  362. VexArpSettings fSettings;
  363. VexArp fArp;
  364. MidiBuffer fMidiInBuffer;
  365. volatile bool fNeedsUpdate;
  366. ScopedPointer<PeggyViewComponent> fView;
  367. ScopedPointer<JucePluginWindow> fWindow;
  368. PluginClassEND(VexArpPlugin)
  369. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexArpPlugin)
  370. };
  371. // -----------------------------------------------------------------------
  372. class VexChorusPlugin : public PluginClass
  373. {
  374. public:
  375. enum Params {
  376. kParamRate = 0,
  377. kParamDepth,
  378. kParamCount
  379. };
  380. VexChorusPlugin(const HostDescriptor* const host)
  381. : PluginClass(host),
  382. fChorus(fParameters)
  383. {
  384. std::memset(fParameters, 0, sizeof(float)*92);
  385. fParameters[76] = 0.3f;
  386. fParameters[77] = 0.6f;
  387. fChorus.setSampleRate(getSampleRate());
  388. }
  389. protected:
  390. // -------------------------------------------------------------------
  391. // Plugin parameter calls
  392. uint32_t getParameterCount() const override
  393. {
  394. return kParamCount;
  395. }
  396. const Parameter* getParameterInfo(const uint32_t index) const override
  397. {
  398. static Parameter paramInfo;
  399. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  400. paramInfo.name = nullptr;
  401. paramInfo.unit = nullptr;
  402. paramInfo.ranges.def = 0.0f;
  403. paramInfo.ranges.min = 0.0f;
  404. paramInfo.ranges.max = 1.0f;
  405. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  406. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  407. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  408. paramInfo.scalePointCount = 0;
  409. paramInfo.scalePoints = nullptr;
  410. switch (index)
  411. {
  412. case kParamRate:
  413. paramInfo.name = "Rate";
  414. paramInfo.ranges.def = 0.3f;
  415. break;
  416. case kParamDepth:
  417. paramInfo.name = "Depth";
  418. paramInfo.ranges.def = 0.6f;
  419. break;
  420. }
  421. paramInfo.hints = static_cast<ParameterHints>(hints);
  422. return &paramInfo;
  423. }
  424. float getParameterValue(const uint32_t index) const override
  425. {
  426. switch (index)
  427. {
  428. case kParamRate:
  429. return fParameters[76];
  430. case kParamDepth:
  431. return fParameters[77];
  432. default:
  433. return 0.0f;
  434. }
  435. }
  436. // -------------------------------------------------------------------
  437. // Plugin state calls
  438. void setParameterValue(const uint32_t index, const float value) override
  439. {
  440. switch (index)
  441. {
  442. case kParamRate:
  443. fParameters[76] = value;
  444. break;
  445. case kParamDepth:
  446. fParameters[77] = value;
  447. break;
  448. default:
  449. break;
  450. }
  451. }
  452. // -------------------------------------------------------------------
  453. // Plugin process calls
  454. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  455. {
  456. if (inBuffer[0] != outBuffer[0])
  457. FloatVectorOperations::copy(outBuffer[0], inBuffer[0], frames);
  458. if (inBuffer[1] != outBuffer[1])
  459. FloatVectorOperations::copy(outBuffer[1], inBuffer[1], frames);
  460. fChorus.processBlock(outBuffer[0], outBuffer[1], frames);
  461. }
  462. // -------------------------------------------------------------------
  463. // Plugin dispatcher calls
  464. void sampleRateChanged(const double sampleRate) override
  465. {
  466. fChorus.setSampleRate(sampleRate);
  467. }
  468. private:
  469. VexChorus fChorus;
  470. float fParameters[92];
  471. PluginClassEND(VexChorusPlugin)
  472. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexChorusPlugin)
  473. };
  474. // -----------------------------------------------------------------------
  475. class VexDelayPlugin : public PluginClass
  476. {
  477. public:
  478. enum Params {
  479. kParamTime = 0,
  480. kParamFeedback,
  481. kParamCount
  482. };
  483. VexDelayPlugin(const HostDescriptor* const host)
  484. : PluginClass(host),
  485. fDelay(fParameters)
  486. {
  487. std::memset(fParameters, 0, sizeof(float)*92);
  488. fParameters[73] = 0.5f;
  489. fParameters[74] = 0.4f;
  490. fDelay.setSampleRate(getSampleRate());
  491. }
  492. protected:
  493. // -------------------------------------------------------------------
  494. // Plugin parameter calls
  495. uint32_t getParameterCount() const override
  496. {
  497. return kParamCount;
  498. }
  499. const Parameter* getParameterInfo(const uint32_t index) const override
  500. {
  501. static Parameter paramInfo;
  502. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  503. paramInfo.name = nullptr;
  504. paramInfo.unit = nullptr;
  505. paramInfo.ranges.def = 0.0f;
  506. paramInfo.ranges.min = 0.0f;
  507. paramInfo.ranges.max = 1.0f;
  508. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  509. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  510. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  511. paramInfo.scalePointCount = 0;
  512. paramInfo.scalePoints = nullptr;
  513. switch (index)
  514. {
  515. case kParamTime:
  516. hints |= PARAMETER_IS_INTEGER;
  517. paramInfo.name = "Time";
  518. paramInfo.unit = "steps";
  519. paramInfo.ranges.def = 4.0f;
  520. paramInfo.ranges.min = 0.0f;
  521. paramInfo.ranges.max = 8.0f;
  522. break;
  523. case kParamFeedback:
  524. paramInfo.name = "Feedback";
  525. paramInfo.unit = "%";
  526. paramInfo.ranges.def = 40.0f;
  527. paramInfo.ranges.min = 0.0f;
  528. paramInfo.ranges.max = 100.0f;
  529. break;
  530. }
  531. paramInfo.hints = static_cast<ParameterHints>(hints);
  532. return &paramInfo;
  533. }
  534. float getParameterValue(const uint32_t index) const override
  535. {
  536. switch (index)
  537. {
  538. case kParamTime:
  539. return fParameters[73] * 8.0f;
  540. case kParamFeedback:
  541. return fParameters[74] * 100.0f;
  542. default:
  543. return 0.0f;
  544. }
  545. }
  546. // -------------------------------------------------------------------
  547. // Plugin state calls
  548. void setParameterValue(const uint32_t index, const float value) override
  549. {
  550. switch (index)
  551. {
  552. case kParamTime:
  553. fParameters[73] = value/8.0f;
  554. break;
  555. case kParamFeedback:
  556. fParameters[74] = value/100.0f;
  557. break;
  558. default:
  559. break;
  560. }
  561. }
  562. // -------------------------------------------------------------------
  563. // Plugin process calls
  564. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  565. {
  566. if (inBuffer[0] != outBuffer[0])
  567. FloatVectorOperations::copy(outBuffer[0], inBuffer[0], frames);
  568. if (inBuffer[1] != outBuffer[1])
  569. FloatVectorOperations::copy(outBuffer[1], inBuffer[1], frames);
  570. const TimeInfo* const timeInfo(getTimeInfo());
  571. const double bpm((timeInfo != nullptr && timeInfo->bbt.valid) ? timeInfo->bbt.beatsPerMinute : 120.0);
  572. fDelay.processBlock(outBuffer[0], outBuffer[1], frames, bpm);
  573. }
  574. // -------------------------------------------------------------------
  575. // Plugin dispatcher calls
  576. void sampleRateChanged(const double sampleRate) override
  577. {
  578. fDelay.setSampleRate(sampleRate);
  579. }
  580. private:
  581. VexDelay fDelay;
  582. float fParameters[92];
  583. PluginClassEND(VexDelayPlugin)
  584. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexDelayPlugin)
  585. };
  586. // -----------------------------------------------------------------------
  587. class VexReverbPlugin : public PluginClass
  588. {
  589. public:
  590. enum Params {
  591. kParamSize = 0,
  592. kParamWidth,
  593. kParamDamp,
  594. kParamCount
  595. };
  596. VexReverbPlugin(const HostDescriptor* const host)
  597. : PluginClass(host),
  598. fReverb(fParameters)
  599. {
  600. std::memset(fParameters, 0, sizeof(float)*92);
  601. fParameters[79] = 0.6f;
  602. fParameters[80] = 0.7f;
  603. fParameters[81] = 0.6f;
  604. }
  605. protected:
  606. // -------------------------------------------------------------------
  607. // Plugin parameter calls
  608. uint32_t getParameterCount() const override
  609. {
  610. return kParamCount;
  611. }
  612. const Parameter* getParameterInfo(const uint32_t index) const override
  613. {
  614. static Parameter paramInfo;
  615. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  616. paramInfo.name = nullptr;
  617. paramInfo.unit = nullptr;
  618. paramInfo.ranges.def = 0.0f;
  619. paramInfo.ranges.min = 0.0f;
  620. paramInfo.ranges.max = 1.0f;
  621. paramInfo.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  622. paramInfo.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  623. paramInfo.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  624. paramInfo.scalePointCount = 0;
  625. paramInfo.scalePoints = nullptr;
  626. switch (index)
  627. {
  628. case kParamSize:
  629. paramInfo.name = "Size";
  630. paramInfo.ranges.def = 0.6f;
  631. break;
  632. case kParamWidth:
  633. paramInfo.name = "Width";
  634. paramInfo.ranges.def = 0.7f;
  635. break;
  636. case kParamDamp:
  637. paramInfo.name = "Damp";
  638. paramInfo.ranges.def = 0.6f;
  639. break;
  640. }
  641. paramInfo.hints = static_cast<ParameterHints>(hints);
  642. return &paramInfo;
  643. }
  644. float getParameterValue(const uint32_t index) const override
  645. {
  646. switch (index)
  647. {
  648. case kParamSize:
  649. return fParameters[79];
  650. case kParamWidth:
  651. return fParameters[80];
  652. case kParamDamp:
  653. return fParameters[81];
  654. default:
  655. return 0.0f;
  656. }
  657. }
  658. // -------------------------------------------------------------------
  659. // Plugin state calls
  660. void setParameterValue(const uint32_t index, const float value) override
  661. {
  662. switch (index)
  663. {
  664. case kParamSize:
  665. fParameters[79] = value;
  666. break;
  667. case kParamWidth:
  668. fParameters[80] = value;
  669. break;
  670. case kParamDamp:
  671. fParameters[81] = value;
  672. break;
  673. default:
  674. break;
  675. }
  676. }
  677. // -------------------------------------------------------------------
  678. // Plugin process calls
  679. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const MidiEvent* const, const uint32_t) override
  680. {
  681. for (uint32_t i=0; i< frames; ++i)
  682. FloatVectorOperations::copyWithMultiply(outBuffer[0], inBuffer[0], 0.5f, frames);
  683. for (uint32_t i=0; i< frames; ++i)
  684. FloatVectorOperations::copyWithMultiply(outBuffer[1], inBuffer[1], 0.5f, frames);
  685. fReverb.processBlock(outBuffer[0], outBuffer[1], frames);
  686. }
  687. private:
  688. VexReverb fReverb;
  689. float fParameters[92];
  690. PluginClassEND(VexReverbPlugin)
  691. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexReverbPlugin)
  692. };
  693. // -----------------------------------------------------------------------
  694. static const PluginDescriptor vexArpDesc = {
  695. /* category */ PLUGIN_CATEGORY_UTILITY,
  696. /* hints */ static_cast<PluginHints>(PLUGIN_HAS_GUI|PLUGIN_NEEDS_UI_JUCE|PLUGIN_USES_TIME),
  697. /* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_EVERYTHING),
  698. /* audioIns */ 0,
  699. /* audioOuts */ 0,
  700. /* midiIns */ 1,
  701. /* midiOuts */ 1,
  702. /* paramIns */ VexArpPlugin::kParamCount,
  703. /* paramOuts */ 0,
  704. /* name */ "VexArp",
  705. /* label */ "vexArp",
  706. /* maker */ "falkTX",
  707. /* copyright */ "GNU GPL v2+",
  708. PluginDescriptorFILL(VexArpPlugin)
  709. };
  710. static const PluginDescriptor vexChorusDesc = {
  711. /* category */ PLUGIN_CATEGORY_MODULATOR,
  712. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  713. /* supports */ static_cast<PluginSupports>(0x0),
  714. /* audioIns */ 2,
  715. /* audioOuts */ 2,
  716. /* midiIns */ 0,
  717. /* midiOuts */ 0,
  718. /* paramIns */ VexChorusPlugin::kParamCount,
  719. /* paramOuts */ 0,
  720. /* name */ "VexChorus",
  721. /* label */ "vexChorus",
  722. /* maker */ "falkTX",
  723. /* copyright */ "GNU GPL v2+",
  724. PluginDescriptorFILL(VexChorusPlugin)
  725. };
  726. static const PluginDescriptor vexDelayDesc = {
  727. /* category */ PLUGIN_CATEGORY_DELAY,
  728. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_TIME),
  729. /* supports */ static_cast<PluginSupports>(0x0),
  730. /* audioIns */ 2,
  731. /* audioOuts */ 2,
  732. /* midiIns */ 0,
  733. /* midiOuts */ 0,
  734. /* paramIns */ VexDelayPlugin::kParamCount,
  735. /* paramOuts */ 0,
  736. /* name */ "VexDelay",
  737. /* label */ "vexDelay",
  738. /* maker */ "falkTX",
  739. /* copyright */ "GNU GPL v2+",
  740. PluginDescriptorFILL(VexDelayPlugin)
  741. };
  742. static const PluginDescriptor vexReverbDesc = {
  743. /* category */ PLUGIN_CATEGORY_DELAY,
  744. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  745. /* supports */ static_cast<PluginSupports>(0x0),
  746. /* audioIns */ 2,
  747. /* audioOuts */ 2,
  748. /* midiIns */ 0,
  749. /* midiOuts */ 0,
  750. /* paramIns */ VexReverbPlugin::kParamCount,
  751. /* paramOuts */ 0,
  752. /* name */ "VexReverb",
  753. /* label */ "vexReverb",
  754. /* maker */ "falkTX",
  755. /* copyright */ "GNU GPL v2+",
  756. PluginDescriptorFILL(VexReverbPlugin)
  757. };
  758. // -----------------------------------------------------------------------
  759. CARLA_EXPORT
  760. void carla_register_native_plugin_vex_fx()
  761. {
  762. carla_register_native_plugin(&vexArpDesc);
  763. carla_register_native_plugin(&vexChorusDesc);
  764. carla_register_native_plugin(&vexDelayDesc);
  765. carla_register_native_plugin(&vexReverbDesc);
  766. }
  767. // -----------------------------------------------------------------------