BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit bb10c50f69f47df39f588778190ea7d765f5f574
parent 00ead59d3ff9ec7015e054dcc75a645bf754efec
Author: Matt Demanett <matt@demanett.net>
Date:   Sun,  5 Apr 2020 23:41:10 -0400

INV: dual polyphonic inverter.

Diffstat:
Mplugin.json | 10++++++++++
Ares-src/Inv-src.svg | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/Inv.svg | 0
Asrc/Inv.cpp | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Inv.hpp | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 2++
6 files changed, 250 insertions(+), 0 deletions(-)

diff --git a/plugin.json b/plugin.json @@ -678,6 +678,16 @@ ] }, { + "slug": "Bogaudio-Inv", + "name": "INV", + "description": "Dual signal inverter", + "tags": [ + "Logic", + "Dual", + "Polyphonic" + ] + }, + { "slug": "Bogaudio-Manual", "name": "MANUAL", "description": "Button controlled gates / triggers", diff --git a/res-src/Inv-src.svg b/res-src/Inv-src.svg @@ -0,0 +1,105 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="45" + height="380" + viewBox="0 0 45 380" +> + <style> + text { + fill: #333; + font-family: 'Roboto', sans-serif; + font-weight: bold; + } + text.title { + font-family: 'Comfortaa', sans-serif; + font-weight: normal; + } + text.brand { + font-family: 'Audiowide', sans-serif; + font-weight: bold; + } + </style> + + <defs> + <symbol id="button" viewBox="0 0 18px 18px"> + <g transform="translate(9 9)"> + <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00" /> + </g> + </symbol> + + <symbol id="button-small" viewBox="0 0 9px 9px"> + <g transform="translate(4.5 4.5)"> + <circle cx="0" cy="0" r="4.1" stroke-width="1" stroke="#00f" fill="#f00" /> + </g> + </symbol> + + <symbol id="input" viewBox="0 0 24px 24px"> + <g transform="translate(12 12)"> + <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#0f0" fill="#0f0" /> + <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#0f0" fill="none" /> + </g> + </symbol> + + <symbol id="output" viewBox="0 0 24px 24px"> + <g transform="translate(12 12)"> + <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#f00" fill="#f00" /> + <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#f00" fill="none" /> + </g> + </symbol> + </defs> + + <rect width="100%" height="100%" fill="#ddd" /> + <polyline points="1,1 44,1 44,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 45,0 45,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <g transform="rotate(-90) translate(-376 13)"> + <text class="title" font-size="7pt" letter-spacing="2.5px">INV</text> + <g transform="translate(0 12)"> + <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text> + <rect width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)" /> + </g> + </g> + + <g transform="translate(0 18)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="113" rx="5" fill="#fafafa" /> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 103)" /> + <use id="GATE1_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <use id="GATE1_INPUT" xlink:href="#input" transform="translate(5 26)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(5 58)">GATE</text> + <text font-size="5pt" letter-spacing="0.3px" transform="translate(1 71)">LATCH</text> + <use id="LATCH1_PARAM" xlink:href="#button-small" transform="translate(24 64)" /> + <use id="IN1_INPUT" xlink:href="#input" transform="translate(5 78)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(13 110)">IN</text> + </g> + <g transform="translate(5.5 113)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 0)" /> + <rect width="34" height="39" rx="5" fill="#bbb" /> + <use id="OUT1_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(9 35)">OUT</text> + </g> + </g> + + <g transform="translate(0 183)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="113" rx="5" fill="#fafafa" /> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 103)" /> + <use id="GATE2_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <use id="GATE2_INPUT" xlink:href="#input" transform="translate(5 26)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(5 58)">GATE</text> + <text font-size="5pt" letter-spacing="0.3px" transform="translate(1 71)">LATCH</text> + <use id="LATCH2_PARAM" xlink:href="#button-small" transform="translate(24 64)" /> + <use id="IN2_INPUT" xlink:href="#input" transform="translate(5 78)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(13 110)">IN</text> + </g> + <g transform="translate(5.5 113)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 0)" /> + <rect width="34" height="39" rx="5" fill="#bbb" /> + <use id="OUT2_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(9 35)">OUT</text> + </g> + </g> +</svg> diff --git a/res/Inv.svg b/res/Inv.svg Binary files differ. diff --git a/src/Inv.cpp b/src/Inv.cpp @@ -0,0 +1,85 @@ + +#include "Inv.hpp" + +void Inv::reset() { + for (int c = 0; c < maxChannels; ++c) { + _trigger[0][c].reset(); + _trigger[1][c].reset(); + } +} + +void Inv::processAll(const ProcessArgs& args) { + processDualChannel(0); + processDualChannel(1); +} + +void Inv::processDualChannel(int i) { + int channels = inputs[IN1_INPUT + 2 * i].getChannels(); + outputs[OUT1_OUTPUT + i].setChannels(channels); + for (int c = 0; c < channels; ++c) { + bool triggered = _trigger[i][c].process(params[GATE1_PARAM + 2 * i].getValue() + inputs[GATE1_INPUT + 2 * i].getPolyVoltage(c)); + if (params[LATCH1_PARAM + 2 * i].getValue() > 0.5f) { + if (triggered) { + _latchedHigh[i][c] = !_latchedHigh[i][c]; + } + } + else { + _latchedHigh[i][c] = false; + } + + float in = inputs[IN1_INPUT + 2 * i].getPolyVoltage(c); + if (_latchedHigh[i][c] || _trigger[i][c].isHigh()) { + in = -in; + } + outputs[OUT1_OUTPUT + i].setVoltage(in, c); + } +} + +struct InvWidget : ModuleWidget { + static constexpr int hp = 3; + + InvWidget(Inv* module) { + setModule(module); + box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); + + { + SvgPanel *panel = new SvgPanel(); + panel->box.size = box.size; + panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Inv.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto gate1ParamPosition = Vec(13.5, 22.0); + auto latch1ParamPosition = Vec(29.4, 81.9); + auto gate2ParamPosition = Vec(13.5, 187.0); + auto latch2ParamPosition = Vec(29.4, 246.9); + + auto gate1InputPosition = Vec(10.5, 44.0); + auto in1InputPosition = Vec(10.5, 96.0); + auto gate2InputPosition = Vec(10.5, 209.0); + auto in2InputPosition = Vec(10.5, 261.0); + + auto out1OutputPosition = Vec(10.5, 134.0); + auto out2OutputPosition = Vec(10.5, 299.0); + // end generated by svg_widgets.rb + + addParam(createParam<Button18>(gate1ParamPosition, module, Inv::GATE1_PARAM)); + addParam(createParam<IndicatorButtonGreen9>(latch1ParamPosition, module, Inv::LATCH1_PARAM)); + addParam(createParam<Button18>(gate2ParamPosition, module, Inv::GATE2_PARAM)); + addParam(createParam<IndicatorButtonGreen9>(latch2ParamPosition, module, Inv::LATCH2_PARAM)); + + addInput(createInput<Port24>(gate1InputPosition, module, Inv::GATE1_INPUT)); + addInput(createInput<Port24>(in1InputPosition, module, Inv::IN1_INPUT)); + addInput(createInput<Port24>(gate2InputPosition, module, Inv::GATE2_INPUT)); + addInput(createInput<Port24>(in2InputPosition, module, Inv::IN2_INPUT)); + + addOutput(createOutput<Port24>(out1OutputPosition, module, Inv::OUT1_OUTPUT)); + addOutput(createOutput<Port24>(out2OutputPosition, module, Inv::OUT2_OUTPUT)); + } +}; + +Model* modelInv = createModel<Inv, InvWidget>("Bogaudio-Inv", "INV", "Dual signal inverter", "Logic", "Dual", "Polyphonic"); diff --git a/src/Inv.hpp b/src/Inv.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "bogaudio.hpp" + +extern Model* modelInv; + +namespace bogaudio { + +struct Inv : BGModule { + enum ParamsIds { + GATE1_PARAM, + LATCH1_PARAM, + GATE2_PARAM, + LATCH2_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + GATE1_INPUT, + IN1_INPUT, + GATE2_INPUT, + IN2_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + OUT1_OUTPUT, + OUT2_OUTPUT, + NUM_OUTPUTS + }; + + Trigger _trigger[2][maxChannels]; + bool _latchedHigh[2][maxChannels] {{},{}}; + + Inv() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(GATE1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 gate"); + configParam(LATCH1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 latch"); + configParam(GATE2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 gate"); + configParam(LATCH2_PARAM, 0.0f, 1.0f, 0.0f, "Channle 2 latch"); + } + + void reset() override; + void processAll(const ProcessArgs& args) override; + void processDualChannel(int i); +}; + +} // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -30,6 +30,7 @@ #include "FMOp.hpp" #include "FlipFlop.hpp" #include "Follow.hpp" +#include "Inv.hpp" #include "Lag.hpp" #include "LFO.hpp" #include "LLFO.hpp" @@ -179,6 +180,7 @@ void init(rack::Plugin *p) { p->addModel(modelCmp); p->addModel(modelCVD); p->addModel(modelFlipFlop); + p->addModel(modelInv); p->addModel(modelManual); p->addModel(modelMult); p->addModel(modelOffset);