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 27KB

10 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
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  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. // -----------------------------------------------------------------------