BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

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");