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.

198 lines
4.4KB

  1. #include "ML_modules.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_ML_modules {
  4. struct TrigSwitch2 : Module {
  5. enum ParamIds {
  6. STEP_PARAM,
  7. NUM_PARAMS = STEP_PARAM + 9
  8. };
  9. enum InputIds {
  10. CV_INPUT,
  11. TRIG_INPUT,
  12. NUM_INPUTS = TRIG_INPUT + 8
  13. };
  14. enum OutputIds {
  15. OUT_OUTPUT,
  16. NUM_OUTPUTS = OUT_OUTPUT+8
  17. };
  18. enum LightIds {
  19. STEP_LIGHT,
  20. NUM_LIGHTS = STEP_LIGHT+8
  21. };
  22. TrigSwitch2() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ) { reset(); };
  23. void step() override;
  24. enum OutMode {
  25. ZERO,
  26. LAST
  27. };
  28. OutMode outMode = ZERO;
  29. json_t *toJson() override {
  30. json_t *rootJ = json_object();
  31. // outMode:
  32. json_object_set_new(rootJ, "outMode", json_integer(outMode));
  33. json_object_set_new(rootJ, "position", json_integer(position));
  34. return rootJ;
  35. };
  36. void fromJson(json_t *rootJ) override {
  37. // outMode:
  38. json_t *outModeJ = json_object_get(rootJ, "outMode");
  39. if(outModeJ) outMode = (OutMode) json_integer_value(outModeJ);
  40. json_t *positionJ = json_object_get(rootJ, "position");
  41. if(positionJ) position = json_integer_value(positionJ);
  42. };
  43. int position=0;
  44. float outs[8] = {};
  45. SchmittTrigger stepTriggers[8];
  46. void reset() override {
  47. position = 0;
  48. for(int i=0; i<8; i++) lights[i].value = 0.0;
  49. for(int i=0; i<8; i++) outs[i]=0.0;
  50. };
  51. };
  52. void TrigSwitch2::step() {
  53. if(outMode==ZERO) { for(int i=0; i<8; i++) outs[i]=0.0; }
  54. for(int i=0; i<8; i++) {
  55. if( stepTriggers[i].process( inputs[TRIG_INPUT+i].normalize(0.0)) + params[STEP_PARAM+i].value ) position = i;
  56. };
  57. outs[position] = inputs[CV_INPUT].normalize(0.0);
  58. for(int i=0; i<8; i++) lights[i].value = (i==position)?1.0:0.0;
  59. for(int i=0; i<8; i++) outputs[OUT_OUTPUT+i].value = outs[i];
  60. };
  61. struct TrigSwitch2OutModeItem : MenuItem {
  62. TrigSwitch2 *trigSwitch2;
  63. TrigSwitch2::OutMode outMode;
  64. void onAction(EventAction &e) override {
  65. trigSwitch2->outMode = outMode;
  66. };
  67. void step() override {
  68. rightText = (trigSwitch2->outMode == outMode)? "✔" : "";
  69. };
  70. };
  71. struct TrigSwitch2Widget : ModuleWidget {
  72. TrigSwitch2Widget(TrigSwitch2 *module);
  73. json_t *toJsonData() ;
  74. void fromJsonData(json_t *root) ;
  75. Menu *createContextMenu() override;
  76. };
  77. TrigSwitch2Widget::TrigSwitch2Widget(TrigSwitch2 *module) : ModuleWidget(module) {
  78. box.size = Vec(15*8, 380);
  79. {
  80. SVGPanel *panel = new SVGPanel();
  81. panel->box.size = box.size;
  82. panel->setBackground(SVG::load(assetPlugin(plugin,"res/TrigSwitch2.svg")));
  83. addChild(panel);
  84. }
  85. addChild(Widget::create<MLScrew>(Vec(15, 0)));
  86. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 0)));
  87. addChild(Widget::create<MLScrew>(Vec(15, 365)));
  88. addChild(Widget::create<MLScrew>(Vec(box.size.x-30, 365)));
  89. const float offset_y = 60, delta_y = 32, row1=14, row2 = 50, row3 = 79;
  90. for (int i=0; i<8; i++) {
  91. addInput(Port::create<MLPort>( Vec(row1, offset_y + i*delta_y), Port::INPUT, module, TrigSwitch2::TRIG_INPUT + i));
  92. addParam(ParamWidget::create<ML_MediumLEDButton>(Vec(row2 , offset_y + i*delta_y +3 ), module, TrigSwitch2::STEP_PARAM + i, 0.0, 1.0, 0.0));
  93. addChild(ModuleLightWidget::create<MLMediumLight<GreenLight>>( Vec(row2 + 4, offset_y + i*delta_y + 7), module, TrigSwitch2::STEP_LIGHT+i));
  94. addOutput(Port::create<MLPort>( Vec(row3, offset_y + i*delta_y), Port::OUTPUT, module, TrigSwitch2::OUT_OUTPUT + i));
  95. }
  96. addInput(Port::create<MLPort>(Vec(row3, 320), Port::INPUT, module, TrigSwitch2::CV_INPUT));
  97. }
  98. Menu *TrigSwitch2Widget::createContextMenu() {
  99. Menu *menu = ModuleWidget::createContextMenu();
  100. MenuLabel *spacerLabel = new MenuLabel();
  101. menu->addChild(spacerLabel);
  102. TrigSwitch2 *trigSwitch2 = dynamic_cast<TrigSwitch2*>(module);
  103. assert(trigSwitch2);
  104. MenuLabel *modeLabel = new MenuLabel();
  105. modeLabel->text = "Output Mode";
  106. menu->addChild(modeLabel);
  107. TrigSwitch2OutModeItem *zeroItem = new TrigSwitch2OutModeItem();
  108. zeroItem->text = "Zero";
  109. zeroItem->trigSwitch2 = trigSwitch2;
  110. zeroItem->outMode = TrigSwitch2::ZERO;
  111. menu->addChild(zeroItem);
  112. TrigSwitch2OutModeItem *lastItem = new TrigSwitch2OutModeItem();
  113. lastItem->text = "Last";
  114. lastItem->trigSwitch2 = trigSwitch2;
  115. lastItem->outMode = TrigSwitch2::LAST;
  116. menu->addChild(lastItem);
  117. return menu;
  118. };
  119. } // namespace rack_plugin_ML_modules
  120. using namespace rack_plugin_ML_modules;
  121. RACK_PLUGIN_MODEL_INIT(ML_modules, TrigSwitch2) {
  122. Model *modelTrigSwitch2 = Model::create<TrigSwitch2, TrigSwitch2Widget>("ML modules", "TrigSwitch2", "TrigSwitch 1->8", SWITCH_TAG, UTILITY_TAG );
  123. return modelTrigSwitch2;
  124. }