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