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.

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