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