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
4.1KB

  1. #include "HetrickCV.hpp"
  2. namespace rack_plugin_HetrickCV {
  3. #ifdef USE_VST2
  4. #define plugin "HetrickCV"
  5. #endif // USE_VST2
  6. struct LogicCombine : Module
  7. {
  8. enum ParamIds
  9. {
  10. NUM_PARAMS
  11. };
  12. enum InputIds
  13. {
  14. IN1_INPUT,
  15. IN2_INPUT,
  16. IN3_INPUT,
  17. IN4_INPUT,
  18. IN5_INPUT,
  19. IN6_INPUT,
  20. IN7_INPUT,
  21. IN8_INPUT,
  22. NUM_INPUTS
  23. };
  24. enum OutputIds
  25. {
  26. OR_OUTPUT,
  27. NOR_OUTPUT,
  28. TRIG_OUTPUT,
  29. NUM_OUTPUTS
  30. };
  31. enum LightIds
  32. {
  33. OR_LIGHT,
  34. NOR_LIGHT,
  35. TRIG_LIGHT,
  36. NUM_LIGHTS
  37. };
  38. bool ins[NUM_INPUTS] = {};
  39. bool trigs[NUM_INPUTS] = {};
  40. float outs[3] = {};
  41. float trigLight;
  42. SchmittTrigger inTrigs[NUM_INPUTS];
  43. bool orState = false;
  44. bool trigState = false;
  45. const float lightLambda = 0.075;
  46. TriggerGenerator trigger;
  47. LogicCombine() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS)
  48. {
  49. }
  50. void step() override;
  51. // For more advanced Module features, read Rack's engine.hpp header file
  52. // - toJson, fromJson: serialization of internal data
  53. // - onSampleRateChange: event triggered by a change of sample rate
  54. // - reset, randomize: implements special behavior when user clicks these from the context menu
  55. };
  56. void LogicCombine::step()
  57. {
  58. orState = false;
  59. trigState = false;
  60. for(int i = 0; i < NUM_INPUTS; i++)
  61. {
  62. ins[i] = (inputs[IN1_INPUT + i].value >= 1.0f);
  63. trigs[i] = inTrigs[i].process(inputs[IN1_INPUT + i].value);
  64. orState = orState || ins[i];
  65. trigState = trigState || trigs[i];
  66. }
  67. outs[0] = orState ? 5.0f : 0.0f;
  68. outs[1] = 5.0f - outs[0];
  69. if(trigState)
  70. {
  71. trigger.trigger();
  72. lights[TRIG_LIGHT].value = 5.0f;
  73. }
  74. outs[2] = trigger.process() ? 5.0f : 0.0f;
  75. if (lights[TRIG_LIGHT].value > 0.01)
  76. lights[TRIG_LIGHT].value -= lights[TRIG_LIGHT].value / lightLambda * engineGetSampleTime();
  77. outputs[OR_OUTPUT].value = outs[0];
  78. outputs[NOR_OUTPUT].value = outs[1];
  79. outputs[TRIG_OUTPUT].value = outs[2];
  80. lights[OR_LIGHT].setBrightness(outs[0]);
  81. lights[NOR_LIGHT].setBrightness(outs[1]);
  82. lights[TRIG_LIGHT].setBrightnessSmooth(outs[2]);
  83. }
  84. struct LogicCombineWidget : ModuleWidget { LogicCombineWidget(LogicCombine *module); };
  85. LogicCombineWidget::LogicCombineWidget(LogicCombine *module) : ModuleWidget(module)
  86. {
  87. box.size = Vec(8 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  88. {
  89. auto *panel = new SVGPanel();
  90. panel->box.size = box.size;
  91. panel->setBackground(SVG::load(assetPlugin(plugin, "res/LogicCombiner.svg")));
  92. addChild(panel);
  93. }
  94. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  95. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)));
  96. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  97. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)));
  98. //////PARAMS//////
  99. //////INPUTS//////
  100. const int inSpacing = 40;
  101. const int outPos = 67;
  102. const int lightPos = outPos + 29;
  103. for(int i = 0; i < LogicCombine::NUM_INPUTS; i++)
  104. {
  105. addInput(Port::create<PJ301MPort>(Vec(10, 50 + (i*inSpacing)), Port::INPUT, module, LogicCombine::IN1_INPUT + i));
  106. }
  107. //////OUTPUTS//////
  108. addOutput(Port::create<PJ301MPort>(Vec(outPos, 150), Port::OUTPUT, module, LogicCombine::OR_OUTPUT));
  109. addOutput(Port::create<PJ301MPort>(Vec(outPos, 195), Port::OUTPUT, module, LogicCombine::NOR_OUTPUT));
  110. addOutput(Port::create<PJ301MPort>(Vec(outPos, 240), Port::OUTPUT, module, LogicCombine::TRIG_OUTPUT));
  111. //////BLINKENLIGHTS//////
  112. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 158), module, LogicCombine::OR_LIGHT));
  113. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 203), module, LogicCombine::NOR_LIGHT));
  114. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 248), module, LogicCombine::TRIG_LIGHT));
  115. }
  116. } // namespace rack_plugin_HetrickCV
  117. using namespace rack_plugin_HetrickCV;
  118. RACK_PLUGIN_MODEL_INIT(HetrickCV, LogicCombine) {
  119. Model *modelLogicCombine = Model::create<LogicCombine, LogicCombineWidget>("HetrickCV", "Logic Combine", "OR Logic (Gate Combiner)", LOGIC_TAG);
  120. return modelLogicCombine;
  121. }