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.

154 lines
3.3KB

  1. #include "ML_modules.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_ML_modules {
  4. struct OctaFlop : Module {
  5. enum ParamIds {
  6. RESET_PARAM,
  7. TOGGLE_PARAM,
  8. NUM_PARAMS = TOGGLE_PARAM+8
  9. };
  10. enum InputIds {
  11. IN1_INPUT,
  12. IN2_INPUT,
  13. IN3_INPUT,
  14. IN4_INPUT,
  15. IN5_INPUT,
  16. IN6_INPUT,
  17. IN7_INPUT,
  18. IN8_INPUT,
  19. TRIG1_INPUT,
  20. TRIG2_INPUT,
  21. TRIG3_INPUT,
  22. TRIG4_INPUT,
  23. TRIG5_INPUT,
  24. TRIG6_INPUT,
  25. TRIG7_INPUT,
  26. TRIG8_INPUT,
  27. RESET_INPUT,
  28. NUM_INPUTS
  29. };
  30. enum OutputIds {
  31. OUT1_OUTPUT,
  32. OUT2_OUTPUT,
  33. OUT3_OUTPUT,
  34. OUT4_OUTPUT,
  35. OUT5_OUTPUT,
  36. OUT6_OUTPUT,
  37. OUT7_OUTPUT,
  38. OUT8_OUTPUT,
  39. NUM_OUTPUTS
  40. };
  41. enum LightIds {
  42. STATE1_LIGHT,
  43. STATE2_LIGHT,
  44. STATE3_LIGHT,
  45. STATE4_LIGHT,
  46. STATE5_LIGHT,
  47. STATE6_LIGHT,
  48. STATE7_LIGHT,
  49. STATE8_LIGHT,
  50. NUM_LIGHTS
  51. };
  52. SchmittTrigger trigger[8], resetTrigger;
  53. float out[8] = {};
  54. bool state[8] = {};
  55. OctaFlop() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ) { for(int i=0; i<8; i++) state[i]=false; };
  56. void step() override;
  57. };
  58. void OctaFlop::step() {
  59. float trig[8];
  60. trig[0] = inputs[TRIG1_INPUT].normalize(0.0) ;
  61. for(int i=1; i<8; i++) trig[i] = inputs[TRIG1_INPUT+i].normalize(10.0-out[i-1]) ;
  62. for(int i=0; i<8; i++) {
  63. if( trigger[i].process(trig[i]) ) {
  64. state[i] = !state[i];
  65. out[i] = state[i]?10.0:0.0;
  66. };
  67. }
  68. if(resetTrigger.process(params[RESET_PARAM].value + inputs[RESET_INPUT].normalize(0.0))) {
  69. for(int i=0; i<8; i++) {
  70. state[i]=false;
  71. out[i] = 0.0;
  72. trigger[i].reset();
  73. };
  74. };
  75. for(int i=0; i<8; i++) {
  76. outputs[OUT1_OUTPUT+i].value = out[i];
  77. lights[STATE1_LIGHT+i].value = out[i];
  78. }
  79. };
  80. struct OctaFlopWidget : ModuleWidget {
  81. OctaFlopWidget(OctaFlop *module);
  82. };
  83. OctaFlopWidget::OctaFlopWidget(OctaFlop *module) : ModuleWidget(module) {
  84. box.size = Vec(15*8, 380);
  85. {
  86. SVGPanel *panel = new SVGPanel();
  87. panel->box.size = box.size;
  88. panel->setBackground(SVG::load(assetPlugin(plugin,"res/OctaFlop.svg")));
  89. addChild(panel);
  90. }
  91. addChild(Widget::create<MLScrew>(Vec(15, 0)));
  92. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 0)));
  93. addChild(Widget::create<MLScrew>(Vec(15, 365)));
  94. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 365)));
  95. const float offset_y = 60, delta_y = 32, row1=15, row2 = 55, row3 = 80;
  96. for( int i=0; i<8; i++) {
  97. addInput(Port::create<MLPort>(Vec(row1, offset_y + i*delta_y ), Port::INPUT, module, OctaFlop::TRIG1_INPUT+i));
  98. // addParam(ParamWidget::create<ML_SmallLEDButton>(Vec(row2 - 3, offset_y + 5 + i*delta_y), module, OctaFlop::TOGGLE_PARAM+i, 0.0, 10.0, 0.0));
  99. addChild(ModuleLightWidget::create<MLSmallLight<GreenLight>>(Vec(row2 +1, offset_y + 9 + i*delta_y), module, OctaFlop::STATE1_LIGHT+i));
  100. addOutput(Port::create<MLPort>(Vec(row3, offset_y + i*delta_y ), Port::OUTPUT, module, OctaFlop::OUT1_OUTPUT+i));
  101. };
  102. addParam(ParamWidget::create<MLButton>(Vec(row1+3, 320), module, OctaFlop::RESET_PARAM, 0.0, 10.0, 0.0));
  103. addInput(Port::create<MLPort>(Vec(row3, 320), Port::INPUT, module, OctaFlop::RESET_INPUT));
  104. }
  105. } // namespace rack_plugin_ML_modules
  106. using namespace rack_plugin_ML_modules;
  107. RACK_PLUGIN_MODEL_INIT(ML_modules, OctaFlop) {
  108. Model *modelOctaFlop = Model::create<OctaFlop, OctaFlopWidget>("ML modules", "OctaFlop", "OctaFlop", UTILITY_TAG, CLOCK_TAG);
  109. return modelOctaFlop;
  110. }