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.

295 lines
9.4KB

  1. /*
  2. * DISTRHO Ildaeil Plugin
  3. * Copyright (C) 2021 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 3 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 LICENSE file.
  16. */
  17. #include "CarlaNativePlugin.h"
  18. #include "DistrhoPlugin.hpp"
  19. #include "DistrhoUI.hpp"
  20. START_NAMESPACE_DISTRHO
  21. // -----------------------------------------------------------------------------------------------------------
  22. static uint32_t host_get_buffer_size(NativeHostHandle);
  23. static double host_get_sample_rate(NativeHostHandle);
  24. static bool host_is_offline(NativeHostHandle);
  25. static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle);
  26. static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event);
  27. static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt);
  28. // -----------------------------------------------------------------------------------------------------------
  29. class IldaeilPlugin : public Plugin
  30. {
  31. const NativePluginDescriptor* fCarlaPluginDescriptor;
  32. NativePluginHandle fCarlaPluginHandle;
  33. NativeHostDescriptor fCarlaHostDescriptor;
  34. CarlaHostHandle fCarlaHostHandle;
  35. NativeTimeInfo fCarlaTimeInfo;
  36. UI* fUI;
  37. public:
  38. IldaeilPlugin()
  39. : Plugin(0, 0, 0),
  40. fCarlaPluginDescriptor(nullptr),
  41. fCarlaPluginHandle(nullptr),
  42. fCarlaHostHandle(nullptr),
  43. fUI(nullptr)
  44. {
  45. fCarlaPluginDescriptor = carla_get_native_rack_plugin();
  46. DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginDescriptor != nullptr,);
  47. memset(&fCarlaHostDescriptor, 0, sizeof(fCarlaHostDescriptor));
  48. memset(&fCarlaTimeInfo, 0, sizeof(fCarlaTimeInfo));
  49. fCarlaHostDescriptor.handle = this;
  50. fCarlaHostDescriptor.resourceDir = carla_get_library_folder();
  51. fCarlaHostDescriptor.uiName = "Ildaeil";
  52. fCarlaHostDescriptor.uiParentId = 0;
  53. fCarlaHostDescriptor.get_buffer_size = host_get_buffer_size;
  54. fCarlaHostDescriptor.get_sample_rate = host_get_sample_rate;
  55. fCarlaHostDescriptor.is_offline = host_is_offline;
  56. fCarlaHostDescriptor.get_time_info = host_get_time_info;
  57. fCarlaHostDescriptor.write_midi_event = host_write_midi_event;
  58. fCarlaHostDescriptor.ui_parameter_changed = nullptr;
  59. fCarlaHostDescriptor.ui_midi_program_changed = nullptr;
  60. fCarlaHostDescriptor.ui_custom_data_changed = nullptr;
  61. fCarlaHostDescriptor.ui_closed = nullptr;
  62. fCarlaHostDescriptor.ui_open_file = nullptr;
  63. fCarlaHostDescriptor.ui_save_file = nullptr;
  64. fCarlaHostDescriptor.dispatcher = host_dispatcher;
  65. fCarlaPluginHandle = fCarlaPluginDescriptor->instantiate(&fCarlaHostDescriptor);
  66. DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginHandle != nullptr,);
  67. fCarlaHostHandle = carla_create_native_plugin_host_handle(fCarlaPluginDescriptor, fCarlaPluginHandle);
  68. }
  69. ~IldaeilPlugin() override
  70. {
  71. if (fCarlaHostHandle != nullptr)
  72. {
  73. carla_host_handle_free(fCarlaHostHandle);
  74. }
  75. if (fCarlaPluginHandle != nullptr)
  76. fCarlaPluginDescriptor->cleanup(fCarlaPluginHandle);
  77. }
  78. const NativeTimeInfo* getTimeInfo()
  79. {
  80. const TimePosition& timePos(getTimePosition());
  81. fCarlaTimeInfo.playing = timePos.playing;
  82. fCarlaTimeInfo.frame = timePos.frame;
  83. fCarlaTimeInfo.bbt.valid = timePos.bbt.valid;
  84. fCarlaTimeInfo.bbt.bar = timePos.bbt.bar;
  85. fCarlaTimeInfo.bbt.beat = timePos.bbt.beat;
  86. fCarlaTimeInfo.bbt.tick = timePos.bbt.tick;
  87. fCarlaTimeInfo.bbt.barStartTick = timePos.bbt.barStartTick;
  88. fCarlaTimeInfo.bbt.beatsPerBar = timePos.bbt.beatsPerBar;
  89. fCarlaTimeInfo.bbt.beatType = timePos.bbt.beatType;
  90. fCarlaTimeInfo.bbt.ticksPerBeat = timePos.bbt.ticksPerBeat;
  91. fCarlaTimeInfo.bbt.beatsPerMinute = timePos.bbt.beatsPerMinute;
  92. return &fCarlaTimeInfo;
  93. }
  94. void resizeUI(const uint width, const uint height)
  95. {
  96. DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
  97. fUI->setSize(width, height);
  98. }
  99. protected:
  100. /* --------------------------------------------------------------------------------------------------------
  101. * Information */
  102. /**
  103. Get the plugin label.
  104. A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
  105. */
  106. const char* getLabel() const override
  107. {
  108. #if DISTRHO_PLUGIN_IS_SYNTH
  109. return "IldaeilSynth";
  110. #elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
  111. return "IldaeilMIDI";
  112. #else
  113. return "IldaeilFX";
  114. #endif
  115. }
  116. /**
  117. Get an extensive comment/description about the plugin.
  118. */
  119. const char* getDescription() const override
  120. {
  121. return "Ildaeil is a mini-plugin host working as a plugin, allowing one-to-one plugin format reusage.";
  122. }
  123. /**
  124. Get the plugin author/maker.
  125. */
  126. const char* getMaker() const override
  127. {
  128. return "DISTRHO";
  129. }
  130. /**
  131. Get the plugin homepage.
  132. */
  133. const char* getHomePage() const override
  134. {
  135. return "https://github.com/DISTRHO/Ildaeil";
  136. }
  137. /**
  138. Get the plugin license name (a single line of text).
  139. For commercial plugins this should return some short copyright information.
  140. */
  141. const char* getLicense() const override
  142. {
  143. return "ISC";
  144. }
  145. /**
  146. Get the plugin version, in hexadecimal.
  147. */
  148. uint32_t getVersion() const override
  149. {
  150. return d_version(1, 0, 0);
  151. }
  152. /**
  153. Get the plugin unique Id.
  154. This value is used by LADSPA, DSSI and VST plugin formats.
  155. */
  156. int64_t getUniqueId() const override
  157. {
  158. #if DISTRHO_PLUGIN_IS_SYNTH
  159. return d_cconst('d', 'I', 'l', 'S');
  160. #elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
  161. return d_cconst('d', 'I', 'l', 'M');
  162. #else
  163. return d_cconst('d', 'I', 'l', 'F');
  164. #endif
  165. }
  166. /* --------------------------------------------------------------------------------------------------------
  167. * Init */
  168. /* --------------------------------------------------------------------------------------------------------
  169. * Internal data */
  170. /* --------------------------------------------------------------------------------------------------------
  171. * Process */
  172. void activate() override
  173. {
  174. if (fCarlaPluginHandle != nullptr)
  175. fCarlaPluginDescriptor->activate(fCarlaPluginHandle);
  176. }
  177. void deactivate() override
  178. {
  179. if (fCarlaPluginHandle != nullptr)
  180. fCarlaPluginDescriptor->deactivate(fCarlaPluginHandle);
  181. }
  182. void run(const float** inputs, float** outputs, uint32_t frames) override
  183. {
  184. if (fCarlaPluginHandle != nullptr)
  185. {
  186. fCarlaPluginDescriptor->process(fCarlaPluginHandle, (float**)inputs, outputs, frames, nullptr, 0);
  187. }
  188. else
  189. {
  190. std::memset(outputs[0], 0, sizeof(float)*frames);
  191. std::memset(outputs[1], 0, sizeof(float)*frames);
  192. }
  193. }
  194. // -------------------------------------------------------------------------------------------------------
  195. private:
  196. /**
  197. Set our plugin class as non-copyable and add a leak detector just in case.
  198. */
  199. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(IldaeilPlugin)
  200. };
  201. // -----------------------------------------------------------------------------------------------------------
  202. static uint32_t host_get_buffer_size(const NativeHostHandle handle)
  203. {
  204. return static_cast<IldaeilPlugin*>(handle)->getBufferSize();
  205. }
  206. static double host_get_sample_rate(const NativeHostHandle handle)
  207. {
  208. return static_cast<IldaeilPlugin*>(handle)->getSampleRate();
  209. }
  210. static bool host_is_offline(NativeHostHandle)
  211. {
  212. return false;
  213. }
  214. static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle)
  215. {
  216. return static_cast<IldaeilPlugin*>(handle)->getTimeInfo();
  217. }
  218. static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event)
  219. {
  220. return false;
  221. }
  222. static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode,
  223. int32_t index, intptr_t value, void* ptr, float opt)
  224. {
  225. switch (opcode)
  226. {
  227. case NATIVE_HOST_OPCODE_UI_RESIZE:
  228. static_cast<IldaeilPlugin*>(handle)->resizeUI(index, value);
  229. break;
  230. default:
  231. break;
  232. }
  233. return 0;
  234. }
  235. /* ------------------------------------------------------------------------------------------------------------
  236. * Plugin entry point, called by DPF to create a new plugin instance. */
  237. Plugin* createPlugin()
  238. {
  239. return new IldaeilPlugin();
  240. }
  241. // -----------------------------------------------------------------------------------------------------------
  242. END_NAMESPACE_DISTRHO