commit fbeb62710aadcc8dd6bb443d9edd51bbbf4db5a9
parent ecff5b2c3514024bb31aa4b2e6cfb29dbf264e2b
Author: Matt Demanett <matt@demanett.net>
Date: Sun, 13 Sep 2020 23:56:06 -0400
VELO: triple-CV VCA; one of the CVs is handy for implementing MIDI velocity.
Diffstat:
14 files changed, 1144 insertions(+), 4 deletions(-)
diff --git a/README-prerelease.md b/README-prerelease.md
@@ -663,6 +663,26 @@ _Polyphony:_ <a href="#polyphony">Polyphonic</a>, with polyphony defined by the

+#### <a name="velo"></a> VELO
+
+A voltage-controlled amplifier with three CV inputs of three different types: a regular one, a bipolar one (good for tremolo), and one that is inverted and scaled (designed for implementing MIDI velocity, and the reason for the module's name).
+
+The LEVEL knob and CV words as on <a href="#VCA">VCA</a>; the knob sets the base VCA level if the LEVEL input is not patched; if it is patched, it expects a unipolar (0-10V) signal, which sets the LEVEL up to the position of the knob (which is to say that the knob attenuates the CV). The LEVEL input is the place to patch in an envelope.
+
+The CV input takes a bipolar (+/-5V) signal, subject to attenuversion by the smaller knob below the LEVEL knob. The resulting value is scaled by whatever value was set by LEVEL (knob and CV) and then added to the LEVEL value (this coupling of CV to LEVEL is enabled is by default, but see below). The CV input is a good place to patch in an LFO, to achieve tremolo.
+
+The VELO input, if in use, takes a unipolar (0-10V) signal, scales it according to the "V. R." (Velocity Range) knob, inverts it, and adds it to the value produced by the previous two knobs and CVs. Thus, if the VELO input is 0V, whatever level the VCA would open to according to the values of the previous inputs is reduced by the number of decibels set by the V. R. knob. When VELO is a full 10V, there is no reduction. If V. R. is fully clockwise, a 0V VELO input will fully close the VCA. The VELO input is designed to be patched to the VELO output of Rack's MIDI-CV module.
+
+The suggested patch inputs are meant as examples; of course any inputs can be used.
+
+The LIN toggle, if on, sets the VCA's to a linear-in-amplitude response; when off, the VCA's response to the controls and CVs is linear-in-decibles.
+
+The bipolar CV is optionally coupled to the LEVEL knob/input, but this coupling can be broken by disabling option "Level knob/CV scales bipolar CV" on the context menu. When the option is enabled, the value of the bipolar CV is scaled by the value of LEVEL (knob and CV) before being added to LEVEL. Otherwise, it is simply added to level. In a patch with an envelope to LEVEL and an LFO to CV, having this option on means the LFO's effect will be proportional to the envelope, which is to say the LFO won't open the VCA when the envelope is off.
+
+Using the bipolar CV, it's possible to drive the VCA past unity gain, up to +12db (4x amplitude). The module soft-clips at +/-12V, and driving the signal into the clipper will result in distortion.
+
+_Polyphony:_ <a href="#polyphony">Polyphonic</a>, with polyphony defined by the IN input.
+
#### <a name="amrm"></a> AM/RM
AM/RM is a ring- and amplitude-modulation effect and CV-controllable variable wave rectifier.
diff --git a/plugin.json b/plugin.json
@@ -544,6 +544,16 @@
]
},
{
+ "slug": "Bogaudio-Velo",
+ "name": "VELO",
+ "description": "Triple-CV VCA, for tremolo, MIDI velocity, etc",
+ "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#velo",
+ "tags": [
+ "Velo",
+ "Polyphonic"
+ ]
+ },
+ {
"slug": "Bogaudio-UMix",
"name": "UMIX",
"description": "8-input unity mixer",
diff --git a/res-pp/Velo-dark-pp.svg b/res-pp/Velo-dark-pp.svg
@@ -0,0 +1,304 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="45.0" height="380.0" viewBox="0 0 45.0 380.0">
+ <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;
+}
+
+polyline {
+ stroke: #333;
+}
+polyline.guide {
+ stroke: #0f0;
+}
+path {
+ stroke: #333;
+}
+
+rect.module-background, .background-fill {
+ fill: #ddd;
+}
+polyline.module-border-inner {
+ stroke: #e4e4e4;
+}
+polyline.module-border-middle {
+ stroke: #ebebeb;
+}
+polyline.module-border-outer {
+ stroke: #f2f2f2;
+}
+
+g.io-group {
+}
+rect.input-background, rect.input-background-filler {
+ fill: #fafafa;
+}
+rect.output-background, rect.output-background-filler {
+ fill: #bbb;
+}
+text.input-label, text.output-label {
+ /* font-size: 6pt; */
+}
+polyline.input-label, polyline.output-label {
+}
+path.input-label, path.output-label {
+}
+
+circle.port-rim {
+ stroke: #f0f0f0;
+}
+circle.port-barrel {
+ stroke: #222;
+ fill: #222;
+}
+circle.knob-center {
+ fill: #eee;
+}
+circle.knob-rim {
+ fill: #333;
+}
+circle.knob-tick {
+ fill: #fff;
+}
+polyline.knob-tick {
+ stroke: #fff;
+}
+
+
+text {
+ fill: #eee;
+}
+
+polyline {
+ stroke: #ccc;
+}
+path {
+ stroke: #ccc;
+}
+
+rect.module-background, .background-fill {
+ fill: #111;
+}
+polyline.module-border-inner {
+ stroke: #191919;
+}
+polyline.module-border-middle {
+ stroke: #111;
+}
+polyline.module-border-outer {
+ stroke: #000;
+}
+
+rect.input-background, rect.input-background-filler {
+ fill: #aaa;
+}
+rect.output-background, rect.output-background-filler {
+ fill: #666;
+}
+text.input-label {
+ fill: #222;
+}
+polyline.input-label, path.input-label {
+ stroke: #222;
+}
+text.output-label {
+ fill: #ddd;
+}
+polyline.output-label, path.output-label {
+ stroke: #ddd;
+}
+
+circle.port-rim {
+ stroke: #c0c0c0;
+}
+circle.port-barrel {
+ stroke: #222;
+ fill: #222;
+}
+circle.knob-center {
+ fill: #888;
+}
+circle.knob-rim {
+ fill: #444;
+}
+circle.knob-tick {
+ fill: #fff;
+}
+polyline.knob-tick {
+ stroke: #fff;
+}
+</style>
+
+ <defs>
+ <symbol id="dial-response-velo" viewBox="0 0 40px 40px">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </symbol>
+ </defs>
+
+
+
+ <rect class="module-background background-fill" width="45.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 44.0,1 44.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke-width="0.8" fill="none"/>
+ <polyline class="module-border-outer" points="0,0 45.0,0 45.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <g transform="rotate(-90) translate(-376.0 13)">
+ <text class="title" font-size="7pt" letter-spacing="2.5px">VELO</text>
+ <g transform="translate(0 12)">
+ <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text>
+ <rect class="background-fill" width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)"/>
+ </g>
+ </g>
+
+
+ <g transform="translate(0 25)">
+ <text font-size="6pt" letter-spacing="2px" text-anchor="middle" transform="translate(22.5 0)">LEVEL</text>
+ <g transform="translate(9.5 9.5)"><svg id="LEVEL_PARAM">
+ <g transform="translate(13 13)">
+ <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f"/>
+ <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f"/>
+ <circle cx="0" cy="0" r="12.5" stroke-width="1" stroke="#00f" fill="none"/>
+ </g>
+ </svg></g>
+ <g transform="translate(0 0)">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="5.0pt" transform="rotate(-240) translate(18 0) rotate(240) translate(-2 2)">0</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-210) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-180) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-150) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-120) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-90) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-60) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-30) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(0) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(30) translate(15 0)"/>
+ <polyline points="0,0 3.5,0" stroke-width="1" transform="rotate(60) translate(15 0)"/>
+ </g>
+ </g>
+ <g transform="translate(14.5 50)"><svg id="LEVEL_ATTENUATOR_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 38)">
+ <g transform="translate(20 20)">
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(-90) translate(10 0)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#ccc" fill="none" transform="rotate(20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#ccc" fill="none" transform="rotate(43)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#ccc" fill="none" transform="rotate(-20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#ccc" fill="none" transform="rotate(-43)"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(0 104)">
+ <text font-size="6pt" letter-spacing="1px" text-anchor="middle" transform="translate(22.5 0)">V. R.</text>
+ <g transform="translate(14.5 11)"><svg id="VELOCITY_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 -1)">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(10.5 144)">
+ <text font-size="5pt" letter-spacing="1px" transform="translate(0 6)">LIN</text>
+ <g transform="translate(15 -1)"><svg id="LINEAR_PARAM">
+ <g transform="translate(4.5 4.5)">
+ <circle r="4" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g transform="translate(0 157)">
+ <g class="io-group" transform="translate(5.5 0)">
+ <rect class="input-background" width="34" height="140" rx="5"/>
+ <rect class="input-background-filler" width="34" height="10" transform="translate(0 133)"/>
+ <g transform="translate(5 3)"><svg id="LEVEL_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 35)">LEVEL</text>
+ <g transform="translate(5 38)"><svg id="CV_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 70)">CV</text>
+ <g transform="translate(5 73)"><svg id="VELOCITY_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 105)">VELO</text>
+ <g transform="translate(5 108)"><svg id="IN_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 140)">IN</text>
+ </g>
+ <g class="io-group" transform="translate(5.5 146)">
+ <rect class="output-background-filler" width="34" height="10" transform="translate(0 -3)"/>
+ <rect class="output-background" width="34" height="35" rx="5"/>
+ <g transform="translate(5 0)"><svg id="OUT_OUTPUT">
+ <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>
+ </svg></g>
+ <text class="output-label" font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text>
+ </g>
+ </g>
+
+
+
+</svg>
diff --git a/res-pp/Velo-lowcontrast-pp.svg b/res-pp/Velo-lowcontrast-pp.svg
@@ -0,0 +1,304 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="45.0" height="380.0" viewBox="0 0 45.0 380.0">
+ <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;
+}
+
+polyline {
+ stroke: #333;
+}
+polyline.guide {
+ stroke: #0f0;
+}
+path {
+ stroke: #333;
+}
+
+rect.module-background, .background-fill {
+ fill: #ddd;
+}
+polyline.module-border-inner {
+ stroke: #e4e4e4;
+}
+polyline.module-border-middle {
+ stroke: #ebebeb;
+}
+polyline.module-border-outer {
+ stroke: #f2f2f2;
+}
+
+g.io-group {
+}
+rect.input-background, rect.input-background-filler {
+ fill: #fafafa;
+}
+rect.output-background, rect.output-background-filler {
+ fill: #bbb;
+}
+text.input-label, text.output-label {
+ /* font-size: 6pt; */
+}
+polyline.input-label, polyline.output-label {
+}
+path.input-label, path.output-label {
+}
+
+circle.port-rim {
+ stroke: #f0f0f0;
+}
+circle.port-barrel {
+ stroke: #222;
+ fill: #222;
+}
+circle.knob-center {
+ fill: #eee;
+}
+circle.knob-rim {
+ fill: #333;
+}
+circle.knob-tick {
+ fill: #fff;
+}
+polyline.knob-tick {
+ stroke: #fff;
+}
+
+
+text {
+ fill: #b3b3b3;
+}
+
+polyline {
+ stroke: #b3b3b3;
+}
+path {
+ stroke: #b3b3b3;
+}
+
+rect.module-background, .background-fill {
+ fill: #333;
+}
+polyline.module-border-inner {
+ stroke: #191919;
+}
+polyline.module-border-middle {
+ stroke: #111;
+}
+polyline.module-border-outer {
+ stroke: #000;
+}
+
+rect.input-background, rect.input-background-filler {
+ fill: #b3b3b3;
+}
+rect.output-background, rect.output-background-filler {
+ fill: #888;
+}
+text.input-label {
+ fill: #666;
+}
+polyline.input-label, path.input-label {
+ stroke: #666;
+}
+text.output-label {
+ fill: #ccc;
+}
+polyline.output-label, path.output-label {
+ stroke: #ccc;
+}
+
+circle.port-rim {
+ stroke: #bbb;
+}
+circle.port-barrel {
+ stroke: #222;
+ fill: #222;
+}
+circle.knob-center {
+ fill: #bbb;
+}
+circle.knob-rim {
+ fill: #555;
+}
+circle.knob-tick {
+ fill: #fff;
+}
+polyline.knob-tick {
+ stroke: #fff;
+}
+</style>
+
+ <defs>
+ <symbol id="dial-response-velo" viewBox="0 0 40px 40px">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </symbol>
+ </defs>
+
+
+
+ <rect class="module-background background-fill" width="45.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 44.0,1 44.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke-width="0.8" fill="none"/>
+ <polyline class="module-border-outer" points="0,0 45.0,0 45.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <g transform="rotate(-90) translate(-376.0 13)">
+ <text class="title" font-size="7pt" letter-spacing="2.5px">VELO</text>
+ <g transform="translate(0 12)">
+ <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text>
+ <rect class="background-fill" width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)"/>
+ </g>
+ </g>
+
+
+ <g transform="translate(0 25)">
+ <text font-size="6pt" letter-spacing="2px" text-anchor="middle" transform="translate(22.5 0)">LEVEL</text>
+ <g transform="translate(9.5 9.5)"><svg id="LEVEL_PARAM">
+ <g transform="translate(13 13)">
+ <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f"/>
+ <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f"/>
+ <circle cx="0" cy="0" r="12.5" stroke-width="1" stroke="#00f" fill="none"/>
+ </g>
+ </svg></g>
+ <g transform="translate(0 0)">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="5.0pt" transform="rotate(-240) translate(18 0) rotate(240) translate(-2 2)">0</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-210) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-180) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-150) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-120) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-90) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-60) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-30) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(0) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(30) translate(15 0)"/>
+ <polyline points="0,0 3.5,0" stroke-width="1" transform="rotate(60) translate(15 0)"/>
+ </g>
+ </g>
+ <g transform="translate(14.5 50)"><svg id="LEVEL_ATTENUATOR_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 38)">
+ <g transform="translate(20 20)">
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(-90) translate(10 0)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#b3b3b3" fill="none" transform="rotate(20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#b3b3b3" fill="none" transform="rotate(43)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#b3b3b3" fill="none" transform="rotate(-20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#b3b3b3" fill="none" transform="rotate(-43)"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(0 104)">
+ <text font-size="6pt" letter-spacing="1px" text-anchor="middle" transform="translate(22.5 0)">V. R.</text>
+ <g transform="translate(14.5 11)"><svg id="VELOCITY_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 -1)">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(10.5 144)">
+ <text font-size="5pt" letter-spacing="1px" transform="translate(0 6)">LIN</text>
+ <g transform="translate(15 -1)"><svg id="LINEAR_PARAM">
+ <g transform="translate(4.5 4.5)">
+ <circle r="4" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g transform="translate(0 157)">
+ <g class="io-group" transform="translate(5.5 0)">
+ <rect class="input-background" width="34" height="140" rx="5"/>
+ <rect class="input-background-filler" width="34" height="10" transform="translate(0 133)"/>
+ <g transform="translate(5 3)"><svg id="LEVEL_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 35)">LEVEL</text>
+ <g transform="translate(5 38)"><svg id="CV_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 70)">CV</text>
+ <g transform="translate(5 73)"><svg id="VELOCITY_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 105)">VELO</text>
+ <g transform="translate(5 108)"><svg id="IN_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 140)">IN</text>
+ </g>
+ <g class="io-group" transform="translate(5.5 146)">
+ <rect class="output-background-filler" width="34" height="10" transform="translate(0 -3)"/>
+ <rect class="output-background" width="34" height="35" rx="5"/>
+ <g transform="translate(5 0)"><svg id="OUT_OUTPUT">
+ <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>
+ </svg></g>
+ <text class="output-label" font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text>
+ </g>
+ </g>
+
+
+
+</svg>
diff --git a/res-pp/Velo-pp.svg b/res-pp/Velo-pp.svg
@@ -0,0 +1,240 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="45.0" height="380.0" viewBox="0 0 45.0 380.0">
+ <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;
+}
+
+polyline {
+ stroke: #333;
+}
+polyline.guide {
+ stroke: #0f0;
+}
+path {
+ stroke: #333;
+}
+
+rect.module-background, .background-fill {
+ fill: #ddd;
+}
+polyline.module-border-inner {
+ stroke: #e4e4e4;
+}
+polyline.module-border-middle {
+ stroke: #ebebeb;
+}
+polyline.module-border-outer {
+ stroke: #f2f2f2;
+}
+
+g.io-group {
+}
+rect.input-background, rect.input-background-filler {
+ fill: #fafafa;
+}
+rect.output-background, rect.output-background-filler {
+ fill: #bbb;
+}
+text.input-label, text.output-label {
+ /* font-size: 6pt; */
+}
+polyline.input-label, polyline.output-label {
+}
+path.input-label, path.output-label {
+}
+
+circle.port-rim {
+ stroke: #f0f0f0;
+}
+circle.port-barrel {
+ stroke: #222;
+ fill: #222;
+}
+circle.knob-center {
+ fill: #eee;
+}
+circle.knob-rim {
+ fill: #333;
+}
+circle.knob-tick {
+ fill: #fff;
+}
+polyline.knob-tick {
+ stroke: #fff;
+}
+</style>
+
+ <defs>
+ <symbol id="dial-response-velo" viewBox="0 0 40px 40px">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </symbol>
+ </defs>
+
+
+
+ <rect class="module-background background-fill" width="45.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 44.0,1 44.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke-width="0.8" fill="none"/>
+ <polyline class="module-border-outer" points="0,0 45.0,0 45.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <g transform="rotate(-90) translate(-376.0 13)">
+ <text class="title" font-size="7pt" letter-spacing="2.5px">VELO</text>
+ <g transform="translate(0 12)">
+ <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text>
+ <rect class="background-fill" width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)"/>
+ </g>
+ </g>
+
+
+ <g transform="translate(0 25)">
+ <text font-size="6pt" letter-spacing="2px" text-anchor="middle" transform="translate(22.5 0)">LEVEL</text>
+ <g transform="translate(9.5 9.5)"><svg id="LEVEL_PARAM">
+ <g transform="translate(13 13)">
+ <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f"/>
+ <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f"/>
+ <circle cx="0" cy="0" r="12.5" stroke-width="1" stroke="#00f" fill="none"/>
+ </g>
+ </svg></g>
+ <g transform="translate(0 0)">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="5.0pt" transform="rotate(-240) translate(18 0) rotate(240) translate(-2 2)">0</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-210) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-180) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-150) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-120) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-90) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-60) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-30) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(0) translate(15 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(30) translate(15 0)"/>
+ <polyline points="0,0 3.5,0" stroke-width="1" transform="rotate(60) translate(15 0)"/>
+ </g>
+ </g>
+ <g transform="translate(14.5 50)"><svg id="LEVEL_ATTENUATOR_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 38)">
+ <g transform="translate(20 20)">
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(-90) translate(10 0)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#333" fill="none" transform="rotate(20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#333" fill="none" transform="rotate(43)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#333" fill="none" transform="rotate(-20)"/>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke-width="0.7" stroke-linecap="round" stroke="#333" fill="none" transform="rotate(-43)"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(0 104)">
+ <text font-size="6pt" letter-spacing="1px" text-anchor="middle" transform="translate(22.5 0)">V. R.</text>
+ <g transform="translate(14.5 11)"><svg id="VELOCITY_PARAM">
+ <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>
+ </svg></g>
+ <g transform="translate(2.5 -1)">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-172.91796067500633) translate(13 0) rotate(172.91796067500633) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-145.13167019494864) translate(10 0)"/>
+
+
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-105.83592135001263) translate(13 0) rotate(105.83592135001263) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-50.26334038989728) translate(14 0) rotate(50.26334038989728) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(-7.620999227554989) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(28.328157299974748) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </g>
+ </g>
+
+ <g transform="translate(10.5 144)">
+ <text font-size="5pt" letter-spacing="1px" transform="translate(0 6)">LIN</text>
+ <g transform="translate(15 -1)"><svg id="LINEAR_PARAM">
+ <g transform="translate(4.5 4.5)">
+ <circle r="4" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g transform="translate(0 157)">
+ <g class="io-group" transform="translate(5.5 0)">
+ <rect class="input-background" width="34" height="140" rx="5"/>
+ <rect class="input-background-filler" width="34" height="10" transform="translate(0 133)"/>
+ <g transform="translate(5 3)"><svg id="LEVEL_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 35)">LEVEL</text>
+ <g transform="translate(5 38)"><svg id="CV_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 70)">CV</text>
+ <g transform="translate(5 73)"><svg id="VELOCITY_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 105)">VELO</text>
+ <g transform="translate(5 108)"><svg id="IN_INPUT">
+ <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>
+ </svg></g>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 140)">IN</text>
+ </g>
+ <g class="io-group" transform="translate(5.5 146)">
+ <rect class="output-background-filler" width="34" height="10" transform="translate(0 -3)"/>
+ <rect class="output-background" width="34" height="35" rx="5"/>
+ <g transform="translate(5 0)"><svg id="OUT_OUTPUT">
+ <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>
+ </svg></g>
+ <text class="output-label" font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text>
+ </g>
+ </g>
+
+
+
+</svg>
diff --git a/res-src/Velo-src.svg b/res-src/Velo-src.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<module hp="3">
+ <style/>
+
+ <defs>
+ <symbol id="dial-response-velo" viewBox="0 0 40px 40px">
+ <g transform="translate(20 20)">
+ <text font-size="5pt" text-anchor="middle" transform="rotate(-240) translate(14 0) rotate(240) translate(0 2)">0dB</text>
+ <text font-size="5pt" text-anchor="middle" var-r="3.0**0.5/60.0**0.5*300.0-240.0" transform="rotate($r) translate(13 0) rotate(-1.0*$r) translate(0 3)">-3</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(6.0**0.5/60.0**0.5*300.0-240.0) translate(10 0)"/>
+ <!-- <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(9.0**0.5/60.0**0.5*300.0-240.0) translate(10 0)"/> -->
+ <!-- <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(12.0**0.5/60.0**0.5*300.0-240.0) translate(10 0)"/> -->
+ <text font-size="5pt" text-anchor="middle" var-r="12.0**0.5/60.0**0.5*300.0-240.0" transform="rotate($r) translate(13 0) rotate(-1.0*$r) translate(0 3)">-12</text>
+ <text font-size="5pt" text-anchor="middle" var-r="24.0**0.5/60.0**0.5*300.0-240.0" transform="rotate($r) translate(14 0) rotate(-1.0*$r) translate(0 3)">-24</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(36.0**0.5/60.0**0.5*300.0-240.0) translate(10 0)"/>
+ <polyline points="0,0 2.5,0" stroke-width="0.7" transform="rotate(48.0**0.5/60.0**0.5*300.0-240.0) translate(10 0)"/>
+ <polyline points="0,0 4,0" stroke-width="1" transform="rotate(60) translate(10 0)"/>
+ <polyline points="-3,0 3,0" stroke-width="1.0"/>
+ <polyline points="0,-3 0,3" stroke-width="1.0"/>
+ </g>
+ </symbol>
+ </defs>
+
+ <def xlink:href="#module3" var-name="VELO"/>
+
+ <g transform="translate(0 25)">
+ <text font-size="6pt" letter-spacing="2px" text-anchor="middle" transform="translate(22.5 0)">LEVEL</text>
+ <def id="LEVEL_PARAM" xlink:href="#knob26" transform="translate(9.5 9.5)"/>
+ <def xlink:href="#dial-linear" transform="translate(0 0)"/>
+ <def id="LEVEL_ATTENUATOR_PARAM" xlink:href="#knob16" transform="translate(14.5 50)"/>
+ <def xlink:href="#dial-centertick" transform="translate(2.5 38)"/>
+ </g>
+
+ <g transform="translate(0 104)">
+ <text font-size="6pt" letter-spacing="1px" text-anchor="middle" transform="translate(22.5 0)">V. R.</text>
+ <def id="VELOCITY_PARAM" xlink:href="#knob16" transform="translate(14.5 11)"/>
+ <def xlink:href="#dial-response-velo" transform="translate(2.5 -1)"/>
+ </g>
+
+ <g transform="translate(10.5 144)">
+ <text font-size="5pt" letter-spacing="1px" transform="translate(0 6)">LIN</text>
+ <def id="LINEAR_PARAM" xlink:href="#button-small" transform="translate(15 -1)"/>
+ </g>
+
+ <g transform="translate(0 157)">
+ <g class="io-group" transform="translate(5.5 0)">
+ <rect class="input-background" width="34" height="140" rx="5"/>
+ <rect class="input-background-filler" width="34" height="10" transform="translate(0 133)"/>
+ <def id="LEVEL_INPUT" xlink:href="#input" transform="translate(5 3)"/>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 35)">LEVEL</text>
+ <def id="CV_INPUT" xlink:href="#input" transform="translate(5 38)"/>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 70)">CV</text>
+ <def id="VELOCITY_INPUT" xlink:href="#input" transform="translate(5 73)"/>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 105)">VELO</text>
+ <def id="IN_INPUT" xlink:href="#input" transform="translate(5 108)"/>
+ <text class="input-label" font-size="5pt" letter-spacing="2px" text-anchor="middle" transform="translate(17 140)">IN</text>
+ </g>
+ <g class="io-group" transform="translate(5.5 146)">
+ <rect class="output-background-filler" width="34" height="10" transform="translate(0 -3)"/>
+ <rect class="output-background" width="34" height="35" rx="5"/>
+ <def id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 0)"/>
+ <text class="output-label" font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text>
+ </g>
+ </g>
+
+ <!-- <polyline points="0,0 0,380" stroke-width="0.7" stroke="#0f0" transform="translate(36.5 0)" /> -->
+ <!-- <polyline points="0,0 0,380" stroke-width="0.7" stroke="#0f0" transform="translate(8.5 0)" /> -->
+</module>
diff --git a/res/Velo-dark.svg b/res/Velo-dark.svg
Binary files differ.
diff --git a/res/Velo-lowcontrast.svg b/res/Velo-lowcontrast.svg
Binary files differ.
diff --git a/res/Velo.svg b/res/Velo.svg
Binary files differ.
diff --git a/src/Velo.cpp b/src/Velo.cpp
@@ -0,0 +1,129 @@
+
+#include "Velo.hpp"
+
+#define LEVEL_SCALES_CV "level_scales_cv"
+
+bool Velo::LevelParamQuantity::isLinear() {
+ return dynamic_cast<Velo*>(module)->isLinear();
+}
+
+void Velo::sampleRateChange() {
+ float sampleRate = APP->engine->getSampleRate();
+ for (int c = 0; c < maxChannels; ++c) {
+ _levelSL[c].setParams(sampleRate, 5.0f, 1.0f);
+ _velocitySL[c].setParams(sampleRate, 5.0f, 1.0f);
+ }
+}
+
+json_t* Velo::toJson(json_t* root) {
+ json_object_set_new(root, LEVEL_SCALES_CV, json_boolean(_levelScalesCV));
+ return root;
+}
+
+void Velo::fromJson(json_t* root) {
+ json_t* s = json_object_get(root, LEVEL_SCALES_CV);
+ if (s) {
+ _levelScalesCV = json_boolean_value(s);
+ }
+}
+
+bool Velo::active() {
+ return inputs[IN_INPUT].isConnected() && outputs[OUT_OUTPUT].isConnected();
+}
+
+void Velo::modulate() {
+ _velocityDb = clamp(params[VELOCITY_PARAM].getValue(), 0.0f, 1.0f);
+ _velocityDb *= _velocityDb;
+ _velocityDb *= Amplifier::minDecibels;
+ assert(_velocityDb <= 0.0f);
+}
+
+void Velo::processAll(const ProcessArgs& args) {
+ int n = inputs[IN_INPUT].getChannels();
+ outputs[OUT_OUTPUT].setChannels(n);
+ for (int c = 0; c < n; ++c) {
+ float level = clamp(params[LEVEL_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[LEVEL_INPUT].isConnected()) {
+ level *= clamp(inputs[LEVEL_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f);
+ }
+ if (inputs[CV_INPUT].isConnected()) {
+ float cv = clamp(inputs[CV_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ cv *= clamp(params[LEVEL_ATTENUATOR_PARAM].getValue(), -1.0f, 1.0f);
+ if (_levelScalesCV) {
+ level += level * cv;
+ }
+ else {
+ level += cv;
+ }
+ }
+ level = clamp(level, 0.0f, 2.0f);
+ level = _levelSL[c].next(level);
+
+ float velocity = 1.0f;
+ if (inputs[VELOCITY_INPUT].isConnected()) {
+ velocity = clamp(inputs[VELOCITY_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f);
+ }
+ velocity = _velocitySL[c].next(velocity);
+ _velocity[c].setLevel((1.0f - velocity) * _velocityDb);
+
+ float out = inputs[IN_INPUT].getVoltage(c);
+ if (isLinear()) {
+ out *= level;
+ }
+ else {
+ level = 1.0f - level;
+ level *= Amplifier::minDecibels;
+ level = std::min(level, 12.0f);
+ _amplifier[c].setLevel(level);
+ out = _amplifier[c].next(out);
+ }
+ out = _velocity[c].next(out);
+ out = _saturator[c].next(out);
+ outputs[OUT_OUTPUT].setVoltage(out, c);
+ }
+}
+
+struct VeloWidget : BGModuleWidget {
+ static constexpr int hp = 3;
+
+ VeloWidget(Velo* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+ setPanel(box.size, "Velo");
+ createScrews();
+
+ // generated by svg_widgets.rb
+ auto levelParamPosition = Vec(9.5, 34.5);
+ auto levelAttenuatorParamPosition = Vec(14.5, 75.0);
+ auto velocityParamPosition = Vec(14.5, 115.0);
+ auto linearParamPosition = Vec(25.5, 143.0);
+
+ auto levelInputPosition = Vec(10.5, 160.0);
+ auto cvInputPosition = Vec(10.5, 195.0);
+ auto velocityInputPosition = Vec(10.5, 230.0);
+ auto inInputPosition = Vec(10.5, 265.0);
+
+ auto outOutputPosition = Vec(10.5, 303.0);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<Knob26>(levelParamPosition, module, Velo::LEVEL_PARAM));
+ addParam(createParam<Knob16>(levelAttenuatorParamPosition, module, Velo::LEVEL_ATTENUATOR_PARAM));
+ addParam(createParam<Knob16>(velocityParamPosition, module, Velo::VELOCITY_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(linearParamPosition, module, Velo::LINEAR_PARAM));
+
+ addInput(createInput<Port24>(levelInputPosition, module, Velo::LEVEL_INPUT));
+ addInput(createInput<Port24>(cvInputPosition, module, Velo::CV_INPUT));
+ addInput(createInput<Port24>(velocityInputPosition, module, Velo::VELOCITY_INPUT));
+ addInput(createInput<Port24>(inInputPosition, module, Velo::IN_INPUT));
+
+ addOutput(createOutput<Port24>(outOutputPosition, module, Velo::OUT_OUTPUT));
+ }
+
+ void contextMenu(Menu* menu) {
+ auto m = dynamic_cast<Velo*>(module);
+ assert(m);
+ menu->addChild(new BoolOptionMenuItem("Level knob/CV scales bipolar CV", [m]() { return &m->_levelScalesCV; }));
+ }
+};
+
+Model* modelVelo = createModel<Velo, VeloWidget>("Bogaudio-Velo", "VELO", "Triple-CV VCA, for tremolo, MIDI velocity, etc", "VCA", "Polyphonic");
diff --git a/src/Velo.hpp b/src/Velo.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
+
+extern Model* modelVelo;
+
+namespace bogaudio {
+
+struct Velo : BGModule {
+ enum ParamsIds {
+ LEVEL_PARAM,
+ LEVEL_ATTENUATOR_PARAM,
+ VELOCITY_PARAM,
+ LINEAR_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ LEVEL_INPUT,
+ CV_INPUT,
+ VELOCITY_INPUT,
+ IN_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ OUT_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ struct LevelParamQuantity : AmplifierParamQuantity {
+ bool isLinear() override;
+ };
+
+ Amplifier _amplifier[maxChannels];
+ bogaudio::dsp::SlewLimiter _levelSL[maxChannels];
+ Amplifier _velocity[maxChannels];
+ bogaudio::dsp::SlewLimiter _velocitySL[maxChannels];
+ Saturator _saturator[maxChannels];
+ float _velocityDb = 0.0f;
+ bool _levelScalesCV = true;
+
+ Velo() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configParam<LevelParamQuantity>(LEVEL_PARAM, 0.0f, 1.0f, 0.8f, "level");
+ configParam(LEVEL_ATTENUATOR_PARAM, -1.0f, 1.0f, 0.0f, "Level CV");
+ configParam<ScaledSquaringParamQuantity<-60>>(VELOCITY_PARAM, 0.0f, 1.0f, 0.3162278f, "Velocity range", " dB");
+ configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "Linear");
+ }
+
+ inline bool isLinear() { return params[LINEAR_PARAM].getValue() > 0.5f; }
+ void sampleRateChange() override;
+ json_t* toJson(json_t* root) override;
+ void fromJson(json_t* root) override;
+ bool active() override;
+ void modulate() override;
+ void processAll(const ProcessArgs& args) override;
+};
+
+} // namespace bogaudio
diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp
@@ -39,6 +39,7 @@
#include "LLFO.hpp"
#include "LLPG.hpp"
#include "Lmtr.hpp"
+#include "LLPG.hpp"
#include "LPG.hpp"
#include "LVCF.hpp"
#include "LVCO.hpp"
@@ -100,6 +101,7 @@
#include "VCF.hpp"
#include "VCM.hpp"
#include "VCO.hpp"
+#include "Velo.hpp"
#include "Vish.hpp"
#include "VU.hpp"
#include "Walk.hpp"
@@ -112,7 +114,6 @@
#include "TestExpander.hpp"
#include "TestVCF.hpp"
-#include "LLPG.hpp"
//NEW_INCLUDES_HERE
Plugin *pluginInstance;
@@ -177,6 +178,7 @@ void init(rack::Plugin *p) {
p->addModel(modelXFade);
p->addModel(modelVCA);
p->addModel(modelVCAmp);
+ p->addModel(modelVelo);
p->addModel(modelUMix);
p->addModel(modelMumix);
diff --git a/src/lpg_common.hpp b/src/lpg_common.hpp
@@ -6,7 +6,7 @@ struct LPGEnvBaseModule : BGModule {
int _gateToTriggerParamID;
int _timeScaleParamID;
float _longTimeScale;
- bool _gateToTrigger = false;
+ bool _gateToTrigger = true;
float _timeScale = 1.0f;
const float _maxVelocityDb = 0.0f;
float _minVelocityDb = -6.0f;
diff --git a/src/param_quantities.hpp b/src/param_quantities.hpp
@@ -29,9 +29,9 @@ struct ScaledSquaringParamQuantity : ParamQuantity {
return;
}
displayValue -= displayOffset;
- float v = fabsf(displayValue) / (float)scale;
+ float v = fabsf(displayValue) / (float)abs(scale);
v = powf(v, 0.5f);
- if (displayValue < 0.0f) {
+ if (displayValue < 0.0f && scale > 0) {
setValue(-v);
}
else {