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.

522 lines
13KB

  1. /*
  2. * Carla Native Plugin API (C++)
  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 doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_NATIVE_HPP_INCLUDED
  18. #define CARLA_NATIVE_HPP_INCLUDED
  19. #include "CarlaNative.h"
  20. #include "CarlaMIDI.h"
  21. #include "CarlaJuceUtils.hpp"
  22. /*!
  23. * @defgroup CarlaNativeAPI Carla Native API
  24. * @{
  25. */
  26. // -----------------------------------------------------------------------
  27. // Plugin Descriptor Class
  28. class PluginDescriptorClass
  29. {
  30. public:
  31. PluginDescriptorClass(const HostDescriptor* const host)
  32. : pHost(host)
  33. {
  34. CARLA_ASSERT(host != nullptr);
  35. }
  36. virtual ~PluginDescriptorClass()
  37. {
  38. }
  39. protected:
  40. // -------------------------------------------------------------------
  41. // Host calls
  42. const HostDescriptor* getHostHandle() const noexcept
  43. {
  44. return pHost;
  45. }
  46. const char* getResourceDir() const noexcept
  47. {
  48. CARLA_ASSERT(pHost != nullptr);
  49. if (pHost != nullptr)
  50. return pHost->resourceDir;
  51. return nullptr;
  52. }
  53. const char* getUiName() const noexcept
  54. {
  55. CARLA_ASSERT(pHost != nullptr);
  56. if (pHost != nullptr)
  57. return pHost->uiName;
  58. return nullptr;
  59. }
  60. uint32_t getBufferSize() const
  61. {
  62. CARLA_ASSERT(pHost != nullptr);
  63. if (pHost != nullptr)
  64. return pHost->get_buffer_size(pHost->handle);
  65. return 0;
  66. }
  67. double getSampleRate() const
  68. {
  69. CARLA_ASSERT(pHost != nullptr);
  70. if (pHost != nullptr)
  71. return pHost->get_sample_rate(pHost->handle);
  72. return 0.0;
  73. }
  74. bool isOffline() const
  75. {
  76. CARLA_ASSERT(pHost != nullptr);
  77. if (pHost != nullptr)
  78. return pHost->is_offline(pHost->handle);
  79. return false;
  80. }
  81. const TimeInfo* getTimeInfo() const
  82. {
  83. CARLA_ASSERT(pHost != nullptr);
  84. if (pHost != nullptr)
  85. return pHost->get_time_info(pHost->handle);
  86. return nullptr;
  87. }
  88. void writeMidiEvent(const MidiEvent* const event) const
  89. {
  90. CARLA_ASSERT(pHost != nullptr);
  91. if (pHost != nullptr)
  92. pHost->write_midi_event(pHost->handle, event);
  93. }
  94. void uiParameterChanged(const uint32_t index, const float value) const
  95. {
  96. CARLA_ASSERT(pHost != nullptr);
  97. if (pHost != nullptr)
  98. pHost->ui_parameter_changed(pHost->handle, index, value);
  99. }
  100. void uiMidiProgramChanged(const uint8_t channel, const uint32_t bank, const uint32_t program) const
  101. {
  102. CARLA_ASSERT(pHost != nullptr);
  103. if (pHost != nullptr)
  104. pHost->ui_midi_program_changed(pHost->handle, channel, bank, program);
  105. }
  106. void uiCustomDataChanged(const char* const key, const char* const value) const
  107. {
  108. CARLA_ASSERT(pHost != nullptr);
  109. if (pHost != nullptr)
  110. pHost->ui_custom_data_changed(pHost->handle, key, value);
  111. }
  112. void uiClosed() const
  113. {
  114. CARLA_ASSERT(pHost != nullptr);
  115. if (pHost != nullptr)
  116. pHost->ui_closed(pHost->handle);
  117. }
  118. const char* uiOpenFile(const bool isDir, const char* const title, const char* const filter) const
  119. {
  120. CARLA_ASSERT(pHost != nullptr);
  121. if (pHost != nullptr)
  122. return pHost->ui_open_file(pHost->handle, isDir, title, filter);
  123. return nullptr;
  124. }
  125. const char* uiSaveFile(const bool isDir, const char* const title, const char* const filter) const
  126. {
  127. CARLA_ASSERT(pHost != nullptr);
  128. if (pHost != nullptr)
  129. return pHost->ui_save_file(pHost->handle, isDir, title, filter);
  130. return nullptr;
  131. }
  132. intptr_t hostDispatcher(const HostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) const
  133. {
  134. CARLA_ASSERT(pHost != nullptr);
  135. if (pHost != nullptr)
  136. return pHost->dispatcher(pHost->handle, opcode, index, value, ptr, opt);
  137. return 0;
  138. }
  139. // -------------------------------------------------------------------
  140. // Plugin parameter calls
  141. virtual uint32_t getParameterCount()
  142. {
  143. return 0;
  144. }
  145. virtual const Parameter* getParameterInfo(const uint32_t index)
  146. {
  147. CARLA_ASSERT(index < getParameterCount());
  148. return nullptr;
  149. // unused
  150. (void)index;
  151. }
  152. virtual float getParameterValue(const uint32_t index)
  153. {
  154. CARLA_ASSERT(index < getParameterCount());
  155. return 0.0f;
  156. // unused
  157. (void)index;
  158. }
  159. virtual const char* getParameterText(const uint32_t index, const float value)
  160. {
  161. CARLA_ASSERT(index < getParameterCount());
  162. return nullptr;
  163. // unused
  164. (void)index;
  165. (void)value;
  166. }
  167. // -------------------------------------------------------------------
  168. // Plugin midi-program calls
  169. virtual uint32_t getMidiProgramCount()
  170. {
  171. return 0;
  172. }
  173. virtual const MidiProgram* getMidiProgramInfo(const uint32_t index)
  174. {
  175. CARLA_ASSERT(index < getMidiProgramCount());
  176. return nullptr;
  177. // unused
  178. (void)index;
  179. }
  180. // -------------------------------------------------------------------
  181. // Plugin state calls
  182. virtual void setParameterValue(const uint32_t index, const float value)
  183. {
  184. CARLA_ASSERT(index < getParameterCount());
  185. return;
  186. // unused
  187. (void)index;
  188. (void)value;
  189. }
  190. virtual void setMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program)
  191. {
  192. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  193. return;
  194. // unused
  195. (void)channel;
  196. (void)bank;
  197. (void)program;
  198. }
  199. virtual void setCustomData(const char* const key, const char* const value)
  200. {
  201. CARLA_ASSERT(key != nullptr);
  202. CARLA_ASSERT(value != nullptr);
  203. return;
  204. // unused
  205. (void)key;
  206. (void)value;
  207. }
  208. // -------------------------------------------------------------------
  209. // Plugin process calls
  210. virtual void activate()
  211. {
  212. }
  213. virtual void deactivate()
  214. {
  215. }
  216. virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) = 0;
  217. // -------------------------------------------------------------------
  218. // Plugin UI calls
  219. virtual void uiShow(const bool show)
  220. {
  221. return;
  222. // unused
  223. (void)show;
  224. }
  225. virtual void uiIdle()
  226. {
  227. }
  228. virtual void uiSetParameterValue(const uint32_t index, const float value)
  229. {
  230. CARLA_ASSERT(index < getParameterCount());
  231. return;
  232. // unused
  233. (void)index;
  234. (void)value;
  235. }
  236. virtual void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program)
  237. {
  238. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  239. return;
  240. // unused
  241. (void)channel;
  242. (void)bank;
  243. (void)program;
  244. }
  245. virtual void uiSetCustomData(const char* const key, const char* const value)
  246. {
  247. CARLA_ASSERT(key != nullptr);
  248. CARLA_ASSERT(value != nullptr);
  249. return;
  250. // unused
  251. (void)key;
  252. (void)value;
  253. }
  254. // -------------------------------------------------------------------
  255. // Plugin state calls
  256. virtual char* getState()
  257. {
  258. return nullptr;
  259. }
  260. virtual void setState(const char* const data)
  261. {
  262. CARLA_ASSERT(data != nullptr);
  263. return;
  264. // unused
  265. (void)data;
  266. }
  267. // -------------------------------------------------------------------
  268. // Plugin dispatcher
  269. virtual intptr_t pluginDispatcher(const PluginDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  270. {
  271. return 0;
  272. // unused
  273. (void)opcode;
  274. (void)index;
  275. (void)value;
  276. (void)ptr;
  277. (void)opt;
  278. }
  279. // -------------------------------------------------------------------
  280. private:
  281. const HostDescriptor* const pHost;
  282. // -------------------------------------------------------------------
  283. #ifndef DOXYGEN
  284. public:
  285. #define handlePtr ((PluginDescriptorClass*)handle)
  286. static uint32_t _get_parameter_count(PluginHandle handle)
  287. {
  288. return handlePtr->getParameterCount();
  289. }
  290. static const Parameter* _get_parameter_info(PluginHandle handle, uint32_t index)
  291. {
  292. return handlePtr->getParameterInfo(index);
  293. }
  294. static float _get_parameter_value(PluginHandle handle, uint32_t index)
  295. {
  296. return handlePtr->getParameterValue(index);
  297. }
  298. static const char* _get_parameter_text(PluginHandle handle, uint32_t index, float value)
  299. {
  300. return handlePtr->getParameterText(index, value);
  301. }
  302. static uint32_t _get_midi_program_count(PluginHandle handle)
  303. {
  304. return handlePtr->getMidiProgramCount();
  305. }
  306. static const MidiProgram* _get_midi_program_info(PluginHandle handle, uint32_t index)
  307. {
  308. return handlePtr->getMidiProgramInfo(index);
  309. }
  310. static void _set_parameter_value(PluginHandle handle, uint32_t index, float value)
  311. {
  312. return handlePtr->setParameterValue(index, value);
  313. }
  314. static void _set_midi_program(PluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program)
  315. {
  316. return handlePtr->setMidiProgram(channel, bank, program);
  317. }
  318. static void _set_custom_data(PluginHandle handle, const char* key, const char* value)
  319. {
  320. return handlePtr->setCustomData(key, value);
  321. }
  322. static void _ui_show(PluginHandle handle, bool show)
  323. {
  324. return handlePtr->uiShow(show);
  325. }
  326. static void _ui_idle(PluginHandle handle)
  327. {
  328. return handlePtr->uiIdle();
  329. }
  330. static void _ui_set_parameter_value(PluginHandle handle, uint32_t index, float value)
  331. {
  332. return handlePtr->uiSetParameterValue(index, value);
  333. }
  334. static void _ui_set_midi_program(PluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program)
  335. {
  336. return handlePtr->uiSetMidiProgram(channel, bank, program);
  337. }
  338. static void _ui_set_custom_data(PluginHandle handle, const char* key, const char* value)
  339. {
  340. return handlePtr->uiSetCustomData(key, value);
  341. }
  342. static void _activate(PluginHandle handle)
  343. {
  344. handlePtr->activate();
  345. }
  346. static void _deactivate(PluginHandle handle)
  347. {
  348. handlePtr->deactivate();
  349. }
  350. static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents)
  351. {
  352. return handlePtr->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents);
  353. }
  354. static char* _get_state(PluginHandle handle)
  355. {
  356. return handlePtr->getState();
  357. }
  358. static void _set_state(PluginHandle handle, const char* data)
  359. {
  360. handlePtr->setState(data);
  361. }
  362. static intptr_t _dispatcher(PluginHandle handle, PluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
  363. {
  364. return handlePtr->pluginDispatcher(opcode, index, value, ptr, opt);
  365. }
  366. #undef handlePtr
  367. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginDescriptorClass)
  368. #endif
  369. };
  370. /**@}*/
  371. // -----------------------------------------------------------------------
  372. #define PluginDescriptorClassEND(ClassName) \
  373. public: \
  374. static PluginHandle _instantiate(HostDescriptor* host) \
  375. { \
  376. return new ClassName(host); \
  377. } \
  378. static void _cleanup(PluginHandle handle) \
  379. { \
  380. delete (ClassName*)handle; \
  381. }
  382. #define PluginDescriptorFILL(ClassName) \
  383. ClassName::_instantiate, \
  384. ClassName::_cleanup, \
  385. ClassName::_get_parameter_count, \
  386. ClassName::_get_parameter_info, \
  387. ClassName::_get_parameter_value, \
  388. ClassName::_get_parameter_text, \
  389. ClassName::_get_midi_program_count, \
  390. ClassName::_get_midi_program_info, \
  391. ClassName::_set_parameter_value, \
  392. ClassName::_set_midi_program, \
  393. ClassName::_set_custom_data, \
  394. ClassName::_ui_show, \
  395. ClassName::_ui_idle, \
  396. ClassName::_ui_set_parameter_value, \
  397. ClassName::_ui_set_midi_program, \
  398. ClassName::_ui_set_custom_data, \
  399. ClassName::_activate, \
  400. ClassName::_deactivate, \
  401. ClassName::_process, \
  402. ClassName::_get_state, \
  403. ClassName::_set_state, \
  404. ClassName::_dispatcher
  405. #endif // CARLA_NATIVE_HPP_INCLUDED