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.

111 lines
3.2KB

  1. #include <iostream>
  2. #include "Southpole.hpp"
  3. #include "dsp/digital.hpp"
  4. namespace rack_plugin_Southpole {
  5. struct Wriggle : Module {
  6. enum ParamIds {
  7. DAMP_PARAM,
  8. TENS_PARAM,
  9. SCALE_PARAM,
  10. OFFSET_PARAM,
  11. NUM_PARAMS
  12. };
  13. enum InputIds {
  14. IN_INPUT,
  15. DAMP_INPUT,
  16. TENS_INPUT,
  17. SCALE_INPUT,
  18. OFFSET_INPUT,
  19. NUM_INPUTS
  20. };
  21. enum OutputIds {
  22. OUT_OUTPUT,
  23. NUM_OUTPUTS
  24. };
  25. enum LightIds {
  26. // DECAY1_LIGHT,
  27. NUM_LIGHTS
  28. };
  29. float a0 = 0.0;
  30. float v0 = 0.0;
  31. float x0 = 0.0;
  32. Wriggle() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  33. }
  34. void step() override;
  35. };
  36. void Wriggle::step() {
  37. float dt = 1./engineGetSampleRate();
  38. float tens = clamp(params[TENS_PARAM].value + inputs[TENS_INPUT].normalize(0.) / 10.0, 0.0f, 1.0f);
  39. float damp = clamp(params[DAMP_PARAM].value + inputs[DAMP_INPUT].normalize(0.) / 10.0, 0.0f, 1.0f);
  40. float scale = clamp(params[SCALE_PARAM].value + inputs[SCALE_INPUT].normalize(0.) / 10.0, 0.0f, 1.0f);
  41. float offset = clamp(params[OFFSET_PARAM].value + inputs[OFFSET_INPUT].normalize(0.) / 10.0, 0.0f, 1.0f);
  42. // semi-parametric Euler... (i know ...)
  43. //float m = 1000.*pow(2., 6.*mass);
  44. float k = pow(2.,18.*tens);
  45. float b = pow(2.,10.*damp-3.);
  46. float xin = inputs[IN_INPUT].value;
  47. v0 = v0 + dt*a0; // - v0 / m;
  48. x0 = x0 + dt*v0;
  49. a0 = - k * (x0-xin) - b * v0; //) / m;
  50. outputs[OUT_OUTPUT].value = clamp( (10. * offset - 5.) + scale * x0, -10.0f, 10.0f );
  51. }
  52. struct WriggleWidget : ModuleWidget {
  53. WriggleWidget(Wriggle *module) : ModuleWidget(module) {
  54. box.size = Vec(15*2, 380);
  55. {
  56. SVGPanel *panel = new SVGPanel();
  57. panel->box.size = box.size;
  58. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Wriggle.svg")));
  59. addChild(panel);
  60. }
  61. const float x1 = 5.;
  62. const float y1 = 40.;
  63. const float yh = 31.;
  64. addInput(Port::create<sp_Port >(Vec(x1, y1+0*yh), Port::INPUT, module, Wriggle::IN_INPUT));
  65. addInput(Port::create<sp_Port >(Vec(x1, y1+1.125*yh), Port::INPUT, module, Wriggle::TENS_INPUT));
  66. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+2*yh), module, Wriggle::TENS_PARAM, 0.0, 1.0, 0.5));
  67. addInput(Port::create<sp_Port >(Vec(x1, y1+3.125*yh), Port::INPUT, module, Wriggle::DAMP_INPUT));
  68. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+4*yh), module, Wriggle::DAMP_PARAM, 0.0, 1.0, 0.5));
  69. addInput(Port::create<sp_Port >(Vec(x1, y1+5.125*yh), Port::INPUT, module, Wriggle::SCALE_INPUT));
  70. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+6*yh), module, Wriggle::SCALE_PARAM, 0.0, 1.0, 0.5));
  71. addInput(Port::create<sp_Port >(Vec(x1, y1+7.125*yh), Port::INPUT, module, Wriggle::OFFSET_INPUT));
  72. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+8*yh), module, Wriggle::OFFSET_PARAM, 0.0, 1.0, 0.5));
  73. addOutput(Port::create<sp_Port >(Vec(x1, y1+9.25*yh), Port::OUTPUT, module, Wriggle::OUT_OUTPUT));
  74. // addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(94, 109), module, Wriggle::DECAY_LIGHT));
  75. }
  76. };
  77. } // namespace rack_plugin_Southpole
  78. using namespace rack_plugin_Southpole;
  79. RACK_PLUGIN_MODEL_INIT(Southpole, Wriggle) {
  80. Model *modelWriggle = Model::create<Wriggle,WriggleWidget>( "Southpole", "Wriggle", "Wriggle - spring model", LFO_TAG, FUNCTION_GENERATOR_TAG);
  81. return modelWriggle;
  82. }