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