BogaudioModules

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

Edge.cpp (3874B)


      1 
      2 #include "Edge.hpp"
      3 
      4 void Edge::reset() {
      5 	for (int c = 0; c < _channels; ++c) {
      6 		_state[c] = LOW_STATE;
      7 		_timer[c].reset();
      8 		_riseOutputPulseGen[c].process(10.0f);
      9 		_fallOutputPulseGen[c].process(10.0f);
     10 	}
     11 }
     12 
     13 int Edge::channels() {
     14 	return inputs[IN_INPUT].getChannels();
     15 }
     16 
     17 void Edge::addChannel(int c) {
     18 	_state[c] = LOW_STATE;
     19 }
     20 
     21 void Edge::modulate() {
     22 	_riseThreshold = params[RISE_PARAM].getValue() * 10.0f;
     23 	_fallThreshold = params[FALL_PARAM].getValue() * 10.0f;
     24 	_holdSeconds = params[HOLD_PARAM].getValue();
     25 	_holdSeconds *= _holdSeconds;
     26 }
     27 
     28 void Edge::processAlways(const ProcessArgs& args) {
     29 	_highLightSum = 0;
     30 }
     31 
     32 void Edge::processAll(const ProcessArgs& args) {
     33 	outputs[HIGH_OUTPUT].setChannels(_channels);
     34 	outputs[RISE_OUTPUT].setChannels(_channels);
     35 	outputs[FALL_OUTPUT].setChannels(_channels);
     36 }
     37 
     38 void Edge::processChannel(const ProcessArgs& args, int c) {
     39 	float in = inputs[IN_INPUT].getPolyVoltage(c);
     40 
     41 	switch (_state[c]) {
     42 		case LOW_STATE: {
     43 			if (in >= _riseThreshold) {
     44 				_state[c] = HIGH_STATE;
     45 				_timer[c].reset();
     46 				_timer[c].setParams(APP->engine->getSampleRate(), _holdSeconds);
     47 				_riseOutputPulseGen[c].trigger(0.001f);
     48 			}
     49 			break;
     50 		}
     51 
     52 		case HIGH_STATE: {
     53 			bool expired = !_timer[c].next();
     54 			++_highLightSum;
     55 
     56 			if (_fallThreshold > _riseThreshold && in > _fallThreshold) {
     57 				_state[c] = HIGH2_STATE;
     58 			}
     59 			else if (in < std::min(_riseThreshold, _fallThreshold) && expired) {
     60 				_state[c] = _riseThreshold > _fallThreshold ? LOW_STATE : LOW2_STATE;
     61 				_fallOutputPulseGen[c].trigger(0.001f);
     62 			}
     63 			break;
     64 		}
     65 
     66 		case HIGH2_STATE: {
     67 			bool expired = !_timer[c].next();
     68 			++_highLightSum;
     69 
     70 			if (in < std::max(_riseThreshold, _fallThreshold) && expired) {
     71 				_state[c] = _riseThreshold > _fallThreshold ? LOW_STATE : LOW2_STATE;
     72 				_fallOutputPulseGen[c].trigger(0.001f);
     73 			}
     74 			break;
     75 		}
     76 
     77 		case LOW2_STATE: {
     78 			if (in < std::min(_riseThreshold, _fallThreshold)) {
     79 				_state[c] = LOW_STATE;
     80 			}
     81 			break;
     82 		}
     83 	}
     84 
     85 	outputs[HIGH_OUTPUT].setVoltage((_state[c] == HIGH_STATE || _state[c] == HIGH2_STATE) * 5.0f, c);
     86 	float st = APP->engine->getSampleTime();
     87 	outputs[RISE_OUTPUT].setVoltage(_riseOutputPulseGen[c].process(st) * 5.0f, c);
     88 	outputs[FALL_OUTPUT].setVoltage(_fallOutputPulseGen[c].process(st) * 5.0f, c);
     89 }
     90 
     91 void Edge::postProcessAlways(const ProcessArgs& args) {
     92 	lights[HIGH_LIGHT].value = _highLightSum * _inverseChannels;
     93 }
     94 
     95 struct EdgeWidget : BGModuleWidget {
     96 	static constexpr int hp = 3;
     97 
     98 	EdgeWidget(Edge* module) {
     99 		setModule(module);
    100 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
    101 		setPanel(box.size, "Edge");
    102 		createScrews();
    103 
    104 		// generated by svg_widgets.rb
    105 		auto riseParamPosition = Vec(8.0, 38.0);
    106 		auto fallParamPosition = Vec(8.0, 102.0);
    107 		auto holdParamPosition = Vec(14.5, 162.0);
    108 
    109 		auto inInputPosition = Vec(10.5, 194.0);
    110 
    111 		auto highOutputPosition = Vec(10.5, 232.0);
    112 		auto riseOutputPosition = Vec(10.5, 267.0);
    113 		auto fallOutputPosition = Vec(10.5, 302.0);
    114 
    115 		auto highLightPosition = Vec(7.5, 258.3);
    116 		// end generated by svg_widgets.rb
    117 
    118 		addParam(createParam<Knob29>(riseParamPosition, module, Edge::RISE_PARAM));
    119 		addParam(createParam<Knob29>(fallParamPosition, module, Edge::FALL_PARAM));
    120 		addParam(createParam<Knob16>(holdParamPosition, module, Edge::HOLD_PARAM));
    121 
    122 		addInput(createInput<Port24>(inInputPosition, module, Edge::IN_INPUT));
    123 
    124 		addOutput(createOutput<Port24>(highOutputPosition, module, Edge::HIGH_OUTPUT));
    125 		addOutput(createOutput<Port24>(riseOutputPosition, module, Edge::RISE_OUTPUT));
    126 		addOutput(createOutput<Port24>(fallOutputPosition, module, Edge::FALL_OUTPUT));
    127 
    128 		addChild(createLight<BGSmallLight<GreenLight>>(highLightPosition, module, Edge::HIGH_LIGHT));
    129 	}
    130 };
    131 
    132 Model* modelEdge = createModel<Edge, EdgeWidget>("Bogaudio-Edge", "EDGE", "Edge detector, gate-to-trigger, comparator", "Logic", "Polyphonic");