Lgsw.cpp (6601B)
1 2 #include "Lgsw.hpp" 3 4 void Lgsw::resetChannel(int c) { 5 _buttonTriggers[c].reset(); 6 _aTriggers[c].reset(); 7 _bTriggers[c].reset(); 8 _lastLogicTrue[c] = false; 9 } 10 11 void Lgsw::reset() { 12 for (int i = 0; i < _channels; ++i) { 13 resetChannel(i); 14 _latchedHigh[i] = false; 15 } 16 } 17 18 int Lgsw::channels() { 19 return inputs[GATE_A_INPUT].getChannels(); 20 } 21 22 void Lgsw::channelsChanged(int before, int after) { 23 for (; before < after; ++before) { 24 resetChannel(before); 25 } 26 } 27 28 void Lgsw::modulate() { 29 _latch = params[LATCH_PARAM].getValue() > 0.5f; 30 } 31 32 void Lgsw::processAlways(const ProcessArgs& args) { 33 _highLightSum = 0; 34 _lowLightSum = 0; 35 } 36 37 void Lgsw::processChannel(const ProcessArgs& args, int c) { 38 bool buttonTriggered = _buttonTriggers[c].process(10.0f*params[GATE_PARAM].getValue()); 39 bool aTriggered = _aTriggers[c].process(inputs[GATE_A_INPUT].getVoltage(c)); 40 bool bTriggered = _bTriggers[c].process(inputs[GATE_B_INPUT].getVoltage(c)); 41 42 if (inputs[LOGIC_MODE_INPUT].isConnected()) { 43 float cv = clamp(inputs[LOGIC_MODE_INPUT].getVoltage(c), 0.0f, 4.5f); 44 _logic = (Logic)(int)cv; 45 } 46 else { 47 _logic = (Logic)clamp((int)params[LOGIC_MODE_PARAM].getValue(), 0, 4); 48 } 49 50 bool triggered = buttonTriggered; 51 bool logicTrue = false; 52 if (inputs[GATE_A_INPUT].isConnected()) { 53 if (inputs[GATE_B_INPUT].isConnected()) { 54 switch (_logic) { 55 case OR_LOGIC: { 56 logicTrue = _aTriggers[c].isHigh() || _bTriggers[c].isHigh(); 57 break; 58 } 59 case AND_LOGIC: { 60 logicTrue = _aTriggers[c].isHigh() && _bTriggers[c].isHigh(); 61 break; 62 } 63 case XOR_LOGIC: { 64 logicTrue = _aTriggers[c].isHigh() != _bTriggers[c].isHigh(); 65 break; 66 } 67 case NOR_LOGIC: { 68 logicTrue = !(_aTriggers[c].isHigh() || _bTriggers[c].isHigh()); 69 break; 70 } 71 case NAND_LOGIC: { 72 logicTrue = !(_aTriggers[c].isHigh() && _bTriggers[c].isHigh()); 73 break; 74 } 75 } 76 77 triggered = triggered || (logicTrue && !_lastLogicTrue[c]); 78 _lastLogicTrue[c] = logicTrue; 79 } 80 else { 81 triggered = triggered || aTriggered; 82 logicTrue = _aTriggers[c].isHigh(); 83 _lastLogicTrue[c] = false; 84 } 85 } 86 else if (inputs[GATE_B_INPUT].isConnected()) { 87 triggered = triggered || bTriggered; 88 logicTrue = _bTriggers[c].isHigh(); 89 _lastLogicTrue[c] = false; 90 } 91 92 if (_latch) { 93 if (triggered) { 94 _latchedHigh[c] = !_latchedHigh[c]; 95 } 96 } 97 else { 98 _latchedHigh[c] = false; 99 } 100 101 if (_latchedHigh[c] || (!_latch && (logicTrue || _buttonTriggers[c].isHigh()))) { 102 ++_highLightSum; 103 104 if (_channels == 1) { 105 outputs[OUT_OUTPUT].setChannels(inputs[HIGH_INPUT].getChannels()); 106 outputs[OUT_OUTPUT].writeVoltages(inputs[HIGH_INPUT].getVoltages()); 107 } 108 else { 109 outputs[OUT_OUTPUT].setChannels(_channels); 110 outputs[OUT_OUTPUT].setVoltage(inputs[HIGH_INPUT].getPolyVoltage(c), c); 111 } 112 } 113 else { 114 ++_lowLightSum; 115 116 if (_channels == 1) { 117 outputs[OUT_OUTPUT].setChannels(inputs[LOW_INPUT].getChannels()); 118 outputs[OUT_OUTPUT].writeVoltages(inputs[LOW_INPUT].getVoltages()); 119 } 120 else { 121 outputs[OUT_OUTPUT].setChannels(_channels); 122 outputs[OUT_OUTPUT].setVoltage(inputs[LOW_INPUT].getPolyVoltage(c), c); 123 } 124 } 125 } 126 127 void Lgsw::postProcessAlways(const ProcessArgs& args) { 128 lights[HIGH_LIGHT].value = _highLightSum * _inverseChannels; 129 lights[LOW_LIGHT].value = _lowLightSum * _inverseChannels; 130 131 lights[LOGIC_OR_LIGHT].value = 0.0f; 132 lights[LOGIC_AND_LIGHT].value = 0.0f; 133 lights[LOGIC_XOR_LIGHT].value = 0.0f; 134 lights[LOGIC_NOR_LIGHT].value = 0.0f; 135 lights[LOGIC_NAND_LIGHT].value = 0.0f; 136 switch (_logic) { 137 case OR_LOGIC: { 138 lights[LOGIC_OR_LIGHT].value = 1.0f; 139 break; 140 } 141 case AND_LOGIC: { 142 lights[LOGIC_AND_LIGHT].value = 1.0f; 143 break; 144 } 145 case XOR_LOGIC: { 146 lights[LOGIC_XOR_LIGHT].value = 1.0f; 147 break; 148 } 149 case NOR_LOGIC: { 150 lights[LOGIC_NOR_LIGHT].value = 1.0f; 151 break; 152 } 153 case NAND_LOGIC: { 154 lights[LOGIC_NAND_LIGHT].value = 1.0f; 155 break; 156 } 157 } 158 } 159 160 struct LgswWidget : SaveLatchToPatchModuleWidget { 161 static constexpr int hp = 3; 162 163 LgswWidget(Lgsw* module) { 164 setModule(module); 165 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 166 setPanel(box.size, "Lgsw"); 167 createScrews(); 168 169 // generated by svg_widgets.rb 170 auto gateParamPosition = Vec(13.5, 22.0); 171 auto latchParamPosition = Vec(31.5, 105.0); 172 auto logicModeParamPosition = Vec(16.0, 178.0); 173 174 auto gateAInputPosition = Vec(10.5, 44.0); 175 auto gateBInputPosition = Vec(10.5, 72.0); 176 auto logicModeInputPosition = Vec(10.5, 193.0); 177 auto high1InputPosition = Vec(10.5, 230.0); 178 auto low1InputPosition = Vec(10.5, 266.0); 179 180 auto out1OutputPosition = Vec(10.5, 304.0); 181 182 auto logicOrLightPosition = Vec(7.5, 121.0); 183 auto logicAndLightPosition = Vec(7.5, 133.0); 184 auto logicXorLightPosition = Vec(7.5, 145.0); 185 auto logicNorLightPosition = Vec(7.5, 157.0); 186 auto logicNandLightPosition = Vec(7.5, 169.0); 187 auto high1LightPosition = Vec(7.5, 256.3); 188 auto low1LightPosition = Vec(7.5, 292.3); 189 // end generated by svg_widgets.rb 190 191 addParam(createParam<Button18>(gateParamPosition, module, Lgsw::GATE_PARAM)); 192 addParam(createParam<IndicatorButtonGreen9>(latchParamPosition, module, Lgsw::LATCH_PARAM)); 193 addParam(createParam<StatefulButton9>(logicModeParamPosition, module, Lgsw::LOGIC_MODE_PARAM)); 194 195 addInput(createInput<Port24>(gateAInputPosition, module, Lgsw::GATE_A_INPUT)); 196 addInput(createInput<Port24>(gateBInputPosition, module, Lgsw::GATE_B_INPUT)); 197 addInput(createInput<Port24>(logicModeInputPosition, module, Lgsw::LOGIC_MODE_INPUT)); 198 addInput(createInput<Port24>(high1InputPosition, module, Lgsw::HIGH_INPUT)); 199 addInput(createInput<Port24>(low1InputPosition, module, Lgsw::LOW_INPUT)); 200 201 addOutput(createOutput<Port24>(out1OutputPosition, module, Lgsw::OUT_OUTPUT)); 202 203 addChild(createLight<BGSmallLight<GreenLight>>(logicOrLightPosition, module, Lgsw::LOGIC_OR_LIGHT)); 204 addChild(createLight<BGSmallLight<GreenLight>>(logicAndLightPosition, module, Lgsw::LOGIC_AND_LIGHT)); 205 addChild(createLight<BGSmallLight<GreenLight>>(logicXorLightPosition, module, Lgsw::LOGIC_XOR_LIGHT)); 206 addChild(createLight<BGSmallLight<GreenLight>>(logicNorLightPosition, module, Lgsw::LOGIC_NOR_LIGHT)); 207 addChild(createLight<BGSmallLight<GreenLight>>(logicNandLightPosition, module, Lgsw::LOGIC_NAND_LIGHT)); 208 addChild(createLight<BGSmallLight<GreenLight>>(high1LightPosition, module, Lgsw::HIGH_LIGHT)); 209 addChild(createLight<BGSmallLight<GreenLight>>(low1LightPosition, module, Lgsw::LOW_LIGHT)); 210 } 211 }; 212 213 Model* modelLgsw = createModel<Lgsw, LgswWidget>("Bogaudio-Lgsw", "LGSW", "2-way signal router with logic", "Switch", "Logic", "Polyphonic");