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
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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. }
  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. const 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. const 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 NativePluginClass
  373. {
  374. public:
  375. enum Params {
  376. kParamRate = 0,
  377. kParamDepth,
  378. kParamCount
  379. };
  380. VexChorusPlugin(const NativeHostDescriptor* const host)
  381. : NativePluginClass(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 NativeParameter* getParameterInfo(const uint32_t index) const override
  397. {
  398. static NativeParameter 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<NativeParameterHints>(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 NativeMidiEvent* 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 NativePluginClass
  476. {
  477. public:
  478. enum Params {
  479. kParamTime = 0,
  480. kParamFeedback,
  481. kParamCount
  482. };
  483. VexDelayPlugin(const NativeHostDescriptor* const host)
  484. : NativePluginClass(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 NativeParameter* getParameterInfo(const uint32_t index) const override
  500. {
  501. static NativeParameter 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<NativeParameterHints>(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 NativeMidiEvent* 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 NativeTimeInfo* 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 NativePluginClass
  588. {
  589. public:
  590. enum Params {
  591. kParamSize = 0,
  592. kParamWidth,
  593. kParamDamp,
  594. kParamCount
  595. };
  596. VexReverbPlugin(const NativeHostDescriptor* const host)
  597. : NativePluginClass(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 NativeParameter* getParameterInfo(const uint32_t index) const override
  613. {
  614. static NativeParameter 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<NativeParameterHints>(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 NativeMidiEvent* 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 NativePluginDescriptor vexArpDesc = {
  695. /* category */ PLUGIN_CATEGORY_UTILITY,
  696. /* hints */ static_cast<NativePluginHints>(PLUGIN_HAS_UI|PLUGIN_NEEDS_UI_JUCE|PLUGIN_USES_TIME),
  697. /* supports */ static_cast<NativePluginSupports>(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, Lucio Asnaghi, rockhardbuns",
  707. /* copyright */ "GNU GPL v2+",
  708. PluginDescriptorFILL(VexArpPlugin)
  709. };
  710. static const NativePluginDescriptor vexChorusDesc = {
  711. /* category */ PLUGIN_CATEGORY_MODULATOR,
  712. /* hints */ static_cast<NativePluginHints>(PLUGIN_IS_RTSAFE),
  713. /* supports */ static_cast<NativePluginSupports>(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, Lucio Asnaghi, rockhardbuns",
  723. /* copyright */ "GNU GPL v2+",
  724. PluginDescriptorFILL(VexChorusPlugin)
  725. };
  726. static const NativePluginDescriptor vexDelayDesc = {
  727. /* category */ PLUGIN_CATEGORY_DELAY,
  728. /* hints */ static_cast<NativePluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_TIME),
  729. /* supports */ static_cast<NativePluginSupports>(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, Lucio Asnaghi, rockhardbuns",
  739. /* copyright */ "GNU GPL v2+",
  740. PluginDescriptorFILL(VexDelayPlugin)
  741. };
  742. static const NativePluginDescriptor vexReverbDesc = {
  743. /* category */ PLUGIN_CATEGORY_DELAY,
  744. /* hints */ static_cast<NativePluginHints>(PLUGIN_IS_RTSAFE),
  745. /* supports */ static_cast<NativePluginSupports>(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, Lucio Asnaghi, rockhardbuns",
  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. // -----------------------------------------------------------------------