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.

247 lines
5.6KB

  1. /*
  2. * DISTRHO Cardinal 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. #ifndef PLUGIN_INSTANCE
  18. # error PLUGIN_INSTANCE undefined
  19. #endif
  20. #ifndef PLUGIN_MODEL
  21. # error PLUGIN_MODEL undefined
  22. #endif
  23. #ifndef PLUGIN_URI
  24. # error PLUGIN_URI undefined
  25. #endif
  26. #define PRIVATE
  27. #include <common.hpp>
  28. #include <engine/Engine.hpp>
  29. #undef PRIVATE
  30. #include <rack.hpp>
  31. #include "src/lv2/buf-size.h"
  32. #include "src/lv2/options.h"
  33. #include "DistrhoUtils.hpp"
  34. using namespace rack;
  35. extern Model* PLUGIN_MODEL;
  36. extern Plugin* PLUGIN_INSTANCE;
  37. namespace rack {
  38. namespace engine {
  39. struct Engine::Internal {
  40. float sampleRate;
  41. };
  42. Engine::Engine()
  43. {
  44. internal = new Internal;
  45. }
  46. Engine::~Engine()
  47. {
  48. delete internal;
  49. }
  50. float Engine::getSampleRate()
  51. {
  52. return internal->sampleRate;
  53. }
  54. }
  55. namespace plugin {
  56. void Plugin::addModel(Model* model)
  57. {
  58. // Check that the model is not added to a plugin already
  59. DISTRHO_SAFE_ASSERT_RETURN(model != nullptr,);
  60. DISTRHO_SAFE_ASSERT_RETURN(model->plugin == nullptr,);
  61. model->plugin = this;
  62. models.push_back(model);
  63. }
  64. Model* modelFromJson(json_t* moduleJ) {
  65. return nullptr;
  66. }
  67. std::vector<Plugin*> plugins;
  68. } // namespace plugin
  69. } // namespace rack
  70. struct PluginLv2 {
  71. Context* context;
  72. Plugin* plugin;
  73. engine::Module* module;
  74. float sampleRate;
  75. int frameCount = 0;
  76. int numInputs, numOutputs, numParams, numLights;
  77. void** ports;
  78. PluginLv2(double sr)
  79. {
  80. // FIXME shared instance for these 2
  81. context = new Context;
  82. context->engine = new Engine;
  83. context->engine->internal->sampleRate = sr;
  84. contextSet(context);
  85. plugin = new Plugin;
  86. PLUGIN_INSTANCE = plugin;
  87. sampleRate = sr;
  88. plugin->addModel(PLUGIN_MODEL);
  89. module = PLUGIN_MODEL->createModule();
  90. numInputs = module->getNumInputs();
  91. numOutputs = module->getNumOutputs();
  92. numParams = module->getNumParams();
  93. numLights = module->getNumLights();
  94. ports = new void*[numInputs+numOutputs+numParams+numLights];
  95. // FIXME for CV ports we need to detect if something is connected
  96. for (int i=numInputs; --i >=0;)
  97. module->inputs[i].channels = 1;
  98. for (int i=numOutputs; --i >=0;)
  99. module->outputs[i].channels = 1;
  100. d_stdout("Loaded %s :: %i inputs, %i outputs, %i params and %i lights",
  101. PLUGIN_URI, numInputs, numOutputs, numParams, numLights);
  102. }
  103. PluginLv2()
  104. {
  105. contextSet(context);
  106. delete[] ports;
  107. delete module;
  108. // FIXME shared instance for this
  109. delete plugin;
  110. delete context;
  111. }
  112. void lv2_connect_port(const uint32_t port, void* const dataLocation)
  113. {
  114. ports[port] = dataLocation;
  115. }
  116. void lv2_activate()
  117. {
  118. contextSet(context);
  119. module->onReset();
  120. }
  121. void lv2_run(const uint32_t sampleCount)
  122. {
  123. if (sampleCount == 0)
  124. return;
  125. contextSet(context);
  126. Module::ProcessArgs args = {
  127. sampleRate,
  128. 1.0f / sampleRate,
  129. frameCount
  130. };
  131. for (int i=numParams; --i >=0;)
  132. module->params[i].setValue(*static_cast<float*>(ports[numInputs+numOutputs+i]) * 0.1f); // FIXME?
  133. for (uint32_t s=0; s<sampleCount; ++s)
  134. {
  135. for (int i=numInputs; --i >=0;)
  136. module->inputs[i].setVoltage(static_cast<const float*>(ports[i])[s] * 5.0f);
  137. module->doProcess(args);
  138. for (int i=numOutputs; --i >=0;)
  139. static_cast<float*>(ports[numInputs+i])[s] = module->outputs[i].getVoltage() * 0.2f;
  140. ++args.frame;
  141. }
  142. frameCount += sampleCount;
  143. }
  144. };
  145. static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, const char* bundlePath, const LV2_Feature* const* features)
  146. {
  147. return new PluginLv2(sampleRate);
  148. }
  149. // -----------------------------------------------------------------------
  150. #define instancePtr ((PluginLv2*)instance)
  151. static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocation)
  152. {
  153. instancePtr->lv2_connect_port(port, dataLocation);
  154. }
  155. static void lv2_activate(LV2_Handle instance)
  156. {
  157. instancePtr->lv2_activate();
  158. }
  159. static void lv2_run(LV2_Handle instance, uint32_t sampleCount)
  160. {
  161. instancePtr->lv2_run(sampleCount);
  162. }
  163. static void lv2_deactivate(LV2_Handle instance)
  164. {
  165. }
  166. static void lv2_cleanup(LV2_Handle instance)
  167. {
  168. delete instancePtr;
  169. }
  170. // -----------------------------------------------------------------------
  171. static const void* lv2_extension_data(const char* uri)
  172. {
  173. return nullptr;
  174. }
  175. #undef instancePtr
  176. // -----------------------------------------------------------------------
  177. static const LV2_Descriptor sLv2Descriptor = {
  178. PLUGIN_URI,
  179. lv2_instantiate,
  180. lv2_connect_port,
  181. lv2_activate,
  182. lv2_run,
  183. lv2_deactivate,
  184. lv2_cleanup,
  185. lv2_extension_data
  186. };
  187. DISTRHO_PLUGIN_EXPORT
  188. const LV2_Descriptor* lv2_descriptor(uint32_t index)
  189. {
  190. USE_NAMESPACE_DISTRHO
  191. return (index == 0) ? &sLv2Descriptor : nullptr;
  192. }
  193. // -----------------------------------------------------------------------