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.

164 lines
4.1KB

  1. #include "ML_modules.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_ML_modules {
  4. struct OctaSwitch : Module {
  5. enum ParamIds {
  6. THRESHOLD_PARAM,
  7. NUM_PARAMS
  8. };
  9. enum InputIds {
  10. THRESHOLD_INPUT,
  11. GATE_INPUT,
  12. A_INPUT = GATE_INPUT + 8,
  13. B_INPUT = A_INPUT + 8,
  14. NUM_INPUTS = B_INPUT + 8
  15. };
  16. enum OutputIds {
  17. OUT_OUTPUT,
  18. NUM_OUTPUTS = OUT_OUTPUT + 8
  19. };
  20. enum LightIds {
  21. NUM_LIGHTS
  22. };
  23. float threshold = 0.0;
  24. OctaSwitch() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ) { };
  25. void step() override;
  26. };
  27. void OctaSwitch::step() {
  28. bool gate[8];
  29. threshold = inputs[THRESHOLD_INPUT].normalize(params[THRESHOLD_PARAM].value);
  30. gate[0] = inputs[GATE_INPUT].normalize(0.0) > threshold;
  31. for(int i=1; i<8; i++) {
  32. if( inputs[GATE_INPUT+i].active ) gate[i] = inputs[GATE_INPUT+i].value > threshold;
  33. else gate[i] = gate[i-1];
  34. }
  35. for(int i=0; i<8; i++) {
  36. outputs[OUT_OUTPUT+i].value = gate[i] ? inputs[B_INPUT+i].normalize(0.0) : inputs[A_INPUT+i].normalize(0.0);
  37. }
  38. };
  39. struct ThresholdDisplayWidget : TransparentWidget {
  40. float *value;
  41. std::shared_ptr<Font> font;
  42. ThresholdDisplayWidget() {
  43. font = Font::load(assetPlugin(plugin, "res/Segment7Standard.ttf"));
  44. };
  45. void draw(NVGcontext *vg) {
  46. // Background
  47. NVGcolor backgroundColor = nvgRGB(0x20, 0x20, 0x20);
  48. NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
  49. nvgBeginPath(vg);
  50. nvgRoundedRect(vg, 0.0, 0.0, box.size.x, box.size.y, 4.0);
  51. nvgFillColor(vg, backgroundColor);
  52. nvgFill(vg);
  53. nvgStrokeWidth(vg, 1.0);
  54. nvgStrokeColor(vg, borderColor);
  55. nvgStroke(vg);
  56. nvgFontSize(vg, 18);
  57. nvgFontFaceId(vg, font->handle);
  58. nvgTextLetterSpacing(vg, 1.0);
  59. char display_string[10];
  60. sprintf(display_string,"%5.1f",*value);
  61. Vec textPos = Vec(3.0f, 17.0f);
  62. NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c);
  63. nvgFillColor(vg, nvgTransRGBA(textColor, 16));
  64. nvgText(vg, textPos.x, textPos.y, "~~~~", NULL);
  65. textColor = nvgRGB(0xda, 0xe9, 0x29);
  66. nvgFillColor(vg, nvgTransRGBA(textColor, 16));
  67. nvgText(vg, textPos.x, textPos.y, "\\\\\\\\", NULL);
  68. {
  69. textColor = nvgRGB(0xf0, 0x00, 0x00);
  70. nvgFillColor(vg, textColor);
  71. nvgText(vg, textPos.x, textPos.y, display_string, NULL);
  72. };
  73. }
  74. };
  75. struct OctaSwitchWidget : ModuleWidget {
  76. OctaSwitchWidget(OctaSwitch *module);
  77. };
  78. OctaSwitchWidget::OctaSwitchWidget(OctaSwitch *module) : ModuleWidget(module) {
  79. box.size = Vec(15*10, 380);
  80. {
  81. SVGPanel *panel = new SVGPanel();
  82. panel->box.size = box.size;
  83. panel->setBackground(SVG::load(assetPlugin(plugin,"res/OctaSwitch.svg")));
  84. addChild(panel);
  85. }
  86. addChild(Widget::create<MLScrew>(Vec(15, 0)));
  87. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 0)));
  88. addChild(Widget::create<MLScrew>(Vec(15, 365)));
  89. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 365)));
  90. const float offset_y = 60, delta_y = 32, row1=15, row2 = 47, row3 = 77, row4 = 110;
  91. addInput(Port::create<MLPort>( Vec(row1, 328 ), Port::INPUT, module, OctaSwitch::THRESHOLD_INPUT));
  92. addParam(ParamWidget::create<SmallBlueMLKnob>( Vec(row2-5, 326), module, OctaSwitch::THRESHOLD_PARAM, -5.0, 10.0, 1.0));
  93. for( int i=0; i<8; i++) {
  94. addInput(Port::create<MLPort>(Vec(row1, offset_y + i*delta_y ), Port::INPUT, module, OctaSwitch::GATE_INPUT+i));
  95. addInput(Port::create<MLPort>(Vec(row2, offset_y + i*delta_y ), Port::INPUT, module, OctaSwitch::A_INPUT+i));
  96. addInput(Port::create<MLPort>(Vec(row3, offset_y + i*delta_y ), Port::INPUT, module, OctaSwitch::B_INPUT+i));
  97. addOutput(Port::create<MLPort>(Vec(row4, offset_y + i*delta_y ), Port::OUTPUT, module, OctaSwitch::OUT_OUTPUT+i));
  98. };
  99. ThresholdDisplayWidget *display = new ThresholdDisplayWidget();
  100. display->box.pos = Vec(row3-3,330);
  101. display->box.size = Vec(65, 20);
  102. display->value = &module->threshold;
  103. addChild(display);
  104. }
  105. } // namespace rack_plugin_ML_modules
  106. using namespace rack_plugin_ML_modules;
  107. RACK_PLUGIN_MODEL_INIT(ML_modules, OctaSwitch) {
  108. Model *modelOctaSwitch = Model::create<OctaSwitch, OctaSwitchWidget>("ML modules", "OctaSwitch", "OctaSwitch", SWITCH_TAG, UTILITY_TAG );
  109. return modelOctaSwitch;
  110. }