Collection of tools useful for audio production
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.

436 lines
11KB

  1. /*
  2. * DISTHRO Plugin Toolkit (DPT)
  3. * Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 license see the GPL.txt file
  16. */
  17. #include "carla_native.hpp"
  18. #include <QtGui/QDialog>
  19. #include "DistrhoPluginMain.cpp"
  20. #if DISTRHO_PLUGIN_HAS_UI
  21. # include "DistrhoUIMain.cpp"
  22. #endif
  23. #ifdef QTCREATOR_TEST
  24. # define DISTRHO_PLUGIN_HAS_UI 1
  25. # define DISTRHO_PLUGIN_IS_SYNTH 1
  26. # define DISTRHO_PLUGIN_WANT_PROGRAMS 1
  27. # define DISTRHO_PLUGIN_WANT_STATE 1
  28. #endif
  29. // -------------------------------------------------
  30. START_NAMESPACE_DISTRHO
  31. #if DISTRHO_PLUGIN_HAS_UI
  32. // -----------------------------------------------------------------------
  33. // Carla UI
  34. class UICarla : public QDialog
  35. {
  36. public:
  37. UICarla(const HostDescriptor* const host, PluginInternal* const plugin)
  38. : QDialog(nullptr),
  39. m_host(host),
  40. m_plugin(plugin),
  41. ui(this, winId(), setParameterCallback, setStateCallback, uiEditParameterCallback, uiSendNoteCallback, uiResizeCallback)
  42. {
  43. setFixedSize(ui.getWidth(), ui.getHeight());
  44. setWindowTitle("TEST GUI");
  45. }
  46. ~UICarla()
  47. {
  48. }
  49. // ---------------------------------------------
  50. void carla_show(const bool yesNo)
  51. {
  52. setVisible(yesNo);
  53. }
  54. void carla_idle()
  55. {
  56. ui.idle();
  57. }
  58. void carla_setParameterValue(const uint32_t index, const float value)
  59. {
  60. ui.parameterChanged(index, value);
  61. }
  62. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  63. void carla_setMidiProgram(const uint32_t realProgram)
  64. {
  65. ui.programChanged(realProgram);
  66. }
  67. # endif
  68. # if DISTRHO_PLUGIN_WANT_STATE
  69. void carla_setCustomData(const char* const key, const char* const value)
  70. {
  71. ui.stateChanged(key, value);
  72. }
  73. # endif
  74. // ---------------------------------------------
  75. protected:
  76. void setParameterValue(uint32_t index, float value)
  77. {
  78. m_host->ui_parameter_changed(m_host->handle, index, value);
  79. }
  80. # if DISTRHO_PLUGIN_WANT_STATE
  81. void setState(const char* key, const char* value)
  82. {
  83. m_host->ui_custom_data_changed(m_host->handle, key, value);
  84. }
  85. # endif
  86. void uiEditParameter(uint32_t, bool)
  87. {
  88. // TODO
  89. }
  90. # if DISTRHO_PLUGIN_IS_SYNTH
  91. void uiSendNote(bool, uint8_t, uint8_t, uint8_t)
  92. {
  93. // TODO
  94. }
  95. # endif
  96. void uiResize(unsigned int width, unsigned int height)
  97. {
  98. setFixedSize(width, height);
  99. }
  100. private:
  101. // Plugin stuff
  102. const HostDescriptor* const m_host;
  103. PluginInternal* const m_plugin;
  104. // UI
  105. UIInternal ui;
  106. // ---------------------------------------------
  107. // Callbacks
  108. static void setParameterCallback(void* ptr, uint32_t rindex, float value)
  109. {
  110. UICarla* _this_ = (UICarla*)ptr;
  111. CARLA_ASSERT(_this_);
  112. _this_->setParameterValue(rindex, value);
  113. }
  114. static void setStateCallback(void* ptr, const char* key, const char* value)
  115. {
  116. # if DISTRHO_PLUGIN_WANT_STATE
  117. UICarla* _this_ = (UICarla*)ptr;
  118. CARLA_ASSERT(_this_);
  119. _this_->setState(key, value);
  120. # else
  121. Q_UNUSED(ptr);
  122. Q_UNUSED(key);
  123. Q_UNUSED(value);
  124. # endif
  125. }
  126. static void uiEditParameterCallback(void* ptr, uint32_t index, bool started)
  127. {
  128. UICarla* _this_ = (UICarla*)ptr;
  129. CARLA_ASSERT(_this_);
  130. _this_->uiEditParameter(index, started);
  131. }
  132. static void uiSendNoteCallback(void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velocity)
  133. {
  134. # if DISTRHO_PLUGIN_IS_SYNTH
  135. UICarla* _this_ = (UICarla*)ptr;
  136. CARLA_ASSERT(_this_);
  137. _this_->uiSendNote(onOff, channel, note, velocity);
  138. # else
  139. Q_UNUSED(ptr);
  140. Q_UNUSED(onOff);
  141. Q_UNUSED(channel);
  142. Q_UNUSED(note);
  143. Q_UNUSED(velocity);
  144. # endif
  145. }
  146. static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
  147. {
  148. UICarla* _this_ = (UICarla*)ptr;
  149. CARLA_ASSERT(_this_);
  150. _this_->uiResize(width, height);
  151. }
  152. };
  153. #endif
  154. // -----------------------------------------------------------------------
  155. // Carla Plugin
  156. class PluginCarla : public PluginDescriptorClass
  157. {
  158. public:
  159. PluginCarla(const HostDescriptor* const host)
  160. : PluginDescriptorClass(host)
  161. {
  162. #if DISTRHO_PLUGIN_HAS_UI
  163. uiPtr = nullptr;
  164. #endif
  165. }
  166. ~PluginCarla()
  167. {
  168. #if DISTRHO_PLUGIN_HAS_UI
  169. if (uiPtr)
  170. delete uiPtr;
  171. #endif
  172. }
  173. protected:
  174. // -------------------------------------------------------------------
  175. // Plugin parameter calls
  176. uint32_t getParameterCount()
  177. {
  178. return plugin.parameterCount();
  179. }
  180. const ::Parameter* getParameterInfo(const uint32_t index)
  181. {
  182. static ::Parameter param;
  183. // reset
  184. param.hints = ::PARAMETER_IS_ENABLED;
  185. {
  186. const uint32_t paramHints = plugin.parameterHints(index);
  187. if (paramHints & PARAMETER_IS_AUTOMABLE)
  188. param.hints |= ::PARAMETER_IS_AUTOMABLE;
  189. if (paramHints & PARAMETER_IS_BOOLEAN)
  190. param.hints |= ::PARAMETER_IS_BOOLEAN;
  191. if (paramHints & PARAMETER_IS_INTEGER)
  192. param.hints |= ::PARAMETER_IS_INTEGER;
  193. if (paramHints & PARAMETER_IS_LOGARITHMIC)
  194. param.hints |= ::PARAMETER_IS_LOGARITHMIC;
  195. if (paramHints & PARAMETER_IS_OUTPUT)
  196. param.hints |= ::PARAMETER_IS_OUTPUT;
  197. }
  198. param.name = plugin.parameterName(index);
  199. param.unit = plugin.parameterUnit(index);
  200. {
  201. const ParameterRanges* const ranges(plugin.parameterRanges(index));
  202. param.ranges.def = ranges->def;
  203. param.ranges.min = ranges->min;
  204. param.ranges.max = ranges->max;
  205. param.ranges.step = ranges->step;
  206. param.ranges.stepSmall = ranges->stepSmall;
  207. param.ranges.stepLarge = ranges->stepLarge;
  208. }
  209. param.scalePointCount = 0;
  210. param.scalePoints = nullptr;
  211. return &param;
  212. }
  213. float getParameterValue(const uint32_t index)
  214. {
  215. return plugin.parameterValue(index);
  216. }
  217. // -------------------------------------------------------------------
  218. // Plugin midi-program calls
  219. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  220. virtual uint32_t getMidiProgramCount()
  221. {
  222. return plugin.programCount();
  223. }
  224. virtual const ::MidiProgram* getMidiProgramInfo(const uint32_t index)
  225. {
  226. static ::MidiProgram midiProgram;
  227. midiProgram.bank = index / 128;
  228. midiProgram.program = index % 128;
  229. midiProgram.name = plugin.programName(index);
  230. return &midiProgram;
  231. }
  232. #endif
  233. // -------------------------------------------------------------------
  234. // Plugin state calls
  235. void setParameterValue(const uint32_t index, const float value)
  236. {
  237. plugin.setParameterValue(index, value);
  238. }
  239. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  240. void setMidiProgram(const uint32_t bank, const uint32_t program)
  241. {
  242. const uint32_t realProgram = bank * 128 + program;
  243. if (realProgram >= plugin.programCount())
  244. return;
  245. plugin.setProgram(realProgram);
  246. }
  247. #endif
  248. #if DISTRHO_PLUGIN_WANT_STATE
  249. void setCustomData(const char* const key, const char* const value)
  250. {
  251. plugin.setState(key, value);
  252. }
  253. #endif
  254. // -------------------------------------------------------------------
  255. // Plugin UI calls
  256. #if DISTRHO_PLUGIN_HAS_UI
  257. void uiShow(const bool show)
  258. {
  259. if (show)
  260. createUiIfNeeded();
  261. if (uiPtr)
  262. uiPtr->carla_show(show);
  263. }
  264. void uiIdle()
  265. {
  266. if (uiPtr)
  267. uiPtr->carla_idle();
  268. }
  269. void uiSetParameterValue(const uint32_t index, const float value)
  270. {
  271. if (uiPtr)
  272. uiPtr->carla_setParameterValue(index, value);
  273. }
  274. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  275. void uiSetMidiProgram(const uint32_t bank, const uint32_t program)
  276. {
  277. uint32_t realProgram = bank * 128 + program;
  278. if (uiPtr)
  279. uiPtr->carla_setMidiProgram(realProgram);
  280. }
  281. # endif
  282. # if DISTRHO_PLUGIN_WANT_STATE
  283. void uiSetCustomData(const char* const key, const char* const value)
  284. {
  285. if (uiPtr)
  286. uiPtr->carla_setCustomData(key, value);
  287. }
  288. # endif
  289. #endif
  290. // -------------------------------------------------------------------
  291. // Plugin process calls
  292. void activate()
  293. {
  294. plugin.activate();
  295. }
  296. void deactivate()
  297. {
  298. plugin.deactivate();
  299. }
  300. #if DISTRHO_PLUGIN_IS_SYNTH
  301. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const ::MidiEvent* const midiEvents)
  302. {
  303. for (uint32_t i=0; i < midiEventCount && i < MAX_MIDI_EVENTS; i++)
  304. {
  305. const ::MidiEvent* midiEvent = &midiEvents[i];
  306. MidiEvent* realEvent = &realMidiEvents[i];
  307. realEvent->buffer[0] = midiEvent->data[0];
  308. realEvent->buffer[1] = midiEvent->data[1];
  309. realEvent->buffer[2] = midiEvent->data[2];
  310. realEvent->frame = midiEvent->time;
  311. }
  312. plugin.run(inBuffer, outBuffer, frames, midiEventCount, realMidiEvents);
  313. }
  314. #else
  315. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const ::MidiEvent* const)
  316. {
  317. plugin.run(inBuffer, outBuffer, frames, 0, nullptr);
  318. }
  319. #endif
  320. // -------------------------------------------------------------------
  321. private:
  322. PluginInternal plugin;
  323. #if DISTRHO_PLUGIN_IS_SYNTH
  324. MidiEvent realMidiEvents[MAX_MIDI_EVENTS];
  325. #endif
  326. #if DISTRHO_PLUGIN_HAS_UI
  327. // UI
  328. UICarla* uiPtr;
  329. void createUiIfNeeded()
  330. {
  331. if (! uiPtr)
  332. {
  333. setLastUiSampleRate(getSampleRate());
  334. uiPtr = new UICarla(getHostHandle(), &plugin);
  335. }
  336. }
  337. #endif
  338. // -------------------------------------------------------------------
  339. public:
  340. static PluginHandle _instantiate(const PluginDescriptor*, HostDescriptor* host)
  341. {
  342. d_lastBufferSize = host->get_buffer_size(host->handle);
  343. d_lastSampleRate = host->get_sample_rate(host->handle);
  344. return new PluginCarla(host);
  345. }
  346. static void _cleanup(PluginHandle handle)
  347. {
  348. delete (PluginCarla*)handle;
  349. }
  350. };
  351. END_NAMESPACE_DISTRHO
  352. // -----------------------------------------------------------------------