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.

86 lines
2.4KB

  1. #include "plugin.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() {
  21. config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
  22. configParam(SHAPE_PARAM, 0.0, 1.0, 0.0, "Shape");
  23. configParam(RISE_PARAM, 0.0, 1.0, 0.0, "Rise time");
  24. configParam(FALL_PARAM, 0.0, 1.0, 0.0, "Fall time");
  25. }
  26. void process(const ProcessArgs &args) override {
  27. float in = inputs[IN_INPUT].getVoltage();
  28. float shape = params[SHAPE_PARAM].getValue();
  29. // minimum and maximum slopes in volts per second
  30. const float slewMin = 0.1;
  31. const float slewMax = 10000.f;
  32. // Amount of extra slew per voltage difference
  33. const float shapeScale = 1/10.f;
  34. // Rise
  35. if (in > out) {
  36. float rise = inputs[RISE_INPUT].getVoltage() / 10.f + params[RISE_PARAM].getValue();
  37. float slew = slewMax * std::pow(slewMin / slewMax, rise);
  38. out += slew * crossfade(1.f, shapeScale * (in - out), shape) * args.sampleTime;
  39. if (out > in)
  40. out = in;
  41. }
  42. // Fall
  43. else if (in < out) {
  44. float fall = inputs[FALL_INPUT].getVoltage() / 10.f + params[FALL_PARAM].getValue();
  45. float slew = slewMax * std::pow(slewMin / slewMax, fall);
  46. out -= slew * crossfade(1.f, shapeScale * (out - in), shape) * args.sampleTime;
  47. if (out < in)
  48. out = in;
  49. }
  50. outputs[OUT_OUTPUT].setVoltage(out);
  51. }
  52. };
  53. struct SlewLimiterWidget : ModuleWidget {
  54. SlewLimiterWidget(::SlewLimiter *module) {
  55. setModule(module);
  56. setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SlewLimiter.svg")));
  57. addChild(createWidget<Knurlie>(Vec(15, 0)));
  58. addChild(createWidget<Knurlie>(Vec(15, 365)));
  59. addParam(createParam<Davies1900hWhiteKnob>(Vec(27, 39), module, ::SlewLimiter::SHAPE_PARAM));
  60. addParam(createParam<BefacoSlidePot>(Vec(15, 102), module, ::SlewLimiter::RISE_PARAM));
  61. addParam(createParam<BefacoSlidePot>(Vec(60, 102), module, ::SlewLimiter::FALL_PARAM));
  62. addInput(createInput<PJ301MPort>(Vec(10, 273), module, ::SlewLimiter::RISE_INPUT));
  63. addInput(createInput<PJ301MPort>(Vec(55, 273), module, ::SlewLimiter::FALL_INPUT));
  64. addInput(createInput<PJ301MPort>(Vec(10, 323), module, ::SlewLimiter::IN_INPUT));
  65. addOutput(createOutput<PJ301MPort>(Vec(55, 323), module, ::SlewLimiter::OUT_OUTPUT));
  66. }
  67. };
  68. Model *modelSlewLimiter = createModel<::SlewLimiter, SlewLimiterWidget>("SlewLimiter");