BogaudioModules

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

commit c1aa59c3118584212cb45c75aa17ab6f4f8d6668
parent 450e09c25b0c9dba336df52153015dba4168ce32
Author: Matt Demanett <matt@demanett.net>
Date:   Mon,  8 Jun 2020 22:21:33 -0400

4MAN: a quad version of MANUAL.

Diffstat:
Mplugin.json | 10++++++++++
Ares-src/FourMan-src.svg | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/FourMan.svg | 0
Asrc/FourMan.cpp | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/FourMan.hpp | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Manual.cpp | 11++++++-----
Msrc/Manual.hpp | 4+++-
Msrc/bogaudio.cpp | 2++
8 files changed, 282 insertions(+), 6 deletions(-)

diff --git a/plugin.json b/plugin.json @@ -800,6 +800,16 @@ ] }, { + "slug": "Bogaudio-FourMan", + "name": "4MAN", + "description": "Quad button-controlled gates / triggers", + "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#fourman", + "tags": [ + "Controller", + "Quad" + ] + }, + { "slug": "Bogaudio-Mult", "name": "MULT", "description": "1:6 or dual 1:3 multiple/splitter", diff --git a/res-src/FourMan-src.svg b/res-src/FourMan-src.svg @@ -0,0 +1,124 @@ +<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="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">4MAN</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="10" fill="#fafafa" transform="translate(0 25)" /> + <rect width="34" height="33" rx="5" fill="#fafafa" /> + <use id="TRIGGER1_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.6 30)">TRIG</text> + </g> + + <g transform="translate(5.5 37)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="38" rx="5" fill="#bbb" /> + <g transform="translate(2 2)"> + <use id="OUT1_OUTPUT" xlink:href="#output" transform="translate(3 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.5 32)">OUT</text> + </g> + </g> + </g> + + <g transform="translate(0 98)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 25)" /> + <rect width="34" height="33" rx="5" fill="#fafafa" /> + <use id="TRIGGER2_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.6 30)">TRIG</text> + </g> + + <g transform="translate(5.5 37)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="38" rx="5" fill="#bbb" /> + <g transform="translate(2 2)"> + <use id="OUT2_OUTPUT" xlink:href="#output" transform="translate(3 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.5 32)">OUT</text> + </g> + </g> + </g> + + <g transform="translate(0 178)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 25)" /> + <rect width="34" height="33" rx="5" fill="#fafafa" /> + <use id="TRIGGER3_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.6 30)">TRIG</text> + </g> + + <g transform="translate(5.5 37)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="38" rx="5" fill="#bbb" /> + <g transform="translate(2 2)"> + <use id="OUT3_OUTPUT" xlink:href="#output" transform="translate(3 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.5 32)">OUT</text> + </g> + </g> + </g> + + <g transform="translate(0 258)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 25)" /> + <rect width="34" height="33" rx="5" fill="#fafafa" /> + <use id="TRIGGER4_PARAM" xlink:href="#button" transform="translate(8 4)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.6 30)">TRIG</text> + </g> + + <g transform="translate(5.5 37)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="38" rx="5" fill="#bbb" /> + <g transform="translate(2 2)"> + <use id="OUT4_OUTPUT" xlink:href="#output" transform="translate(3 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(6.5 32)">OUT</text> + </g> + </g> + </g> +</svg> diff --git a/res/FourMan.svg b/res/FourMan.svg Binary files differ. diff --git a/src/FourMan.cpp b/src/FourMan.cpp @@ -0,0 +1,77 @@ + +#include "FourMan.hpp" + +void FourMan::reset() { + for (int i = 0; i < 4; i++) { + _trigger[i].reset(); + _pulse[i].process(10.0f); + } +} + +void FourMan::sampleRateChange() { + _sampleTime = APP->engine->getSampleTime(); +} + +void FourMan::processAll(const ProcessArgs& args) { + bool initialPulse = false; + if (_initialDelay && !_initialDelay->next()) { + initialPulse = true; + delete _initialDelay; + _initialDelay = NULL; + } + + for (int i = 0; i < 4; i++) { + bool high = _trigger[i].process(params[TRIGGER1_PARAM + i].getValue()) || _trigger[i].isHigh() || (initialPulse && _triggerOnLoad && _shouldTriggerOnLoad); + if (high) { + _pulse[i].trigger(0.001f); + } + high = _pulse[i].process(_sampleTime); + + outputs[OUT1_OUTPUT + i].setVoltage(high ? 5.0f : 0.0f); + } +} + +struct FourManWidget : TriggerOnLoadModuleWidget { + static constexpr int hp = 3; + + FourManWidget(FourMan* module) + : TriggerOnLoadModuleWidget("Trigger on load") + { + 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/FourMan.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto trigger1ParamPosition = Vec(13.5, 22.0); + auto trigger2ParamPosition = Vec(13.5, 102.0); + auto trigger3ParamPosition = Vec(13.5, 182.0); + auto trigger4ParamPosition = Vec(13.5, 262.0); + + auto out1OutputPosition = Vec(10.5, 57.0); + auto out2OutputPosition = Vec(10.5, 137.0); + auto out3OutputPosition = Vec(10.5, 217.0); + auto out4OutputPosition = Vec(10.5, 297.0); + // end generated by svg_widgets.rb + + addParam(createParam<Button18>(trigger1ParamPosition, module, FourMan::TRIGGER1_PARAM)); + addParam(createParam<Button18>(trigger2ParamPosition, module, FourMan::TRIGGER2_PARAM)); + addParam(createParam<Button18>(trigger3ParamPosition, module, FourMan::TRIGGER3_PARAM)); + addParam(createParam<Button18>(trigger4ParamPosition, module, FourMan::TRIGGER4_PARAM)); + + addOutput(createOutput<Port24>(out1OutputPosition, module, FourMan::OUT1_OUTPUT)); + addOutput(createOutput<Port24>(out2OutputPosition, module, FourMan::OUT2_OUTPUT)); + addOutput(createOutput<Port24>(out3OutputPosition, module, FourMan::OUT3_OUTPUT)); + addOutput(createOutput<Port24>(out4OutputPosition, module, FourMan::OUT4_OUTPUT)); + } +}; + +Model* modelFourMan = createModel<FourMan, FourManWidget>("Bogaudio-FourMan", "4MAN", "Quad button-controlled gates / triggers", "Controller", "Quad"); diff --git a/src/FourMan.hpp b/src/FourMan.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include "bogaudio.hpp" +#include "trigger_on_load.hpp" +#include "dsp/signal.hpp" + +extern Model* modelFourMan; + +namespace bogaudio { + +struct FourMan : TriggerOnLoadModule { + enum ParamsIds { + TRIGGER1_PARAM, + TRIGGER2_PARAM, + TRIGGER3_PARAM, + TRIGGER4_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + NUM_INPUTS + }; + + enum OutputsIds { + OUT1_OUTPUT, + OUT2_OUTPUT, + OUT3_OUTPUT, + OUT4_OUTPUT, + NUM_OUTPUTS + }; + + Trigger _trigger[4]; + rack::dsp::PulseGenerator _pulse[4]; + float _sampleTime = 1.0f; + bogaudio::dsp::Timer* _initialDelay = NULL; + + FourMan() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(TRIGGER1_PARAM, 0.0f, 1.0f, 0.0f, "Trigger 1"); + configParam(TRIGGER2_PARAM, 0.0f, 1.0f, 0.0f, "Trigger 2"); + configParam(TRIGGER3_PARAM, 0.0f, 1.0f, 0.0f, "Trigger 3"); + configParam(TRIGGER4_PARAM, 0.0f, 1.0f, 0.0f, "Trigger 4"); + _triggerOnLoad = false; + _initialDelay = new bogaudio::dsp::Timer(APP->engine->getSampleRate(), 0.01f); + } + virtual ~FourMan() { + if (_initialDelay) { + delete _initialDelay; + } + } + + void reset() override; + void sampleRateChange() override; + void processAll(const ProcessArgs& args) override; + bool shouldTriggerOnNextLoad() override { + return true; + } +}; + +} // namespace bogaudio diff --git a/src/Manual.cpp b/src/Manual.cpp @@ -6,7 +6,11 @@ void Manual::reset() { _pulse.process(10.0f); } -void Manual::processChannel(const ProcessArgs& args, int _c) { +void Manual::sampleRateChange() { + _sampleTime = APP->engine->getSampleTime(); +} + +void Manual::processAll(const ProcessArgs& args) { bool initialPulse = false; if (_initialDelay && !_initialDelay->next()) { initialPulse = true; @@ -17,11 +21,8 @@ void Manual::processChannel(const ProcessArgs& args, int _c) { bool high = _trigger.process(params[TRIGGER_PARAM].getValue()) || _trigger.isHigh() || (initialPulse && _triggerOnLoad && _shouldTriggerOnLoad); if (high) { _pulse.trigger(0.001f); - _pulse.process(APP->engine->getSampleTime()); - } - else { - high = _pulse.process(APP->engine->getSampleTime()); } + high = _pulse.process(_sampleTime); float out = high ? 5.0f : 0.0f; outputs[OUT1_OUTPUT].setVoltage(out); diff --git a/src/Manual.hpp b/src/Manual.hpp @@ -32,6 +32,7 @@ struct Manual : TriggerOnLoadModule { Trigger _trigger; rack::dsp::PulseGenerator _pulse; + float _sampleTime; bogaudio::dsp::Timer* _initialDelay = NULL; Manual() { @@ -47,7 +48,8 @@ struct Manual : TriggerOnLoadModule { } void reset() override; - void processChannel(const ProcessArgs& args, int _c) override; + void sampleRateChange() override; + void processAll(const ProcessArgs& args) override; bool shouldTriggerOnNextLoad() override { return true; } diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -28,6 +28,7 @@ #include "EQS.hpp" #include "FFB.hpp" #include "FMOp.hpp" +#include "FourMan.hpp" #include "FlipFlop.hpp" #include "Follow.hpp" #include "Inv.hpp" @@ -190,6 +191,7 @@ void init(rack::Plugin *p) { p->addModel(modelFlipFlop); p->addModel(modelInv); p->addModel(modelManual); + p->addModel(modelFourMan); p->addModel(modelMult); p->addModel(modelOffset); p->addModel(modelSlew);