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.

SlewLimiter.cpp 2.3KB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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(createWidget<Knurlie>(Vec(15, 0)));
  53. addChild(createWidget<Knurlie>(Vec(15, 365)));
  54. addParam(createParam<Davies1900hWhiteKnob>(Vec(27, 39), module, ::SlewLimiter::SHAPE_PARAM, 0.0, 1.0, 0.0));
  55. addParam(createParam<BefacoSlidePot>(Vec(15, 102), module, ::SlewLimiter::RISE_PARAM, 0.0, 1.0, 0.0));
  56. addParam(createParam<BefacoSlidePot>(Vec(60, 102), module, ::SlewLimiter::FALL_PARAM, 0.0, 1.0, 0.0));
  57. addInput(createPort<PJ301MPort>(Vec(10, 273), PortWidget::INPUT, module, ::SlewLimiter::RISE_INPUT));
  58. addInput(createPort<PJ301MPort>(Vec(55, 273), PortWidget::INPUT, module, ::SlewLimiter::FALL_INPUT));
  59. addInput(createPort<PJ301MPort>(Vec(10, 323), PortWidget::INPUT, module, ::SlewLimiter::IN_INPUT));
  60. addOutput(createPort<PJ301MPort>(Vec(55, 323), PortWidget::OUTPUT, module, ::SlewLimiter::OUT_OUTPUT));
  61. }
  62. };
  63. Model *modelSlewLimiter = createModel<SlewLimiter, SlewLimiterWidget>("SlewLimiter");