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.

133 lines
5.3KB

  1. #include "plugin.hpp"
  2. using simd::float_4;
  3. struct STMix : Module {
  4. // NOTE: not including auxiliary channel
  5. static const int numMixerChannels = 4;
  6. enum ParamIds {
  7. ENUMS(GAIN_PARAM, numMixerChannels),
  8. NUM_PARAMS
  9. };
  10. enum InputIds {
  11. // +1 for aux
  12. ENUMS(LEFT_INPUT, numMixerChannels + 1),
  13. ENUMS(RIGHT_INPUT, numMixerChannels + 1),
  14. NUM_INPUTS
  15. };
  16. enum OutputIds {
  17. LEFT_OUTPUT,
  18. RIGHT_OUTPUT,
  19. NUM_OUTPUTS
  20. };
  21. enum LightIds {
  22. ENUMS(LEFT_LED, 3),
  23. ENUMS(RIGHT_LED, 3),
  24. NUM_LIGHTS
  25. };
  26. STMix() {
  27. config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
  28. for (int i = 0; i < numMixerChannels; ++i) {
  29. configParam(GAIN_PARAM + i, 0.f, 1.f, 0.f, string::f("Gain %d", i + 1));
  30. }
  31. }
  32. void process(const ProcessArgs& args) override {
  33. float_4 out_left[4] = {};
  34. float_4 out_right[4] = {};
  35. int numActivePolyphonyEngines = 1;
  36. for (int i = 0; i < numMixerChannels + 1; ++i) {
  37. const int stereoPolyChannels = std::max(inputs[LEFT_INPUT + i].getChannels(),
  38. inputs[RIGHT_INPUT + i].getChannels());
  39. numActivePolyphonyEngines = std::max(numActivePolyphonyEngines, stereoPolyChannels);
  40. }
  41. for (int i = 0; i < numMixerChannels + 1; ++i) {
  42. for (int c = 0; c < numActivePolyphonyEngines; c += 4) {
  43. const float_4 in_left = inputs[LEFT_INPUT + i].getNormalPolyVoltageSimd<float_4>(0.f, c);
  44. const float_4 in_right = inputs[RIGHT_INPUT + i].getNormalPolyVoltageSimd<float_4>(in_left, c);
  45. const float gain = (i < numMixerChannels) ? params[GAIN_PARAM + i].getValue() : 1.f;
  46. out_left[c / 4] += in_left * gain;
  47. out_right[c / 4] += in_right * gain;
  48. }
  49. }
  50. outputs[LEFT_OUTPUT].setChannels(numActivePolyphonyEngines);
  51. outputs[RIGHT_OUTPUT].setChannels(numActivePolyphonyEngines);
  52. for (int c = 0; c < numActivePolyphonyEngines; c += 4) {
  53. outputs[LEFT_OUTPUT].setVoltageSimd(out_left[c / 4], c);
  54. outputs[RIGHT_OUTPUT].setVoltageSimd(out_right[c / 4], c);
  55. }
  56. if (numActivePolyphonyEngines == 1) {
  57. lights[LEFT_LED + 0].setSmoothBrightness(outputs[LEFT_OUTPUT].getVoltage() / 5.f, args.sampleTime);
  58. lights[RIGHT_LED + 0].setSmoothBrightness(outputs[RIGHT_OUTPUT].getVoltage() / 5.f, args.sampleTime);
  59. lights[LEFT_LED + 1].setBrightness(0.f);
  60. lights[RIGHT_LED + 1].setBrightness(0.f);
  61. lights[LEFT_LED + 2].setBrightness(0.f);
  62. lights[RIGHT_LED + 2].setBrightness(0.f);
  63. }
  64. else {
  65. lights[LEFT_LED + 0].setBrightness(0.f);
  66. lights[RIGHT_LED + 0].setBrightness(0.f);
  67. lights[LEFT_LED + 1].setBrightness(0.f);
  68. lights[RIGHT_LED + 1].setBrightness(0.f);
  69. float b_left = 0.f;
  70. float b_right = 0.f;
  71. for (int c = 0; c < numActivePolyphonyEngines; c++) {
  72. b_left += std::pow(out_left[c / 4][c % 4], 2);
  73. b_right += std::pow(out_right[c / 4][c % 4], 2);
  74. }
  75. b_left = std::sqrt(b_left) / 5.f;
  76. b_right = std::sqrt(b_right) / 5.f;
  77. lights[LEFT_LED + 2].setSmoothBrightness(b_left, args.sampleTime);
  78. lights[RIGHT_LED + 2].setSmoothBrightness(b_right, args.sampleTime);
  79. }
  80. }
  81. };
  82. struct STMixWidget : ModuleWidget {
  83. STMixWidget(STMix* module) {
  84. setModule(module);
  85. setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/STMix.svg")));
  86. addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, 0)));
  87. addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  88. addParam(createParamCentered<Davies1900hWhiteKnob>(mm2px(Vec(21.0, 18.141)), module, STMix::GAIN_PARAM + 0));
  89. addParam(createParamCentered<Davies1900hWhiteKnob>(mm2px(Vec(21.0, 41.451)), module, STMix::GAIN_PARAM + 1));
  90. addParam(createParamCentered<Davies1900hWhiteKnob>(mm2px(Vec(21.0, 64.318)), module, STMix::GAIN_PARAM + 2));
  91. addParam(createParamCentered<Davies1900hWhiteKnob>(mm2px(Vec(21.0, 87.124)), module, STMix::GAIN_PARAM + 3));
  92. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 13.108)), module, STMix::LEFT_INPUT + 0));
  93. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 36.175)), module, STMix::LEFT_INPUT + 1));
  94. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 59.243)), module, STMix::LEFT_INPUT + 2));
  95. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 82.311)), module, STMix::LEFT_INPUT + 3));
  96. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 105.378)), module, STMix::LEFT_INPUT + 4));
  97. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 23.108)), module, STMix::RIGHT_INPUT + 0));
  98. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 46.354)), module, STMix::RIGHT_INPUT + 1));
  99. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 69.237)), module, STMix::RIGHT_INPUT + 2));
  100. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 92.132)), module, STMix::RIGHT_INPUT + 3));
  101. addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.3, 115.379)), module, STMix::RIGHT_INPUT + 4));
  102. addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(23.8, 105.422)), module, STMix::LEFT_OUTPUT));
  103. addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(23.8, 115.392)), module, STMix::RIGHT_OUTPUT));
  104. addChild(createLightCentered<MediumLight<RedGreenBlueLight>>(mm2px(Vec(16.8, 103.0)), module, STMix::LEFT_LED));
  105. addChild(createLightCentered<MediumLight<RedGreenBlueLight>>(mm2px(Vec(16.8, 113.0)), module, STMix::RIGHT_LED));
  106. }
  107. };
  108. Model* modelSTMix = createModel<STMix, STMixWidget>("STMix");