BogaudioModules

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

commit f26b74d0bcb5b667d8b9b65b325f9ac748fb7c80
parent 2e846b3adc0cff68a327c3e961ba5e719a4e7199
Author: Matt Demanett <matt@demanett.net>
Date:   Wed,  9 May 2018 00:31:25 -0400

VU meter module; revisions to VCAmp.

Diffstat:
Mres-src/VCAmp-src.svg | 11++---------
Ares-src/VU-src.svg | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mres/VCAmp.svg | 0
Ares/VU.svg | 0
Msrc/VCAmp.cpp | 18++++--------------
Asrc/VU.cpp | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/VU.hpp | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 2++
Msrc/widgets.cpp | 14++++++++++++++
Msrc/widgets.hpp | 2++
10 files changed, 341 insertions(+), 23 deletions(-)

diff --git a/res-src/VCAmp-src.svg b/res-src/VCAmp-src.svg @@ -35,7 +35,6 @@ <symbol id="sliderguide-db" viewBox="0 0 20px 183px"> <g transform="translate(0 6.5)"> <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> - <!-- <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-4 2.2)">12</text> --> </g> <g transform="translate(0 20.67)"> <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> @@ -57,18 +56,12 @@ <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-24</text> </g> - <g transform="translate(0 119.83)"> - <!-- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> --> - <!-- <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-36</text> --> - <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-10 2.2)">- dB -</text> - </g> <g transform="translate(0 148.17)"> <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-48</text> </g> - <g transform="translate(0 176.5)"> - <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> - <!-- <text font-size="5.0pt" transform="translate(7 0) rotate(-90) translate(-5 2.2)">-&infin;</text> --> + <g transform="translate(0 170)"> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-9 6)">dB</text> </g> </symbol> diff --git a/res-src/VU-src.svg b/res-src/VU-src.svg @@ -0,0 +1,145 @@ +<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="vu" viewBox="0 0 18px 180px"> + <!-- <rect width="18" height="180" x="0" y="0" rx="0" fill="#ccc" /> --> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 0)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 0)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 15)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 15)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 30)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 30)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 45)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 45)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 60)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 60)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 75)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 75)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 90)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 90)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 105)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 105)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 120)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 120)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 135)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 135)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 150)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 150)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(3 165)" /> + <rect width="5" height="13" x="0" y="1" rx="0" fill="#aaa" transform="translate(10 165)" /> + </symbol> + + <symbol id="guide-db" viewBox="0 0 20px 183px"> + <g transform="translate(0 15)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(0) translate(-2.5 2.6)">6</text> + </g> + <g transform="translate(0 30)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(0) translate(-2.5 2.6)">0</text> + </g> + <g transform="translate(0 45)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-4 2.2)">-6</text> + </g> + <g transform="translate(0 60)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-12</text> + </g> + <g transform="translate(0 90)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-24</text> + </g> + <g transform="translate(0 120)"> + <!-- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" /> --> + <!-- <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-36</text> --> + <!-- <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-10 2.2)">- dB -</text> --> + </g> + <g transform="translate(0 150)"> + <polyline points="0,0 3,0" stroke="#333" fille="none" transform="translate(11 0)" /> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-48</text> + </g> + <g transform="translate(0 170)"> + <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-9 4.5)">dB</text> + </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">VU</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 id="VU_WIDGET" xlink:href="#vu" transform="translate(13.5 -1)" /> + <use xlink:href="#guide-db" transform="translate(0 -1)" /> + </g> + + <g transform="translate(0 200)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 63)" /> + <rect width="34" height="70" rx="5" fill="#fafafa" /> + <use id="L_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">L</text> + <use id="R_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="0.5px" transform="translate(9 70)">R (L)</text> + </g> + <g transform="translate(5.5 76)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="70" rx="5" fill="#bbb" /> + <use id="L_OUTPUT" xlink:href="#output" transform="translate(5 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 32)">L</text> + <use id="R_OUTPUT" xlink:href="#output" transform="translate(5 35)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 67)">R</text> + </g> + </g> +</svg> diff --git a/res/VCAmp.svg b/res/VCAmp.svg Binary files differ. diff --git a/res/VU.svg b/res/VU.svg Binary files differ. diff --git a/src/VCAmp.cpp b/src/VCAmp.cpp @@ -59,20 +59,10 @@ struct VUSlider : Knob { float db = dynamic_cast<VCAmp*>(module)->_rmsLevel; if (db > 0.0f) { db = amplitudeToDecibels(db); - if (db > -60.0f) { - nvgBeginPath(vg); - nvgRoundedRect(vg, 2, 4, 14, 5, 1.0); - if (db < -24.0f) { - nvgFillColor(vg, nvgRGBA(0x55, 0xff, 0x00, (1.0f - (db + 24.0f) / -36.0f) * (float)0xff)); - } - else if (db < 0.0f) { - nvgFillColor(vg, nvgRGBA((1.0f - db / -24.0f) * 0xff, 0xff, 0x00, 0xff)); - } - else { - nvgFillColor(vg, nvgRGBA(0xff, (1.0f - db / 18.0f) * 0xff, 0x00, 0xff)); - } - nvgFill(vg); - } + nvgBeginPath(vg); + nvgRoundedRect(vg, 2, 4, 14, 5, 1.0); + nvgFillColor(vg, decibelsToColor(db)); + nvgFill(vg); } } nvgRestore(vg); diff --git a/src/VU.cpp b/src/VU.cpp @@ -0,0 +1,124 @@ + +#include "VU.hpp" + +void VU::onSampleRateChange() { + _lRms.setSampleRate(engineGetSampleRate()); + _rRms.setSampleRate(engineGetSampleRate()); +} + +void VU::step() { + float left = 0.0f; + float right = 0.0f; + if (inputs[L_INPUT].active) { + left = inputs[L_INPUT].value; + } + if (inputs[R_INPUT].active) { + right = inputs[R_INPUT].value; + } + else { + right = left; + } + _lLevel = _lRms.next(left) / 5.0f; + _rLevel = _rRms.next(right) / 5.0f; + outputs[L_OUTPUT].value = left; + outputs[R_OUTPUT].value = right; +} + +struct VUDisplay : OpaqueWidget { + struct Level { + float db; + NVGcolor color; + Level(float db, const NVGcolor& color) : db(db), color(color) {} + }; + + const NVGcolor bgColor = nvgRGBA(0xaa, 0xaa, 0xaa, 0xff); + VU* _module; + std::vector<Level> _levels; + + VUDisplay(VU* module) : _module(module) { + for (int i = 1; i <= 36; ++i) { + float db = 12.0f - i*2.0f; + _levels.push_back(Level(db, decibelsToColor(db))); + } + } + + virtual void draw(NVGcontext* vg) override { + float lDb = _module->_lLevel; + if (lDb > 0.0f) { + lDb = amplitudeToDecibels(lDb); + } + else { + lDb = -100.0f; + } + float rDb = _module->_rLevel; + if (rDb > 0.0f) { + rDb = amplitudeToDecibels(rDb); + } + else { + rDb = -100.0f; + } + + nvgSave(vg); + for (int i = 0; i < 180; i += 5) { + const Level& l = _levels.at(i / 5); + + nvgBeginPath(vg); + nvgRect(vg, 3, i + 1, 5, 4); + nvgFillColor(vg, bgColor); + nvgFill(vg); + if (lDb > l.db) { + nvgFillColor(vg, l.color); + nvgFill(vg); + } + + nvgBeginPath(vg); + nvgRect(vg, 10, i + 1, 5, 4); + nvgFillColor(vg, bgColor); + nvgFill(vg); + if (rDb > l.db) { + nvgFillColor(vg, l.color); + nvgFill(vg); + } + } + nvgRestore(vg); + } +}; + +struct VUWidget : ModuleWidget { + VUWidget(VU* module) : ModuleWidget(module) { + box.size = Vec(RACK_GRID_WIDTH * 3, RACK_GRID_HEIGHT); + + { + SVGPanel *panel = new SVGPanel(); + panel->box.size = box.size; + panel->setBackground(SVG::load(assetPlugin(plugin, "res/VU.svg"))); + addChild(panel); + } + + { + auto display = new VUDisplay(module); + display->box.pos = Vec(13.5, 16.5); + display->box.size = Vec(18, 180); + addChild(display); + } + + addChild(Widget::create<ScrewSilver>(Vec(0, 0))); + addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto lInputPosition = Vec(10.5, 203.0); + auto rInputPosition = Vec(10.5, 238.0); + + auto lOutputPosition = Vec(10.5, 276.0); + auto rOutputPosition = Vec(10.5, 311.0); + // end generated by svg_widgets.rb + + addInput(Port::create<Port24>(lInputPosition, Port::INPUT, module, VU::L_INPUT)); + addInput(Port::create<Port24>(rInputPosition, Port::INPUT, module, VU::R_INPUT)); + + addOutput(Port::create<Port24>(lOutputPosition, Port::OUTPUT, module, VU::L_OUTPUT)); + addOutput(Port::create<Port24>(rOutputPosition, Port::OUTPUT, module, VU::R_OUTPUT)); + } +}; + +Model* modelVU = Model::create<VU, VUWidget>("Bogaudio", "Bogaudio-VU", "VU", VISUAL_TAG, DUAL_TAG, UTILITY_TAG); diff --git a/src/VU.hpp b/src/VU.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "bogaudio.hpp" +#include "dsp/signal.hpp" + +using namespace bogaudio::dsp; + +extern Model* modelVU; + +namespace bogaudio { + +struct VU : Module { + enum ParamsIds { + NUM_PARAMS + }; + + enum InputsIds { + L_INPUT, + R_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + L_OUTPUT, + R_OUTPUT, + NUM_OUTPUTS + }; + + enum LightsIds { + NUM_LIGHTS + }; + + RootMeanSquare _lRms; + RootMeanSquare _rRms; + float _lLevel = 0.0f; + float _rLevel = 0.0f; + + VU() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + onSampleRateChange(); + _lRms.setSensitivity(0.05f); + _rRms.setSensitivity(0.05f); + } + + virtual void onSampleRateChange() override; + virtual void step() override; +}; + +} // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -34,6 +34,7 @@ #include "VCA.hpp" #include "VCAL.hpp" #include "VCAmp.hpp" +#include "VU.hpp" #include "Test.hpp" #include "Test2.hpp" @@ -94,6 +95,7 @@ void init(rack::Plugin *p) { #ifdef EXPERIMENTAL p->addModel(modelVCAL); p->addModel(modelVCAmp); + p->addModel(modelVU); #endif #ifdef TEST diff --git a/src/widgets.cpp b/src/widgets.cpp @@ -107,3 +107,17 @@ void StatefulButton::onDragEnd(EventDragEnd& e) { StatefulButton9::StatefulButton9() : StatefulButton("res/button_9px_0.svg", "res/button_9px_1.svg") { } + + +NVGcolor bogaudio::decibelsToColor(float db) { + if (db < -80.0f) { + return nvgRGBA(0x00, 0x00, 0x00, 0x00); + } + if (db < -24.0f) { + return nvgRGBA(0x55, 0xff, 0x00, (1.0f - (db + 24.0f) / -56.0f) * (float)0xff); + } + if (db < 0.0f) { + return nvgRGBA((1.0f - db / -24.0f) * 0xff, 0xff, 0x00, 0xff); + } + return nvgRGBA(0xff, (1.0f - db / 18.0f) * 0xff, 0x00, 0xff); +} diff --git a/src/widgets.hpp b/src/widgets.hpp @@ -62,4 +62,6 @@ struct StatefulButton9 : StatefulButton { StatefulButton9(); }; +NVGcolor decibelsToColor(float db); + } // namespace bogaudio