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.

205 lines
4.9KB

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