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.

301 lines
9.6KB

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