Stack.cpp (3281B)
1 2 #include "Stack.hpp" 3 4 bool Stack::active() { 5 return outputs[OUT_OUTPUT].isConnected() || outputs[THRU_OUTPUT].isConnected(); 6 } 7 8 int Stack::channels() { 9 return inputs[IN_INPUT].getChannels(); 10 } 11 12 void Stack::modulateChannel(int c) { 13 _semitones[c] = roundf(params[OCTAVE_PARAM].getValue()) * 12.0f; 14 _semitones[c] += roundf(params[SEMIS_PARAM].getValue()); 15 if (inputs[CV_INPUT].isConnected()) { 16 _semitones[c] += clamp(inputs[CV_INPUT].getPolyVoltage(c), -5.0f, 5.0f) * 10.0f; 17 } 18 if (params[QUANTIZE_PARAM].getValue() > 0.5f) { 19 _semitones[c] = roundf(_semitones[c]); 20 } 21 } 22 23 void Stack::processChannel(const ProcessArgs& args, int c) { 24 float inCV = clamp(inputs[IN_INPUT].getVoltage(c), _minCVOut, _maxCVOut); 25 float fine = params[FINE_PARAM].getValue(); 26 27 if (_semitones[c] != _lastSemitones[c] || inCV != _lastInCV[c] || fine != _lastFine[c]) { 28 _lastSemitones[c] = _semitones[c]; 29 _lastInCV[c] = inCV; 30 _lastFine[c] = fine; 31 _outCV[c] = clamp(semitoneToCV((inCV != 0.0f ? cvToSemitone(inCV) : referenceSemitone) + _semitones[c] + fine), _minCVOut, _maxCVOut); 32 } 33 34 if (inputs[IN_INPUT].isConnected()) { 35 outputs[THRU_OUTPUT].setChannels(_channels); 36 outputs[THRU_OUTPUT].setVoltage(inCV, c); 37 } 38 else { 39 outputs[THRU_OUTPUT].setVoltage(_semitones[c] / 10.0); 40 } 41 outputs[OUT_OUTPUT].setChannels(_channels); 42 outputs[OUT_OUTPUT].setVoltage(_outCV[c], c); 43 } 44 45 void Stack::processBypass(const ProcessArgs& args) { 46 int cn = channels(); 47 outputs[THRU_OUTPUT].setChannels(cn); 48 outputs[OUT_OUTPUT].setChannels(cn); 49 for (int c = 0; c < cn; ++c) { 50 float out = inputs[IN_INPUT].getVoltage(c); 51 outputs[THRU_OUTPUT].setVoltage(out, c); 52 outputs[OUT_OUTPUT].setVoltage(out, c); 53 } 54 } 55 56 struct StackWidget : BGModuleWidget { 57 static constexpr int hp = 3; 58 59 StackWidget(Stack* module) { 60 setModule(module); 61 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 62 setPanel(box.size, "Stack"); 63 createScrews(); 64 65 // generated by svg_widgets.rb 66 auto semisParamPosition = Vec(9.5, 32.5); 67 auto octaveParamPosition = Vec(14.5, 86.5); 68 auto fineParamPosition = Vec(14.5, 126.5); 69 auto quantizeParamPosition = Vec(29.0, 192.0); 70 71 auto cvInputPosition = Vec(10.5, 157.0); 72 auto inInputPosition = Vec(10.5, 215.0); 73 74 auto thruOutputPosition = Vec(10.5, 253.0); 75 auto outOutputPosition = Vec(10.5, 289.0); 76 // end generated by svg_widgets.rb 77 78 addParam(createParam<Knob26>(semisParamPosition, module, Stack::SEMIS_PARAM)); 79 { 80 auto w = createParam<Knob16>(octaveParamPosition, module, Stack::OCTAVE_PARAM); 81 auto k = dynamic_cast<SvgKnob*>(w); 82 k->minAngle = -0.5 * M_PI; 83 k->maxAngle = 0.5 * M_PI; 84 addParam(w); 85 } 86 addParam(createParam<Knob16>(fineParamPosition, module, Stack::FINE_PARAM)); 87 addParam(createParam<IndicatorButtonGreen9>(quantizeParamPosition, module, Stack::QUANTIZE_PARAM)); 88 89 addInput(createInput<Port24>(cvInputPosition, module, Stack::CV_INPUT)); 90 addInput(createInput<Port24>(inInputPosition, module, Stack::IN_INPUT)); 91 92 addOutput(createOutput<Port24>(thruOutputPosition, module, Stack::THRU_OUTPUT)); 93 addOutput(createOutput<Port24>(outOutputPosition, module, Stack::OUT_OUTPUT)); 94 } 95 }; 96 97 Model* modelStack = bogaudio::createModel<Stack, StackWidget>("Bogaudio-Stack", "STACK", "Pitch CV transposer", "Tuner", "Polyphonic");