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.

96 lines
2.8KB

  1. #include "Template.hpp"
  2. namespace rack_plugin_PG_Instruments {
  3. struct PGVCF : Module
  4. {
  5. enum ParamIds
  6. {
  7. FREQUENCY_PARAM,
  8. RESONANCE_PARAM,
  9. NUM_PARAMS
  10. };
  11. enum InputIds
  12. {
  13. INPUT,
  14. CUTOFF,
  15. NUM_INPUTS
  16. };
  17. enum OutputIds
  18. {
  19. LOWPASS_OUTPUT,
  20. BANDPASS_OUTPUT,
  21. HIGHPASS_OUTPUT,
  22. NUM_OUTPUTS
  23. };
  24. float buf0;
  25. float buf1;
  26. float buf2;
  27. float buf3;
  28. float feedback;
  29. PGVCF() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, 0)
  30. {
  31. buf0 = buf1 = buf2 = buf3 = 0.0f;
  32. }
  33. void step() override
  34. {
  35. calculateFeedback();
  36. float calcCutoff = getCalculatedCutoff();
  37. buf0 += calcCutoff * (inputs[INPUT].value - buf0 + feedback * (buf0 - buf1));
  38. buf1 += calcCutoff * (buf0 - buf1);
  39. buf2 += calcCutoff * (buf1 - buf2);
  40. buf3 += calcCutoff * (buf2 - buf3);
  41. outputs[LOWPASS_OUTPUT].value = buf3;
  42. outputs[BANDPASS_OUTPUT].value = buf0 - buf3;
  43. outputs[HIGHPASS_OUTPUT].value = inputs[INPUT].value - buf3;
  44. }
  45. void calculateFeedback()
  46. {
  47. feedback = params[RESONANCE_PARAM].value + params[RESONANCE_PARAM].value / (1.0f - getCalculatedCutoff());
  48. }
  49. float getCalculatedCutoff()
  50. {
  51. return fmax(fmin(params[FREQUENCY_PARAM].value + inputs[CUTOFF].value, 0.99f), 0.01f);
  52. }
  53. };
  54. struct PGVCFWidget : ModuleWidget
  55. {
  56. PGVCFWidget(PGVCF *module) : ModuleWidget(module)
  57. {
  58. setPanel(SVG::load(assetPlugin(plugin, "res/PGVCF.svg")));
  59. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  60. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  61. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  62. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  63. addInput(Port::create<PJ301MPort>(Vec(30, 100), Port::INPUT, module, PGVCF::INPUT));
  64. addInput(Port::create<PJ301MPort>(Vec(30, 140), Port::INPUT, module, PGVCF::CUTOFF));
  65. addParam(ParamWidget::create<RoundBlackKnob>(Vec(70, 100), module, PGVCF::FREQUENCY_PARAM, 0.0f, 1.0f, 0.5f));
  66. addParam(ParamWidget::create<RoundBlackKnob>(Vec(110, 100), module, PGVCF::RESONANCE_PARAM, 0.0f, 0.99f, 0.5f));
  67. addOutput(Port::create<PJ301MPort>(Vec(150, 100), Port::OUTPUT, module, PGVCF::LOWPASS_OUTPUT));
  68. addOutput(Port::create<PJ301MPort>(Vec(150, 140), Port::OUTPUT, module, PGVCF::BANDPASS_OUTPUT));
  69. addOutput(Port::create<PJ301MPort>(Vec(150, 180), Port::OUTPUT, module, PGVCF::HIGHPASS_OUTPUT));
  70. }
  71. };
  72. } // namespace rack_plugin_PG_Instruments
  73. using namespace rack_plugin_PG_Instruments;
  74. RACK_PLUGIN_MODEL_INIT(PG_Instruments, PGVCF) {
  75. Model *modelPGVCF = Model::create<PGVCF, PGVCFWidget>("PG-Instruments", "PGVCF", "PG VCF", ATTENUATOR_TAG);
  76. return modelPGVCF;
  77. }