BogaudioModules

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

commit 4adba336dd323b4f88f67b0c89b730164cae07bd
parent 3dce7a876ee0dc9a69fcb73913a7f59019f7183b
Author: Matt Demanett <matt@demanett.net>
Date:   Fri,  1 Jun 2018 00:35:37 -0400

MIX8: 8-channel mixer.

Diffstat:
Ares-src/Mix8-src.svg | 324+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/Mix8.svg | 0
Msrc/Mix4.cpp | 85+++++++++++++++++--------------------------------------------------------------
Msrc/Mix4.hpp | 4++--
Asrc/Mix8.cpp | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Mix8.hpp | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 2++
Msrc/mixer.hpp | 7+++++++
8 files changed, 689 insertions(+), 69 deletions(-)

diff --git a/res-src/Mix8-src.svg b/res-src/Mix8-src.svg @@ -0,0 +1,324 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="405" + height="380" + viewBox="0 0 405 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="knob-smallest" viewBox="0 0 16px 16px"> + <g transform="translate(8 8)"> + <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f" /> + <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f" /> + <circle r="7.5" stroke-width="1" stroke="#00f" fill="none" /> + </g> + </symbol> + + <symbol id="knobguide-centertick" viewBox="0 0 40px 40px"> + <g transform="translate(20 20)"> + <g transform="rotate(-90) translate(10 0)"> + <polyline points="0,0 4,0" stroke-width="1" stroke="#333" /> + </g> + <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(20)" /> + <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(43)" /> + <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(-20)" /> + <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(-43)" /> + </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 404,1 404,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 404.5,0.5 404.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 405,0 405,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <!-- <rect width="175" height="20" fill="#0f0" transform="translate(0 0)" /> --> + <!-- <rect width="175" height="20" fill="#0f0" transform="translate(230 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(10 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(395 0)" /> --> + + <text class="title" x="175" y="19" font-size="12pt" letter-spacing="4px">MIX8</text> + <g transform="translate(162.5 374)"> + <text class="brand" font-size="8pt" letter-spacing="2px">BOGAUDIO</text> + <rect width="3.0" height="3" fill="#ddd" transform="translate(24 -5)" /> + </g> + + <g transform="translate(4 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH1</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL1_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE1_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN1_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV1_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN1_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN1_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(48 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH2</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL2_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE2_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN2_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV2_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN2_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN2_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(92 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH3</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL3_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE3_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN3_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV3_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN3_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN3_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(136 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH4</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL4_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE4_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN4_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV4_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN4_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN4_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(180 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH5</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL5_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE5_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN5_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV5_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN5_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN5_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(224 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH6</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL6_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE6_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN6_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV6_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN6_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN6_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(268 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH7</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL7_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE7_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN7_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV7_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN7_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN7_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(312 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">CH8</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="LEVEL8_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <use id="MUTE8_PARAM" xlink:href="#button" transform="translate(12.5 165)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 192)">MUTE</text> + <use id="PAN8_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 203)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 191)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 228)">PAN</text> + <g transform="translate(5.5 232)"> + <rect width="34" height="108" rx="5" fill="#fafafa" /> + <use id="CV8_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <use id="PAN8_INPUT" xlink:href="#input" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">PAN</text> + <use id="IN8_INPUT" xlink:href="#input" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">IN</text> + </g> + <!-- <rect width="9" height="40" fill="#f00" transform="translate(39.5 300)" /> --> + </g> + + <g transform="translate(356 20)"> + <!-- <rect width="39" height="344" fill="#ccc" transform="translate(3 0)" /> --> + <text font-size="5pt" letter-spacing="2px" transform="translate(13.7 9)">MIX</text> + <use xlink:href="#sliderguide-db" transform="translate(0 12)" /> + <use id="MIX_PARAM" xlink:href="#slider" transform="translate(13.5 12)" /> + <g transform="translate(5.5 229)"> + <rect width="34" height="50" rx="5" fill="#fafafa" /> + <use id="MIX_CV_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> + <rect width="34" height="73" rx="5" fill="#bbb" transform="translate(0 38)" /> + <rect width="34" height="5" fill="#bbb" transform="translate(0 38)" /> + <use id="L_OUTPUT" xlink:href="#output" transform="translate(5 41)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15.5 73)">L</text> + <use id="R_OUTPUT" xlink:href="#output" transform="translate(5 76)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 108)">R</text> + </g> + </g> + <!-- <polyline points="0,0 225,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(0 360)" /> --> +</svg> diff --git a/res/Mix8.svg b/res/Mix8.svg Binary files differ. diff --git a/src/Mix4.cpp b/src/Mix4.cpp @@ -56,13 +56,6 @@ void Mix4::step() { } } -struct MuteButton : ToggleButton { - MuteButton() { - addFrame(SVG::load(assetPlugin(plugin, "res/button_18px_0.svg"))); - addFrame(SVG::load(assetPlugin(plugin, "res/button_18px_1_orange.svg"))); - } -}; - struct Mix4Widget : ModuleWidget { Mix4Widget(Mix4* module) : ModuleWidget(module) { box.size = Vec(RACK_GRID_WIDTH * 15, RACK_GRID_HEIGHT); @@ -112,74 +105,19 @@ struct Mix4Widget : ModuleWidget { auto rOutputPosition = Vec(186.5, 325.0); // end generated by svg_widgets.rb - { - auto slider = ParamWidget::create<VUSlider151>( - level1ParamPosition, - module, - Mix4::LEVEL1_PARAM, - 0.0, - 1.0, - abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) - ); - dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel1.rms)); - addParam(slider); - } + addSlider(level1ParamPosition, module, Mix4::LEVEL1_PARAM, module->_channel1.rms); addParam(ParamWidget::create<Knob16>(pan1ParamPosition, module, Mix4::PAN1_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<MuteButton>(mute1ParamPosition, module, Mix4::MUTE1_PARAM, 0.0, 1.0, 0.0)); - { - auto slider = ParamWidget::create<VUSlider151>( - level2ParamPosition, - module, - Mix4::LEVEL2_PARAM, - 0.0, - 1.0, - abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) - ); - dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel2.rms)); - addParam(slider); - } + addSlider(level2ParamPosition, module, Mix4::LEVEL2_PARAM, module->_channel2.rms); addParam(ParamWidget::create<Knob16>(pan2ParamPosition, module, Mix4::PAN2_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<MuteButton>(mute2ParamPosition, module, Mix4::MUTE2_PARAM, 0.0, 1.0, 0.0)); - { - auto slider = ParamWidget::create<VUSlider151>( - level3ParamPosition, - module, - Mix4::LEVEL3_PARAM, - 0.0, - 1.0, - abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) - ); - dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel3.rms)); - addParam(slider); - } + addSlider(level3ParamPosition, module, Mix4::LEVEL3_PARAM, module->_channel3.rms); addParam(ParamWidget::create<Knob16>(pan3ParamPosition, module, Mix4::PAN3_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<MuteButton>(mute3ParamPosition, module, Mix4::MUTE3_PARAM, 0.0, 1.0, 0.0)); - { - auto slider = ParamWidget::create<VUSlider151>( - level4ParamPosition, - module, - Mix4::LEVEL4_PARAM, - 0.0, - 1.0, - abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) - ); - dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel4.rms)); - addParam(slider); - } + addSlider(level4ParamPosition, module, Mix4::LEVEL4_PARAM, module->_channel4.rms); addParam(ParamWidget::create<Knob16>(pan4ParamPosition, module, Mix4::PAN4_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<MuteButton>(mute4ParamPosition, module, Mix4::MUTE4_PARAM, 0.0, 1.0, 0.0)); - { - auto slider = ParamWidget::create<VUSlider151>( - mixParamPosition, - module, - Mix4::MIX_PARAM, - 0.0, - 1.0, - abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) - ); - dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_rmsLevel)); - addParam(slider); - } + addSlider(mixParamPosition, module, Mix4::MIX_PARAM, module->_rmsLevel); addInput(Port::create<Port24>(cv1InputPosition, Port::INPUT, module, Mix4::CV1_INPUT)); addInput(Port::create<Port24>(pan1InputPosition, Port::INPUT, module, Mix4::PAN1_INPUT)); @@ -198,6 +136,19 @@ struct Mix4Widget : ModuleWidget { addOutput(Port::create<Port24>(lOutputPosition, Port::OUTPUT, module, Mix4::L_OUTPUT)); addOutput(Port::create<Port24>(rOutputPosition, Port::OUTPUT, module, Mix4::R_OUTPUT)); } + + void addSlider(Vec position, Mix4* module, int id, float& rms) { + auto slider = ParamWidget::create<VUSlider151>( + position, + module, + id, + 0.0, + 1.0, + abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) + ); + dynamic_cast<VUSlider*>(slider)->setVULevel(&rms); + addParam(slider); + } }; Model* modelMix4 = Model::create<Mix4, Mix4Widget>("Bogaudio", "Bogaudio-Mix4", "Mix4", MIXER_TAG, PANNING_TAG, DUAL_TAG); diff --git a/src/Mix4.hpp b/src/Mix4.hpp @@ -2,12 +2,12 @@ #include "bogaudio.hpp" #include "mixer.hpp" - -extern Model* modelMix4; #include "dsp/signal.hpp" using namespace bogaudio::dsp; +extern Model* modelMix4; + namespace bogaudio { struct Mix4 : Module { diff --git a/src/Mix8.cpp b/src/Mix8.cpp @@ -0,0 +1,222 @@ + +#include "Mix8.hpp" + +void Mix8::onSampleRateChange() { + float sr = engineGetSampleRate(); + _channel1.setSampleRate(sr); + _channel2.setSampleRate(sr); + _channel3.setSampleRate(sr); + _channel4.setSampleRate(sr); + _channel5.setSampleRate(sr); + _channel6.setSampleRate(sr); + _channel7.setSampleRate(sr); + _channel8.setSampleRate(sr); + _slewLimiter.setParams(sr, MixerChannel::slewTimeMS); + _rms.setSampleRate(sr); +} + +void Mix8::step() { + bool stereo = outputs[L_OUTPUT].active && outputs[R_OUTPUT].active; + _channel1.next(stereo); + _channel2.next(stereo); + _channel3.next(stereo); + _channel4.next(stereo); + _channel5.next(stereo); + _channel6.next(stereo); + _channel7.next(stereo); + _channel8.next(stereo); + + float level = params[MIX_PARAM].value; + if (inputs[MIX_CV_INPUT].active) { + level *= clamp(inputs[MIX_CV_INPUT].value / 10.0f, 0.0f, 1.0f); + } + level *= MixerChannel::maxDecibels - MixerChannel::minDecibels; + level += MixerChannel::minDecibels; + _amplifier.setLevel(_slewLimiter.next(level)); + + float mono = 0.0f; + mono += _channel1.out; + mono += _channel2.out; + mono += _channel3.out; + mono += _channel4.out; + mono += _channel5.out; + mono += _channel6.out; + mono += _channel7.out; + mono += _channel8.out; + mono = _amplifier.next(mono); + _rmsLevel = _rms.next(mono) / 5.0f; + + if (stereo) { + float left = 0.0f; + left += _channel1.left; + left += _channel2.left; + left += _channel3.left; + left += _channel4.left; + left += _channel5.left; + left += _channel6.left; + left += _channel7.left; + left += _channel8.left; + left = _amplifier.next(left); + outputs[L_OUTPUT].value = left; + + float right = 0.0f; + right += _channel1.right; + right += _channel2.right; + right += _channel3.right; + right += _channel4.right; + right += _channel5.right; + right += _channel6.right; + right += _channel7.right; + right += _channel8.right; + right = _amplifier.next(right); + outputs[R_OUTPUT].value = right; + } + else { + outputs[L_OUTPUT].value = outputs[R_OUTPUT].value = mono; + } +} + +struct Mix8Widget : ModuleWidget { + Mix8Widget(Mix8* module) : ModuleWidget(module) { + box.size = Vec(RACK_GRID_WIDTH * 27, RACK_GRID_HEIGHT); + + { + SVGPanel *panel = new SVGPanel(); + panel->box.size = box.size; + panel->setBackground(SVG::load(assetPlugin(plugin, "res/Mix8.svg"))); + addChild(panel); + } + + addChild(Widget::create<ScrewSilver>(Vec(15, 0))); + addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0))); + addChild(Widget::create<ScrewSilver>(Vec(15, 365))); + addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365))); + + // generated by svg_widgets.rb + auto level1ParamPosition = Vec(17.5, 32.0); + auto mute1ParamPosition = Vec(17.2, 185.7); + auto pan1ParamPosition = Vec(18.5, 223.0); + auto level2ParamPosition = Vec(61.5, 32.0); + auto mute2ParamPosition = Vec(61.2, 185.7); + auto pan2ParamPosition = Vec(62.5, 223.0); + auto level3ParamPosition = Vec(105.5, 32.0); + auto mute3ParamPosition = Vec(105.2, 185.7); + auto pan3ParamPosition = Vec(106.5, 223.0); + auto level4ParamPosition = Vec(149.5, 32.0); + auto mute4ParamPosition = Vec(149.2, 185.7); + auto pan4ParamPosition = Vec(150.5, 223.0); + auto level5ParamPosition = Vec(193.5, 32.0); + auto mute5ParamPosition = Vec(193.2, 185.7); + auto pan5ParamPosition = Vec(194.5, 223.0); + auto level6ParamPosition = Vec(237.5, 32.0); + auto mute6ParamPosition = Vec(237.2, 185.7); + auto pan6ParamPosition = Vec(238.5, 223.0); + auto level7ParamPosition = Vec(281.5, 32.0); + auto mute7ParamPosition = Vec(281.2, 185.7); + auto pan7ParamPosition = Vec(282.5, 223.0); + auto level8ParamPosition = Vec(325.5, 32.0); + auto mute8ParamPosition = Vec(325.2, 185.7); + auto pan8ParamPosition = Vec(326.5, 223.0); + auto mixParamPosition = Vec(369.5, 32.0); + + auto cv1InputPosition = Vec(14.5, 255.0); + auto pan1InputPosition = Vec(14.5, 290.0); + auto in1InputPosition = Vec(14.5, 325.0); + auto cv2InputPosition = Vec(58.5, 255.0); + auto pan2InputPosition = Vec(58.5, 290.0); + auto in2InputPosition = Vec(58.5, 325.0); + auto cv3InputPosition = Vec(102.5, 255.0); + auto pan3InputPosition = Vec(102.5, 290.0); + auto in3InputPosition = Vec(102.5, 325.0); + auto cv4InputPosition = Vec(146.5, 255.0); + auto pan4InputPosition = Vec(146.5, 290.0); + auto in4InputPosition = Vec(146.5, 325.0); + auto cv5InputPosition = Vec(190.5, 255.0); + auto pan5InputPosition = Vec(190.5, 290.0); + auto in5InputPosition = Vec(190.5, 325.0); + auto cv6InputPosition = Vec(234.5, 255.0); + auto pan6InputPosition = Vec(234.5, 290.0); + auto in6InputPosition = Vec(234.5, 325.0); + auto cv7InputPosition = Vec(278.5, 255.0); + auto pan7InputPosition = Vec(278.5, 290.0); + auto in7InputPosition = Vec(278.5, 325.0); + auto cv8InputPosition = Vec(322.5, 255.0); + auto pan8InputPosition = Vec(322.5, 290.0); + auto in8InputPosition = Vec(322.5, 325.0); + auto mixCvInputPosition = Vec(366.5, 252.0); + + auto lOutputPosition = Vec(366.5, 290.0); + auto rOutputPosition = Vec(366.5, 325.0); + // end generated by svg_widgets.rb + + addSlider(level1ParamPosition, module, Mix8::LEVEL1_PARAM, module->_channel1.rms); + addParam(ParamWidget::create<MuteButton>(mute1ParamPosition, module, Mix8::MUTE1_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan1ParamPosition, module, Mix8::PAN1_PARAM, -1.0, 1.0, 0.0)); + addSlider(level2ParamPosition, module, Mix8::LEVEL2_PARAM, module->_channel2.rms); + addParam(ParamWidget::create<MuteButton>(mute2ParamPosition, module, Mix8::MUTE2_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan2ParamPosition, module, Mix8::PAN2_PARAM, -1.0, 1.0, 0.0)); + addSlider(level3ParamPosition, module, Mix8::LEVEL3_PARAM, module->_channel3.rms); + addParam(ParamWidget::create<MuteButton>(mute3ParamPosition, module, Mix8::MUTE3_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan3ParamPosition, module, Mix8::PAN3_PARAM, -1.0, 1.0, 0.0)); + addSlider(level4ParamPosition, module, Mix8::LEVEL4_PARAM, module->_channel4.rms); + addParam(ParamWidget::create<MuteButton>(mute4ParamPosition, module, Mix8::MUTE4_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan4ParamPosition, module, Mix8::PAN4_PARAM, -1.0, 1.0, 0.0)); + addSlider(level5ParamPosition, module, Mix8::LEVEL5_PARAM, module->_channel5.rms); + addParam(ParamWidget::create<MuteButton>(mute5ParamPosition, module, Mix8::MUTE5_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan5ParamPosition, module, Mix8::PAN5_PARAM, -1.0, 1.0, 0.0)); + addSlider(level6ParamPosition, module, Mix8::LEVEL6_PARAM, module->_channel6.rms); + addParam(ParamWidget::create<MuteButton>(mute6ParamPosition, module, Mix8::MUTE6_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan6ParamPosition, module, Mix8::PAN6_PARAM, -1.0, 1.0, 0.0)); + addSlider(level7ParamPosition, module, Mix8::LEVEL7_PARAM, module->_channel7.rms); + addParam(ParamWidget::create<MuteButton>(mute7ParamPosition, module, Mix8::MUTE7_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan7ParamPosition, module, Mix8::PAN7_PARAM, -1.0, 1.0, 0.0)); + addSlider(level8ParamPosition, module, Mix8::LEVEL8_PARAM, module->_channel8.rms); + addParam(ParamWidget::create<MuteButton>(mute8ParamPosition, module, Mix8::MUTE8_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob16>(pan8ParamPosition, module, Mix8::PAN8_PARAM, -1.0, 1.0, 0.0)); + addSlider(mixParamPosition, module, Mix8::MIX_PARAM, module->_rmsLevel); + + addInput(Port::create<Port24>(cv1InputPosition, Port::INPUT, module, Mix8::CV1_INPUT)); + addInput(Port::create<Port24>(pan1InputPosition, Port::INPUT, module, Mix8::PAN1_INPUT)); + addInput(Port::create<Port24>(in1InputPosition, Port::INPUT, module, Mix8::IN1_INPUT)); + addInput(Port::create<Port24>(cv2InputPosition, Port::INPUT, module, Mix8::CV2_INPUT)); + addInput(Port::create<Port24>(pan2InputPosition, Port::INPUT, module, Mix8::PAN2_INPUT)); + addInput(Port::create<Port24>(in2InputPosition, Port::INPUT, module, Mix8::IN2_INPUT)); + addInput(Port::create<Port24>(cv3InputPosition, Port::INPUT, module, Mix8::CV3_INPUT)); + addInput(Port::create<Port24>(pan3InputPosition, Port::INPUT, module, Mix8::PAN3_INPUT)); + addInput(Port::create<Port24>(in3InputPosition, Port::INPUT, module, Mix8::IN3_INPUT)); + addInput(Port::create<Port24>(cv4InputPosition, Port::INPUT, module, Mix8::CV4_INPUT)); + addInput(Port::create<Port24>(pan4InputPosition, Port::INPUT, module, Mix8::PAN4_INPUT)); + addInput(Port::create<Port24>(in4InputPosition, Port::INPUT, module, Mix8::IN4_INPUT)); + addInput(Port::create<Port24>(cv5InputPosition, Port::INPUT, module, Mix8::CV5_INPUT)); + addInput(Port::create<Port24>(pan5InputPosition, Port::INPUT, module, Mix8::PAN5_INPUT)); + addInput(Port::create<Port24>(in5InputPosition, Port::INPUT, module, Mix8::IN5_INPUT)); + addInput(Port::create<Port24>(cv6InputPosition, Port::INPUT, module, Mix8::CV6_INPUT)); + addInput(Port::create<Port24>(pan6InputPosition, Port::INPUT, module, Mix8::PAN6_INPUT)); + addInput(Port::create<Port24>(in6InputPosition, Port::INPUT, module, Mix8::IN6_INPUT)); + addInput(Port::create<Port24>(cv7InputPosition, Port::INPUT, module, Mix8::CV7_INPUT)); + addInput(Port::create<Port24>(pan7InputPosition, Port::INPUT, module, Mix8::PAN7_INPUT)); + addInput(Port::create<Port24>(in7InputPosition, Port::INPUT, module, Mix8::IN7_INPUT)); + addInput(Port::create<Port24>(cv8InputPosition, Port::INPUT, module, Mix8::CV8_INPUT)); + addInput(Port::create<Port24>(pan8InputPosition, Port::INPUT, module, Mix8::PAN8_INPUT)); + addInput(Port::create<Port24>(in8InputPosition, Port::INPUT, module, Mix8::IN8_INPUT)); + addInput(Port::create<Port24>(mixCvInputPosition, Port::INPUT, module, Mix8::MIX_CV_INPUT)); + + addOutput(Port::create<Port24>(lOutputPosition, Port::OUTPUT, module, Mix8::L_OUTPUT)); + addOutput(Port::create<Port24>(rOutputPosition, Port::OUTPUT, module, Mix8::R_OUTPUT)); + } + + void addSlider(Vec position, Mix8* module, int id, float& rms) { + auto slider = ParamWidget::create<VUSlider151>( + position, + module, + id, + 0.0, + 1.0, + abs(MixerChannel::minDecibels) / (MixerChannel::maxDecibels - MixerChannel::minDecibels) + ); + dynamic_cast<VUSlider*>(slider)->setVULevel(&rms); + addParam(slider); + } +}; + +Model* modelMix8 = Model::create<Mix8, Mix8Widget>("Bogaudio", "Bogaudio-Mix8", "Mix8"); diff --git a/src/Mix8.hpp b/src/Mix8.hpp @@ -0,0 +1,114 @@ +#pragma once + +#include "bogaudio.hpp" +#include "mixer.hpp" +#include "dsp/signal.hpp" + +using namespace bogaudio::dsp; + +extern Model* modelMix8; + +namespace bogaudio { + +struct Mix8 : Module { + enum ParamsIds { + LEVEL1_PARAM, + MUTE1_PARAM, + PAN1_PARAM, + LEVEL2_PARAM, + MUTE2_PARAM, + PAN2_PARAM, + LEVEL3_PARAM, + MUTE3_PARAM, + PAN3_PARAM, + LEVEL4_PARAM, + MUTE4_PARAM, + PAN4_PARAM, + LEVEL5_PARAM, + MUTE5_PARAM, + PAN5_PARAM, + LEVEL6_PARAM, + MUTE6_PARAM, + PAN6_PARAM, + LEVEL7_PARAM, + MUTE7_PARAM, + PAN7_PARAM, + LEVEL8_PARAM, + MUTE8_PARAM, + PAN8_PARAM, + MIX_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + CV1_INPUT, + PAN1_INPUT, + IN1_INPUT, + CV2_INPUT, + PAN2_INPUT, + IN2_INPUT, + CV3_INPUT, + PAN3_INPUT, + IN3_INPUT, + CV4_INPUT, + PAN4_INPUT, + IN4_INPUT, + CV5_INPUT, + PAN5_INPUT, + IN5_INPUT, + CV6_INPUT, + PAN6_INPUT, + IN6_INPUT, + CV7_INPUT, + PAN7_INPUT, + IN7_INPUT, + CV8_INPUT, + PAN8_INPUT, + IN8_INPUT, + MIX_CV_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + L_OUTPUT, + R_OUTPUT, + NUM_OUTPUTS + }; + + enum LightsIds { + NUM_LIGHTS + }; + + MixerChannel _channel1; + MixerChannel _channel2; + MixerChannel _channel3; + MixerChannel _channel4; + MixerChannel _channel5; + MixerChannel _channel6; + MixerChannel _channel7; + MixerChannel _channel8; + Amplifier _amplifier; + SlewLimiter _slewLimiter; + RootMeanSquare _rms; + float _rmsLevel = 0.0f; + + Mix8() + : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) + , _channel1(params[LEVEL1_PARAM], params[PAN1_PARAM], params[MUTE1_PARAM], inputs[IN1_INPUT], inputs[CV1_INPUT], inputs[PAN1_INPUT]) + , _channel2(params[LEVEL2_PARAM], params[PAN2_PARAM], params[MUTE2_PARAM], inputs[IN2_INPUT], inputs[CV2_INPUT], inputs[PAN2_INPUT]) + , _channel3(params[LEVEL3_PARAM], params[PAN3_PARAM], params[MUTE3_PARAM], inputs[IN3_INPUT], inputs[CV3_INPUT], inputs[PAN3_INPUT]) + , _channel4(params[LEVEL4_PARAM], params[PAN4_PARAM], params[MUTE4_PARAM], inputs[IN4_INPUT], inputs[CV4_INPUT], inputs[PAN4_INPUT]) + , _channel5(params[LEVEL5_PARAM], params[PAN5_PARAM], params[MUTE5_PARAM], inputs[IN5_INPUT], inputs[CV4_INPUT], inputs[PAN5_INPUT]) + , _channel6(params[LEVEL6_PARAM], params[PAN6_PARAM], params[MUTE6_PARAM], inputs[IN6_INPUT], inputs[CV4_INPUT], inputs[PAN6_INPUT]) + , _channel7(params[LEVEL7_PARAM], params[PAN7_PARAM], params[MUTE7_PARAM], inputs[IN7_INPUT], inputs[CV4_INPUT], inputs[PAN7_INPUT]) + , _channel8(params[LEVEL8_PARAM], params[PAN8_PARAM], params[MUTE8_PARAM], inputs[IN8_INPUT], inputs[CV4_INPUT], inputs[PAN8_INPUT]) + { + onSampleRateChange(); + _rms.setSensitivity(0.05f); + } + + virtual void onSampleRateChange() override; + virtual void step() override; +}; + +} // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -18,6 +18,7 @@ #include "RM.hpp" #include "VCM.hpp" #include "Mix4.hpp" +#include "Mix8.hpp" #include "ADSR.hpp" #include "Bool.hpp" @@ -76,6 +77,7 @@ void init(rack::Plugin *p) { p->addModel(modelRM); p->addModel(modelVCM); p->addModel(modelMix4); + p->addModel(modelMix8); #endif #ifdef EXPERIMENTAL diff --git a/src/mixer.hpp b/src/mixer.hpp @@ -53,4 +53,11 @@ struct MixerChannel { void next(bool stereo); // input from _in; outputs on out, left, right, rms. }; +struct MuteButton : ToggleButton { + MuteButton() { + addFrame(SVG::load(assetPlugin(plugin, "res/button_18px_0.svg"))); + addFrame(SVG::load(assetPlugin(plugin, "res/button_18px_1_orange.svg"))); + } +}; + } // namespace bogaudio