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.

DistrhoPluginCarla.cpp 12KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /*
  2. * DISTRHO Plugin Toolkit (DPT)
  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 Lesser General Public
  7. * License as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * For a full copy of the license see the LGPL.txt file
  15. */
  16. #include "CarlaNative.hpp"
  17. #include "CarlaString.hpp"
  18. #include "DistrhoPluginMain.cpp"
  19. #if DISTRHO_PLUGIN_HAS_UI
  20. # include "DistrhoUIMain.cpp"
  21. #endif
  22. // -----------------------------------------------------------------------
  23. START_NAMESPACE_DISTRHO
  24. #if DISTRHO_PLUGIN_HAS_UI
  25. // -----------------------------------------------------------------------
  26. // Carla UI
  27. #if ! DISTRHO_PLUGIN_WANT_STATE
  28. static const setStateFunc setStateCallback = nullptr;
  29. #endif
  30. #if ! DISTRHO_PLUGIN_IS_SYNTH
  31. static const sendNoteFunc sendNoteCallback = nullptr;
  32. #endif
  33. class UICarla
  34. {
  35. public:
  36. UICarla(const NativeHostDescriptor* const host, PluginExporter* const plugin)
  37. : fHost(host),
  38. fPlugin(plugin),
  39. fUI(this, 0, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback)
  40. {
  41. fUI.setTitle(host->uiName);
  42. }
  43. // ---------------------------------------------
  44. void carla_show(const bool yesNo)
  45. {
  46. fUI.setVisible(yesNo);
  47. }
  48. void carla_idle()
  49. {
  50. fUI.idle();
  51. }
  52. void carla_setParameterValue(const uint32_t index, const float value)
  53. {
  54. fUI.parameterChanged(index, value);
  55. }
  56. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  57. void carla_setMidiProgram(const uint32_t realProgram)
  58. {
  59. fUI.programChanged(realProgram);
  60. }
  61. #endif
  62. #if DISTRHO_PLUGIN_WANT_STATE
  63. void carla_setCustomData(const char* const key, const char* const value)
  64. {
  65. fUI.stateChanged(key, value);
  66. }
  67. #endif
  68. void carla_setUiTitle(const char* const uiTitle)
  69. {
  70. fUI.setTitle(uiTitle);
  71. }
  72. // ---------------------------------------------
  73. protected:
  74. void handleEditParameter(const uint32_t, const bool)
  75. {
  76. // TODO
  77. }
  78. void handleSetParameterValue(const uint32_t rindex, const float value)
  79. {
  80. fHost->ui_parameter_changed(fHost->handle, rindex, value);
  81. }
  82. void handleSetState(const char* const key, const char* const value)
  83. {
  84. fHost->ui_custom_data_changed(fHost->handle, key, value);
  85. }
  86. void handleSendNote(const uint8_t, const uint8_t, const uint8_t)
  87. {
  88. // TODO
  89. }
  90. void handleUiResize(const unsigned int width, const unsigned int height)
  91. {
  92. fUI.setSize(width, height);
  93. }
  94. // ---------------------------------------------
  95. private:
  96. // Plugin stuff
  97. const NativeHostDescriptor* const fHost;
  98. PluginExporter* const fPlugin;
  99. // UI
  100. UIExporter fUI;
  101. // ---------------------------------------------
  102. // Callbacks
  103. #define handlePtr ((UICarla*)ptr)
  104. static void editParameterCallback(void* ptr, uint32_t index, bool started)
  105. {
  106. handlePtr->handleEditParameter(index, started);
  107. }
  108. static void setParameterCallback(void* ptr, uint32_t rindex, float value)
  109. {
  110. handlePtr->handleSetParameterValue(rindex, value);
  111. }
  112. #if DISTRHO_PLUGIN_WANT_STATE
  113. static void setStateCallback(void* ptr, const char* key, const char* value)
  114. {
  115. handlePtr->handleSetState(key, value);
  116. }
  117. #endif
  118. #if DISTRHO_PLUGIN_IS_SYNTH
  119. static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity)
  120. {
  121. handlePtr->handleSendNote(channel, note, velocity);
  122. }
  123. #endif
  124. static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
  125. {
  126. handlePtr->handleUiResize(width, height);
  127. }
  128. #undef handlePtr
  129. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UICarla)
  130. };
  131. #endif // DISTRHO_PLUGIN_HAS_UI
  132. // -----------------------------------------------------------------------
  133. // Carla Plugin
  134. class PluginCarla : public NativePluginClass
  135. {
  136. public:
  137. PluginCarla(const NativeHostDescriptor* const host)
  138. : NativePluginClass(host)
  139. {
  140. #if DISTRHO_PLUGIN_HAS_UI
  141. fUiPtr = nullptr;
  142. #endif
  143. }
  144. ~PluginCarla() override
  145. {
  146. #if DISTRHO_PLUGIN_HAS_UI
  147. if (fUiPtr != nullptr)
  148. {
  149. delete fUiPtr;
  150. fUiPtr = nullptr;
  151. }
  152. #endif
  153. }
  154. protected:
  155. // -------------------------------------------------------------------
  156. // Plugin parameter calls
  157. uint32_t getParameterCount() const override
  158. {
  159. return fPlugin.getParameterCount();
  160. }
  161. const NativeParameter* getParameterInfo(const uint32_t index) const override
  162. {
  163. CARLA_ASSERT(index < getParameterCount());
  164. static NativeParameter param;
  165. // reset
  166. param.hints = ::PARAMETER_IS_ENABLED;
  167. param.scalePointCount = 0;
  168. param.scalePoints = nullptr;
  169. {
  170. int nativeParamHints = ::PARAMETER_IS_ENABLED;
  171. const uint32_t paramHints = fPlugin.getParameterHints(index);
  172. if (paramHints & PARAMETER_IS_AUTOMABLE)
  173. nativeParamHints |= ::PARAMETER_IS_AUTOMABLE;
  174. if (paramHints & PARAMETER_IS_BOOLEAN)
  175. nativeParamHints |= ::PARAMETER_IS_BOOLEAN;
  176. if (paramHints & PARAMETER_IS_INTEGER)
  177. nativeParamHints |= ::PARAMETER_IS_INTEGER;
  178. if (paramHints & PARAMETER_IS_LOGARITHMIC)
  179. nativeParamHints |= ::PARAMETER_IS_LOGARITHMIC;
  180. if (paramHints & PARAMETER_IS_OUTPUT)
  181. nativeParamHints |= ::PARAMETER_IS_OUTPUT;
  182. param.hints = static_cast<NativeParameterHints>(nativeParamHints);
  183. }
  184. param.name = fPlugin.getParameterName(index);
  185. param.unit = fPlugin.getParameterUnit(index);
  186. {
  187. const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
  188. param.ranges.def = ranges.def;
  189. param.ranges.min = ranges.min;
  190. param.ranges.max = ranges.max;
  191. //param.ranges.step = ranges.step;
  192. //param.ranges.stepSmall = ranges.stepSmall;
  193. //param.ranges.stepLarge = ranges.stepLarge;
  194. }
  195. return &param;
  196. }
  197. float getParameterValue(const uint32_t index) const override
  198. {
  199. CARLA_ASSERT(index < getParameterCount());
  200. return fPlugin.getParameterValue(index);
  201. }
  202. // -------------------------------------------------------------------
  203. // Plugin midi-program calls
  204. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  205. uint32_t getMidiProgramCount() const override
  206. {
  207. return fPlugin.getProgramCount();
  208. }
  209. const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const override
  210. {
  211. CARLA_ASSERT(index < getMidiProgramCount());
  212. if (index >= fPlugin.getProgramCount())
  213. return nullptr;
  214. static NativeMidiProgram midiProgram;
  215. midiProgram.bank = index / 128;
  216. midiProgram.program = index % 128;
  217. midiProgram.name = fPlugin.getProgramName(index);
  218. return &midiProgram;
  219. }
  220. #endif
  221. // -------------------------------------------------------------------
  222. // Plugin state calls
  223. void setParameterValue(const uint32_t index, const float value) override
  224. {
  225. CARLA_ASSERT(index < getParameterCount());
  226. fPlugin.setParameterValue(index, value);
  227. }
  228. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  229. void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override
  230. {
  231. const uint32_t realProgram(bank * 128 + program);
  232. if (realProgram >= fPlugin.getProgramCount())
  233. return;
  234. fPlugin.setProgram(realProgram);
  235. }
  236. #endif
  237. #if DISTRHO_PLUGIN_WANT_STATE
  238. void setCustomData(const char* const key, const char* const value) override
  239. {
  240. CARLA_ASSERT(key != nullptr);
  241. CARLA_ASSERT(value != nullptr);
  242. fPlugin.setState(key, value);
  243. }
  244. #endif
  245. // -------------------------------------------------------------------
  246. // Plugin process calls
  247. void activate() override
  248. {
  249. fPlugin.activate();
  250. }
  251. void deactivate() override
  252. {
  253. fPlugin.deactivate();
  254. }
  255. #if DISTRHO_PLUGIN_IS_SYNTH
  256. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
  257. {
  258. uint32_t i;
  259. for (i=0; i < midiEventCount && i < kMaxMidiEvents; ++i)
  260. {
  261. const NativeMidiEvent* const midiEvent(&midiEvents[i]);
  262. MidiEvent* const realMidiEvent(&fRealMidiEvents[i]);
  263. realMidiEvent->frame = midiEvent->time;
  264. realMidiEvent->size = midiEvent->size;
  265. for (uint8_t j=0; j < midiEvent->size; ++j)
  266. realMidiEvent->buf[j] = midiEvent->data[j];
  267. }
  268. fPlugin.run(inBuffer, outBuffer, frames, fRealMidiEvents, i);
  269. }
  270. #else
  271. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override
  272. {
  273. fPlugin.run(inBuffer, outBuffer, frames);
  274. }
  275. #endif
  276. // -------------------------------------------------------------------
  277. // Plugin UI calls
  278. #if DISTRHO_PLUGIN_HAS_UI
  279. void uiShow(const bool show) override
  280. {
  281. if (show)
  282. createUiIfNeeded();
  283. if (fUiPtr != nullptr)
  284. fUiPtr->carla_show(show);
  285. }
  286. void uiIdle() override
  287. {
  288. CARLA_ASSERT(fUiPtr != nullptr);
  289. if (fUiPtr != nullptr)
  290. fUiPtr->carla_idle();
  291. }
  292. void uiSetParameterValue(const uint32_t index, const float value) override
  293. {
  294. CARLA_ASSERT(fUiPtr != nullptr);
  295. CARLA_ASSERT(index < getParameterCount());
  296. if (fUiPtr != nullptr)
  297. fUiPtr->carla_setParameterValue(index, value);
  298. }
  299. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  300. void uiSetMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override
  301. {
  302. CARLA_ASSERT(fUiPtr != nullptr);
  303. const uint32_t realProgram(bank * 128 + program);
  304. if (realProgram >= fPlugin.getProgramCount())
  305. return;
  306. if (fUiPtr != nullptr)
  307. fUiPtr->carla_setMidiProgram(realProgram);
  308. }
  309. # endif
  310. # if DISTRHO_PLUGIN_WANT_STATE
  311. void uiSetCustomData(const char* const key, const char* const value) override
  312. {
  313. CARLA_ASSERT(fUiPtr != nullptr);
  314. CARLA_ASSERT(key != nullptr);
  315. CARLA_ASSERT(value != nullptr);
  316. if (fUiPtr != nullptr)
  317. fUiPtr->carla_setCustomData(key, value);
  318. }
  319. # endif
  320. #endif
  321. // -------------------------------------------------------------------
  322. // Plugin dispatcher calls
  323. void bufferSizeChanged(const uint32_t bufferSize) override
  324. {
  325. fPlugin.setBufferSize(bufferSize, true);
  326. }
  327. void sampleRateChanged(const double sampleRate) override
  328. {
  329. fPlugin.setSampleRate(sampleRate, true);
  330. }
  331. #if DISTRHO_PLUGIN_HAS_UI
  332. void uiNameChanged(const char* const uiName) override
  333. {
  334. if (fUiPtr != nullptr)
  335. fUiPtr->carla_setUiTitle(uiName);
  336. }
  337. #endif
  338. // -------------------------------------------------------------------
  339. private:
  340. PluginExporter fPlugin;
  341. #if DISTRHO_PLUGIN_IS_SYNTH
  342. MidiEvent fRealMidiEvents[kMaxMidiEvents];
  343. #endif
  344. #if DISTRHO_PLUGIN_HAS_UI
  345. // UI
  346. UICarla* fUiPtr;
  347. void createUiIfNeeded()
  348. {
  349. if (fUiPtr == nullptr)
  350. {
  351. d_lastUiSampleRate = getSampleRate();
  352. fUiPtr = new UICarla(getHostHandle(), &fPlugin);
  353. }
  354. }
  355. #endif
  356. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginCarla)
  357. // -------------------------------------------------------------------
  358. public:
  359. static NativePluginHandle _instantiate(const NativeHostDescriptor* host)
  360. {
  361. d_lastBufferSize = host->get_buffer_size(host->handle);
  362. d_lastSampleRate = host->get_sample_rate(host->handle);
  363. return new PluginCarla(host);
  364. }
  365. static void _cleanup(NativePluginHandle handle)
  366. {
  367. delete (PluginCarla*)handle;
  368. }
  369. };
  370. END_NAMESPACE_DISTRHO
  371. // -----------------------------------------------------------------------