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.

152 lines
4.2KB

  1. #include "HetrickCV.hpp"
  2. namespace rack_plugin_HetrickCV {
  3. struct Boolean3 : Module
  4. {
  5. enum ParamIds
  6. {
  7. NUM_PARAMS
  8. };
  9. enum InputIds
  10. {
  11. INA_INPUT,
  12. INB_INPUT,
  13. INC_INPUT,
  14. NUM_INPUTS
  15. };
  16. enum OutputIds
  17. {
  18. OR_OUTPUT,
  19. AND_OUTPUT,
  20. XOR_OUTPUT,
  21. NOR_OUTPUT,
  22. NAND_OUTPUT,
  23. XNOR_OUTPUT,
  24. NUM_OUTPUTS
  25. };
  26. enum LightIds
  27. {
  28. OR_LIGHT,
  29. AND_LIGHT,
  30. XOR_LIGHT,
  31. NOR_LIGHT,
  32. NAND_LIGHT,
  33. XNOR_LIGHT,
  34. INA_LIGHT,
  35. INB_LIGHT,
  36. INC_LIGHT,
  37. NUM_LIGHTS
  38. };
  39. HysteresisGate ins[3];
  40. bool inA = false;
  41. bool inB = false;
  42. bool inC = false;
  43. float outs[6] = {};
  44. Boolean3() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS)
  45. {
  46. }
  47. void step() override;
  48. // For more advanced Module features, read Rack's engine.hpp header file
  49. // - toJson, fromJson: serialization of internal data
  50. // - onSampleRateChange: event triggered by a change of sample rate
  51. // - reset, randomize: implements special behavior when user clicks these from the context menu
  52. };
  53. void Boolean3::step()
  54. {
  55. inA = ins[0].process(inputs[INA_INPUT].value);
  56. inB = ins[1].process(inputs[INB_INPUT].value);
  57. inC = ins[2].process(inputs[INC_INPUT].value);
  58. lights[INA_LIGHT].value = inA ? 5.0f : 0.0f;
  59. lights[INB_LIGHT].value = inB ? 5.0f : 0.0f;
  60. lights[INC_LIGHT].value = inC ? 5.0f : 0.0f;
  61. if(inputs[INC_INPUT].active)
  62. {
  63. outs[0] = ((inA || inB) || inC) ? 5.0f : 0.0f;
  64. outs[1] = ((inA && inB) && inC) ? 5.0f : 0.0f;
  65. outs[2] = (!inA && (inB ^ inC)) || (inA && !(inB || inC)) ? 5.0f : 0.0f;
  66. outs[3] = 5.0f - outs[0];
  67. outs[4] = 5.0f - outs[1];
  68. outs[5] = 5.0f - outs[2];
  69. }
  70. else
  71. {
  72. outs[0] = (inA || inB) ? 5.0f : 0.0f;
  73. outs[1] = (inA && inB) ? 5.0f : 0.0f;
  74. outs[2] = (inA != inB) ? 5.0f : 0.0f;
  75. outs[3] = 5.0f - outs[0];
  76. outs[4] = 5.0f - outs[1];
  77. outs[5] = 5.0f - outs[2];
  78. }
  79. outputs[OR_OUTPUT].value = outs[0];
  80. outputs[AND_OUTPUT].value = outs[1];
  81. outputs[XOR_OUTPUT].value = outs[2];
  82. outputs[NOR_OUTPUT].value = outs[3];
  83. outputs[NAND_OUTPUT].value = outs[4];
  84. outputs[XNOR_OUTPUT].value = outs[5];
  85. lights[OR_LIGHT].value = outs[0];
  86. lights[AND_LIGHT].value = outs[1];
  87. lights[XOR_LIGHT].value = outs[2];
  88. lights[NOR_LIGHT].value = outs[3];
  89. lights[NAND_LIGHT].value = outs[4];
  90. lights[XNOR_LIGHT].value = outs[5];
  91. }
  92. struct Boolean3Widget : ModuleWidget { Boolean3Widget(Boolean3 *module); };
  93. Boolean3Widget::Boolean3Widget(Boolean3 *module) : ModuleWidget(module)
  94. {
  95. box.size = Vec(6 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  96. {
  97. auto *panel = new SVGPanel();
  98. panel->box.size = box.size;
  99. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Boolean3.svg")));
  100. addChild(panel);
  101. }
  102. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  103. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)));
  104. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  105. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)));
  106. //////INPUTS//////
  107. addInput(Port::create<PJ301MPort>(Vec(10, 105), Port::INPUT, module, Boolean3::INA_INPUT));
  108. addInput(Port::create<PJ301MPort>(Vec(10, 195), Port::INPUT, module, Boolean3::INB_INPUT));
  109. addInput(Port::create<PJ301MPort>(Vec(10, 285), Port::INPUT, module, Boolean3::INC_INPUT));
  110. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(18, 92), module, Boolean3::INA_LIGHT));
  111. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(18, 182), module, Boolean3::INB_LIGHT));
  112. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(18, 272), module, Boolean3::INC_LIGHT));
  113. //////OUTPUTS//////
  114. for(int i = 0; i < 6; i++)
  115. {
  116. const int yPos = i*45;
  117. addOutput(Port::create<PJ301MPort>(Vec(45, 60 + yPos), Port::OUTPUT, module, Boolean3::OR_OUTPUT + i));
  118. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(74, 68 + yPos), module, Boolean3::OR_LIGHT + i));
  119. }
  120. }
  121. } // namespace rack_plugin_HetrickCV
  122. using namespace rack_plugin_HetrickCV;
  123. RACK_PLUGIN_MODEL_INIT(HetrickCV, Boolean3) {
  124. Model *modelBoolean3 = Model::create<Boolean3, Boolean3Widget>("HetrickCV", "Boolean3", "Boolean Logic", LOGIC_TAG);
  125. return modelBoolean3;
  126. }