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 17KB

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