Assign.cpp (3999B)
1 2 #include "Assign.hpp" 3 4 void Assign::reset() { 5 _resetTrigger.reset(); 6 _nextAssign = 0; 7 for (int c = 0; c < maxChannels; ++c) { 8 _gateTrigger[c].reset(); 9 _gateHigh[c] = false; 10 _pitchInAssignment[c] = -1; 11 _gateInAssignment[c] = -1; 12 _pitchOutAssignment[c] = -1; 13 _gateOutAssignment[c] = -1; 14 _lastPitchOut[c] = 0.0f; 15 _assignedAtStep[c] = 0; 16 } 17 } 18 19 int Assign::channels() { 20 return inputs[GATE_INPUT].getChannels(); 21 } 22 23 void Assign::addChannel(int c) { 24 _gateTrigger[c].reset(); 25 } 26 27 void Assign::removeChannel(int c) { 28 _gateHigh[c] = false; 29 _assignedAtStep[c] = 0; 30 if (_pitchInAssignment[c] >= 0) { 31 _pitchOutAssignment[_pitchInAssignment[c]] = -1; 32 _lastPitchOut[_pitchInAssignment[c]] = 0.0f; 33 _pitchInAssignment[c] = -1; 34 } 35 if (_gateInAssignment[c] >= 0) { 36 _gateOutAssignment[_gateInAssignment[c]] = -1; 37 _gateInAssignment[c] = -1; 38 } 39 if (_nextAssign == c) { 40 _nextAssign = 0; 41 } 42 } 43 44 void Assign::modulate() { 45 _channelsOut = clamp((int)params[CHANNELS_PARAM].getValue(), 1, 16); 46 } 47 48 void Assign::postProcess(const ProcessArgs& args) { 49 ++_step; 50 if (_resetTrigger.process(inputs[RESET_INPUT].getVoltage())) { 51 _nextAssign = 0; 52 } 53 54 for (int c = 0; c < _channels; ++c) { 55 if (_gateTrigger[c].process(inputs[GATE_INPUT].getPolyVoltage(c))) { 56 _gateHigh[c] = true; 57 58 if (_gateOutAssignment[_nextAssign] >= 0) { 59 int a = _nextAssign + 1; 60 int n = a + _channelsOut; 61 unsigned long minStep = -1; 62 int minI = _nextAssign; 63 for (; a < n; ++a) { 64 int i = a % _channelsOut; 65 if (_gateOutAssignment[i] < 0) { 66 _nextAssign = i; 67 goto CHANNEL_SELECTED; 68 } 69 if (_assignedAtStep[i] < minStep) { 70 minStep = _assignedAtStep[i]; 71 minI = i; 72 } 73 } 74 _nextAssign = minI; 75 } 76 77 CHANNEL_SELECTED: 78 _pitchInAssignment[c] = _nextAssign; 79 _gateInAssignment[c] = _nextAssign; 80 _pitchOutAssignment[_nextAssign] = c; 81 _gateOutAssignment[_nextAssign] = c; 82 _assignedAtStep[c] = _step; 83 _nextAssign = (_nextAssign + 1) % _channelsOut; 84 } 85 else if (!_gateTrigger[c].isHigh() && _gateHigh[c]) { 86 _gateHigh[c] = false; 87 _pitchOutAssignment[_pitchInAssignment[c]] = -1; 88 _pitchInAssignment[c] = -1; 89 _gateOutAssignment[_gateInAssignment[c]] = -1; 90 _gateInAssignment[c] = -1; 91 } 92 } 93 94 outputs[PITCH_OUTPUT].setChannels(_channelsOut); 95 outputs[GATE_OUTPUT].setChannels(_channelsOut); 96 for (int c = 0; c < _channelsOut; ++c) { 97 float pitch = _lastPitchOut[c]; 98 if (_pitchOutAssignment[c] >= 0) { 99 _lastPitchOut[c] = pitch = inputs[PITCH_INPUT].getPolyVoltage(_pitchOutAssignment[c]); 100 } 101 outputs[PITCH_OUTPUT].setVoltage(pitch, c); 102 103 float gate = _gateOutAssignment[c] >= 0 ? inputs[GATE_INPUT].getPolyVoltage(_gateOutAssignment[c]) : 0.0f; 104 outputs[GATE_OUTPUT].setVoltage(gate, c); 105 } 106 } 107 108 struct AssignWidget : BGModuleWidget { 109 static constexpr int hp = 3; 110 111 AssignWidget(Assign* module) { 112 setModule(module); 113 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 114 setPanel(box.size, "Assign"); 115 createScrews(); 116 117 // generated by svg_widgets.rb 118 auto channelsParamPosition = Vec(9.5, 34.0); 119 120 auto pitchInputPosition = Vec(10.5, 78.0); 121 auto gateInputPosition = Vec(10.5, 113.0); 122 auto resetInputPosition = Vec(10.5, 148.0); 123 124 auto pitchOutputPosition = Vec(10.5, 186.0); 125 auto gateOutputPosition = Vec(10.5, 221.0); 126 // end generated by svg_widgets.rb 127 128 addParam(createParam<Knob26>(channelsParamPosition, module, Assign::CHANNELS_PARAM)); 129 130 addInput(createInput<Port24>(pitchInputPosition, module, Assign::PITCH_INPUT)); 131 addInput(createInput<Port24>(gateInputPosition, module, Assign::GATE_INPUT)); 132 addInput(createInput<Port24>(resetInputPosition, module, Assign::RESET_INPUT)); 133 134 addOutput(createOutput<Port24>(pitchOutputPosition, module, Assign::PITCH_OUTPUT)); 135 addOutput(createOutput<Port24>(gateOutputPosition, module, Assign::GATE_OUTPUT)); 136 } 137 }; 138 139 Model* modelAssign = createModel<Assign, AssignWidget>("Bogaudio-Assign", "ASSIGN", "Polyphonic voice (re)assigner", "Polyphonic");