#include "Stack.hpp" void Stack::step() { lights[QUANTIZE_LIGHT].value = params[QUANTIZE_PARAM].value > 0.5; if (!(outputs[OUT_OUTPUT].active || outputs[THRU_OUTPUT].active)) { return; } float semitones = params[OCTAVE_PARAM].value * 12.0; semitones += params[SEMIS_PARAM].value; if (inputs[CV_INPUT].active) { semitones += clamp(inputs[CV_INPUT].value, -5.0f, 5.0f) * 10.0; } if (params[QUANTIZE_PARAM].value > 0.5) { semitones = roundf(semitones); } float inCV = 0.0f; if (inputs[IN_INPUT].active) { inCV = clamp(inputs[IN_INPUT].value, _minCVOut, _maxCVOut); } float fine = params[FINE_PARAM].value; if (_semitones != semitones || _inCV != inCV || _fine != fine) { _semitones = semitones; _inCV = inCV; _fine = fine; _outCV = clamp(semitoneToCV((_inCV != 0.0f ? cvToSemitone(_inCV) : referenceSemitone) + _semitones + _fine), _minCVOut, _maxCVOut); } if (inputs[IN_INPUT].active) { outputs[THRU_OUTPUT].value = _inCV; } else { outputs[THRU_OUTPUT].value = _semitones / 10.0; } outputs[OUT_OUTPUT].value = _outCV; } struct StackWidget : ModuleWidget { static constexpr int hp = 3; StackWidget(Stack* module) : ModuleWidget(module) { box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); { SVGPanel *panel = new SVGPanel(); panel->box.size = box.size; panel->setBackground(SVG::load(assetPlugin(plugin, "res/Stack.svg"))); addChild(panel); } addChild(Widget::create(Vec(0, 0))); addChild(Widget::create(Vec(box.size.x - 15, 365))); // generated by svg_widgets.rb auto semisParamPosition = Vec(9.5, 32.5); auto octaveParamPosition = Vec(14.5, 86.5); auto fineParamPosition = Vec(14.5, 126.5); auto quantizeParamPosition = Vec(28.4, 191.9); auto cvInputPosition = Vec(10.5, 157.0); auto inInputPosition = Vec(10.5, 215.0); auto thruOutputPosition = Vec(10.5, 253.0); auto outOutputPosition = Vec(10.5, 289.0); auto quantizeLightPosition = Vec(8.5, 193.5); // end generated by svg_widgets.rb { auto w = ParamWidget::create(semisParamPosition, module, Stack::SEMIS_PARAM, 0.0, 11.0, 0.0); dynamic_cast(w)->snap = true; addParam(w); } { auto w = ParamWidget::create(octaveParamPosition, module, Stack::OCTAVE_PARAM, -3.0, 3.0, 0.0); auto k = dynamic_cast(w); k->snap = true; k->minAngle = -0.5 * M_PI; k->maxAngle = 0.5 * M_PI; addParam(w); } addParam(ParamWidget::create(fineParamPosition, module, Stack::FINE_PARAM, -0.99, 0.99, 0.0)); addParam(ParamWidget::create(quantizeParamPosition, module, Stack::QUANTIZE_PARAM, 0.0, 1.0, 1.0)); addInput(Port::create(cvInputPosition, Port::INPUT, module, Stack::CV_INPUT)); addInput(Port::create(inInputPosition, Port::INPUT, module, Stack::IN_INPUT)); addOutput(Port::create(thruOutputPosition, Port::OUTPUT, module, Stack::THRU_OUTPUT)); addOutput(Port::create(outOutputPosition, Port::OUTPUT, module, Stack::OUT_OUTPUT)); addChild(ModuleLightWidget::create>(quantizeLightPosition, module, Stack::QUANTIZE_LIGHT)); } }; RACK_PLUGIN_MODEL_INIT(Bogaudio, Stack) { Model *modelStack = createModel("Bogaudio-Stack", "Stack", "pitch CV processor", TUNER_TAG); return modelStack; }