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.

444 lines
11KB

  1. /*
  2. * Carla Native Plugin API
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * 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 COPYING file
  16. */
  17. #ifndef CARLA_NATIVE_MM_H
  18. #define CARLA_NATIVE_MM_H
  19. #include "carla_native.h"
  20. #include "carla_includes.h"
  21. class PluginDescriptorClass {
  22. public:
  23. PluginDescriptorClass(const PluginDescriptorClass* master)
  24. {
  25. if (master)
  26. {
  27. desc.category = master->desc.category;
  28. desc.hints = master->desc.hints;
  29. desc.name = master->desc.name;
  30. desc.label = master->desc.label;
  31. desc.maker = master->desc.maker;
  32. desc.copyright = master->desc.copyright;
  33. desc.portCount = master->desc.portCount;
  34. desc.ports = master->desc.ports;
  35. desc.midiProgramCount = master->desc.midiProgramCount;
  36. desc.midiPrograms = master->desc.midiPrograms;
  37. host = master->host;
  38. }
  39. else
  40. {
  41. desc.category = PLUGIN_CATEGORY_NONE;
  42. desc.hints = 0;
  43. desc.name = nullptr;
  44. desc.label = nullptr;
  45. desc.maker = nullptr;
  46. desc.copyright = nullptr;
  47. desc.portCount = 0;
  48. desc.ports = nullptr;
  49. desc.midiProgramCount = 0;
  50. desc.midiPrograms = nullptr;
  51. host = nullptr;
  52. }
  53. _initDescriptor();
  54. }
  55. virtual ~PluginDescriptorClass()
  56. {
  57. }
  58. uint32_t getBufferSize() const
  59. {
  60. CARLA_ASSERT(host);
  61. if (host)
  62. return host->get_buffer_size(host->handle);
  63. return 0;
  64. }
  65. double getSampleRate() const
  66. {
  67. CARLA_ASSERT(host);
  68. if (host)
  69. return host->get_sample_rate(host->handle);
  70. return 0.0;
  71. }
  72. const TimeInfo* getTimeInfo() const
  73. {
  74. CARLA_ASSERT(host);
  75. if (host)
  76. return host->get_time_info(host->handle);
  77. return nullptr;
  78. }
  79. void writeMidiEvent(MidiEvent* event)
  80. {
  81. CARLA_ASSERT(host);
  82. if (host)
  83. host->write_midi_event(host->handle, event);
  84. }
  85. // -------------------------------------------------------------------
  86. PluginDescriptor* descriptorInit()
  87. {
  88. desc.category = getCategory();
  89. desc.hints = getHints();
  90. desc.name = getName();
  91. desc.label = getLabel();
  92. desc.maker = getMaker();
  93. desc.copyright = getCopyright();
  94. return &desc;
  95. }
  96. // -------------------------------------------------------------------
  97. protected:
  98. virtual PluginDescriptorClass* createMe() = 0;
  99. virtual void deleteMe() = 0;
  100. virtual PluginCategory getCategory()
  101. {
  102. return PLUGIN_CATEGORY_NONE;
  103. }
  104. virtual uint32_t getHints()
  105. {
  106. return 0;
  107. }
  108. virtual const char* getName()
  109. {
  110. return nullptr;
  111. }
  112. virtual const char* getLabel()
  113. {
  114. return nullptr;
  115. }
  116. virtual const char* getMaker()
  117. {
  118. return nullptr;
  119. }
  120. virtual const char* getCopyright()
  121. {
  122. return nullptr;
  123. }
  124. // -------------------------------------------------------------------
  125. virtual uint32_t getPortCount()
  126. {
  127. return 0;
  128. }
  129. virtual PortType getPortType(uint32_t index)
  130. {
  131. CARLA_ASSERT(index < getPortCount());
  132. return PORT_TYPE_NULL;
  133. }
  134. virtual uint32_t getPortHints(uint32_t index)
  135. {
  136. CARLA_ASSERT(index < getPortCount());
  137. return 0;
  138. }
  139. virtual const char* getPortName(uint32_t index)
  140. {
  141. CARLA_ASSERT(index < getPortCount());
  142. return nullptr;
  143. }
  144. virtual void getParameterRanges(uint32_t index, ParameterRanges* ranges)
  145. {
  146. CARLA_ASSERT(index < getPortCount());
  147. CARLA_ASSERT(ranges);
  148. }
  149. virtual double getParameterValue(uint32_t index)
  150. {
  151. CARLA_ASSERT(index < getPortCount());
  152. return 0.0;
  153. }
  154. virtual const char* getParameterText(uint32_t index)
  155. {
  156. CARLA_ASSERT(index < getPortCount());
  157. return nullptr;
  158. }
  159. virtual const char* getParameterUnit(uint32_t index)
  160. {
  161. CARLA_ASSERT(index < getPortCount());
  162. return nullptr;
  163. }
  164. // -------------------------------------------------------------------
  165. virtual uint32_t getMidiProgramCount()
  166. {
  167. return 0;
  168. }
  169. virtual void getMidiProgram(uint32_t index, MidiProgram* midiProgram)
  170. {
  171. CARLA_ASSERT(index < getMidiProgramCount());
  172. CARLA_ASSERT(midiProgram);
  173. }
  174. // -------------------------------------------------------------------
  175. virtual void setParameterValue(uint32_t index, double value)
  176. {
  177. CARLA_ASSERT(index < getPortCount());
  178. Q_UNUSED(value);
  179. }
  180. virtual void setMidiProgram(uint32_t bank, uint32_t program)
  181. {
  182. CARLA_ASSERT(program < 128);
  183. Q_UNUSED(bank);
  184. }
  185. virtual void setCustomData(const char* key, const char* value)
  186. {
  187. CARLA_ASSERT(key);
  188. CARLA_ASSERT(value);
  189. }
  190. // -------------------------------------------------------------------
  191. virtual void activate()
  192. {
  193. }
  194. virtual void deactivate()
  195. {
  196. }
  197. // -------------------------------------------------------------------
  198. virtual void showGui(bool show)
  199. {
  200. Q_UNUSED(show);
  201. }
  202. virtual void idleGui()
  203. {
  204. }
  205. // -------------------------------------------------------------------
  206. virtual void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
  207. {
  208. CARLA_ASSERT(inBuffer);
  209. CARLA_ASSERT(outBuffer);
  210. CARLA_ASSERT(midiEvents);
  211. Q_UNUSED(frames);
  212. Q_UNUSED(midiEventCount);
  213. }
  214. // -------------------------------------------------------------------
  215. private:
  216. PluginDescriptor desc;
  217. const HostDescriptor* host;
  218. void _initDescriptor()
  219. {
  220. desc.instantiate = _instantiate;
  221. desc.activate = _activate;
  222. desc.deactivate = _deactivate;
  223. desc.cleanup = _cleanup;
  224. desc.get_parameter_ranges = _get_parameter_ranges;
  225. desc.get_parameter_value = _get_parameter_value;
  226. desc.get_parameter_text = _get_parameter_text;
  227. desc.get_parameter_unit = _get_parameter_unit;
  228. desc.set_parameter_value = _set_parameter_value;
  229. desc.set_midi_program = _set_midi_program;
  230. desc.set_custom_data = _set_custom_data;
  231. desc.show_gui = _show_gui;
  232. desc.idle_gui = _idle_gui;
  233. desc.process = _process;
  234. desc._singleton = this;
  235. desc._init = _init;
  236. desc._fini = _fini;
  237. }
  238. static PluginHandle _instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host)
  239. {
  240. PluginDescriptorClass* singleton = (PluginDescriptorClass*)_this_->_singleton;
  241. singleton->host = host;
  242. return singleton->createMe();
  243. }
  244. static void _activate(PluginHandle handle)
  245. {
  246. ((PluginDescriptorClass*)handle)->activate();
  247. }
  248. static void _deactivate(PluginHandle handle)
  249. {
  250. ((PluginDescriptorClass*)handle)->deactivate();
  251. }
  252. static void _cleanup(PluginHandle handle)
  253. {
  254. ((PluginDescriptorClass*)handle)->deleteMe();
  255. }
  256. static void _get_parameter_ranges(PluginHandle handle, uint32_t index, ParameterRanges* ranges)
  257. {
  258. ((PluginDescriptorClass*)handle)->getParameterRanges(index, ranges);
  259. }
  260. static double _get_parameter_value(PluginHandle handle, uint32_t index)
  261. {
  262. return ((PluginDescriptorClass*)handle)->getParameterValue(index);
  263. }
  264. static const char* _get_parameter_text(PluginHandle handle, uint32_t index)
  265. {
  266. return ((PluginDescriptorClass*)handle)->getParameterText(index);
  267. }
  268. static const char* _get_parameter_unit(PluginHandle handle, uint32_t index)
  269. {
  270. return ((PluginDescriptorClass*)handle)->getParameterUnit(index);
  271. }
  272. static void _set_parameter_value(PluginHandle handle, uint32_t index, double value)
  273. {
  274. return ((PluginDescriptorClass*)handle)->setParameterValue(index, value);
  275. }
  276. static void _set_midi_program(PluginHandle handle, uint32_t bank, uint32_t program)
  277. {
  278. return ((PluginDescriptorClass*)handle)->setMidiProgram(bank, program);
  279. }
  280. static void _set_custom_data(PluginHandle handle, const char* key, const char* value)
  281. {
  282. return ((PluginDescriptorClass*)handle)->setCustomData(key, value);
  283. }
  284. static void _show_gui(PluginHandle handle, bool show)
  285. {
  286. return ((PluginDescriptorClass*)handle)->showGui(show);
  287. }
  288. static void _idle_gui(PluginHandle handle)
  289. {
  290. return ((PluginDescriptorClass*)handle)->idleGui();
  291. }
  292. static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
  293. {
  294. return ((PluginDescriptorClass*)handle)->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents);
  295. }
  296. static void _init(PluginDescriptor* const _this_)
  297. {
  298. ((PluginDescriptorClass*)_this_->_singleton)->_handleInit();
  299. }
  300. static void _fini(PluginDescriptor* const _this_)
  301. {
  302. ((PluginDescriptorClass*)_this_->_singleton)->_handleFini();
  303. }
  304. void _handleInit()
  305. {
  306. desc.portCount = getPortCount();
  307. if (desc.portCount > 0)
  308. {
  309. desc.ports = new PluginPort [desc.portCount];
  310. for (uint32_t i=0; i < desc.portCount; i++)
  311. {
  312. PluginPort* const port = &desc.ports[i];
  313. port->type = getPortType(i);
  314. port->hints = getPortHints(i);
  315. port->name = getPortName(i);
  316. }
  317. }
  318. desc.midiProgramCount = getMidiProgramCount();
  319. if (desc.midiProgramCount > 0)
  320. {
  321. desc.midiPrograms = new MidiProgram [desc.midiProgramCount];
  322. for (uint32_t i=0; i < desc.midiProgramCount; i++)
  323. getMidiProgram(i, &desc.midiPrograms[i]);
  324. }
  325. }
  326. void _handleFini()
  327. {
  328. if (desc.midiProgramCount > 0 && desc.midiPrograms)
  329. delete[] desc.midiPrograms;
  330. desc.midiProgramCount = 0;
  331. desc.midiPrograms = nullptr;
  332. if (desc.portCount > 0 && desc.ports)
  333. delete[] desc.ports;
  334. desc.portCount = 0;
  335. desc.ports = nullptr;
  336. }
  337. };
  338. // -----------------------------------------------------------------------
  339. #define CARLA_REGISTER_NATIVE_PLUGIN_MM(label, descMM) \
  340. void carla_register_native_plugin_##label () __attribute__((constructor)); \
  341. void carla_register_native_plugin_##label () { carla_register_native_plugin(descMM.descriptorInit()); }
  342. #endif // CARLA_NATIVE_MM_H