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.

85 lines
2.5KB

  1. #include "Befaco.hpp"
  2. struct SlewLimiter : Module {
  3. enum ParamIds {
  4. SHAPE_PARAM,
  5. RISE_PARAM,
  6. FALL_PARAM,
  7. NUM_PARAMS
  8. };
  9. enum InputIds {
  10. RISE_INPUT,
  11. FALL_INPUT,
  12. IN_INPUT,
  13. NUM_INPUTS
  14. };
  15. enum OutputIds {
  16. OUT_OUTPUT,
  17. NUM_OUTPUTS
  18. };
  19. float out = 0.0;
  20. SlewLimiter() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {}
  21. void step() override;
  22. };
  23. void ::SlewLimiter::step() {
  24. float in = inputs[IN_INPUT].value;
  25. float shape = params[SHAPE_PARAM].value;
  26. // minimum and maximum slopes in volts per second
  27. const float slewMin = 0.1;
  28. const float slewMax = 10000.0;
  29. // Amount of extra slew per voltage difference
  30. const float shapeScale = 1/10.0;
  31. // Rise
  32. if (in > out) {
  33. float rise = inputs[RISE_INPUT].value / 10.0 + params[RISE_PARAM].value;
  34. float slew = slewMax * powf(slewMin / slewMax, rise);
  35. out += slew * crossfade(1.0f, shapeScale * (in - out), shape) * engineGetSampleTime();
  36. if (out > in)
  37. out = in;
  38. }
  39. // Fall
  40. else if (in < out) {
  41. float fall = inputs[FALL_INPUT].value / 10.0 + params[FALL_PARAM].value;
  42. float slew = slewMax * powf(slewMin / slewMax, fall);
  43. out -= slew * crossfade(1.0f, shapeScale * (out - in), shape) * engineGetSampleTime();
  44. if (out < in)
  45. out = in;
  46. }
  47. outputs[OUT_OUTPUT].value = out;
  48. }
  49. struct SlewLimiterWidget : ModuleWidget {
  50. SlewLimiterWidget(SlewLimiter *module) : ModuleWidget(module) {
  51. setPanel(SVG::load(assetPlugin(plugin, "res/SlewLimiter.svg")));
  52. addChild(Widget::create<Knurlie>(Vec(15, 0)));
  53. addChild(Widget::create<Knurlie>(Vec(15, 365)));
  54. addParam(ParamWidget::create<Davies1900hWhiteKnob>(Vec(27, 39), module, ::SlewLimiter::SHAPE_PARAM, 0.0, 1.0, 0.0));
  55. addParam(ParamWidget::create<BefacoSlidePot>(Vec(15, 102), module, ::SlewLimiter::RISE_PARAM, 0.0, 1.0, 0.0));
  56. addParam(ParamWidget::create<BefacoSlidePot>(Vec(60, 102), module, ::SlewLimiter::FALL_PARAM, 0.0, 1.0, 0.0));
  57. addInput(Port::create<PJ301MPort>(Vec(10, 273), Port::INPUT, module, ::SlewLimiter::RISE_INPUT));
  58. addInput(Port::create<PJ301MPort>(Vec(55, 273), Port::INPUT, module, ::SlewLimiter::FALL_INPUT));
  59. addInput(Port::create<PJ301MPort>(Vec(10, 323), Port::INPUT, module, ::SlewLimiter::IN_INPUT));
  60. addOutput(Port::create<PJ301MPort>(Vec(55, 323), Port::OUTPUT, module, ::SlewLimiter::OUT_OUTPUT));
  61. }
  62. };
  63. RACK_PLUGIN_MODEL_INIT(Befaco, SlewLimiter) {
  64. Model *modelSlewLimiter = Model::create<SlewLimiter, SlewLimiterWidget>("Befaco", "SlewLimiter", "Slew Limiter", SLEW_LIMITER_TAG, ENVELOPE_FOLLOWER_TAG);
  65. return modelSlewLimiter;
  66. }