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.

122 lines
4.6KB

  1. #include "dsp/digital.hpp"
  2. #include "qwelk.hpp"
  3. #include "qwelk_common.h"
  4. namespace rack_plugin_Qwelk {
  5. struct ModuleMix : Module {
  6. enum ParamIds {
  7. PARAM_GAIN_M,
  8. PARAM_GAIN_S,
  9. PARAM_GAIN_MS,
  10. PARAM_GAIN_L,
  11. PARAM_GAIN_R,
  12. PARAM_GAIN_LR,
  13. NUM_PARAMS
  14. };
  15. enum InputIds {
  16. IN_L,
  17. IN_R,
  18. IN_M,
  19. IN_S,
  20. IN_GAIN_M,
  21. IN_GAIN_S,
  22. IN_GAIN_L,
  23. IN_GAIN_R,
  24. NUM_INPUTS
  25. };
  26. enum OutputIds {
  27. OUT_M,
  28. OUT_S,
  29. OUT_L,
  30. OUT_R,
  31. NUM_OUTPUTS
  32. };
  33. enum LightIds {
  34. NUM_LIGHTS
  35. };
  36. ModuleMix() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  37. void step() override;
  38. };
  39. static inline float _max(float a, float b) {return a < b ? b : a;}
  40. void ModuleMix::step() {
  41. if (inputs[IN_L].active && inputs[IN_R].active) {
  42. float iam = _max(inputs[IN_GAIN_M].value, 0.f) / 10.0;
  43. float ias = _max(inputs[IN_GAIN_S].value, 0.f) / 10.0;
  44. float ams = params[PARAM_GAIN_MS].value;
  45. float am = inputs[IN_GAIN_M].active ? params[PARAM_GAIN_M].value * iam : params[PARAM_GAIN_M].value;
  46. float as = inputs[IN_GAIN_S].active ? params[PARAM_GAIN_S].value * ias : params[PARAM_GAIN_S].value;
  47. float l = inputs[IN_L].value;
  48. float r = inputs[IN_R].value;
  49. float m = l + r;
  50. float s = l - r;
  51. outputs[OUT_M].value = m * ams * am;
  52. outputs[OUT_S].value = s * ams * as;
  53. }
  54. if (inputs[IN_M].active && inputs[IN_S].active) {
  55. float ial = _max(inputs[IN_GAIN_L].value, 0.f) / 10.0;
  56. float iar = _max(inputs[IN_GAIN_R].value, 0.f) / 10.0;
  57. float alr = params[PARAM_GAIN_LR].value;
  58. float al = inputs[IN_GAIN_L].active ? params[PARAM_GAIN_L].value * ial : params[PARAM_GAIN_L].value;
  59. float ar = inputs[IN_GAIN_R].active ? params[PARAM_GAIN_R].value * iar : params[PARAM_GAIN_R].value;
  60. float m = inputs[IN_M].value;
  61. float s = inputs[IN_S].value;
  62. float l = (m + s) * 0.5;
  63. float r = (m - s) * 0.5;
  64. outputs[OUT_L].value = l * alr * al;
  65. outputs[OUT_R].value = r * alr * ar;
  66. }
  67. }
  68. struct WidgetMix : ModuleWidget {
  69. WidgetMix(ModuleMix *module);
  70. };
  71. WidgetMix::WidgetMix(ModuleMix *module) : ModuleWidget(module) {
  72. setPanel(SVG::load(assetPlugin(plugin, "res/Mix.svg")));
  73. addChild(Widget::create<ScrewSilver>(Vec(5, 0)));
  74. addChild(Widget::create<ScrewSilver>(Vec(5, 365)));
  75. float x = box.size.x / 2.0 - 27;
  76. addInput(Port::create<PJ301MPort>(Vec(x , 25), Port::INPUT, module, ModuleMix::IN_L));
  77. addInput(Port::create<PJ301MPort>(Vec(x + 30, 25), Port::INPUT, module, ModuleMix::IN_R));
  78. addParam(ParamWidget::create<SmallKnob>(Vec(x + 28, 55), module, ModuleMix::PARAM_GAIN_MS, 0.0, 1.0, 1.0));
  79. addParam(ParamWidget::create<TinyKnob>(Vec(x , 90), module, ModuleMix::PARAM_GAIN_M, 0.0, 1.0, 1.0));
  80. addInput(Port::create<PJ301MPort>(Vec(x + 30 , 88), Port::INPUT, module, ModuleMix::IN_GAIN_M));
  81. addOutput(Port::create<PJ301MPort>(Vec(x + 30, 113), Port::OUTPUT, module, ModuleMix::OUT_M));
  82. addParam(ParamWidget::create<TinyKnob>(Vec(x , 147), module, ModuleMix::PARAM_GAIN_S, 0.0, 1.0, 1.0));
  83. addInput(Port::create<PJ301MPort>(Vec(x + 30 , 145), Port::INPUT, module, ModuleMix::IN_GAIN_S));
  84. addOutput(Port::create<PJ301MPort>(Vec(x + 30, 169), Port::OUTPUT, module, ModuleMix::OUT_S));
  85. addInput(Port::create<PJ301MPort>(Vec(x , 210), Port::INPUT, module, ModuleMix::IN_M));
  86. addInput(Port::create<PJ301MPort>(Vec(x + 30, 210), Port::INPUT, module, ModuleMix::IN_S));
  87. addParam(ParamWidget::create<SmallKnob>(Vec(x + 28, 240), module, ModuleMix::PARAM_GAIN_LR, 0.0, 1.0, 1.0));
  88. addParam(ParamWidget::create<TinyKnob>(Vec(x , 275), module, ModuleMix::PARAM_GAIN_L, 0.0, 1.0, 1.0));
  89. addInput(Port::create<PJ301MPort>(Vec(x + 30 , 273), Port::INPUT, module, ModuleMix::IN_GAIN_L));
  90. addOutput(Port::create<PJ301MPort>(Vec(x + 30, 298), Port::OUTPUT, module, ModuleMix::OUT_L));
  91. addParam(ParamWidget::create<TinyKnob>(Vec(x , 332), module, ModuleMix::PARAM_GAIN_R, 0.0, 1.0, 1.0));
  92. addInput(Port::create<PJ301MPort>(Vec(x + 30 , 330), Port::INPUT, module, ModuleMix::IN_GAIN_R));
  93. addOutput(Port::create<PJ301MPort>(Vec(x + 30, 355), Port::OUTPUT, module, ModuleMix::OUT_R));
  94. }
  95. } // namespace rack_plugin_Qwelk
  96. using namespace rack_plugin_Qwelk;
  97. RACK_PLUGIN_MODEL_INIT(Qwelk, Mix) {
  98. Model *modelMix = Model::create<ModuleMix, WidgetMix>(
  99. TOSTRING(SLUG), "Mix", "Mix", UTILITY_TAG, MIXER_TAG, AMPLIFIER_TAG);
  100. return modelMix;
  101. }