BogaudioModules

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

commit e5ae4d2dd633f75c2472a15060a80b2b42791331
parent 8d099cb0a6389f715be1740c729f388f900cd39d
Author: Matt Demanett <matt@demanett.net>
Date:   Thu,  9 May 2019 21:48:12 -0400

MIX1: a fader/VCA, much like VCAMP (but with a mute); borrows from MIX4/8. #44

Diffstat:
Ares-src/Mix1-src.svg | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/Mix1.svg | 0
Asrc/Mix1.cpp | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Mix1.hpp | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 4+++-
Msrc/mixer.cpp | 6+++++-
Msrc/mixer.hpp | 5++++-
7 files changed, 268 insertions(+), 3 deletions(-)

diff --git a/res-src/Mix1-src.svg b/res-src/Mix1-src.svg @@ -0,0 +1,136 @@ +<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="slider" viewBox="0 0 18px 151x"> + <rect width="18" height="151" fill="none" /> + <rect width="6" height="145" x="6" y="3" rx="2" stroke-width="1" stroke="#888" fill="#222" /> + <g transform="translate(0 40)"> + <rect width="18" height="13" rx="1.5" fill="#777" /> + <rect width="18" height="9" x="0" y="2" fill="#444" /> + <polyline points="0,6.5 18,6.5" stroke="#fafafa" stroke-width="1" fill="none" /> + <rect width="14" height="5" x="2" y="4" rx="1.0" fill="#ddd" transform="translate(0 0)" /> + </g> + </symbol> + + <symbol id="sliderguide-db" viewBox="0 0 20px 151px"> + <g transform="translate(0 6.5)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + </g> + <g transform="translate(0 19.05)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(0) translate(-2.5 2.6)">0</text> + </g> + <g transform="translate(0 32.86)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-4 2.2)">-6</text> + </g> + <g transform="translate(0 46.05)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-12</text> + </g> + <g transform="translate(0 72.41)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-24</text> + </g> + <g transform="translate(0 125.14)"> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> + <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(28 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-48</text> + </g> + <g transform="translate(0 151.5)"> + <!-- <polyline points="0,0 6.5,0" stroke="#333" fill="none" transform="translate(10.5 0)" /> --> + <text font-size="6.0pt" transform="translate(7 -10) rotate(-90) translate(-9 4)">dB</text> + </g> + </symbol> + + <symbol id="button" viewBox="0 0 20px 20px"> + <g transform="translate(10 10)"> + <circle cx="0" cy="0" r="8.8" 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" /> + + <!-- <polyline points="22.5,0 22.5,380" stroke-width="0.5" stroke="#0f0" /> --> + <!-- <rect width="45" height="10" fill="#0f0" transform="translate(0 68)" /> --> + <!-- <rect width="45" height="10" fill="#0f0" transform="translate(0 127)" /> --> + <!-- <rect width="45" height="10" fill="#0f0" transform="translate(0 177)" /> --> + + <g transform="rotate(-90) translate(-376 13)"> + <text class="title" font-size="7pt" letter-spacing="2.5px">MIX1</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)"> + <use xlink:href="#sliderguide-db" transform="translate(0 0)" /> + <use id="LEVEL_PARAM" xlink:href="#slider" transform="translate(13.5 0)" /> + </g> + + <g transform="translate(0 173)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 120)" /> + <rect width="34" height="127" rx="5" fill="#fafafa" /> + <use id="MUTE_PARAM" xlink:href="#button" transform="translate(7 2)" /> + <use id="MUTE_INPUT" xlink:href="#input" transform="translate(5 25)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(5 57)">MUTE</text> + <use id="LEVEL_INPUT" xlink:href="#input" transform="translate(5 60)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 92)">LEVEL</text> + <use id="IN_INPUT" xlink:href="#input" transform="translate(5 95)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 127)">IN</text> + </g> + <g transform="translate(5.5 133)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="35" rx="5" fill="#bbb" /> + <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text> + </g> + </g> +</svg> diff --git a/res/Mix1.svg b/res/Mix1.svg Binary files differ. diff --git a/src/Mix1.cpp b/src/Mix1.cpp @@ -0,0 +1,62 @@ + +#include "Mix1.hpp" + +void Mix1::onSampleRateChange() { + _channel.setSampleRate(engineGetSampleRate()); +} + +void Mix1::step() { + _channel.next(false, false); + outputs[OUT_OUTPUT].value = _channel.out; +} + +struct Mix1Widget : ModuleWidget { + static constexpr int hp = 3; + + Mix1Widget(Mix1* 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/Mix1.svg"))); + addChild(panel); + } + + addChild(Widget::create<ScrewSilver>(Vec(0, 0))); + addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto levelParamPosition = Vec(13.5, 18.0); + auto muteParamPosition = Vec(13.2, 175.7); + + auto muteInputPosition = Vec(10.5, 198.0); + auto levelInputPosition = Vec(10.5, 233.0); + auto inInputPosition = Vec(10.5, 268.0); + + auto outOutputPosition = Vec(10.5, 306.0); + // end generated by svg_widgets.rb + + { + auto slider = ParamWidget::create<VUSlider151>( + levelParamPosition, + module, + Mix1::LEVEL_PARAM, + 0.0, + 1.0, + fabsf(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) + ); + dynamic_cast<VUSlider*>(slider)->setVULevel(&module->_channel.rms); + addParam(slider); + } + addParam(ParamWidget::create<MuteButton>(muteParamPosition, module, Mix1::MUTE_PARAM, 0.0, 1.0, 0.0)); + + addInput(Port::create<Port24>(muteInputPosition, Port::INPUT, module, Mix1::MUTE_INPUT)); + addInput(Port::create<Port24>(levelInputPosition, Port::INPUT, module, Mix1::LEVEL_INPUT)); + addInput(Port::create<Port24>(inInputPosition, Port::INPUT, module, Mix1::IN_INPUT)); + + addOutput(Port::create<Port24>(outOutputPosition, Port::OUTPUT, module, Mix1::OUT_OUTPUT)); + } +}; + +Model* modelMix1 = createModel<Mix1, Mix1Widget>("Bogaudio-Mix1", "MIX1", "fader/amplifier with mute", AMPLIFIER_TAG); diff --git a/src/Mix1.hpp b/src/Mix1.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include "bogaudio.hpp" +#include "mixer.hpp" +#include "dsp/signal.hpp" + +using namespace bogaudio::dsp; + +extern Model* modelMix1; + +namespace bogaudio { + +struct Mix1 : Module { + enum ParamsIds { + LEVEL_PARAM, + MUTE_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + MUTE_INPUT, + LEVEL_INPUT, + IN_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + OUT_OUTPUT, + NUM_OUTPUTS + }; + + enum LightsIds { + NUM_LIGHTS + }; + + MixerChannel _channel; + + Mix1() + : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) + , _channel( + params[LEVEL_PARAM], + params[LEVEL_PARAM], // not used + params[MUTE_PARAM], + inputs[IN_INPUT], + inputs[LEVEL_INPUT], + inputs[LEVEL_INPUT], // not used + 1000.0f, + &inputs[MUTE_INPUT] + ) + { + onSampleRateChange(); + } + + void onSampleRateChange() override; + void step() override; +}; + +} // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -29,6 +29,7 @@ #include "Lmtr.hpp" #include "Manual.hpp" #include "Matrix88.hpp" +#include "Mix1.hpp" #include "Mix4.hpp" #include "Mix8.hpp" #include "Mult.hpp" @@ -96,8 +97,9 @@ void init(rack::Plugin *p) { p->addModel(modelWalk); #endif - p->addModel(modelMix4); p->addModel(modelMix8); + p->addModel(modelMix4); + p->addModel(modelMix1); p->addModel(modelVCM); p->addModel(modelUMix); p->addModel(modelMatrix88); diff --git a/src/mixer.cpp b/src/mixer.cpp @@ -18,7 +18,11 @@ void MixerChannel::next(bool stereo, bool solo) { return; } - bool muted = solo ? _muteParam.value < 2.0f : _muteParam.value > 0.5f; + float mute = _muteParam.value; + if (_muteInput) { + mute += clamp(_muteInput->value, 0.0f, 10.0f); + } + bool muted = solo ? mute < 2.0f : mute > 0.5f; if (muted) { _amplifier.setLevel(_levelSL.next(minDecibels)); } diff --git a/src/mixer.hpp b/src/mixer.hpp @@ -25,6 +25,7 @@ struct MixerChannel { Input& _inInput; Input& _levelInput; Input& _panInput; + Input* _muteInput; float out = 0.0f; float left = 0.0f; @@ -38,7 +39,8 @@ struct MixerChannel { Input& in, Input& levelCv, Input& panCv, - float sampleRate = 1000.0f + float sampleRate = 1000.0f, + Input* muteCv = NULL ) : _levelParam(level) , _panParam(pan) @@ -46,6 +48,7 @@ struct MixerChannel { , _inInput(in) , _levelInput(levelCv) , _panInput(panCv) + , _muteInput(muteCv) { setSampleRate(sampleRate); _rms.setSensitivity(0.05f);