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.

706 lines
21KB

  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. using namespace juce;
  19. #include "vex/cArp.h"
  20. #include "vex/cChorus.h"
  21. #include "vex/cDelay.h"
  22. #include "vex/cReverb.h"
  23. // -----------------------------------------------------------------------
  24. class VexArpPlugin : public PluginDescriptorClass
  25. {
  26. public:
  27. enum Params {
  28. kParamOnOff = 0,
  29. kParamLength,
  30. kParamTimeMode,
  31. kParamSyncMode,
  32. kParamFailMode,
  33. kParamVelMode,
  34. kParamCount
  35. };
  36. VexArpPlugin(const HostDescriptor* const host)
  37. : PluginDescriptorClass(host),
  38. fSettings(),
  39. fArp(&fSettings)
  40. {
  41. for (int i=0; i < 8; ++i)
  42. fSettings.grid[i*10] = true;
  43. fSettings.grid[1] = true;
  44. fSettings.grid[2] = true;
  45. fSettings.grid[3] = true;
  46. fSettings.grid[41] = true;
  47. fSettings.grid[42] = true;
  48. fSettings.grid[43] = true;
  49. fSettings.grid[44] = true;
  50. fSettings.grid[45] = true;
  51. fArp.setSampleRate(getSampleRate());
  52. fMidiInBuffer.ensureSize(512*4);
  53. }
  54. protected:
  55. // -------------------------------------------------------------------
  56. // Plugin parameter calls
  57. uint32_t getParameterCount() override
  58. {
  59. return kParamCount;
  60. }
  61. const Parameter* getParameterInfo(const uint32_t index) override
  62. {
  63. static Parameter paramInfo;
  64. static ParameterScalePoint scalePoints[4];
  65. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE|PARAMETER_IS_INTEGER;
  66. paramInfo.name = nullptr;
  67. paramInfo.unit = nullptr;
  68. paramInfo.ranges.def = 0.0f;
  69. paramInfo.ranges.min = 0.0f;
  70. paramInfo.ranges.max = 1.0f;
  71. paramInfo.ranges.step = 1.0f;
  72. paramInfo.ranges.stepSmall = 1.0f;
  73. paramInfo.ranges.stepLarge = 1.0f;
  74. paramInfo.scalePointCount = 0;
  75. paramInfo.scalePoints = nullptr;
  76. switch (index)
  77. {
  78. case kParamOnOff:
  79. hints |= PARAMETER_IS_BOOLEAN;
  80. paramInfo.name = "On/Off";
  81. paramInfo.ranges.def = 0.0f;
  82. paramInfo.ranges.min = 0.0f;
  83. paramInfo.ranges.max = 1.0f;
  84. break;
  85. case kParamLength:
  86. paramInfo.name = "Length";
  87. paramInfo.ranges.def = 8.0f;
  88. paramInfo.ranges.min = 1.0f;
  89. paramInfo.ranges.max = 16.0f;
  90. break;
  91. case kParamTimeMode:
  92. hints |= PARAMETER_USES_SCALEPOINTS;
  93. paramInfo.name = "Time Signature";
  94. paramInfo.ranges.def = 2.0f;
  95. paramInfo.ranges.min = 1.0f;
  96. paramInfo.ranges.max = 3.0f;
  97. paramInfo.scalePointCount = 3;
  98. paramInfo.scalePoints = scalePoints;
  99. scalePoints[0].label = "8";
  100. scalePoints[1].label = "16";
  101. scalePoints[2].label = "32";
  102. scalePoints[0].value = 1.0f;
  103. scalePoints[1].value = 2.0f;
  104. scalePoints[2].value = 3.0f;
  105. break;
  106. case kParamSyncMode:
  107. hints |= PARAMETER_USES_SCALEPOINTS;
  108. paramInfo.name = "Sync Mode";
  109. paramInfo.ranges.def = 1.0f;
  110. paramInfo.ranges.min = 1.0f;
  111. paramInfo.ranges.max = 2.0f;
  112. paramInfo.scalePointCount = 2;
  113. paramInfo.scalePoints = scalePoints;
  114. scalePoints[0].label = "Key Sync";
  115. scalePoints[1].label = "Bar Sync";
  116. scalePoints[0].value = 1.0f;
  117. scalePoints[1].value = 2.0f;
  118. break;
  119. case kParamFailMode:
  120. hints |= PARAMETER_USES_SCALEPOINTS;
  121. paramInfo.name = "Fail Mode";
  122. paramInfo.ranges.def = 1.0f;
  123. paramInfo.ranges.min = 1.0f;
  124. paramInfo.ranges.max = 3.0f;
  125. paramInfo.scalePointCount = 3;
  126. paramInfo.scalePoints = scalePoints;
  127. scalePoints[0].label = "Silent Step";
  128. scalePoints[1].label = "Skip One";
  129. scalePoints[2].label = "Skip Two";
  130. scalePoints[0].value = 1.0f;
  131. scalePoints[1].value = 2.0f;
  132. scalePoints[2].value = 3.0f;
  133. break;
  134. case kParamVelMode:
  135. hints |= PARAMETER_USES_SCALEPOINTS;
  136. paramInfo.name = "Velocity Mode";
  137. paramInfo.ranges.def = 1.0f;
  138. paramInfo.ranges.min = 1.0f;
  139. paramInfo.ranges.max = 3.0f;
  140. paramInfo.scalePointCount = 3;
  141. paramInfo.scalePoints = scalePoints;
  142. scalePoints[0].label = "Pattern Velocity";
  143. scalePoints[1].label = "Input Velocity";
  144. scalePoints[2].label = "Sum Velocities";
  145. scalePoints[0].value = 1.0f;
  146. scalePoints[1].value = 2.0f;
  147. scalePoints[2].value = 3.0f;
  148. break;
  149. }
  150. paramInfo.hints = static_cast<ParameterHints>(hints);
  151. return &paramInfo;
  152. }
  153. float getParameterValue(const uint32_t index) override
  154. {
  155. switch (index)
  156. {
  157. case kParamOnOff:
  158. return fSettings.on ? 1.0f : 0.0f;
  159. case kParamLength:
  160. return fSettings.length;
  161. case kParamTimeMode:
  162. return fSettings.timeMode;
  163. case kParamSyncMode:
  164. return fSettings.syncMode;
  165. case kParamFailMode:
  166. return fSettings.failMode;
  167. case kParamVelMode:
  168. return fSettings.velMode;
  169. default:
  170. return 0.0f;
  171. }
  172. }
  173. // -------------------------------------------------------------------
  174. // Plugin state calls
  175. void setParameterValue(const uint32_t index, const float value)
  176. {
  177. switch (index)
  178. {
  179. case kParamOnOff:
  180. fSettings.on = (value > 0.5f);
  181. break;
  182. case kParamLength:
  183. fSettings.length = value;
  184. break;
  185. case kParamTimeMode:
  186. fSettings.timeMode = value;
  187. break;
  188. case kParamSyncMode:
  189. fSettings.syncMode = value;
  190. break;
  191. case kParamFailMode:
  192. fSettings.failMode = value;
  193. break;
  194. case kParamVelMode:
  195. fSettings.velMode = value;
  196. break;
  197. }
  198. }
  199. // -------------------------------------------------------------------
  200. // Plugin process calls
  201. void process(float**, float**, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) override
  202. {
  203. if (! fSettings.on)
  204. {
  205. for (uint32_t i=0; i < midiEventCount; ++i)
  206. writeMidiEvent(&midiEvents[i]);
  207. return;
  208. }
  209. const TimeInfo* const timeInfo(getTimeInfo());
  210. double ppqPos, barStartPos, bpm;
  211. if (timeInfo->bbt.valid)
  212. {
  213. ppqPos = 0.0;
  214. barStartPos = 0.0;
  215. bpm = timeInfo->bbt.beatsPerMinute;
  216. }
  217. else
  218. {
  219. double ppqBar = double(timeInfo->bbt.bar - 1) * timeInfo->bbt.beatsPerBar;
  220. double ppqBeat = double(timeInfo->bbt.beat - 1);
  221. double ppqTick = double(timeInfo->bbt.tick) / timeInfo->bbt.ticksPerBeat;
  222. ppqPos = ppqBar + ppqBeat + ppqTick;
  223. barStartPos = ppqBar;
  224. bpm = 120.0;
  225. }
  226. fMidiInBuffer.clear();
  227. for (uint32_t i=0; i < midiEventCount; ++i)
  228. {
  229. const MidiEvent* const midiEvent(&midiEvents[i]);
  230. fMidiInBuffer.addEvent(MidiMessage(midiEvent->data, midiEvent->size, midiEvent->time), timeInfo->frame);
  231. }
  232. const MidiBuffer& outMidiBuffer(fArp.processMidi(fMidiInBuffer, timeInfo->playing, ppqPos, barStartPos, bpm, frames));
  233. MidiBuffer::Iterator outBufferIterator(outMidiBuffer);
  234. MidiMessage midiMessage(0xf4);
  235. int sampleNumber;
  236. MidiEvent tmpEvent;
  237. tmpEvent.port = 0;
  238. while (outBufferIterator.getNextEvent(midiMessage, sampleNumber))
  239. {
  240. tmpEvent.size = midiMessage.getRawDataSize();
  241. tmpEvent.time = midiMessage.getTimeStamp();
  242. if (tmpEvent.size > 4)
  243. continue;
  244. std::memcpy(tmpEvent.data, midiMessage.getRawData(), sizeof(uint8_t)*tmpEvent.size);
  245. writeMidiEvent(&tmpEvent);
  246. }
  247. }
  248. private:
  249. VexArpSettings fSettings;
  250. VexArp fArp;
  251. MidiBuffer fMidiInBuffer;
  252. PluginDescriptorClassEND(VexArpPlugin)
  253. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexArpPlugin)
  254. };
  255. // -----------------------------------------------------------------------
  256. class VexChorusPlugin : public PluginDescriptorClass
  257. {
  258. public:
  259. enum Params {
  260. kParamDepth = 0,
  261. kParamRate,
  262. kParamCount
  263. };
  264. VexChorusPlugin(const HostDescriptor* const host)
  265. : PluginDescriptorClass(host),
  266. chorus(parameters)
  267. {
  268. parameters[0] = 0.6f;
  269. parameters[1] = 0.3f;
  270. chorus.setSampleRate(getSampleRate());
  271. }
  272. protected:
  273. // -------------------------------------------------------------------
  274. // Plugin parameter calls
  275. uint32_t getParameterCount() override
  276. {
  277. return kParamCount;
  278. }
  279. const Parameter* getParameterInfo(const uint32_t index) override
  280. {
  281. static Parameter paramInfo;
  282. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  283. paramInfo.name = nullptr;
  284. paramInfo.unit = nullptr;
  285. paramInfo.ranges.def = 0.0f;
  286. paramInfo.ranges.min = 0.0f;
  287. paramInfo.ranges.max = 1.0f;
  288. paramInfo.ranges.step = 1.0f;
  289. paramInfo.ranges.stepSmall = 1.0f;
  290. paramInfo.ranges.stepLarge = 1.0f;
  291. paramInfo.scalePointCount = 0;
  292. paramInfo.scalePoints = nullptr;
  293. switch (index)
  294. {
  295. case kParamDepth:
  296. paramInfo.name = "Depth";
  297. paramInfo.ranges.def = 0.6f;
  298. paramInfo.ranges.min = 0.0f;
  299. paramInfo.ranges.max = 1.0f;
  300. break;
  301. case kParamRate:
  302. paramInfo.name = "Rate";
  303. paramInfo.ranges.def = 0.3f;
  304. paramInfo.ranges.min = 0.0f;
  305. paramInfo.ranges.max = 1.0f;
  306. break;
  307. }
  308. paramInfo.hints = static_cast<ParameterHints>(hints);
  309. return &paramInfo;
  310. }
  311. float getParameterValue(const uint32_t index) override
  312. {
  313. if (index < kParamCount)
  314. return parameters[index];
  315. return 0.0f;
  316. }
  317. // -------------------------------------------------------------------
  318. // Plugin state calls
  319. void setParameterValue(const uint32_t index, const float value)
  320. {
  321. if (index < kParamCount)
  322. parameters[index] = value;
  323. }
  324. // -------------------------------------------------------------------
  325. // Plugin process calls
  326. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  327. {
  328. if (inBuffer[0] != outBuffer[0])
  329. carla_copyFloat(outBuffer[0], inBuffer[0], frames);
  330. if (inBuffer[1] != outBuffer[1])
  331. carla_copyFloat(outBuffer[1], inBuffer[1], frames);
  332. chorus.processBlock(outBuffer[0], outBuffer[1], frames);
  333. }
  334. private:
  335. VexChorus chorus;
  336. float parameters[2];
  337. PluginDescriptorClassEND(VexChorusPlugin)
  338. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexChorusPlugin)
  339. };
  340. // -----------------------------------------------------------------------
  341. class VexDelayPlugin : public PluginDescriptorClass
  342. {
  343. public:
  344. enum Params {
  345. kParamTime = 0,
  346. kParamFeedback,
  347. kParamCount
  348. };
  349. VexDelayPlugin(const HostDescriptor* const host)
  350. : PluginDescriptorClass(host),
  351. delay(parameters)
  352. {
  353. parameters[0] = 4.0f;
  354. parameters[1] = 40.0f;
  355. delay.setSampleRate(getSampleRate());
  356. }
  357. protected:
  358. // -------------------------------------------------------------------
  359. // Plugin parameter calls
  360. uint32_t getParameterCount() override
  361. {
  362. return kParamCount;
  363. }
  364. const Parameter* getParameterInfo(const uint32_t index) override
  365. {
  366. static Parameter paramInfo;
  367. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  368. paramInfo.name = nullptr;
  369. paramInfo.unit = nullptr;
  370. paramInfo.ranges.def = 0.0f;
  371. paramInfo.ranges.min = 0.0f;
  372. paramInfo.ranges.max = 1.0f;
  373. paramInfo.ranges.step = 1.0f;
  374. paramInfo.ranges.stepSmall = 1.0f;
  375. paramInfo.ranges.stepLarge = 1.0f;
  376. paramInfo.scalePointCount = 0;
  377. paramInfo.scalePoints = nullptr;
  378. switch (index)
  379. {
  380. case kParamTime:
  381. hints |= PARAMETER_IS_INTEGER;
  382. paramInfo.name = "Time";
  383. paramInfo.ranges.def = 4.0f;
  384. paramInfo.ranges.min = 0.0f;
  385. paramInfo.ranges.max = 8.0f;
  386. break;
  387. case kParamFeedback:
  388. paramInfo.name = "Feedback";
  389. paramInfo.unit = "%";
  390. paramInfo.ranges.def = 40.0f;
  391. paramInfo.ranges.min = 0.0f;
  392. paramInfo.ranges.max = 100.0f;
  393. break;
  394. }
  395. paramInfo.hints = static_cast<ParameterHints>(hints);
  396. return &paramInfo;
  397. }
  398. float getParameterValue(const uint32_t index) override
  399. {
  400. if (index < kParamCount)
  401. return parameters[index];
  402. return 0.0f;
  403. }
  404. // -------------------------------------------------------------------
  405. // Plugin state calls
  406. void setParameterValue(const uint32_t index, const float value)
  407. {
  408. if (index < kParamCount)
  409. parameters[index] = value;
  410. }
  411. // -------------------------------------------------------------------
  412. // Plugin process calls
  413. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  414. {
  415. if (inBuffer[0] != outBuffer[0])
  416. carla_copyFloat(outBuffer[0], inBuffer[0], frames);
  417. if (inBuffer[1] != outBuffer[1])
  418. carla_copyFloat(outBuffer[1], inBuffer[1], frames);
  419. const TimeInfo* const timeInfo(getTimeInfo());
  420. const double bpm(timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0);
  421. delay.processBlock(outBuffer[0], outBuffer[1], frames, bpm);
  422. }
  423. private:
  424. VexDelay delay;
  425. float parameters[2];
  426. PluginDescriptorClassEND(VexDelayPlugin)
  427. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexDelayPlugin)
  428. };
  429. // -----------------------------------------------------------------------
  430. class VexReverbPlugin : public PluginDescriptorClass
  431. {
  432. public:
  433. enum Params {
  434. kParamSize = 0,
  435. kParamWidth,
  436. kParamDamp,
  437. kParamCount
  438. };
  439. VexReverbPlugin(const HostDescriptor* const host)
  440. : PluginDescriptorClass(host),
  441. reverb(parameters)
  442. {
  443. parameters[0] = 0.6f;
  444. parameters[1] = 0.7f;
  445. parameters[2] = 0.6f;
  446. }
  447. protected:
  448. // -------------------------------------------------------------------
  449. // Plugin parameter calls
  450. uint32_t getParameterCount() override
  451. {
  452. return kParamCount;
  453. }
  454. const Parameter* getParameterInfo(const uint32_t index) override
  455. {
  456. static Parameter paramInfo;
  457. int hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  458. paramInfo.name = nullptr;
  459. paramInfo.unit = nullptr;
  460. paramInfo.ranges.def = 0.0f;
  461. paramInfo.ranges.min = 0.0f;
  462. paramInfo.ranges.max = 1.0f;
  463. paramInfo.ranges.step = 1.0f;
  464. paramInfo.ranges.stepSmall = 1.0f;
  465. paramInfo.ranges.stepLarge = 1.0f;
  466. paramInfo.scalePointCount = 0;
  467. paramInfo.scalePoints = nullptr;
  468. switch (index)
  469. {
  470. case kParamSize:
  471. paramInfo.name = "Size";
  472. paramInfo.ranges.def = 0.6f;
  473. paramInfo.ranges.min = 0.0f;
  474. paramInfo.ranges.max = 1.0f;
  475. break;
  476. case kParamWidth:
  477. paramInfo.name = "Width";
  478. paramInfo.ranges.def = 0.7f;
  479. paramInfo.ranges.min = 0.0f;
  480. paramInfo.ranges.max = 1.0f;
  481. break;
  482. case kParamDamp:
  483. paramInfo.name = "Damp";
  484. paramInfo.ranges.def = 0.6f;
  485. paramInfo.ranges.min = 0.0f;
  486. paramInfo.ranges.max = 1.0f;
  487. break;
  488. }
  489. paramInfo.hints = static_cast<ParameterHints>(hints);
  490. return &paramInfo;
  491. }
  492. float getParameterValue(const uint32_t index) override
  493. {
  494. if (index < kParamCount)
  495. return parameters[index];
  496. return 0.0f;
  497. }
  498. // -------------------------------------------------------------------
  499. // Plugin state calls
  500. void setParameterValue(const uint32_t index, const float value)
  501. {
  502. if (index < kParamCount)
  503. parameters[index] = value;
  504. }
  505. // -------------------------------------------------------------------
  506. // Plugin process calls
  507. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  508. {
  509. for (uint32_t i=0; i< frames; ++i)
  510. outBuffer[0][i] = inBuffer[0][i]/2.0f;
  511. for (uint32_t i=0; i< frames; ++i)
  512. outBuffer[1][i] = inBuffer[1][i]/2.0f;
  513. reverb.processBlock(outBuffer[0], outBuffer[1], frames);
  514. }
  515. private:
  516. VexReverb reverb;
  517. float parameters[3];
  518. PluginDescriptorClassEND(VexReverbPlugin)
  519. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VexReverbPlugin)
  520. };
  521. // -----------------------------------------------------------------------
  522. static const PluginDescriptor vexArpDesc = {
  523. /* category */ PLUGIN_CATEGORY_UTILITY,
  524. /* hints */ static_cast<PluginHints>(0x0),
  525. /* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_EVERYTHING),
  526. /* audioIns */ 0,
  527. /* audioOuts */ 0,
  528. /* midiIns */ 1,
  529. /* midiOuts */ 1,
  530. /* paramIns */ VexArpPlugin::kParamCount,
  531. /* paramOuts */ 0,
  532. /* name */ "Vex Arp",
  533. /* label */ "vexArp",
  534. /* maker */ "falkTX",
  535. /* copyright */ "GNU GPL v2+",
  536. PluginDescriptorFILL(VexArpPlugin)
  537. };
  538. static const PluginDescriptor vexChorusDesc = {
  539. /* category */ PLUGIN_CATEGORY_MODULATOR,
  540. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  541. /* supports */ static_cast<PluginSupports>(0x0),
  542. /* audioIns */ 2,
  543. /* audioOuts */ 2,
  544. /* midiIns */ 0,
  545. /* midiOuts */ 0,
  546. /* paramIns */ VexChorusPlugin::kParamCount,
  547. /* paramOuts */ 0,
  548. /* name */ "Vex Chorus",
  549. /* label */ "vexChorus",
  550. /* maker */ "falkTX",
  551. /* copyright */ "GNU GPL v2+",
  552. PluginDescriptorFILL(VexChorusPlugin)
  553. };
  554. static const PluginDescriptor vexDelayDesc = {
  555. /* category */ PLUGIN_CATEGORY_DELAY,
  556. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  557. /* supports */ static_cast<PluginSupports>(0x0),
  558. /* audioIns */ 2,
  559. /* audioOuts */ 2,
  560. /* midiIns */ 0,
  561. /* midiOuts */ 0,
  562. /* paramIns */ VexDelayPlugin::kParamCount,
  563. /* paramOuts */ 0,
  564. /* name */ "Vex Delay",
  565. /* label */ "vexDelay",
  566. /* maker */ "falkTX",
  567. /* copyright */ "GNU GPL v2+",
  568. PluginDescriptorFILL(VexDelayPlugin)
  569. };
  570. static const PluginDescriptor vexReverbDesc = {
  571. /* category */ PLUGIN_CATEGORY_DELAY,
  572. /* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
  573. /* supports */ static_cast<PluginSupports>(0x0),
  574. /* audioIns */ 2,
  575. /* audioOuts */ 2,
  576. /* midiIns */ 0,
  577. /* midiOuts */ 0,
  578. /* paramIns */ VexReverbPlugin::kParamCount,
  579. /* paramOuts */ 0,
  580. /* name */ "Vex Reverb",
  581. /* label */ "vexReverb",
  582. /* maker */ "falkTX",
  583. /* copyright */ "GNU GPL v2+",
  584. PluginDescriptorFILL(VexReverbPlugin)
  585. };
  586. // -----------------------------------------------------------------------
  587. CARLA_EXPORT
  588. void carla_register_native_plugin_vex()
  589. {
  590. carla_register_native_plugin(&vexArpDesc);
  591. carla_register_native_plugin(&vexChorusDesc);
  592. carla_register_native_plugin(&vexDelayDesc);
  593. carla_register_native_plugin(&vexReverbDesc);
  594. }
  595. // -----------------------------------------------------------------------
  596. #include "vex/freeverb/allpass.cpp"
  597. #include "vex/freeverb/comb.cpp"
  598. #include "vex/freeverb/revmodel.cpp"
  599. // -----------------------------------------------------------------------