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.

118 lines
4.6KB

  1. #include "plugin.hpp"
  2. struct MidSide : Module {
  3. enum ParamIds {
  4. ENC_WIDTH_PARAM,
  5. DEC_WIDTH_PARAM,
  6. NUM_PARAMS
  7. };
  8. enum InputIds {
  9. ENC_WIDTH_INPUT,
  10. ENC_LEFT_INPUT,
  11. ENC_RIGHT_INPUT,
  12. DEC_WIDTH_INPUT,
  13. DEC_MID_INPUT,
  14. DEC_SIDES_INPUT,
  15. NUM_INPUTS
  16. };
  17. enum OutputIds {
  18. ENC_MID_OUTPUT,
  19. ENC_SIDES_OUTPUT,
  20. DEC_LEFT_OUTPUT,
  21. DEC_RIGHT_OUTPUT,
  22. NUM_OUTPUTS
  23. };
  24. enum LightIds {
  25. NUM_LIGHTS
  26. };
  27. MidSide() {
  28. config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
  29. configParam(ENC_WIDTH_PARAM, 0.f, 2.f, 1.f, "Encoder width", "%", 0, 100);
  30. configParam(DEC_WIDTH_PARAM, 0.f, 2.f, 1.f, "Decoder width", "%", 0, 100);
  31. configInput(ENC_WIDTH_INPUT, "Encoder width");
  32. configInput(ENC_LEFT_INPUT, "Encoder left");
  33. configInput(ENC_RIGHT_INPUT, "Encoder right");
  34. configInput(DEC_WIDTH_INPUT, "Decoder width");
  35. configInput(DEC_MID_INPUT, "Decoder mid");
  36. configInput(DEC_SIDES_INPUT, "Decoder sides");
  37. configOutput(ENC_MID_OUTPUT, "Encoder mid");
  38. configOutput(ENC_SIDES_OUTPUT, "Encoder sides");
  39. configOutput(DEC_LEFT_OUTPUT, "Decoder left");
  40. configOutput(DEC_RIGHT_OUTPUT, "Decoder right");
  41. }
  42. void process(const ProcessArgs& args) override {
  43. using simd::float_4;
  44. // Encoder
  45. {
  46. int channels = std::max(inputs[ENC_LEFT_INPUT].getChannels(), inputs[ENC_RIGHT_INPUT].getChannels());
  47. outputs[ENC_MID_OUTPUT].setChannels(channels);
  48. outputs[ENC_SIDES_OUTPUT].setChannels(channels);
  49. for (int c = 0; c < channels; c += 4) {
  50. float_4 width = params[ENC_WIDTH_PARAM].getValue();
  51. width += inputs[ENC_WIDTH_INPUT].getPolyVoltageSimd<float_4>(c) / 10 * 2;
  52. width = simd::fmax(width, 0.f);
  53. float_4 left = inputs[ENC_LEFT_INPUT].getVoltageSimd<float_4>(c);
  54. float_4 right = inputs[ENC_RIGHT_INPUT].getVoltageSimd<float_4>(c);
  55. float_4 mid = (left + right) / 2;
  56. float_4 sides = (left - right) / 2 * width;
  57. outputs[ENC_MID_OUTPUT].setVoltageSimd(mid, c);
  58. outputs[ENC_SIDES_OUTPUT].setVoltageSimd(sides, c);
  59. }
  60. }
  61. // Decoder
  62. {
  63. int channels = std::max(inputs[DEC_MID_INPUT].getChannels(), inputs[DEC_SIDES_INPUT].getChannels());
  64. outputs[DEC_LEFT_OUTPUT].setChannels(channels);
  65. outputs[DEC_RIGHT_OUTPUT].setChannels(channels);
  66. for (int c = 0; c < channels; c += 4) {
  67. float_4 width = params[DEC_WIDTH_PARAM].getValue();
  68. width += inputs[DEC_WIDTH_INPUT].getPolyVoltageSimd<float_4>(c) / 10 * 2;
  69. width = simd::fmax(width, 0.f);
  70. float_4 mid = inputs[DEC_MID_INPUT].getVoltageSimd<float_4>(c);
  71. float_4 sides = inputs[DEC_SIDES_INPUT].getVoltageSimd<float_4>(c);
  72. float_4 left = mid + sides * width;
  73. float_4 right = mid - sides * width;
  74. outputs[DEC_LEFT_OUTPUT].setVoltageSimd(left, c);
  75. outputs[DEC_RIGHT_OUTPUT].setVoltageSimd(right, c);
  76. }
  77. }
  78. }
  79. };
  80. struct MidSideWidget : ModuleWidget {
  81. MidSideWidget(MidSide* module) {
  82. setModule(module);
  83. setPanel(createPanel(asset::plugin(pluginInstance, "res/MidSide.svg")));
  84. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  85. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  86. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  87. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  88. addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(7.285, 25.203)), module, MidSide::ENC_WIDTH_PARAM));
  89. addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(7.285, 80.583)), module, MidSide::DEC_WIDTH_PARAM));
  90. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(18.122, 25.142)), module, MidSide::ENC_WIDTH_INPUT));
  91. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.285, 41.373)), module, MidSide::ENC_LEFT_INPUT));
  92. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(18.122, 41.373)), module, MidSide::ENC_RIGHT_INPUT));
  93. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(18.122, 80.603)), module, MidSide::DEC_WIDTH_INPUT));
  94. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.285, 96.859)), module, MidSide::DEC_MID_INPUT));
  95. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(18.122, 96.859)), module, MidSide::DEC_SIDES_INPUT));
  96. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.285, 57.679)), module, MidSide::ENC_MID_OUTPUT));
  97. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.122, 57.679)), module, MidSide::ENC_SIDES_OUTPUT));
  98. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.285, 113.115)), module, MidSide::DEC_LEFT_OUTPUT));
  99. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(18.122, 113.115)), module, MidSide::DEC_RIGHT_OUTPUT));
  100. }
  101. };
  102. Model* modelMidSide = createModel<MidSide, MidSideWidget>("MidSide");