commit 07019a8aeda019d1aaa875cbf9cd003f009eaacf
parent 36627cceac18e412711ca138b9f4f54c6e074270
Author: Matt Demanett <matt@demanett.net>
Date: Thu, 17 May 2018 00:06:05 -0400
MIX4 module; VCAmp fixes.
Diffstat:
14 files changed, 690 insertions(+), 69 deletions(-)
diff --git a/res-src/Mix4-src.svg b/res-src/Mix4-src.svg
@@ -0,0 +1,230 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="225"
+ height="380"
+ viewBox="0 0 225 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 183px">
+ <rect width="6" height="177" x="6" y="3" rx="2" stroke-width="1" stroke="#888" fill="#222" />
+ <g transform="translate(0 85)">
+ <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 183px">
+ <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 20.67)">
+ <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)">6</text>
+ </g>
+ <g transform="translate(0 34.83)">
+ <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 49)">
+ <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 63.17)">
+ <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 91.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)" />
+ <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-7 2.2)">-24</text>
+ </g>
+ <g transform="translate(0 148.17)">
+ <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 170)">
+ <text font-size="6.0pt" transform="translate(7 0) 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 269,1 269,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" />
+ <polyline points="0.5,0.5 269.5,0.5 269.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" />
+ <polyline points="0,0 270,0 270,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" />
+
+ <!-- <rect width="85" height="20" fill="#0f0" transform="translate(0 0)" /> -->
+ <!-- <rect width="85" height="20" fill="#0f0" transform="translate(140 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(215 0)" /> -->
+
+ <text class="title" x="85" y="19" font-size="12pt" letter-spacing="4px">MIX4</text>
+ <g transform="translate(72.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 10)" />
+ <use id="LEVEL1_PARAM" xlink:href="#slider" transform="translate(13.5 10)" />
+ <use id="PAN1_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 201)" />
+ <use xlink:href="#knobguide-centertick" transform="translate(2.5 189)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(14 226)">PAN</text>
+ <use id="MUTE1_PARAM" xlink:href="#button" transform="translate(12.5 232)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(10 260)">MUTE</text>
+ <g transform="translate(5.5 267)">
+ <rect width="34" height="73" rx="5" fill="#fafafa" />
+ <use id="CV1_INPUT" xlink:href="#input" transform="translate(5 3)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(11 35)">CV</text>
+ <use id="IN1_INPUT" xlink:href="#input" transform="translate(5 38)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 70)">IN</text>
+ </g>
+ <!-- <rect width="8" height="40" fill="#f00" transform="translate(39.5 300)" /> -->
+ </g>
+
+ <g transform="translate(47 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 10)" />
+ <use id="LEVEL2_PARAM" xlink:href="#slider" transform="translate(13.5 10)" />
+ <use id="PAN2_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 201)" />
+ <use xlink:href="#knobguide-centertick" transform="translate(2.5 189)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(14 226)">PAN</text>
+ <use id="MUTE2_PARAM" xlink:href="#button" transform="translate(12.5 232)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(10 260)">MUTE</text>
+ <g transform="translate(5.5 267)">
+ <rect width="34" height="73" rx="5" fill="#fafafa" />
+ <use id="CV2_INPUT" xlink:href="#input" transform="translate(5 3)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(11 35)">CV</text>
+ <use id="IN2_INPUT" xlink:href="#input" transform="translate(5 38)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 70)">IN</text>
+ </g>
+ <!-- <rect width="8" height="40" fill="#f00" transform="translate(39.5 300)" /> -->
+ </g>
+
+ <g transform="translate(90 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 10)" />
+ <use id="LEVEL3_PARAM" xlink:href="#slider" transform="translate(13.5 10)" />
+ <use id="PAN3_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 201)" />
+ <use xlink:href="#knobguide-centertick" transform="translate(2.5 189)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(14 226)">PAN</text>
+ <use id="MUTE3_PARAM" xlink:href="#button" transform="translate(12.5 232)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(10 260)">MUTE</text>
+ <g transform="translate(5.5 267)">
+ <rect width="34" height="73" rx="5" fill="#fafafa" />
+ <use id="CV3_INPUT" xlink:href="#input" transform="translate(5 3)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(11 35)">CV</text>
+ <use id="IN3_INPUT" xlink:href="#input" transform="translate(5 38)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 70)">IN</text>
+ </g>
+ <!-- <rect width="8" height="40" fill="#f00" transform="translate(39.5 300)" /> -->
+ </g>
+
+ <g transform="translate(133 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 10)" />
+ <use id="LEVEL4_PARAM" xlink:href="#slider" transform="translate(13.5 10)" />
+ <use id="PAN4_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 201)" />
+ <use xlink:href="#knobguide-centertick" transform="translate(2.5 189)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(14 226)">PAN</text>
+ <use id="MUTE4_PARAM" xlink:href="#button" transform="translate(12.5 232)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(10 260)">MUTE</text>
+ <g transform="translate(5.5 267)">
+ <rect width="34" height="73" rx="5" fill="#fafafa" />
+ <use id="CV4_INPUT" xlink:href="#input" transform="translate(5 3)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(11 35)">CV</text>
+ <use id="IN4_INPUT" xlink:href="#input" transform="translate(5 38)" />
+ <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 70)">IN</text>
+ </g>
+ <!-- <rect width="8" height="40" fill="#f00" transform="translate(39.5 300)" /> -->
+ </g>
+
+ <g transform="translate(176 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 10)" />
+ <use id="MIX_PARAM" xlink:href="#slider" transform="translate(13.5 10)" />
+ <g transform="translate(5.5 230)">
+ <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(11 35)">CV</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>
+</svg>
diff --git a/res-src/VCAmp-src.svg b/res-src/VCAmp-src.svg
@@ -28,40 +28,48 @@
<g transform="translate(0 85)">
<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 183px">
<g transform="translate(0 6.5)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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 20.67)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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)">6</text>
</g>
- <g transform="translate(0 35.83)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <g transform="translate(0 34.83)">
+ <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 49)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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 63.17)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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 91.5)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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 148.17)">
- <polyline points="0,0 5,0" stroke="#333" fille="none" transform="translate(11 0)" />
+ <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 170)">
- <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-9 6)">dB</text>
+ <text font-size="6.0pt" transform="translate(7 0) rotate(-90) translate(-9 4)">dB</text>
</g>
</symbol>
@@ -108,7 +116,7 @@
<rect width="34" height="10" fill="#fafafa" transform="translate(0 63)" />
<rect width="34" height="70" rx="5" fill="#fafafa" />
<use id="CV_INPUT" xlink:href="#input" transform="translate(5 3)" />
- <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 35)">CV</text>
+ <text font-size="5pt" letter-spacing="2px" transform="translate(11 35)">CV</text>
<use id="IN_INPUT" xlink:href="#input" transform="translate(5 38)" />
<text font-size="5pt" letter-spacing="2px" transform="translate(12.5 70)">IN</text>
</g>
diff --git a/res-src/VU-src.svg b/res-src/VU-src.svg
@@ -53,32 +53,32 @@
<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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)" /> -->
+ <!-- <polyline points="0,0 5,0" stroke="#333" fill="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)" />
+ <polyline points="0,0 3,0" stroke="#333" fill="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)">
diff --git a/res/Mix4.svg b/res/Mix4.svg
Binary files differ.
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/Mix4.cpp b/src/Mix4.cpp
@@ -0,0 +1,188 @@
+
+#include "Mix4.hpp"
+
+void Mix4::onSampleRateChange() {
+ float sr = engineGetSampleRate();
+ _channel1.setSampleRate(sr);
+ _channel2.setSampleRate(sr);
+ _channel3.setSampleRate(sr);
+ _channel4.setSampleRate(sr);
+ _slewLimiter.setParams(sr, slewTimeMS);
+ _rms.setSampleRate(sr);
+}
+
+void Mix4::step() {
+ bool stereo = outputs[L_OUTPUT].active && outputs[R_OUTPUT].active;
+ _channel1.next(stereo);
+ _channel2.next(stereo);
+ _channel3.next(stereo);
+ _channel4.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 *= maxDecibels - minDecibels;
+ level += minDecibels;
+ _amplifier.setLevel(_slewLimiter.next(level));
+
+ float mono = 0.0f;
+ mono += _channel1.out;
+ mono += _channel2.out;
+ mono += _channel3.out;
+ mono += _channel4.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 = _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 = _amplifier.next(right);
+ outputs[R_OUTPUT].value = right;
+ }
+ else {
+ outputs[L_OUTPUT].value = outputs[R_OUTPUT].value = mono;
+ }
+}
+
+struct Mix4Widget : ModuleWidget {
+ Mix4Widget(Mix4* module) : ModuleWidget(module) {
+ box.size = Vec(RACK_GRID_WIDTH * 15, RACK_GRID_HEIGHT);
+
+ {
+ SVGPanel *panel = new SVGPanel();
+ panel->box.size = box.size;
+ panel->setBackground(SVG::load(assetPlugin(plugin, "res/Mix4.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.5);
+ auto pan1ParamPosition = Vec(18.5, 221.0);
+ auto mute1ParamPosition = Vec(17.2, 252.7);
+ auto level2ParamPosition = Vec(60.5, 32.5);
+ auto pan2ParamPosition = Vec(61.5, 221.0);
+ auto mute2ParamPosition = Vec(60.2, 252.7);
+ auto level3ParamPosition = Vec(103.5, 32.5);
+ auto pan3ParamPosition = Vec(104.5, 221.0);
+ auto mute3ParamPosition = Vec(103.2, 252.7);
+ auto level4ParamPosition = Vec(146.5, 32.5);
+ auto pan4ParamPosition = Vec(147.5, 221.0);
+ auto mute4ParamPosition = Vec(146.2, 252.7);
+ auto mixParamPosition = Vec(189.5, 32.5);
+
+ auto cv1InputPosition = Vec(14.5, 290.0);
+ auto in1InputPosition = Vec(14.5, 325.0);
+ auto cv2InputPosition = Vec(57.5, 290.0);
+ auto in2InputPosition = Vec(57.5, 325.0);
+ auto cv3InputPosition = Vec(100.5, 290.0);
+ auto in3InputPosition = Vec(100.5, 325.0);
+ auto cv4InputPosition = Vec(143.5, 290.0);
+ auto in4InputPosition = Vec(143.5, 325.0);
+ auto mixCvInputPosition = Vec(186.5, 253.0);
+
+ auto lOutputPosition = Vec(186.5, 291.0);
+ auto rOutputPosition = Vec(186.5, 326.0);
+ // end generated by svg_widgets.rb
+
+ {
+ auto slider = ParamWidget::create<VUSlider>(
+ level1ParamPosition,
+ module,
+ Mix4::LEVEL1_PARAM,
+ 0.0,
+ 1.0,
+ abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel1.rms));
+ addParam(slider);
+ }
+ addParam(ParamWidget::create<Knob16>(pan1ParamPosition, module, Mix4::PAN1_PARAM, -1.0, 1.0, 0.0));
+ addParam(ParamWidget::create<StatefulButton18>(mute1ParamPosition, module, Mix4::MUTE1_PARAM, 0.0, 1.0, 0.0));
+ {
+ auto slider = ParamWidget::create<VUSlider>(
+ level2ParamPosition,
+ module,
+ Mix4::LEVEL2_PARAM,
+ 0.0,
+ 1.0,
+ abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel2.rms));
+ addParam(slider);
+ }
+ addParam(ParamWidget::create<Knob16>(pan2ParamPosition, module, Mix4::PAN2_PARAM, -1.0, 1.0, 0.0));
+ addParam(ParamWidget::create<StatefulButton18>(mute2ParamPosition, module, Mix4::MUTE2_PARAM, 0.0, 1.0, 0.0));
+ {
+ auto slider = ParamWidget::create<VUSlider>(
+ level3ParamPosition,
+ module,
+ Mix4::LEVEL3_PARAM,
+ 0.0,
+ 1.0,
+ abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel3.rms));
+ addParam(slider);
+ }
+ addParam(ParamWidget::create<Knob16>(pan3ParamPosition, module, Mix4::PAN3_PARAM, -1.0, 1.0, 0.0));
+ addParam(ParamWidget::create<StatefulButton18>(mute3ParamPosition, module, Mix4::MUTE3_PARAM, 0.0, 1.0, 0.0));
+ {
+ auto slider = ParamWidget::create<VUSlider>(
+ level4ParamPosition,
+ module,
+ Mix4::LEVEL4_PARAM,
+ 0.0,
+ 1.0,
+ abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_channel4.rms));
+ addParam(slider);
+ }
+ addParam(ParamWidget::create<Knob16>(pan4ParamPosition, module, Mix4::PAN4_PARAM, -1.0, 1.0, 0.0));
+ addParam(ParamWidget::create<StatefulButton18>(mute4ParamPosition, module, Mix4::MUTE4_PARAM, 0.0, 1.0, 0.0));
+ {
+ auto slider = ParamWidget::create<VUSlider>(
+ mixParamPosition,
+ module,
+ Mix4::MIX_PARAM,
+ 0.0,
+ 1.0,
+ abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_rmsLevel));
+ addParam(slider);
+ }
+
+ addInput(Port::create<Port24>(cv1InputPosition, Port::INPUT, module, Mix4::CV1_INPUT));
+ addInput(Port::create<Port24>(in1InputPosition, Port::INPUT, module, Mix4::IN1_INPUT));
+ addInput(Port::create<Port24>(cv2InputPosition, Port::INPUT, module, Mix4::CV2_INPUT));
+ addInput(Port::create<Port24>(in2InputPosition, Port::INPUT, module, Mix4::IN2_INPUT));
+ addInput(Port::create<Port24>(cv3InputPosition, Port::INPUT, module, Mix4::CV3_INPUT));
+ addInput(Port::create<Port24>(in3InputPosition, Port::INPUT, module, Mix4::IN3_INPUT));
+ addInput(Port::create<Port24>(cv4InputPosition, Port::INPUT, module, Mix4::CV4_INPUT));
+ addInput(Port::create<Port24>(in4InputPosition, Port::INPUT, module, Mix4::IN4_INPUT));
+ addInput(Port::create<Port24>(mixCvInputPosition, Port::INPUT, module, Mix4::MIX_CV_INPUT));
+
+ addOutput(Port::create<Port24>(lOutputPosition, Port::OUTPUT, module, Mix4::L_OUTPUT));
+ addOutput(Port::create<Port24>(rOutputPosition, Port::OUTPUT, module, Mix4::R_OUTPUT));
+ }
+};
+
+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
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "mixer.hpp"
+
+extern Model* modelMix4;
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
+
+namespace bogaudio {
+
+struct Mix4 : Module {
+ enum ParamsIds {
+ LEVEL1_PARAM,
+ PAN1_PARAM,
+ MUTE1_PARAM,
+ LEVEL2_PARAM,
+ PAN2_PARAM,
+ MUTE2_PARAM,
+ LEVEL3_PARAM,
+ PAN3_PARAM,
+ MUTE3_PARAM,
+ LEVEL4_PARAM,
+ PAN4_PARAM,
+ MUTE4_PARAM,
+ MIX_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ CV1_INPUT,
+ IN1_INPUT,
+ CV2_INPUT,
+ IN2_INPUT,
+ CV3_INPUT,
+ IN3_INPUT,
+ CV4_INPUT,
+ IN4_INPUT,
+ MIX_CV_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ L_OUTPUT,
+ R_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ enum LightsIds {
+ NUM_LIGHTS
+ };
+
+ const float maxDecibels = 12.0f;
+ const float minDecibels = Amplifier::minDecibels;
+ const float slewTimeMS = 1.0f;
+
+ MixerChannel _channel1;
+ MixerChannel _channel2;
+ MixerChannel _channel3;
+ MixerChannel _channel4;
+ Amplifier _amplifier;
+ SlewLimiter _slewLimiter;
+ RootMeanSquare _rms;
+ float _rmsLevel = 0.0f;
+
+ Mix4()
+ : 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])
+ , _channel2(params[LEVEL2_PARAM], params[PAN2_PARAM], params[MUTE2_PARAM], inputs[IN2_INPUT], inputs[CV2_INPUT])
+ , _channel3(params[LEVEL3_PARAM], params[PAN3_PARAM], params[MUTE3_PARAM], inputs[IN3_INPUT], inputs[CV3_INPUT])
+ , _channel4(params[LEVEL4_PARAM], params[PAN4_PARAM], params[MUTE4_PARAM], inputs[IN4_INPUT], inputs[CV4_INPUT])
+ {
+ onSampleRateChange();
+ _rms.setSensitivity(0.05f);
+ }
+
+ virtual void onSampleRateChange() override;
+ virtual void step() override;
+};
+
+} // namespace bogaudio
diff --git a/src/VCAmp.cpp b/src/VCAmp.cpp
@@ -19,56 +19,6 @@ void VCAmp::step() {
}
}
-struct VUSlider : Knob {
- const float slideHeight = 13.0f;
-
- VUSlider() {
- box.size = Vec(18.0f, 183.0f);
- }
-
- virtual void draw(NVGcontext* vg) override {
- nvgSave(vg);
- {
- nvgBeginPath(vg);
- nvgRoundedRect(vg, 6, 3, 6, 177, 2);
- nvgFillColor(vg, nvgRGBA(0x22, 0x22, 0x22, 0xff));
- nvgFill(vg);
- nvgStrokeColor(vg, nvgRGBA(0x88, 0x88, 0x88, 0xff));
- nvgStroke(vg);
- }
- nvgRestore(vg);
-
- nvgSave(vg);
- {
- nvgTranslate(vg, 0, 170.0f * (1.0f - value));
- nvgBeginPath(vg);
- nvgRoundedRect(vg, 0, 0, 18, 13, 1.5);
- nvgFillColor(vg, nvgRGBA(0x77, 0x77, 0x77, 0xff));
- nvgFill(vg);
-
- nvgBeginPath(vg);
- nvgRect(vg, 0, 2, 18, 9);
- nvgFillColor(vg, nvgRGBA(0x44, 0x44, 0x44, 0xff));
- nvgFill(vg);
-
- nvgBeginPath(vg);
- nvgRoundedRect(vg, 2, 4, 14, 5, 1.0);
- nvgFillColor(vg, nvgRGBA(0xaa, 0xaa, 0xaa, 0xff));
- nvgFill(vg);
-
- float db = dynamic_cast<VCAmp*>(module)->_rmsLevel;
- if (db > 0.0f) {
- db = amplitudeToDecibels(db);
- nvgBeginPath(vg);
- nvgRoundedRect(vg, 2, 4, 14, 5, 1.0);
- nvgFillColor(vg, decibelsToColor(db));
- nvgFill(vg);
- }
- }
- nvgRestore(vg);
- }
-};
-
struct VCAmpWidget : ModuleWidget {
VCAmpWidget(VCAmp* module) : ModuleWidget(module) {
box.size = Vec(RACK_GRID_WIDTH * 3, RACK_GRID_HEIGHT);
@@ -92,14 +42,16 @@ struct VCAmpWidget : ModuleWidget {
auto outOutputPosition = Vec(10.5, 286.0);
// end generated by svg_widgets.rb
- addParam(ParamWidget::create<VUSlider>(
+ auto slider = ParamWidget::create<VUSlider>(
levelParamPosition,
module,
VCAmp::LEVEL_PARAM,
0.0,
1.0,
abs(module->minDecibels) / (module->maxDecibels - module->minDecibels)
- ));
+ );
+ dynamic_cast<VUSlider*>(slider)->setVULevel(&(module->_rmsLevel));
+ addParam(slider);
addInput(Port::create<Port24>(cvInputPosition, Port::INPUT, module, VCAmp::CV_INPUT));
addInput(Port::create<Port24>(inInputPosition, Port::INPUT, module, VCAmp::IN_INPUT));
diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp
@@ -17,6 +17,7 @@
#include "RM.hpp"
#include "VCM.hpp"
+#include "Mix4.hpp"
#include "ADSR.hpp"
#include "Bool.hpp"
@@ -73,6 +74,7 @@ void init(rack::Plugin *p) {
#ifdef EXPERIMENTAL
p->addModel(modelRM);
p->addModel(modelVCM);
+ p->addModel(modelMix4);
#endif
#ifdef EXPERIMENTAL
diff --git a/src/mixer.cpp b/src/mixer.cpp
@@ -0,0 +1,34 @@
+
+#include "mixer.hpp"
+
+void MixerChannel::setSampleRate(float sampleRate) {
+ _slewLimiter.setParams(sampleRate, slewTimeMS);
+ _rms.setSampleRate(sampleRate);
+}
+
+void MixerChannel::next(bool stereo) {
+ if (!_inInput.active) {
+ rms = out = left = right = 0.0f;
+ return;
+ }
+
+ if (_muteParam.value > 0.5f) {
+ _amplifier.setLevel(_slewLimiter.next(minDecibels));
+ }
+ else {
+ float level = clamp(_levelParam.value, 0.0f, 1.0f);
+ if (_cvInput.active) {
+ level *= clamp(_cvInput.value / 10.0f, 0.0f, 1.0f);
+ }
+ level *= maxDecibels - minDecibels;
+ level += minDecibels;
+ _amplifier.setLevel(_slewLimiter.next(level));
+ }
+
+ out = _amplifier.next(_inInput.value);
+ rms = _rms.next(out) / 5.0f;
+ if (stereo) {
+ _panner.setPan(clamp(_panParam.value, -1.0f, 1.0f));
+ _panner.next(out, left, right);
+ }
+}
diff --git a/src/mixer.hpp b/src/mixer.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
+
+namespace bogaudio {
+
+struct MixerChannel {
+ const float maxDecibels = 12.0f;
+ const float minDecibels = Amplifier::minDecibels;
+ const float slewTimeMS = 1.0f;
+
+ Amplifier _amplifier;
+ Panner _panner;
+ SlewLimiter _slewLimiter;
+ RootMeanSquare _rms;
+
+ Param& _levelParam;
+ Param& _panParam;
+ Param& _muteParam;
+ Input& _inInput;
+ Input& _cvInput;
+
+ float out = 0.0f;
+ float left = 0.0f;
+ float right = 0.0f;
+ float rms = 0.0f;
+
+ MixerChannel(
+ Param& level,
+ Param& pan,
+ Param& mute,
+ Input& in,
+ Input& cv,
+ float sampleRate = 1000.0f
+ )
+ : _levelParam(level)
+ , _panParam(pan)
+ , _muteParam(mute)
+ , _inInput(in)
+ , _cvInput(cv)
+ {
+ setSampleRate(sampleRate);
+ _rms.setSensitivity(0.05f);
+ }
+
+ void setSampleRate(float sampleRate);
+ void next(bool stereo); // input from _in; outputs on out, left, right, rms.
+};
+
+} // namespace bogaudio
diff --git a/src/widgets.cpp b/src/widgets.cpp
@@ -1,7 +1,9 @@
#include "widgets.hpp"
+#include "dsp/signal.hpp"
using namespace bogaudio;
+using namespace bogaudio::dsp;
Button18::Button18() {
addFrame(SVG::load(assetPlugin(plugin, "res/button_18px_0.svg")));
@@ -109,6 +111,10 @@ StatefulButton9::StatefulButton9() : StatefulButton("res/button_9px_0.svg", "res
}
+StatefulButton18::StatefulButton18() : StatefulButton("res/button_18px_0.svg", "res/button_18px_1.svg") {
+}
+
+
NVGcolor bogaudio::decibelsToColor(float db) {
if (db < -80.0f) {
return nvgRGBA(0x00, 0x00, 0x00, 0x00);
@@ -121,3 +127,51 @@ NVGcolor bogaudio::decibelsToColor(float db) {
}
return nvgRGBA(0xff, (1.0f - db / 18.0f) * 0xff, 0x00, 0xff);
}
+
+
+void VUSlider::draw(NVGcontext* vg) {
+ nvgSave(vg);
+ {
+ nvgBeginPath(vg);
+ nvgRoundedRect(vg, 6, 3, 6, 177, 2);
+ nvgFillColor(vg, nvgRGBA(0x22, 0x22, 0x22, 0xff));
+ nvgFill(vg);
+ nvgStrokeColor(vg, nvgRGBA(0x88, 0x88, 0x88, 0xff));
+ nvgStroke(vg);
+ }
+ nvgRestore(vg);
+
+ nvgSave(vg);
+ {
+ nvgTranslate(vg, 0, 170.0f * (1.0f - value));
+ nvgBeginPath(vg);
+ nvgRoundedRect(vg, 0, 0, 18, 13, 1.5);
+ nvgFillColor(vg, nvgRGBA(0x77, 0x77, 0x77, 0xff));
+ nvgFill(vg);
+
+ nvgBeginPath(vg);
+ nvgRect(vg, 0, 2, 18, 9);
+ nvgFillColor(vg, nvgRGBA(0x44, 0x44, 0x44, 0xff));
+ nvgFill(vg);
+
+ nvgBeginPath(vg);
+ nvgRect(vg, 0, 6, 18, 1);
+ nvgFillColor(vg, nvgRGBA(0xfa, 0xfa, 0xfa, 0xff));
+ nvgFill(vg);
+
+ nvgBeginPath(vg);
+ nvgRoundedRect(vg, 2, 4, 14, 5, 1.0);
+ nvgFillColor(vg, nvgRGBA(0xaa, 0xaa, 0xaa, 0xff));
+ nvgFill(vg);
+
+ float db = _vuLevel ? *_vuLevel : 0.0f;
+ if (db > 0.0f) {
+ db = amplitudeToDecibels(db);
+ nvgBeginPath(vg);
+ nvgRoundedRect(vg, 2, 4, 14, 5, 1.0);
+ nvgFillColor(vg, decibelsToColor(db));
+ nvgFill(vg);
+ }
+ }
+ nvgRestore(vg);
+}
diff --git a/src/widgets.hpp b/src/widgets.hpp
@@ -62,6 +62,24 @@ struct StatefulButton9 : StatefulButton {
StatefulButton9();
};
+struct StatefulButton18 : StatefulButton {
+ StatefulButton18();
+};
+
NVGcolor decibelsToColor(float db);
+struct VUSlider : Knob {
+ const float slideHeight = 13.0f;
+ float* _vuLevel = NULL;
+
+ VUSlider() {
+ box.size = Vec(18.0f, 183.0f);
+ }
+
+ void setVULevel(float* vuLevel) {
+ _vuLevel = vuLevel;
+ }
+ virtual void draw(NVGcontext* vg) override;
+};
+
} // namespace bogaudio