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.

CarlaNative.hpp 16KB

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