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.

130 lines
5.1KB

  1. #include "Fundamental.hpp"
  2. #include "dsp/digital.hpp"
  3. #include "dsp/filter.hpp"
  4. template <int TYPE>
  5. struct SequentialSwitch : Module {
  6. enum ParamIds {
  7. CHANNELS_PARAM,
  8. NUM_PARAMS
  9. };
  10. enum InputIds {
  11. CLOCK_INPUT,
  12. RESET_INPUT,
  13. ENUMS(IN_INPUT, TYPE == 1 ? 1 : 4),
  14. NUM_INPUTS
  15. };
  16. enum OutputIds {
  17. ENUMS(OUT_OUTPUT, TYPE == 1 ? 4 : 1),
  18. NUM_OUTPUTS
  19. };
  20. enum LightIds {
  21. ENUMS(CHANNEL_LIGHT, 4),
  22. NUM_LIGHTS
  23. };
  24. SchmittTrigger clockTrigger;
  25. SchmittTrigger resetTrigger;
  26. int channel = 0;
  27. SlewLimiter channelFilter[4];
  28. SequentialSwitch() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  29. for (int i = 0; i < 4; i++) {
  30. channelFilter[i].rise = 0.01f;
  31. channelFilter[i].fall = 0.01f;
  32. }
  33. }
  34. void step() override {
  35. // Determine current channel
  36. if (clockTrigger.process(inputs[CLOCK_INPUT].value / 2.f)) {
  37. channel++;
  38. }
  39. if (resetTrigger.process(inputs[RESET_INPUT].value / 2.f)) {
  40. channel = 0;
  41. }
  42. int channels = 4 - (int) params[CHANNELS_PARAM].value;
  43. channel %= channels;
  44. // Filter channels
  45. for (int i = 0; i < 4; i++) {
  46. channelFilter[i].process(channel == i ? 1.0f : 0.0f);
  47. }
  48. // Set outputs
  49. if (TYPE == 1) {
  50. float out = inputs[IN_INPUT + 0].value;
  51. for (int i = 0; i < 4; i++) {
  52. outputs[OUT_OUTPUT + i].value = channelFilter[i].out * out;
  53. }
  54. }
  55. else {
  56. float out = 0.0f;
  57. for (int i = 0; i < 4; i++) {
  58. out += channelFilter[i].out * inputs[IN_INPUT + i].value;
  59. }
  60. outputs[OUT_OUTPUT + 0].value = out;
  61. }
  62. // Set lights
  63. for (int i = 0; i < 4; i++) {
  64. lights[CHANNEL_LIGHT + i].setBrightness(channelFilter[i].out);
  65. }
  66. }
  67. };
  68. SequentialSwitch1Widget::SequentialSwitch1Widget() {
  69. typedef SequentialSwitch<1> TSequentialSwitch;
  70. TSequentialSwitch *module = new TSequentialSwitch();
  71. setModule(module);
  72. setPanel(SVG::load(assetPlugin(plugin, "res/SequentialSwitch1.svg")));
  73. addChild(createScrew<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  74. addChild(createScrew<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  75. addParam(createParam<CKSSThree>(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM, 0.0f, 2.0f, 0.0f));
  76. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT));
  77. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT));
  78. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUT + 0));
  79. addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUT + 0));
  80. addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUT + 1));
  81. addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUT + 2));
  82. addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUT + 3));
  83. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0));
  84. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1));
  85. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 97.7167)), module, TSequentialSwitch::CHANNEL_LIGHT + 2));
  86. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 107.716)), module, TSequentialSwitch::CHANNEL_LIGHT + 3));
  87. }
  88. SequentialSwitch2Widget::SequentialSwitch2Widget() {
  89. typedef SequentialSwitch<2> TSequentialSwitch;
  90. TSequentialSwitch *module = new TSequentialSwitch();
  91. setModule(module);
  92. setPanel(SVG::load(assetPlugin(plugin, "res/SequentialSwitch2.svg")));
  93. addChild(createScrew<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  94. addChild(createScrew<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  95. addParam(createParam<CKSSThree>(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM, 0.0f, 2.0f, 0.0f));
  96. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT));
  97. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT));
  98. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUT + 0));
  99. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUT + 1));
  100. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUT + 2));
  101. addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUT + 3));
  102. addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUT + 0));
  103. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0));
  104. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1));
  105. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 82.6285)), module, TSequentialSwitch::CHANNEL_LIGHT + 2));
  106. addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 92.6276)), module, TSequentialSwitch::CHANNEL_LIGHT + 3));
  107. }