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.

131 lines
4.3KB

  1. #include "Template.hpp"
  2. namespace rack_plugin_PG_Instruments {
  3. struct PGStereoVCF : Module
  4. {
  5. enum ParamIds
  6. {
  7. FREQUENCY_PARAM,
  8. RESONANCE_PARAM,
  9. NUM_PARAMS
  10. };
  11. enum InputIds
  12. {
  13. LEFT_INPUT,
  14. RIGHT_INPUT,
  15. CUTOFF,
  16. NUM_INPUTS
  17. };
  18. enum OutputIds
  19. {
  20. LEFT_LOWPASS_OUTPUT,
  21. RIGHT_LOWPASS_OUTPUT,
  22. LEFT_BANDPASS_OUTPUT,
  23. RIGHT_BANDPASS_OUTPUT,
  24. LEFT_HIGHPASS_OUTPUT,
  25. RIGHT_HIGHPASS_OUTPUT,
  26. NUM_OUTPUTS
  27. };
  28. float buf0[2];
  29. float buf1[2];
  30. float buf2[2];
  31. float buf3[2];
  32. float feedback;
  33. PGStereoVCF() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, 0)
  34. {
  35. for(int i = 0; i < 2; i++)
  36. buf0[i] = buf1[i] = buf2[i] = buf3[i] = 0.0f;
  37. }
  38. void step() override
  39. {
  40. calculateFeedback();
  41. float calcCutoff = getCalculatedCutoff();
  42. for(int i = 0; i < 2; i++)
  43. {
  44. float input;
  45. if (i)
  46. input = inputs[RIGHT_INPUT].value;
  47. else
  48. input = inputs[LEFT_INPUT].value;
  49. buf0[i] += calcCutoff * (input - buf0[i] + feedback * (buf0[i] - buf1[i]));
  50. buf1[i] += calcCutoff * (buf0[i] - buf1[i]);
  51. buf2[i] += calcCutoff * (buf1[i] - buf2[i]);
  52. buf3[i] += calcCutoff * (buf2[i] - buf3[i]);
  53. if (i)
  54. {
  55. outputs[RIGHT_LOWPASS_OUTPUT].value = buf3[i];
  56. outputs[RIGHT_BANDPASS_OUTPUT].value = buf0[i] - buf3[i];
  57. outputs[RIGHT_HIGHPASS_OUTPUT].value = inputs[RIGHT_INPUT].value - buf3[i];
  58. }
  59. else
  60. {
  61. outputs[LEFT_LOWPASS_OUTPUT].value = buf3[i];
  62. outputs[LEFT_BANDPASS_OUTPUT].value = buf0[i] - buf3[i];
  63. outputs[LEFT_HIGHPASS_OUTPUT].value = inputs[LEFT_INPUT].value - buf3[i];
  64. }
  65. }
  66. }
  67. void calculateFeedback()
  68. {
  69. feedback = params[RESONANCE_PARAM].value + params[RESONANCE_PARAM].value / (1.0f - getCalculatedCutoff());
  70. }
  71. float getCalculatedCutoff()
  72. {
  73. return fmax(fmin(params[FREQUENCY_PARAM].value + inputs[CUTOFF].value, 0.99f), 0.01f);
  74. }
  75. };
  76. struct PGStereoVCFWidget : ModuleWidget
  77. {
  78. PGStereoVCFWidget(PGStereoVCF *module) : ModuleWidget(module)
  79. {
  80. setPanel(SVG::load(assetPlugin(plugin, "res/PGStereoVCF.svg")));
  81. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  82. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  83. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  84. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  85. addInput(Port::create<PJ301MPort>(Vec(20, 100), Port::INPUT, module, PGStereoVCF::LEFT_INPUT));
  86. addInput(Port::create<PJ301MPort>(Vec(20, 140), Port::INPUT, module, PGStereoVCF::RIGHT_INPUT));
  87. addInput(Port::create<PJ301MPort>(Vec(20, 180), Port::INPUT, module, PGStereoVCF::CUTOFF));
  88. addParam(ParamWidget::create<RoundBlackKnob>(Vec(50, 100), module, PGStereoVCF::FREQUENCY_PARAM, 0.0f, 1.0f, 0.5f));
  89. addParam(ParamWidget::create<RoundBlackKnob>(Vec(90, 100), module, PGStereoVCF::RESONANCE_PARAM, 0.0f, 0.99f, 0.5f));
  90. addOutput(Port::create<PJ301MPort>(Vec(130, 100), Port::OUTPUT, module, PGStereoVCF::LEFT_LOWPASS_OUTPUT));
  91. addOutput(Port::create<PJ301MPort>(Vec(130, 140), Port::OUTPUT, module, PGStereoVCF::LEFT_BANDPASS_OUTPUT));
  92. addOutput(Port::create<PJ301MPort>(Vec(130, 180), Port::OUTPUT, module, PGStereoVCF::LEFT_HIGHPASS_OUTPUT));
  93. addOutput(Port::create<PJ301MPort>(Vec(160, 100), Port::OUTPUT, module, PGStereoVCF::RIGHT_LOWPASS_OUTPUT));
  94. addOutput(Port::create<PJ301MPort>(Vec(160, 140), Port::OUTPUT, module, PGStereoVCF::RIGHT_BANDPASS_OUTPUT));
  95. addOutput(Port::create<PJ301MPort>(Vec(160, 180), Port::OUTPUT, module, PGStereoVCF::RIGHT_HIGHPASS_OUTPUT));
  96. }
  97. };
  98. } // namespace rack_plugin_PG_Instruments
  99. using namespace rack_plugin_PG_Instruments;
  100. RACK_PLUGIN_MODEL_INIT(PG_Instruments, PGStereoVCF) {
  101. Model *modelPGStereoVCF = Model::create<PGStereoVCF, PGStereoVCFWidget>("PG-Instruments", "PGStereoVCF", "PG Stereo VCF", ATTENUATOR_TAG);
  102. return modelPGStereoVCF;
  103. }