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.

608 lines
17KB

  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. // Native Plugin Class
  28. class NativePluginClass
  29. {
  30. public:
  31. NativePluginClass(const NativeHostDescriptor* const host)
  32. : pHost(host)
  33. {
  34. CARLA_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
  47. {
  48. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);
  49. return pHost->resourceDir;
  50. }
  51. const char* getUiName() const
  52. {
  53. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);
  54. return pHost->uiName;
  55. }
  56. uint32_t getBufferSize() const
  57. {
  58. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, 0);
  59. return pHost->get_buffer_size(pHost->handle);
  60. }
  61. double getSampleRate() const
  62. {
  63. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, 0.0);
  64. return pHost->get_sample_rate(pHost->handle);
  65. }
  66. bool isOffline() const
  67. {
  68. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, false);
  69. return pHost->is_offline(pHost->handle);
  70. }
  71. const NativeTimeInfo* getTimeInfo() const
  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. // unused
  214. (void)value;
  215. }
  216. // -------------------------------------------------------------------
  217. // Plugin midi-program calls
  218. virtual uint32_t getMidiProgramCount() const
  219. {
  220. return 0;
  221. }
  222. virtual const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const
  223. {
  224. CARLA_SAFE_ASSERT_RETURN(index < getMidiProgramCount(), nullptr);
  225. return nullptr;
  226. }
  227. // -------------------------------------------------------------------
  228. // Plugin state calls
  229. virtual void setParameterValue(const uint32_t index, const float value)
  230. {
  231. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  232. return;
  233. // unused
  234. (void)value;
  235. }
  236. virtual void setMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program)
  237. {
  238. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  239. return;
  240. // unused
  241. (void)bank;
  242. (void)program;
  243. }
  244. virtual void setCustomData(const char* const key, const char* const value)
  245. {
  246. CARLA_SAFE_ASSERT_RETURN(key != nullptr,);
  247. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  248. }
  249. // -------------------------------------------------------------------
  250. // Plugin process calls
  251. virtual void activate()
  252. {
  253. }
  254. virtual void deactivate()
  255. {
  256. }
  257. virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) = 0;
  258. // -------------------------------------------------------------------
  259. // Plugin UI calls
  260. virtual void uiShow(const bool show)
  261. {
  262. return;
  263. // unused
  264. (void)show;
  265. }
  266. virtual void uiIdle()
  267. {
  268. }
  269. virtual void uiSetParameterValue(const uint32_t index, const float value)
  270. {
  271. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  272. return;
  273. // unused
  274. (void)value;
  275. }
  276. virtual void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program)
  277. {
  278. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  279. return;
  280. // unused
  281. (void)bank;
  282. (void)program;
  283. }
  284. virtual void uiSetCustomData(const char* const key, const char* const value)
  285. {
  286. CARLA_SAFE_ASSERT_RETURN(key != nullptr,);
  287. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  288. }
  289. // -------------------------------------------------------------------
  290. // Plugin state calls
  291. virtual char* getState() const
  292. {
  293. return nullptr;
  294. }
  295. virtual void setState(const char* const data)
  296. {
  297. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  298. }
  299. // -------------------------------------------------------------------
  300. // Plugin dispatcher calls
  301. virtual void bufferSizeChanged(const uint32_t bufferSize)
  302. {
  303. return;
  304. // unused
  305. (void)bufferSize;
  306. }
  307. virtual void sampleRateChanged(const double sampleRate)
  308. {
  309. CARLA_SAFE_ASSERT_RETURN(sampleRate > 0.0,);
  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. CARLA_SAFE_ASSERT_RETURN(uiName != nullptr,);
  320. }
  321. // -------------------------------------------------------------------
  322. private:
  323. const NativeHostDescriptor* const pHost;
  324. // -------------------------------------------------------------------
  325. #ifndef DOXYGEN
  326. public:
  327. #define handlePtr ((NativePluginClass*)handle)
  328. static uint32_t _get_parameter_count(NativePluginHandle handle)
  329. {
  330. return handlePtr->getParameterCount();
  331. }
  332. static const NativeParameter* _get_parameter_info(NativePluginHandle handle, uint32_t index)
  333. {
  334. return handlePtr->getParameterInfo(index);
  335. }
  336. static float _get_parameter_value(NativePluginHandle handle, uint32_t index)
  337. {
  338. return handlePtr->getParameterValue(index);
  339. }
  340. static const char* _get_parameter_text(NativePluginHandle handle, uint32_t index, float value)
  341. {
  342. return handlePtr->getParameterText(index, value);
  343. }
  344. static uint32_t _get_midi_program_count(NativePluginHandle handle)
  345. {
  346. return handlePtr->getMidiProgramCount();
  347. }
  348. static const NativeMidiProgram* _get_midi_program_info(NativePluginHandle handle, uint32_t index)
  349. {
  350. return handlePtr->getMidiProgramInfo(index);
  351. }
  352. static void _set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
  353. {
  354. handlePtr->setParameterValue(index, value);
  355. }
  356. static void _set_midi_program(NativePluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program)
  357. {
  358. handlePtr->setMidiProgram(channel, bank, program);
  359. }
  360. static void _set_custom_data(NativePluginHandle handle, const char* key, const char* value)
  361. {
  362. handlePtr->setCustomData(key, value);
  363. }
  364. static void _ui_show(NativePluginHandle handle, bool show)
  365. {
  366. handlePtr->uiShow(show);
  367. }
  368. static void _ui_idle(NativePluginHandle handle)
  369. {
  370. handlePtr->uiIdle();
  371. }
  372. static void _ui_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
  373. {
  374. handlePtr->uiSetParameterValue(index, value);
  375. }
  376. static void _ui_set_midi_program(NativePluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program)
  377. {
  378. handlePtr->uiSetMidiProgram(channel, bank, program);
  379. }
  380. static void _ui_set_custom_data(NativePluginHandle handle, const char* key, const char* value)
  381. {
  382. handlePtr->uiSetCustomData(key, value);
  383. }
  384. static void _activate(NativePluginHandle handle)
  385. {
  386. handlePtr->activate();
  387. }
  388. static void _deactivate(NativePluginHandle handle)
  389. {
  390. handlePtr->deactivate();
  391. }
  392. static void _process(NativePluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
  393. {
  394. handlePtr->process(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
  395. }
  396. static char* _get_state(NativePluginHandle handle)
  397. {
  398. return handlePtr->getState();
  399. }
  400. static void _set_state(NativePluginHandle handle, const char* data)
  401. {
  402. handlePtr->setState(data);
  403. }
  404. static intptr_t _dispatcher(NativePluginHandle handle, NativePluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
  405. {
  406. switch(opcode)
  407. {
  408. case PLUGIN_OPCODE_NULL:
  409. return 0;
  410. case PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
  411. CARLA_SAFE_ASSERT_RETURN(value > 0, 0);
  412. handlePtr->bufferSizeChanged(static_cast<uint32_t>(value));
  413. return 0;
  414. case PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
  415. handlePtr->sampleRateChanged(static_cast<double>(opt));
  416. return 0;
  417. case PLUGIN_OPCODE_OFFLINE_CHANGED:
  418. handlePtr->offlineChanged(value != 0);
  419. return 0;
  420. case PLUGIN_OPCODE_UI_NAME_CHANGED:
  421. handlePtr->uiNameChanged(static_cast<const char*>(ptr));
  422. return 0;
  423. }
  424. return 0;
  425. // unused
  426. (void)index;
  427. }
  428. #undef handlePtr
  429. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginClass)
  430. #endif
  431. };
  432. /**@}*/
  433. // -----------------------------------------------------------------------
  434. #define PluginClassEND(ClassName) \
  435. public: \
  436. static NativePluginHandle _instantiate(const NativeHostDescriptor* host) \
  437. { \
  438. return (host != nullptr) ? new ClassName(host) : nullptr; \
  439. } \
  440. static void _cleanup(NativePluginHandle handle) \
  441. { \
  442. delete (ClassName*)handle; \
  443. }
  444. #define PluginDescriptorFILL(ClassName) \
  445. ClassName::_instantiate, \
  446. ClassName::_cleanup, \
  447. ClassName::_get_parameter_count, \
  448. ClassName::_get_parameter_info, \
  449. ClassName::_get_parameter_value, \
  450. ClassName::_get_parameter_text, \
  451. ClassName::_get_midi_program_count, \
  452. ClassName::_get_midi_program_info, \
  453. ClassName::_set_parameter_value, \
  454. ClassName::_set_midi_program, \
  455. ClassName::_set_custom_data, \
  456. ClassName::_ui_show, \
  457. ClassName::_ui_idle, \
  458. ClassName::_ui_set_parameter_value, \
  459. ClassName::_ui_set_midi_program, \
  460. ClassName::_ui_set_custom_data, \
  461. ClassName::_activate, \
  462. ClassName::_deactivate, \
  463. ClassName::_process, \
  464. ClassName::_get_state, \
  465. ClassName::_set_state, \
  466. ClassName::_dispatcher
  467. // -----------------------------------------------------------------------
  468. #endif // CARLA_NATIVE_HPP_INCLUDED