Detune.cpp (2953B)
1 2 #include "Detune.hpp" 3 4 bool Detune::active() { 5 return outputs[OUT_PLUS_OUTPUT].isConnected() || outputs[OUT_MINUS_OUTPUT].isConnected() || outputs[THRU_OUTPUT].isConnected(); 6 } 7 8 int Detune::channels() { 9 return inputs[IN_INPUT].getChannels(); 10 } 11 12 void Detune::modulateChannel(int c) { 13 _cents[c] = params[CENTS_PARAM].getValue(); 14 if (inputs[CV_INPUT].isConnected()) { 15 _cents[c] *= clamp(inputs[CV_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); 16 _cents[c] = roundf(_cents[c]); 17 } 18 _cents[c] /= 100.0f; 19 } 20 21 void Detune::processChannel(const ProcessArgs& args, int c) { 22 float inCV = inputs[IN_INPUT].getVoltage(c); 23 24 if (_cents[c] != _lastCents[c] || inCV != _lastInCV[c]) { 25 _lastCents[c] = _cents[c]; 26 _lastInCV[c] = inCV; 27 if (_cents[c] < 0.001f) { 28 _plusCV[c] = inCV; 29 _minusCV[c] = inCV; 30 } 31 else { 32 float semitone = cvToSemitone(inCV); 33 _plusCV[c] = semitoneToCV(semitone + _cents[c]); 34 _minusCV[c] = semitoneToCV(semitone - _cents[c]); 35 } 36 } 37 38 outputs[THRU_OUTPUT].setChannels(_channels); 39 outputs[THRU_OUTPUT].setVoltage(inCV, c); 40 outputs[OUT_PLUS_OUTPUT].setChannels(_channels); 41 outputs[OUT_PLUS_OUTPUT].setVoltage(_plusCV[c], c); 42 outputs[OUT_MINUS_OUTPUT].setChannels(_channels); 43 outputs[OUT_MINUS_OUTPUT].setVoltage(_minusCV[c], c); 44 } 45 46 void Detune::processBypass(const ProcessArgs& args) { 47 int cn = channels(); 48 outputs[THRU_OUTPUT].setChannels(cn); 49 outputs[OUT_PLUS_OUTPUT].setChannels(cn); 50 outputs[OUT_MINUS_OUTPUT].setChannels(cn); 51 for (int c = 0; c < cn; ++c) { 52 float out = inputs[IN_INPUT].getVoltage(c); 53 outputs[THRU_OUTPUT].setVoltage(out, c); 54 outputs[OUT_PLUS_OUTPUT].setVoltage(out, c); 55 outputs[OUT_MINUS_OUTPUT].setVoltage(out, c); 56 } 57 } 58 59 struct DetuneWidget : BGModuleWidget { 60 static constexpr int hp = 3; 61 62 DetuneWidget(Detune* module) { 63 setModule(module); 64 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 65 setPanel(box.size, "Detune"); 66 createScrews(); 67 68 // generated by svg_widgets.rb 69 auto centsParamPosition = Vec(9.5, 32.5); 70 71 auto cvInputPosition = Vec(10.5, 77.0); 72 auto inInputPosition = Vec(10.5, 126.0); 73 74 auto thruOutputPosition = Vec(10.5, 164.0); 75 auto outPlusOutputPosition = Vec(10.5, 200.0); 76 auto outMinusOutputPosition = Vec(10.5, 236.0); 77 // end generated by svg_widgets.rb 78 79 addParam(createParam<Knob26>(centsParamPosition, module, Detune::CENTS_PARAM)); 80 81 addInput(createInput<Port24>(cvInputPosition, module, Detune::CV_INPUT)); 82 addInput(createInput<Port24>(inInputPosition, module, Detune::IN_INPUT)); 83 84 addOutput(createOutput<Port24>(thruOutputPosition, module, Detune::THRU_OUTPUT)); 85 addOutput(createOutput<Port24>(outPlusOutputPosition, module, Detune::OUT_PLUS_OUTPUT)); 86 addOutput(createOutput<Port24>(outMinusOutputPosition, module, Detune::OUT_MINUS_OUTPUT)); 87 } 88 }; 89 90 Model* modelDetune = bogaudio::createModel<Detune, DetuneWidget>("Bogaudio-Detune", "DETUNE", "Pitch CV processor for detuning oscillator pairs", "Tuner", "Polyphonic");