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.

1716 lines
45KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012-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 GPL.txt file
  16. */
  17. // for UINT32_MAX
  18. #define __STDC_LIMIT_MACROS
  19. #include <cstdint>
  20. #include "CarlaNative.hpp"
  21. #include "CarlaMIDI.h"
  22. #include "CarlaString.hpp"
  23. #include "RtList.hpp"
  24. #include <QtCore/QThread>
  25. #include "zynaddsubfx/Misc/Master.h"
  26. #include "zynaddsubfx/Misc/Part.h"
  27. #include "zynaddsubfx/Misc/Util.h"
  28. #include "zynaddsubfx/Effects/Alienwah.h"
  29. #include "zynaddsubfx/Effects/Chorus.h"
  30. #include "zynaddsubfx/Effects/Reverb.h"
  31. #ifdef WANT_ZYNADDSUBFX_UI
  32. // FIXME
  33. # ifdef override
  34. # define override_hack
  35. # undef override
  36. # endif
  37. # include "zynaddsubfx/UI/common.H"
  38. # include "zynaddsubfx/UI/MasterUI.h"
  39. # include <FL/Fl_Shared_Image.H>
  40. # include <FL/Fl_Tiled_Image.H>
  41. # include <FL/Fl_Dial.H>
  42. # include <FL/Fl_Theme.H>
  43. # ifdef override_hack
  44. # define override
  45. # undef override_hack
  46. # endif
  47. #endif
  48. #include <ctime>
  49. #include <set>
  50. #include <string>
  51. // Dummy variables and functions for linking purposes
  52. const char* instance_name = nullptr;
  53. class WavFile;
  54. namespace Nio {
  55. bool start(void){return 1;}
  56. void stop(void){}
  57. bool setSource(std::string){return true;}
  58. bool setSink(std::string){return true;}
  59. std::set<std::string> getSources(void){return std::set<std::string>();}
  60. std::set<std::string> getSinks(void){return std::set<std::string>();}
  61. std::string getSource(void){return "";}
  62. std::string getSink(void){return "";}
  63. void waveNew(WavFile*){}
  64. void waveStart(void){}
  65. void waveStop(void){}
  66. void waveEnd(void){}
  67. }
  68. SYNTH_T* synth = nullptr;
  69. #ifdef WANT_ZYNADDSUBFX_UI
  70. #define PIXMAP_PATH "/resources/zynaddsubfx/"
  71. static Fl_Tiled_Image* gModuleBackdrop = nullptr;
  72. static CarlaString gPixmapPath;
  73. extern CarlaString gUiPixmapPath;
  74. void set_module_parameters(Fl_Widget* o)
  75. {
  76. CARLA_ASSERT(gModuleBackdrop != nullptr);
  77. o->box(FL_DOWN_FRAME);
  78. o->align(o->align() | FL_ALIGN_IMAGE_BACKDROP);
  79. o->color(FL_BLACK);
  80. o->labeltype(FL_SHADOW_LABEL);
  81. if (gModuleBackdrop != nullptr)
  82. o->image(gModuleBackdrop);
  83. }
  84. #endif
  85. // -----------------------------------------------------------------------
  86. class ZynAddSubFxPrograms
  87. {
  88. public:
  89. ZynAddSubFxPrograms()
  90. : fInitiated(false)
  91. {
  92. }
  93. ~ZynAddSubFxPrograms()
  94. {
  95. if (! fInitiated)
  96. return;
  97. for (auto it = fPrograms.begin(); it.valid(); it.next())
  98. {
  99. const ProgramInfo*& pInfo(*it);
  100. delete pInfo;
  101. }
  102. fPrograms.clear();
  103. }
  104. void init()
  105. {
  106. if (fInitiated)
  107. return;
  108. fInitiated = true;
  109. fPrograms.append(new ProgramInfo(0, 0, "default"));
  110. Master& master (Master::getInstance());
  111. pthread_mutex_lock(&master.mutex);
  112. // refresh banks
  113. master.bank.rescanforbanks();
  114. for (uint32_t i=0, size = master.bank.banks.size(); i < size; ++i)
  115. {
  116. if (master.bank.banks[i].dir.empty())
  117. continue;
  118. master.bank.loadbank(master.bank.banks[i].dir);
  119. for (unsigned int instrument = 0; instrument < BANK_SIZE; ++instrument)
  120. {
  121. const std::string insName(master.bank.getname(instrument));
  122. if (insName.empty() || insName[0] == '\0' || insName[0] == ' ')
  123. continue;
  124. fPrograms.append(new ProgramInfo(i+1, instrument, insName.c_str()));
  125. }
  126. }
  127. pthread_mutex_unlock(&master.mutex);
  128. }
  129. void load(Master* const master, const uint8_t channel, const uint32_t bank, const uint32_t program)
  130. {
  131. if (bank == 0)
  132. {
  133. pthread_mutex_lock(&master->mutex);
  134. master->partonoff(channel, 1);
  135. master->part[channel]->defaults();
  136. master->part[channel]->applyparameters(false);
  137. pthread_mutex_unlock(&master->mutex);
  138. return;
  139. }
  140. const std::string& bankdir(master->bank.banks[bank-1].dir);
  141. if (! bankdir.empty())
  142. {
  143. pthread_mutex_lock(&master->mutex);
  144. master->partonoff(channel, 1);
  145. master->bank.loadbank(bankdir);
  146. master->bank.loadfromslot(program, master->part[channel]);
  147. master->part[channel]->applyparameters(false);
  148. pthread_mutex_unlock(&master->mutex);
  149. }
  150. }
  151. uint32_t count()
  152. {
  153. return fPrograms.count();
  154. }
  155. const MidiProgram* getInfo(const uint32_t index)
  156. {
  157. if (index >= fPrograms.count())
  158. return nullptr;
  159. const ProgramInfo*& pInfo(fPrograms.getAt(index));
  160. fRetProgram.bank = pInfo->bank;
  161. fRetProgram.program = pInfo->prog;
  162. fRetProgram.name = pInfo->name;
  163. return &fRetProgram;
  164. }
  165. private:
  166. struct ProgramInfo {
  167. uint32_t bank;
  168. uint32_t prog;
  169. const char* name;
  170. ProgramInfo(uint32_t bank_, uint32_t prog_, const char* name_)
  171. : bank(bank_),
  172. prog(prog_),
  173. name(carla_strdup(name_)) {}
  174. ~ProgramInfo()
  175. {
  176. if (name != nullptr)
  177. {
  178. delete[] name;
  179. name = nullptr;
  180. }
  181. }
  182. #ifdef CARLA_PROPER_CPP11_SUPPORT
  183. ProgramInfo() = delete;
  184. ProgramInfo(ProgramInfo&) = delete;
  185. ProgramInfo(const ProgramInfo&) = delete;
  186. #endif
  187. };
  188. bool fInitiated;
  189. MidiProgram fRetProgram;
  190. NonRtList<const ProgramInfo*> fPrograms;
  191. CARLA_DECLARE_NON_COPYABLE(ZynAddSubFxPrograms)
  192. };
  193. static ZynAddSubFxPrograms sPrograms;
  194. // -----------------------------------------------------------------------
  195. class ZynAddSubFxInstanceCount
  196. {
  197. public:
  198. ZynAddSubFxInstanceCount()
  199. : fCount(0)
  200. {
  201. }
  202. ~ZynAddSubFxInstanceCount()
  203. {
  204. CARLA_ASSERT(fCount == 0);
  205. }
  206. void addOne(HostDescriptor* const host)
  207. {
  208. if (fCount++ == 0)
  209. {
  210. CARLA_ASSERT(synth == nullptr);
  211. CARLA_ASSERT(denormalkillbuf == nullptr);
  212. reinit(host);
  213. #ifdef WANT_ZYNADDSUBFX_UI
  214. if (gPixmapPath.isEmpty())
  215. {
  216. gPixmapPath = host->resource_dir;
  217. gPixmapPath += PIXMAP_PATH;
  218. gUiPixmapPath = gPixmapPath;
  219. }
  220. #endif
  221. }
  222. }
  223. void removeOne()
  224. {
  225. if (--fCount == 0)
  226. {
  227. CARLA_ASSERT(synth != nullptr);
  228. CARLA_ASSERT(denormalkillbuf != nullptr);
  229. Master::deleteInstance();
  230. delete[] denormalkillbuf;
  231. denormalkillbuf = nullptr;
  232. delete synth;
  233. synth = nullptr;
  234. }
  235. }
  236. void reinit(HostDescriptor* const host)
  237. {
  238. Master::deleteInstance();
  239. if (denormalkillbuf != nullptr)
  240. {
  241. delete[] denormalkillbuf;
  242. denormalkillbuf = nullptr;
  243. }
  244. if (synth != nullptr)
  245. {
  246. delete synth;
  247. synth = nullptr;
  248. }
  249. synth = new SYNTH_T();
  250. synth->buffersize = host->get_buffer_size(host->handle);
  251. synth->samplerate = host->get_sample_rate(host->handle);
  252. synth->alias();
  253. config.init();
  254. config.cfg.SoundBufferSize = synth->buffersize;
  255. config.cfg.SampleRate = synth->samplerate;
  256. config.cfg.GzipCompression = 0;
  257. sprng(std::time(nullptr));
  258. denormalkillbuf = new float[synth->buffersize];
  259. for (int i=0; i < synth->buffersize; ++i)
  260. denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
  261. Master::getInstance();
  262. }
  263. private:
  264. int fCount;
  265. CARLA_DECLARE_NON_COPYABLE(ZynAddSubFxInstanceCount)
  266. };
  267. static ZynAddSubFxInstanceCount sInstanceCount;
  268. // -----------------------------------------------------------------------
  269. class ZynAddSubFxThread : public QThread
  270. {
  271. public:
  272. ZynAddSubFxThread(Master* const master, const HostDescriptor* const host)
  273. : fMaster(master),
  274. kHost(host),
  275. #ifdef WANT_ZYNADDSUBFX_UI
  276. fUi(nullptr),
  277. fUiClosed(0),
  278. fNextUiAction(-1),
  279. #endif
  280. fQuit(false),
  281. fChangeProgram(false),
  282. fNextChannel(0),
  283. fNextBank(0),
  284. fNextProgram(0)
  285. {
  286. }
  287. ~ZynAddSubFxThread()
  288. {
  289. // must be closed by now
  290. #ifdef WANT_ZYNADDSUBFX_UI
  291. CARLA_ASSERT(fUi == nullptr);
  292. #endif
  293. CARLA_ASSERT(fQuit);
  294. }
  295. void loadProgramLater(const uint8_t channel, const uint32_t bank, const uint32_t program)
  296. {
  297. fNextChannel = channel;
  298. fNextBank = bank;
  299. fNextProgram = program;
  300. fChangeProgram = true;
  301. }
  302. void stopLoadProgramLater()
  303. {
  304. fChangeProgram = false;
  305. fNextChannel = 0;
  306. fNextBank = 0;
  307. fNextProgram = 0;
  308. }
  309. void setMaster(Master* const master)
  310. {
  311. fMaster = master;
  312. }
  313. void stop()
  314. {
  315. fQuit = true;
  316. quit();
  317. }
  318. #ifdef WANT_ZYNADDSUBFX_UI
  319. void uiHide()
  320. {
  321. fNextUiAction = 0;
  322. }
  323. void uiShow()
  324. {
  325. fNextUiAction = 1;
  326. }
  327. void uiRepaint()
  328. {
  329. if (fUi != nullptr)
  330. fNextUiAction = 2;
  331. }
  332. #endif
  333. protected:
  334. void run() override
  335. {
  336. while (! fQuit)
  337. {
  338. #ifdef WANT_ZYNADDSUBFX_UI
  339. Fl::lock();
  340. if (fNextUiAction == 2) // repaint
  341. {
  342. CARLA_ASSERT(fUi != nullptr);
  343. if (fUi != nullptr)
  344. fUi->refresh_master_ui();
  345. }
  346. else if (fNextUiAction == 1) // init/show
  347. {
  348. static bool initialized = false;
  349. if (! initialized)
  350. {
  351. initialized = true;
  352. fl_register_images();
  353. Fl_Dial::default_style(Fl_Dial::PIXMAP_DIAL);
  354. if (Fl_Shared_Image* const img = Fl_Shared_Image::get(gPixmapPath + "knob.png"))
  355. Fl_Dial::default_image(img);
  356. if (Fl_Shared_Image* const img = Fl_Shared_Image::get(gPixmapPath + "window_backdrop.png"))
  357. Fl::scheme_bg(new Fl_Tiled_Image(img));
  358. if(Fl_Shared_Image* const img = Fl_Shared_Image::get(gPixmapPath + "module_backdrop.png"))
  359. gModuleBackdrop = new Fl_Tiled_Image(img);
  360. Fl::background(50, 50, 50);
  361. Fl::background2(70, 70, 70);
  362. Fl::foreground(255, 255, 255);
  363. Fl_Theme::set("Cairo");
  364. }
  365. CARLA_ASSERT(fUi == nullptr);
  366. if (fUi == nullptr)
  367. {
  368. fUiClosed = 0;
  369. fUi = new MasterUI(fMaster, &fUiClosed);
  370. fUi->showUI();
  371. }
  372. }
  373. else if (fNextUiAction == 0) // close
  374. {
  375. CARLA_ASSERT(fUi != nullptr);
  376. if (fUi != nullptr)
  377. {
  378. delete fUi;
  379. fUi = nullptr;
  380. }
  381. }
  382. fNextUiAction = -1;
  383. if (fUiClosed != 0)
  384. {
  385. fUiClosed = 0;
  386. fNextUiAction = 0;
  387. kHost->ui_closed(kHost->handle);
  388. }
  389. Fl::check();
  390. Fl::unlock();
  391. #endif
  392. if (fChangeProgram)
  393. {
  394. fChangeProgram = false;
  395. sPrograms.load(fMaster, fNextChannel, fNextBank, fNextProgram);
  396. fNextChannel = 0;
  397. fNextBank = 0;
  398. fNextProgram = 0;
  399. #ifdef WANT_ZYNADDSUBFX_UI
  400. if (fUi != nullptr)
  401. {
  402. Fl::lock();
  403. fUi->refresh_master_ui();
  404. Fl::unlock();
  405. }
  406. #endif
  407. carla_msleep(15);
  408. }
  409. else
  410. {
  411. carla_msleep(30);
  412. }
  413. }
  414. #ifdef WANT_ZYNADDSUBFX_UI
  415. if (fQuit && fUi != nullptr)
  416. {
  417. Fl::lock();
  418. delete fUi;
  419. fUi = nullptr;
  420. Fl::check();
  421. Fl::unlock();
  422. }
  423. #endif
  424. }
  425. private:
  426. Master* fMaster;
  427. const HostDescriptor* const kHost;
  428. #ifdef WANT_ZYNADDSUBFX_UI
  429. MasterUI* fUi;
  430. int fUiClosed;
  431. int fNextUiAction;
  432. #endif
  433. bool fQuit;
  434. bool fChangeProgram;
  435. uint8_t fNextChannel;
  436. uint32_t fNextBank;
  437. uint32_t fNextProgram;
  438. };
  439. // -----------------------------------------------------------------------
  440. #define ZynPluginDescriptorClassEND(ClassName) \
  441. public: \
  442. static PluginHandle _instantiate(const PluginDescriptor*, HostDescriptor* host) \
  443. { \
  444. sInstanceCount.addOne(host); \
  445. return new ClassName(host); \
  446. } \
  447. static void _cleanup(PluginHandle handle) \
  448. { \
  449. delete (ClassName*)handle; \
  450. sInstanceCount.removeOne(); \
  451. }
  452. // -----------------------------------------------------------------------
  453. class FxAlienWahPlugin : public PluginDescriptorClass
  454. {
  455. public:
  456. static const uint32_t kParamCount = 11;
  457. static const uint32_t kProgramCount = 4;
  458. FxAlienWahPlugin(const HostDescriptor* const host)
  459. : PluginDescriptorClass(host),
  460. efxoutl(new float[synth->buffersize]),
  461. efxoutr(new float[synth->buffersize]),
  462. fEffect(false, efxoutl, efxoutr)
  463. {
  464. }
  465. ~FxAlienWahPlugin()
  466. {
  467. if (efxoutl != nullptr)
  468. {
  469. delete[] efxoutl;
  470. efxoutl = nullptr;
  471. }
  472. if (efxoutr != nullptr)
  473. {
  474. delete[] efxoutr;
  475. efxoutr = nullptr;
  476. }
  477. }
  478. protected:
  479. // -------------------------------------------------------------------
  480. // Plugin parameter calls
  481. uint32_t getParameterCount() override
  482. {
  483. return kParamCount;
  484. }
  485. const Parameter* getParameterInfo(const uint32_t index) override
  486. {
  487. if (index >= kParamCount)
  488. return nullptr;
  489. static Parameter param;
  490. int hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  491. param.name = nullptr;
  492. param.unit = nullptr;
  493. param.ranges.def = 1.0f;
  494. param.ranges.min = 0.0f;
  495. param.ranges.max = 127.0f;
  496. param.ranges.step = 1.0f;
  497. param.ranges.stepSmall = 1.0f;
  498. param.ranges.stepLarge = 20.0f;
  499. param.scalePointCount = 0;
  500. param.scalePoints = nullptr;
  501. switch (index)
  502. {
  503. case 0:
  504. hints |= PARAMETER_IS_AUTOMABLE;
  505. param.name = "Volume";
  506. param.ranges.def = 127.0f;
  507. break;
  508. case 1:
  509. hints |= PARAMETER_IS_AUTOMABLE;
  510. param.name = "Panning";
  511. param.ranges.def = 64.0f;
  512. break;
  513. case 2:
  514. hints |= PARAMETER_IS_AUTOMABLE;
  515. param.name = "LFO Frequency";
  516. param.ranges.def = 70.0f;
  517. break;
  518. case 3:
  519. hints |= PARAMETER_IS_AUTOMABLE;
  520. param.name = "LFO Randomness";
  521. param.ranges.def = 0.0f;
  522. break;
  523. case 4:
  524. hints |= PARAMETER_IS_AUTOMABLE;
  525. param.name = "LFO Type";
  526. param.ranges.def = 0.0f;
  527. break;
  528. case 5:
  529. hints |= PARAMETER_IS_AUTOMABLE;
  530. param.name = "LFO Stereo";
  531. param.ranges.def = 62.0f;
  532. break;
  533. case 6:
  534. hints |= PARAMETER_IS_AUTOMABLE;
  535. param.name = "Depth";
  536. param.ranges.def = 60.0f;
  537. break;
  538. case 7:
  539. hints |= PARAMETER_IS_AUTOMABLE;
  540. param.name = "Feedback";
  541. param.ranges.def = 105.0f;
  542. break;
  543. case 8:
  544. param.name = "Delay";
  545. param.ranges.def = 25.0f;
  546. break;
  547. case 9:
  548. hints |= PARAMETER_IS_AUTOMABLE;
  549. param.name = "Cross";
  550. param.ranges.def = 0.0f;
  551. break;
  552. case 10:
  553. hints |= PARAMETER_IS_AUTOMABLE;
  554. param.name = "Phase";
  555. param.ranges.def = 64.0f;
  556. break;
  557. }
  558. param.hints = static_cast<ParameterHints>(hints);
  559. return &param;
  560. }
  561. float getParameterValue(const uint32_t index) override
  562. {
  563. return fEffect.getpar(index);
  564. }
  565. // -------------------------------------------------------------------
  566. // Plugin midi-program calls
  567. uint32_t getMidiProgramCount() override
  568. {
  569. return kProgramCount;
  570. }
  571. const MidiProgram* getMidiProgramInfo(const uint32_t index) override
  572. {
  573. if (index >= kProgramCount)
  574. return nullptr;
  575. static MidiProgram midiProg;
  576. midiProg.bank = 0;
  577. midiProg.program = index;
  578. midiProg.name = nullptr;
  579. switch (index)
  580. {
  581. case 0:
  582. midiProg.name = "AlienWah1";
  583. break;
  584. case 1:
  585. midiProg.name = "AlienWah2";
  586. break;
  587. case 2:
  588. midiProg.name = "AlienWah3";
  589. break;
  590. case 3:
  591. midiProg.name = "AlienWah4";
  592. break;
  593. }
  594. return &midiProg;
  595. }
  596. // -------------------------------------------------------------------
  597. // Plugin state calls
  598. void setParameterValue(const uint32_t index, const float value) override
  599. {
  600. fEffect.changepar(index, value);
  601. }
  602. void setMidiProgram(const uint8_t, const uint32_t, const uint32_t program) override
  603. {
  604. fEffect.setpreset(program);
  605. }
  606. // -------------------------------------------------------------------
  607. // Plugin process calls
  608. void activate() override
  609. {
  610. fEffect.cleanup();
  611. }
  612. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  613. {
  614. CARLA_ASSERT(synth->buffersize == static_cast<int>(frames));
  615. fEffect.out(Stereo<float*>(inBuffer[0], inBuffer[1]));
  616. for (uint32_t i=0; i<frames; ++i)
  617. {
  618. outBuffer[0][i] = inBuffer[0][i]/2.0f + efxoutl[i]/2.0f;
  619. outBuffer[1][i] = inBuffer[1][i]/2.0f + efxoutr[i]/2.0f;
  620. }
  621. }
  622. private:
  623. float* efxoutl;
  624. float* efxoutr;
  625. Alienwah fEffect;
  626. ZynPluginDescriptorClassEND(FxAlienWahPlugin)
  627. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FxAlienWahPlugin)
  628. };
  629. // -----------------------------------------------------------------------
  630. class FxChorusPlugin : public PluginDescriptorClass
  631. {
  632. public:
  633. static const uint32_t kParamCount = 12;
  634. static const uint32_t kProgramCount = 10;
  635. FxChorusPlugin(const HostDescriptor* const host)
  636. : PluginDescriptorClass(host),
  637. efxoutl(new float[synth->buffersize]),
  638. efxoutr(new float[synth->buffersize]),
  639. fEffect(false, efxoutl, efxoutr)
  640. {
  641. }
  642. ~FxChorusPlugin()
  643. {
  644. if (efxoutl != nullptr)
  645. {
  646. delete[] efxoutl;
  647. efxoutl = nullptr;
  648. }
  649. if (efxoutr != nullptr)
  650. {
  651. delete[] efxoutr;
  652. efxoutr = nullptr;
  653. }
  654. }
  655. protected:
  656. // -------------------------------------------------------------------
  657. // Plugin parameter calls
  658. uint32_t getParameterCount() override
  659. {
  660. return kParamCount;
  661. }
  662. const Parameter* getParameterInfo(const uint32_t index) override
  663. {
  664. if (index >= kParamCount)
  665. return nullptr;
  666. static Parameter param;
  667. int hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  668. param.name = nullptr;
  669. param.unit = nullptr;
  670. param.ranges.def = 1.0f;
  671. param.ranges.min = 0.0f;
  672. param.ranges.max = 127.0f;
  673. param.ranges.step = 1.0f;
  674. param.ranges.stepSmall = 1.0f;
  675. param.ranges.stepLarge = 20.0f;
  676. param.scalePointCount = 0;
  677. param.scalePoints = nullptr;
  678. switch (index)
  679. {
  680. case 0:
  681. hints |= PARAMETER_IS_AUTOMABLE;
  682. param.name = "Volume";
  683. param.ranges.def = 64.0f;
  684. break;
  685. case 1:
  686. hints |= PARAMETER_IS_AUTOMABLE;
  687. param.name = "Panning";
  688. param.ranges.def = 64.0f;
  689. break;
  690. case 2:
  691. hints |= PARAMETER_IS_AUTOMABLE;
  692. param.name = "LFO Frequency";
  693. param.ranges.def = 50.0f;
  694. break;
  695. case 3:
  696. hints |= PARAMETER_IS_AUTOMABLE;
  697. param.name = "LFO Randomness";
  698. param.ranges.def = 0.0f;
  699. break;
  700. case 4:
  701. hints |= PARAMETER_IS_AUTOMABLE;
  702. param.name = "LFO Type";
  703. param.ranges.def = 0.0f;
  704. break;
  705. case 5:
  706. hints |= PARAMETER_IS_AUTOMABLE;
  707. param.name = "LFO Stereo";
  708. param.ranges.def = 90.0f;
  709. break;
  710. case 6:
  711. hints |= PARAMETER_IS_AUTOMABLE;
  712. param.name = "Depth";
  713. param.ranges.def = 40.0f;
  714. break;
  715. case 7:
  716. hints |= PARAMETER_IS_AUTOMABLE;
  717. param.name = "Delay";
  718. param.ranges.def = 85.0f;
  719. break;
  720. case 8:
  721. hints |= PARAMETER_IS_AUTOMABLE;
  722. param.name = "Feedback";
  723. param.ranges.def = 64.0f;
  724. break;
  725. case 9:
  726. hints |= PARAMETER_IS_AUTOMABLE;
  727. param.name = "Cross";
  728. param.ranges.def = 119.0f;
  729. break;
  730. case 10:
  731. hints |= PARAMETER_IS_AUTOMABLE;
  732. param.name = "Flange Mode";
  733. param.ranges.def = 0.0f;
  734. break;
  735. case 11:
  736. hints |= PARAMETER_IS_AUTOMABLE;
  737. param.name = "Subtract Output";
  738. param.ranges.def = 0.0f;
  739. param.ranges.max = 1.0f;
  740. break;
  741. }
  742. param.hints = static_cast<ParameterHints>(hints);
  743. return &param;
  744. }
  745. float getParameterValue(const uint32_t index) override
  746. {
  747. return fEffect.getpar(index);
  748. }
  749. // -------------------------------------------------------------------
  750. // Plugin midi-program calls
  751. uint32_t getMidiProgramCount() override
  752. {
  753. return kProgramCount;
  754. }
  755. const MidiProgram* getMidiProgramInfo(const uint32_t index) override
  756. {
  757. if (index >= kProgramCount)
  758. return nullptr;
  759. static MidiProgram midiProg;
  760. midiProg.bank = 0;
  761. midiProg.program = index;
  762. midiProg.name = nullptr;
  763. switch (index)
  764. {
  765. case 0:
  766. midiProg.name = "Chorus1";
  767. break;
  768. case 1:
  769. midiProg.name = "Chorus2";
  770. break;
  771. case 2:
  772. midiProg.name = "Chorus3";
  773. break;
  774. case 3:
  775. midiProg.name = "Celeste1";
  776. break;
  777. case 4:
  778. midiProg.name = "Celeste2";
  779. break;
  780. case 5:
  781. midiProg.name = "Flange1";
  782. break;
  783. case 6:
  784. midiProg.name = "Flange2";
  785. break;
  786. case 7:
  787. midiProg.name = "Flange3";
  788. break;
  789. case 8:
  790. midiProg.name = "Flange4";
  791. break;
  792. case 9:
  793. midiProg.name = "Flange5";
  794. break;
  795. }
  796. return &midiProg;
  797. }
  798. // -------------------------------------------------------------------
  799. // Plugin state calls
  800. void setParameterValue(const uint32_t index, const float value) override
  801. {
  802. fEffect.changepar(index, value);
  803. }
  804. void setMidiProgram(const uint8_t, const uint32_t, const uint32_t program) override
  805. {
  806. fEffect.setpreset(program);
  807. }
  808. // -------------------------------------------------------------------
  809. // Plugin process calls
  810. void activate() override
  811. {
  812. fEffect.cleanup();
  813. }
  814. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  815. {
  816. CARLA_ASSERT(synth->buffersize == static_cast<int>(frames));
  817. fEffect.out(Stereo<float*>(inBuffer[0], inBuffer[1]));
  818. for (uint32_t i=0; i<frames; ++i)
  819. {
  820. outBuffer[0][i] = inBuffer[0][i]/2.0f + efxoutl[i]/2.0f;
  821. outBuffer[1][i] = inBuffer[1][i]/2.0f + efxoutr[i]/2.0f;
  822. }
  823. }
  824. private:
  825. float* efxoutl;
  826. float* efxoutr;
  827. Chorus fEffect;
  828. ZynPluginDescriptorClassEND(FxChorusPlugin)
  829. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FxChorusPlugin)
  830. };
  831. // -----------------------------------------------------------------------
  832. class FxReverbPlugin : public PluginDescriptorClass
  833. {
  834. public:
  835. static const uint32_t kParamCount = 13;
  836. static const uint32_t kProgramCount = 13;
  837. FxReverbPlugin(const HostDescriptor* const host)
  838. : PluginDescriptorClass(host),
  839. efxoutl(new float[synth->buffersize]),
  840. efxoutr(new float[synth->buffersize]),
  841. fEffect(false, efxoutl, efxoutr)
  842. {
  843. }
  844. ~FxReverbPlugin()
  845. {
  846. if (efxoutl != nullptr)
  847. {
  848. delete[] efxoutl;
  849. efxoutl = nullptr;
  850. }
  851. if (efxoutr != nullptr)
  852. {
  853. delete[] efxoutr;
  854. efxoutr = nullptr;
  855. }
  856. }
  857. protected:
  858. // -------------------------------------------------------------------
  859. // Plugin parameter calls
  860. uint32_t getParameterCount() override
  861. {
  862. return kParamCount;
  863. }
  864. const Parameter* getParameterInfo(const uint32_t index) override
  865. {
  866. if (index >= kParamCount)
  867. return nullptr;
  868. static Parameter param;
  869. int hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  870. param.name = nullptr;
  871. param.unit = nullptr;
  872. param.ranges.def = 1.0f;
  873. param.ranges.min = 0.0f;
  874. param.ranges.max = 127.0f;
  875. param.ranges.step = 1.0f;
  876. param.ranges.stepSmall = 1.0f;
  877. param.ranges.stepLarge = 20.0f;
  878. param.scalePointCount = 0;
  879. param.scalePoints = nullptr;
  880. switch (index)
  881. {
  882. case 0:
  883. hints |= PARAMETER_IS_AUTOMABLE;
  884. param.name = "Volume";
  885. param.ranges.def = 80.0f;
  886. break;
  887. case 1:
  888. hints |= PARAMETER_IS_AUTOMABLE;
  889. param.name = "Panning";
  890. param.ranges.def = 64.0f;
  891. break;
  892. case 2:
  893. hints |= PARAMETER_IS_AUTOMABLE;
  894. param.name = "Time";
  895. param.ranges.def = 63.0f;
  896. break;
  897. case 3:
  898. param.name = "Delay";
  899. param.ranges.def = 24.0f;
  900. break;
  901. case 4:
  902. hints |= PARAMETER_IS_AUTOMABLE;
  903. param.name = "Feedback";
  904. param.ranges.def = 0.0f;
  905. break;
  906. case 5:
  907. hints = 0x0;
  908. param.name = "unused1";
  909. break;
  910. case 6:
  911. hints = 0x0;
  912. param.name = "unused2";
  913. break;
  914. case 7:
  915. param.name = "Low-Pass Filter";
  916. param.ranges.def = 85.0f;
  917. break;
  918. case 8:
  919. param.name = "High-Pass Filter";
  920. param.ranges.def = 5.0f;
  921. break;
  922. case 9:
  923. hints |= PARAMETER_IS_AUTOMABLE;
  924. param.name = "Damp";
  925. param.ranges.def = 83.0f;
  926. break;
  927. case 10:
  928. param.name = "Type";
  929. param.ranges.def = 1.0f;
  930. param.ranges.max = 2.0f;
  931. break;
  932. case 11:
  933. param.name = "Room size";
  934. param.ranges.def = 64.0f;
  935. break;
  936. case 12:
  937. param.name = "Bandwidth";
  938. param.ranges.def = 20.0f;
  939. break;
  940. }
  941. param.hints = static_cast<ParameterHints>(hints);
  942. return &param;
  943. }
  944. float getParameterValue(const uint32_t index) override
  945. {
  946. return fEffect.getpar(index);
  947. }
  948. // -------------------------------------------------------------------
  949. // Plugin midi-program calls
  950. uint32_t getMidiProgramCount() override
  951. {
  952. return kProgramCount;
  953. }
  954. const MidiProgram* getMidiProgramInfo(const uint32_t index) override
  955. {
  956. if (index >= kProgramCount)
  957. return nullptr;
  958. static MidiProgram midiProg;
  959. midiProg.bank = 0;
  960. midiProg.program = index;
  961. midiProg.name = nullptr;
  962. switch (index)
  963. {
  964. case 0:
  965. midiProg.name = "Cathedral1";
  966. break;
  967. case 1:
  968. midiProg.name = "Cathedral2";
  969. break;
  970. case 2:
  971. midiProg.name = "Cathedral3";
  972. break;
  973. case 3:
  974. midiProg.name = "Hall1";
  975. break;
  976. case 4:
  977. midiProg.name = "Hall2";
  978. break;
  979. case 5:
  980. midiProg.name = "Room1";
  981. break;
  982. case 6:
  983. midiProg.name = "Room2";
  984. break;
  985. case 7:
  986. midiProg.name = "Basement";
  987. break;
  988. case 8:
  989. midiProg.name = "Tunnel";
  990. break;
  991. case 9:
  992. midiProg.name = "Echoed1";
  993. break;
  994. case 10:
  995. midiProg.name = "Echoed2";
  996. break;
  997. case 11:
  998. midiProg.name = "VeryLong1";
  999. break;
  1000. case 12:
  1001. midiProg.name = "VeryLong2";
  1002. break;
  1003. }
  1004. return &midiProg;
  1005. }
  1006. // -------------------------------------------------------------------
  1007. // Plugin state calls
  1008. void setParameterValue(const uint32_t index, const float value) override
  1009. {
  1010. fEffect.changepar(index, value);
  1011. }
  1012. void setMidiProgram(const uint8_t, const uint32_t, const uint32_t program) override
  1013. {
  1014. fEffect.setpreset(program);
  1015. }
  1016. // -------------------------------------------------------------------
  1017. // Plugin process calls
  1018. void activate() override
  1019. {
  1020. fEffect.cleanup();
  1021. }
  1022. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const MidiEvent* const) override
  1023. {
  1024. CARLA_ASSERT(synth->buffersize == static_cast<int>(frames));
  1025. fEffect.out(Stereo<float*>(inBuffer[0], inBuffer[1]));
  1026. for (uint32_t i=0; i<frames; ++i)
  1027. {
  1028. outBuffer[0][i] = inBuffer[0][i]/2.0f + efxoutl[i]/2.0f;
  1029. outBuffer[1][i] = inBuffer[1][i]/2.0f + efxoutr[i]/2.0f;
  1030. }
  1031. }
  1032. private:
  1033. float* efxoutl;
  1034. float* efxoutr;
  1035. Reverb fEffect;
  1036. ZynPluginDescriptorClassEND(FxReverbPlugin)
  1037. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FxReverbPlugin)
  1038. };
  1039. // -----------------------------------------------------------------------
  1040. class ZynAddSubFxPlugin : public PluginDescriptorClass
  1041. {
  1042. public:
  1043. enum Parameters {
  1044. PARAMETER_COUNT = 0
  1045. };
  1046. ZynAddSubFxPlugin(const HostDescriptor* const host)
  1047. : PluginDescriptorClass(host),
  1048. fMaster(new Master()),
  1049. fSampleRate(getSampleRate()),
  1050. fIsActive(false),
  1051. fThread(fMaster, host)
  1052. {
  1053. fThread.start();
  1054. for (int i = 0; i < NUM_MIDI_PARTS; ++i)
  1055. fMaster->partonoff(i, 1);
  1056. sPrograms.init();
  1057. }
  1058. ~ZynAddSubFxPlugin() override
  1059. {
  1060. //ensure that everything has stopped
  1061. pthread_mutex_lock(&fMaster->mutex);
  1062. pthread_mutex_unlock(&fMaster->mutex);
  1063. fThread.stop();
  1064. fThread.wait();
  1065. delete fMaster;
  1066. fMaster = nullptr;
  1067. }
  1068. protected:
  1069. // -------------------------------------------------------------------
  1070. // Plugin parameter calls
  1071. uint32_t getParameterCount() override
  1072. {
  1073. return PARAMETER_COUNT;
  1074. }
  1075. const Parameter* getParameterInfo(const uint32_t index) override
  1076. {
  1077. CARLA_ASSERT(index < getParameterCount());
  1078. //if (index >= PARAMETER_COUNT)
  1079. return nullptr;
  1080. static Parameter param;
  1081. param.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  1082. param.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  1083. param.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  1084. param.scalePointCount = 0;
  1085. param.scalePoints = nullptr;
  1086. switch (index)
  1087. {
  1088. #if 0
  1089. case PARAMETER_MASTER:
  1090. param.hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  1091. param.name = "Master Volume";
  1092. param.unit = nullptr;
  1093. param.ranges.min = 0.0f;
  1094. param.ranges.max = 100.0f;
  1095. param.ranges.def = 100.0f;
  1096. break;
  1097. #endif
  1098. }
  1099. return &param;
  1100. }
  1101. float getParameterValue(const uint32_t index) override
  1102. {
  1103. CARLA_ASSERT(index < getParameterCount());
  1104. switch (index)
  1105. {
  1106. #if 0
  1107. case PARAMETER_MASTER:
  1108. return fMaster->Pvolume;
  1109. #endif
  1110. default:
  1111. return 0.0f;
  1112. }
  1113. }
  1114. // -------------------------------------------------------------------
  1115. // Plugin midi-program calls
  1116. uint32_t getMidiProgramCount() override
  1117. {
  1118. return sPrograms.count();
  1119. }
  1120. const MidiProgram* getMidiProgramInfo(const uint32_t index) override
  1121. {
  1122. return sPrograms.getInfo(index);
  1123. }
  1124. // -------------------------------------------------------------------
  1125. // Plugin state calls
  1126. void setParameterValue(const uint32_t index, const float value) override
  1127. {
  1128. CARLA_ASSERT(index < getParameterCount());
  1129. switch (index)
  1130. {
  1131. }
  1132. return;
  1133. // unused, TODO
  1134. (void)value;
  1135. }
  1136. void setMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override
  1137. {
  1138. if (bank >= fMaster->bank.banks.size())
  1139. return;
  1140. if (program >= BANK_SIZE)
  1141. return;
  1142. if (isOffline() || ! fIsActive)
  1143. {
  1144. sPrograms.load(fMaster, channel, bank, program);
  1145. #ifdef WANT_ZYNADDSUBFX_UI
  1146. fThread.uiRepaint();
  1147. #endif
  1148. }
  1149. else
  1150. fThread.loadProgramLater(channel, bank, program);
  1151. }
  1152. void setCustomData(const char* const key, const char* const value) override
  1153. {
  1154. CARLA_ASSERT(key != nullptr);
  1155. CARLA_ASSERT(value != nullptr);
  1156. if (std::strcmp(key, "CarlaAlternateFile1") == 0) // xmz
  1157. fMaster->loadXML(value);
  1158. else if (std::strcmp(key, "CarlaAlternateFile2") == 0) // xiz
  1159. fMaster->part[0]->loadXMLinstrument(value);
  1160. }
  1161. // -------------------------------------------------------------------
  1162. // Plugin process calls
  1163. void activate() override
  1164. {
  1165. fIsActive = true;
  1166. }
  1167. void deactivate() override
  1168. {
  1169. fIsActive = false;
  1170. }
  1171. void process(float**, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) override
  1172. {
  1173. if (pthread_mutex_trylock(&fMaster->mutex) != 0)
  1174. {
  1175. carla_zeroFloat(outBuffer[0], frames);
  1176. carla_zeroFloat(outBuffer[1], frames);
  1177. return;
  1178. }
  1179. for (uint32_t i=0; i < midiEventCount; ++i)
  1180. {
  1181. const MidiEvent* const midiEvent(&midiEvents[i]);
  1182. const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent->data);
  1183. const uint8_t channel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent->data);
  1184. if (MIDI_IS_STATUS_NOTE_OFF(status))
  1185. {
  1186. const uint8_t note = midiEvent->data[1];
  1187. fMaster->noteOff(channel, note);
  1188. }
  1189. else if (MIDI_IS_STATUS_NOTE_ON(status))
  1190. {
  1191. const uint8_t note = midiEvent->data[1];
  1192. const uint8_t velo = midiEvent->data[2];
  1193. fMaster->noteOn(channel, note, velo);
  1194. }
  1195. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
  1196. {
  1197. const uint8_t note = midiEvent->data[1];
  1198. const uint8_t pressure = midiEvent->data[2];
  1199. fMaster->polyphonicAftertouch(channel, note, pressure);
  1200. }
  1201. else if (MIDI_IS_STATUS_CONTROL_CHANGE(status))
  1202. {
  1203. const uint8_t control = midiEvent->data[1];
  1204. const uint8_t value = midiEvent->data[2];
  1205. fMaster->setController(channel, control, value);
  1206. }
  1207. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
  1208. {
  1209. const uint8_t lsb = midiEvent->data[1];
  1210. const uint8_t msb = midiEvent->data[2];
  1211. const int value = ((msb << 7) | lsb) - 8192;
  1212. fMaster->setController(channel, C_pitchwheel, value);
  1213. }
  1214. }
  1215. fMaster->GetAudioOutSamples(frames, fSampleRate, outBuffer[0], outBuffer[1]);
  1216. pthread_mutex_unlock(&fMaster->mutex);
  1217. }
  1218. #ifdef WANT_ZYNADDSUBFX_UI
  1219. // -------------------------------------------------------------------
  1220. // Plugin UI calls
  1221. void uiShow(const bool show) override
  1222. {
  1223. if (show)
  1224. fThread.uiShow();
  1225. else
  1226. fThread.uiHide();
  1227. }
  1228. #endif
  1229. // -------------------------------------------------------------------
  1230. // Plugin state calls
  1231. char* getState() override
  1232. {
  1233. config.save();
  1234. char* data = nullptr;
  1235. fMaster->getalldata(&data);
  1236. return data;
  1237. }
  1238. void setState(const char* const data) override
  1239. {
  1240. fThread.stopLoadProgramLater();
  1241. fMaster->putalldata((char*)data, 0);
  1242. fMaster->applyparameters(true);
  1243. }
  1244. // -------------------------------------------------------------------
  1245. // Plugin dispatcher
  1246. intptr_t pluginDispatcher(const PluginDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr) override
  1247. {
  1248. switch (opcode)
  1249. {
  1250. case PLUGIN_OPCODE_NULL:
  1251. break;
  1252. case PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
  1253. // TODO
  1254. break;
  1255. case PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
  1256. // TODO
  1257. break;
  1258. case PLUGIN_OPCODE_OFFLINE_CHANGED:
  1259. break;
  1260. case PLUGIN_OPCODE_UI_NAME_CHANGED:
  1261. #ifdef WANT_ZYNADDSUBFX_UI
  1262. // TODO
  1263. #endif
  1264. break;
  1265. }
  1266. return 0;
  1267. // unused
  1268. (void)index;
  1269. (void)value;
  1270. (void)ptr;
  1271. }
  1272. // -------------------------------------------------------------------
  1273. private:
  1274. Master* fMaster;
  1275. unsigned fSampleRate;
  1276. bool fIsActive;
  1277. ZynAddSubFxThread fThread;
  1278. ZynPluginDescriptorClassEND(ZynAddSubFxPlugin)
  1279. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ZynAddSubFxPlugin)
  1280. };
  1281. // -----------------------------------------------------------------------
  1282. static const PluginDescriptor fxAlienWahDesc = {
  1283. /* category */ PLUGIN_CATEGORY_MODULATOR,
  1284. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1285. /* audioIns */ 2,
  1286. /* audioOuts */ 2,
  1287. /* midiIns */ 0,
  1288. /* midiOuts */ 0,
  1289. /* paramIns */ FxAlienWahPlugin::kParamCount,
  1290. /* paramOuts */ 0,
  1291. /* name */ "ZynAlienWah",
  1292. /* label */ "zynAlienWah",
  1293. /* maker */ "falkTX",
  1294. /* copyright */ "GNU GPL v2+",
  1295. PluginDescriptorFILL(FxAlienWahPlugin)
  1296. };
  1297. static const PluginDescriptor fxChorusDesc = {
  1298. /* category */ PLUGIN_CATEGORY_MODULATOR,
  1299. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1300. /* audioIns */ 2,
  1301. /* audioOuts */ 2,
  1302. /* midiIns */ 0,
  1303. /* midiOuts */ 0,
  1304. /* paramIns */ FxChorusPlugin::kParamCount,
  1305. /* paramOuts */ 0,
  1306. /* name */ "ZynChorus",
  1307. /* label */ "zynChorus",
  1308. /* maker */ "falkTX",
  1309. /* copyright */ "GNU GPL v2+",
  1310. PluginDescriptorFILL(FxChorusPlugin)
  1311. };
  1312. #if 0
  1313. static const PluginDescriptor fxDistortionDesc = {
  1314. /* category */ PLUGIN_CATEGORY_MODULATOR,
  1315. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1316. /* audioIns */ 2,
  1317. /* audioOuts */ 2,
  1318. /* midiIns */ 0,
  1319. /* midiOuts */ 0,
  1320. /* paramIns */ FxDistortionPlugin::kParamCount,
  1321. /* paramOuts */ 0,
  1322. /* name */ "ZynDistortion",
  1323. /* label */ "zynDistortion",
  1324. /* maker */ "falkTX",
  1325. /* copyright */ "GNU GPL v2+",
  1326. PluginDescriptorFILL(FxDistortionPlugin)
  1327. };
  1328. static const PluginDescriptor fxDynamicFilterDesc = {
  1329. /* category */ PLUGIN_CATEGORY_FILTER,
  1330. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1331. /* audioIns */ 2,
  1332. /* audioOuts */ 2,
  1333. /* midiIns */ 0,
  1334. /* midiOuts */ 0,
  1335. /* paramIns */ FxDynamicFilterPlugin::kParamCount,
  1336. /* paramOuts */ 0,
  1337. /* name */ "ZynDynamicFilter",
  1338. /* label */ "zynDynamicFilter",
  1339. /* maker */ "falkTX",
  1340. /* copyright */ "GNU GPL v2+",
  1341. PluginDescriptorFILL(FxDynamicFilterPlugin)
  1342. };
  1343. static const PluginDescriptor fxEchoDesc = {
  1344. /* category */ PLUGIN_CATEGORY_DELAY,
  1345. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1346. /* audioIns */ 2,
  1347. /* audioOuts */ 2,
  1348. /* midiIns */ 0,
  1349. /* midiOuts */ 0,
  1350. /* paramIns */ FxEchoPlugin::kParamCount,
  1351. /* paramOuts */ 0,
  1352. /* name */ "ZynEcho",
  1353. /* label */ "zynEcho",
  1354. /* maker */ "falkTX",
  1355. /* copyright */ "GNU GPL v2+",
  1356. PluginDescriptorFILL(FxEchoPlugin)
  1357. };
  1358. static const PluginDescriptor fxEqDesc = {
  1359. /* category */ PLUGIN_CATEGORY_EQ,
  1360. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1361. /* audioIns */ 2,
  1362. /* audioOuts */ 2,
  1363. /* midiIns */ 0,
  1364. /* midiOuts */ 0,
  1365. /* paramIns */ FxEqPlugin::kParamCount,
  1366. /* paramOuts */ 0,
  1367. /* name */ "ZynEq",
  1368. /* label */ "zynEq",
  1369. /* maker */ "falkTX",
  1370. /* copyright */ "GNU GPL v2+",
  1371. PluginDescriptorFILL(FxEqPlugin)
  1372. };
  1373. static const PluginDescriptor fxPhaserDesc = {
  1374. /* category */ PLUGIN_CATEGORY_MODULATOR,
  1375. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1376. /* audioIns */ 2,
  1377. /* audioOuts */ 2,
  1378. /* midiIns */ 0,
  1379. /* midiOuts */ 0,
  1380. /* paramIns */ FxPhaserPlugin::kParamCount,
  1381. /* paramOuts */ 0,
  1382. /* name */ "ZynPhaser",
  1383. /* label */ "zynPhaser",
  1384. /* maker */ "falkTX",
  1385. /* copyright */ "GNU GPL v2+",
  1386. PluginDescriptorFILL(FxPhaserPlugin)
  1387. };
  1388. #endif
  1389. static const PluginDescriptor fxReverbDesc = {
  1390. /* category */ PLUGIN_CATEGORY_DELAY,
  1391. /* hints */ static_cast<PluginHints>(PLUGIN_USES_STATIC_BUFFERS),
  1392. /* audioIns */ 2,
  1393. /* audioOuts */ 2,
  1394. /* midiIns */ 0,
  1395. /* midiOuts */ 0,
  1396. /* paramIns */ FxReverbPlugin::kParamCount,
  1397. /* paramOuts */ 0,
  1398. /* name */ "ZynReverb",
  1399. /* label */ "zynReverb",
  1400. /* maker */ "falkTX",
  1401. /* copyright */ "GNU GPL v2+",
  1402. PluginDescriptorFILL(FxReverbPlugin)
  1403. };
  1404. static const PluginDescriptor zynaddsubfxDesc = {
  1405. /* category */ PLUGIN_CATEGORY_SYNTH,
  1406. #ifdef WANT_ZYNADDSUBFX_UI
  1407. /* hints */ static_cast<PluginHints>(PLUGIN_IS_SYNTH|PLUGIN_HAS_GUI|PLUGIN_USES_STATE),
  1408. #else
  1409. /* hints */ static_cast<PluginHints>(PLUGIN_IS_SYNTH|PLUGIN_USES_STATE),
  1410. #endif
  1411. /* audioIns */ 0,
  1412. /* audioOuts */ 2,
  1413. /* midiIns */ 1,
  1414. /* midiOuts */ 0,
  1415. /* paramIns */ ZynAddSubFxPlugin::PARAMETER_COUNT,
  1416. /* paramOuts */ 0,
  1417. /* name */ "ZynAddSubFX",
  1418. /* label */ "zynaddsubfx",
  1419. /* maker */ "falkTX",
  1420. /* copyright */ "GNU GPL v2+",
  1421. PluginDescriptorFILL(ZynAddSubFxPlugin)
  1422. };
  1423. // -----------------------------------------------------------------------
  1424. void carla_register_native_plugin_zynaddsubfx()
  1425. {
  1426. carla_register_native_plugin(&fxAlienWahDesc);
  1427. carla_register_native_plugin(&fxChorusDesc);
  1428. #if 0
  1429. carla_register_native_plugin(&fxDistortionDesc);
  1430. carla_register_native_plugin(&fxDynamicFilterDesc);
  1431. carla_register_native_plugin(&fxEchoDesc);
  1432. carla_register_native_plugin(&fxEqDesc);
  1433. carla_register_native_plugin(&fxPhaserDesc);
  1434. #endif
  1435. carla_register_native_plugin(&fxReverbDesc);
  1436. carla_register_native_plugin(&zynaddsubfxDesc);
  1437. }
  1438. // -----------------------------------------------------------------------