commit 8ee3fd95d72548ecef9008b1819886d2ea9f8e7f
parent 51ccb8081d614c84063e7656ba8a48daefa934dd
Author: Matt Demanett <matt@demanett.net>
Date: Mon, 5 Oct 2020 20:21:30 -0400
MX44CVM: CV and mutes expander for MATRIX44. #144
Diffstat:
24 files changed, 1435 insertions(+), 39 deletions(-)
diff --git a/README-prerelease.md b/README-prerelease.md
@@ -628,7 +628,7 @@ _Polyphony:_ <a href="#polyphony">Polyphonic</a>, as on MATRIX44.
#### <a name="matrix44"></a> MATRIX44
-An 4x4 channel matrix mixer. Each input can be routed with an independent level to each of the eight output mixes.
+A 4x4 channel matrix mixer. Each input can be routed with an independent level to each of the eight output mixes. MATRIX44 is expandable with <a href="matrix44cvm">MATRIX44CVM</a>.
*Note that the matrix knobs are attenuverters, and default to zero.* That means there will be no output, regardless of the inputs, until some knobs are changed to non-zero values.
@@ -642,6 +642,12 @@ The knobs visually indicate their values with green/orange colors. This can be
_Polyphony:_ <a href="#polyphony">Polyphonic</a>, with polyphonic channels defined by input 1.
+#### <a name="matrix44cvm"></a> MX44CVM
+
+An expander for MATRIX44, adding CVs and mutes for each point in the mix matrix. The CVs are bipolar (+/-5v), and each is attenuverted by its corresponding knob when in use. The mute buttons will mute the corresponding mix point, overriding the knob and CV. As <a href="mix8">MIX8</a> and others, the mute buttons can be right-clicked to solo that mix point -- all others will be muted. A subsequent click on a soloed button restores the previous state, and other muted buttons retake effect.
+
+MX44CVM must be positioned to the right of, and adjacent to, the MATRIX44 module it will expand. See <a href="#expanders">notes on expanders</a>.
+
#### <a name="matrix88"></a> MATRIX88
An 8x8 version of MATRIX44.
diff --git a/plugin.json b/plugin.json
@@ -606,6 +606,17 @@
]
},
{
+ "slug": "Bogaudio-Matrix44Cvm",
+ "name": "MX44CVM",
+ "description": "CV and mutes expander for MATRIX44",
+ "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#matrix44cvm",
+ "tags": [
+ "Mixer",
+ "Expander",
+ "Polyphonic"
+ ]
+ },
+ {
"slug": "Bogaudio-Matrix88",
"name": "MATRIX88",
"description": "8x8 matrix mixer",
diff --git a/res-pp/Matrix44Cvm-dark-pp.svg b/res-pp/Matrix44Cvm-dark-pp.svg
@@ -0,0 +1,360 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="150.0" height="380.0" viewBox="0 0 150.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>
+
+
+
+ <rect class="module-background background-fill" width="150.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 149.0,1 149.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 149.5,0.5 149.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 150.0,0 150.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <text class="title" font-size="12pt" letter-spacing="2.5px" text-anchor="middle" transform="translate(75.0 19)">MX44CVM</text>
+ <g transform="translate(0 374)">
+ <text class="brand" font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(75.0 0)">BOGAUDIO</text>
+ <rect class="background-fill" width="3" height="3" transform="translate(59.5 -5)"/>
+ </g>
+
+
+
+
+
+
+
+ <g transform="translate(10 54)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -5)">MUTE</text>
+
+ <g transform="translate(6.75 6.75)"><svg id="MUTE11_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 39.25)"><svg id="MUTE21_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 71.75)"><svg id="MUTE31_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 104.25)"><svg id="MUTE41_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(39.25 6.75)"><svg id="MUTE12_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 39.25)"><svg id="MUTE22_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 71.75)"><svg id="MUTE32_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 104.25)"><svg id="MUTE42_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(71.75 6.75)"><svg id="MUTE13_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 39.25)"><svg id="MUTE23_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 71.75)"><svg id="MUTE33_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 104.25)"><svg id="MUTE43_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(104.25 6.75)"><svg id="MUTE14_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 39.25)"><svg id="MUTE24_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 71.75)"><svg id="MUTE34_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 104.25)"><svg id="MUTE44_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g class="io-group" transform="translate(10 214)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -8)">CV</text>
+ <rect class="input-background" width="130" height="130" rx="5" transform="translate(0 0)"/>
+
+ <g transform="translate(4.25 4.25)"><svg id="CV11_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>
+ <g transform="translate(4.25 36.75)"><svg id="CV21_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>
+ <g transform="translate(4.25 69.25)"><svg id="CV31_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>
+ <g transform="translate(4.25 101.75)"><svg id="CV41_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>
+
+ <g transform="translate(36.75 4.25)"><svg id="CV12_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>
+ <g transform="translate(36.75 36.75)"><svg id="CV22_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>
+ <g transform="translate(36.75 69.25)"><svg id="CV32_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>
+ <g transform="translate(36.75 101.75)"><svg id="CV42_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>
+
+ <g transform="translate(69.25 4.25)"><svg id="CV13_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>
+ <g transform="translate(69.25 36.75)"><svg id="CV23_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>
+ <g transform="translate(69.25 69.25)"><svg id="CV33_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>
+ <g transform="translate(69.25 101.75)"><svg id="CV43_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>
+
+ <g transform="translate(101.75 4.25)"><svg id="CV14_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>
+ <g transform="translate(101.75 36.75)"><svg id="CV24_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>
+ <g transform="translate(101.75 69.25)"><svg id="CV34_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>
+ <g transform="translate(101.75 101.75)"><svg id="CV44_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>
+ </g>
+
+
+
+
+
+
+</svg>
diff --git a/res-pp/Matrix44Cvm-lowcontrast-pp.svg b/res-pp/Matrix44Cvm-lowcontrast-pp.svg
@@ -0,0 +1,360 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="150.0" height="380.0" viewBox="0 0 150.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>
+
+
+
+ <rect class="module-background background-fill" width="150.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 149.0,1 149.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 149.5,0.5 149.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 150.0,0 150.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <text class="title" font-size="12pt" letter-spacing="2.5px" text-anchor="middle" transform="translate(75.0 19)">MX44CVM</text>
+ <g transform="translate(0 374)">
+ <text class="brand" font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(75.0 0)">BOGAUDIO</text>
+ <rect class="background-fill" width="3" height="3" transform="translate(59.5 -5)"/>
+ </g>
+
+
+
+
+
+
+
+ <g transform="translate(10 54)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -5)">MUTE</text>
+
+ <g transform="translate(6.75 6.75)"><svg id="MUTE11_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 39.25)"><svg id="MUTE21_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 71.75)"><svg id="MUTE31_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 104.25)"><svg id="MUTE41_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(39.25 6.75)"><svg id="MUTE12_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 39.25)"><svg id="MUTE22_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 71.75)"><svg id="MUTE32_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 104.25)"><svg id="MUTE42_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(71.75 6.75)"><svg id="MUTE13_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 39.25)"><svg id="MUTE23_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 71.75)"><svg id="MUTE33_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 104.25)"><svg id="MUTE43_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(104.25 6.75)"><svg id="MUTE14_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 39.25)"><svg id="MUTE24_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 71.75)"><svg id="MUTE34_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 104.25)"><svg id="MUTE44_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g class="io-group" transform="translate(10 214)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -8)">CV</text>
+ <rect class="input-background" width="130" height="130" rx="5" transform="translate(0 0)"/>
+
+ <g transform="translate(4.25 4.25)"><svg id="CV11_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>
+ <g transform="translate(4.25 36.75)"><svg id="CV21_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>
+ <g transform="translate(4.25 69.25)"><svg id="CV31_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>
+ <g transform="translate(4.25 101.75)"><svg id="CV41_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>
+
+ <g transform="translate(36.75 4.25)"><svg id="CV12_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>
+ <g transform="translate(36.75 36.75)"><svg id="CV22_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>
+ <g transform="translate(36.75 69.25)"><svg id="CV32_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>
+ <g transform="translate(36.75 101.75)"><svg id="CV42_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>
+
+ <g transform="translate(69.25 4.25)"><svg id="CV13_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>
+ <g transform="translate(69.25 36.75)"><svg id="CV23_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>
+ <g transform="translate(69.25 69.25)"><svg id="CV33_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>
+ <g transform="translate(69.25 101.75)"><svg id="CV43_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>
+
+ <g transform="translate(101.75 4.25)"><svg id="CV14_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>
+ <g transform="translate(101.75 36.75)"><svg id="CV24_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>
+ <g transform="translate(101.75 69.25)"><svg id="CV34_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>
+ <g transform="translate(101.75 101.75)"><svg id="CV44_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>
+ </g>
+
+
+
+
+
+
+</svg>
diff --git a/res-pp/Matrix44Cvm-pp.svg b/res-pp/Matrix44Cvm-pp.svg
@@ -0,0 +1,296 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="150.0" height="380.0" viewBox="0 0 150.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>
+
+
+
+ <rect class="module-background background-fill" width="150.0" height="380.0"/>
+
+
+ <polyline class="module-border-inner" points="1,1 149.0,1 149.0,379.0 1,379.0 1,1" stroke-width="0.5" fill="none"/>
+ <polyline class="module-border-middle" points="0.5,0.5 149.5,0.5 149.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 150.0,0 150.0,380.0 0,380.0 0,0" stroke-width="1" fill="none"/>
+
+ <text class="title" font-size="12pt" letter-spacing="2.5px" text-anchor="middle" transform="translate(75.0 19)">MX44CVM</text>
+ <g transform="translate(0 374)">
+ <text class="brand" font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(75.0 0)">BOGAUDIO</text>
+ <rect class="background-fill" width="3" height="3" transform="translate(59.5 -5)"/>
+ </g>
+
+
+
+
+
+
+
+ <g transform="translate(10 54)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -5)">MUTE</text>
+
+ <g transform="translate(6.75 6.75)"><svg id="MUTE11_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 39.25)"><svg id="MUTE21_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 71.75)"><svg id="MUTE31_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(6.75 104.25)"><svg id="MUTE41_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(39.25 6.75)"><svg id="MUTE12_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 39.25)"><svg id="MUTE22_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 71.75)"><svg id="MUTE32_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(39.25 104.25)"><svg id="MUTE42_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(71.75 6.75)"><svg id="MUTE13_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 39.25)"><svg id="MUTE23_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 71.75)"><svg id="MUTE33_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(71.75 104.25)"><svg id="MUTE43_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+
+ <g transform="translate(104.25 6.75)"><svg id="MUTE14_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 39.25)"><svg id="MUTE24_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 71.75)"><svg id="MUTE34_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ <g transform="translate(104.25 104.25)"><svg id="MUTE44_PARAM">
+ <g transform="translate(9 9)">
+ <circle cx="0" cy="0" r="8.5" stroke-width="1" stroke="#00f" fill="#f00"/>
+ </g>
+ </svg></g>
+ </g>
+
+ <g class="io-group" transform="translate(10 214)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate(65.0 -8)">CV</text>
+ <rect class="input-background" width="130" height="130" rx="5" transform="translate(0 0)"/>
+
+ <g transform="translate(4.25 4.25)"><svg id="CV11_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>
+ <g transform="translate(4.25 36.75)"><svg id="CV21_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>
+ <g transform="translate(4.25 69.25)"><svg id="CV31_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>
+ <g transform="translate(4.25 101.75)"><svg id="CV41_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>
+
+ <g transform="translate(36.75 4.25)"><svg id="CV12_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>
+ <g transform="translate(36.75 36.75)"><svg id="CV22_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>
+ <g transform="translate(36.75 69.25)"><svg id="CV32_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>
+ <g transform="translate(36.75 101.75)"><svg id="CV42_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>
+
+ <g transform="translate(69.25 4.25)"><svg id="CV13_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>
+ <g transform="translate(69.25 36.75)"><svg id="CV23_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>
+ <g transform="translate(69.25 69.25)"><svg id="CV33_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>
+ <g transform="translate(69.25 101.75)"><svg id="CV43_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>
+
+ <g transform="translate(101.75 4.25)"><svg id="CV14_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>
+ <g transform="translate(101.75 36.75)"><svg id="CV24_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>
+ <g transform="translate(101.75 69.25)"><svg id="CV34_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>
+ <g transform="translate(101.75 101.75)"><svg id="CV44_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>
+ </g>
+
+
+
+
+
+
+</svg>
diff --git a/res-src/Matrix44Cvm-src.svg b/res-src/Matrix44Cvm-src.svg
@@ -0,0 +1,65 @@
+<module hp="10">
+ <style/>
+
+ <def xlink:href="#module" var-name="MX44CVM" var-letterspacing="2.5"/>
+
+ <!-- <rect width="$width" height="20" fill="#0f0" transform="translate(0 20)"/> -->
+ <!-- <rect width="$width" height="20" fill="#0f0" transform="translate(0 178)"/> -->
+ <!-- <rect width="$width" height="20" fill="#0f0" transform="translate(0 345)"/> -->
+
+ <g var-w="130/4.0">
+ <g transform="translate(10 54)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate($width/2.0-10 -5)">MUTE</text>
+
+ <def id="MUTE11_PARAM" xlink:href="#button" transform="translate(0*$w+$w/2.0-9.5 0*$w+$w/2.0-9.5)"/>
+ <def id="MUTE21_PARAM" xlink:href="#button" transform="translate(0*$w+$w/2.0-9.5 1*$w+$w/2.0-9.5)"/>
+ <def id="MUTE31_PARAM" xlink:href="#button" transform="translate(0*$w+$w/2.0-9.5 2*$w+$w/2.0-9.5)"/>
+ <def id="MUTE41_PARAM" xlink:href="#button" transform="translate(0*$w+$w/2.0-9.5 3*$w+$w/2.0-9.5)"/>
+
+ <def id="MUTE12_PARAM" xlink:href="#button" transform="translate(1*$w+$w/2.0-9.5 0*$w+$w/2.0-9.5)"/>
+ <def id="MUTE22_PARAM" xlink:href="#button" transform="translate(1*$w+$w/2.0-9.5 1*$w+$w/2.0-9.5)"/>
+ <def id="MUTE32_PARAM" xlink:href="#button" transform="translate(1*$w+$w/2.0-9.5 2*$w+$w/2.0-9.5)"/>
+ <def id="MUTE42_PARAM" xlink:href="#button" transform="translate(1*$w+$w/2.0-9.5 3*$w+$w/2.0-9.5)"/>
+
+ <def id="MUTE13_PARAM" xlink:href="#button" transform="translate(2*$w+$w/2.0-9.5 0*$w+$w/2.0-9.5)"/>
+ <def id="MUTE23_PARAM" xlink:href="#button" transform="translate(2*$w+$w/2.0-9.5 1*$w+$w/2.0-9.5)"/>
+ <def id="MUTE33_PARAM" xlink:href="#button" transform="translate(2*$w+$w/2.0-9.5 2*$w+$w/2.0-9.5)"/>
+ <def id="MUTE43_PARAM" xlink:href="#button" transform="translate(2*$w+$w/2.0-9.5 3*$w+$w/2.0-9.5)"/>
+
+ <def id="MUTE14_PARAM" xlink:href="#button" transform="translate(3*$w+$w/2.0-9.5 0*$w+$w/2.0-9.5)"/>
+ <def id="MUTE24_PARAM" xlink:href="#button" transform="translate(3*$w+$w/2.0-9.5 1*$w+$w/2.0-9.5)"/>
+ <def id="MUTE34_PARAM" xlink:href="#button" transform="translate(3*$w+$w/2.0-9.5 2*$w+$w/2.0-9.5)"/>
+ <def id="MUTE44_PARAM" xlink:href="#button" transform="translate(3*$w+$w/2.0-9.5 3*$w+$w/2.0-9.5)"/>
+ </g>
+
+ <g class="io-group" transform="translate(10 214)">
+ <text font-size="8pt" letter-spacing="2px" text-anchor="middle" transform="translate($width/2.0-10 -8)">CV</text>
+ <rect class="input-background" width="130" height="130" rx="5" transform="translate(0 0)"/>
+
+ <def id="CV11_INPUT" xlink:href="#input" transform="translate(0*$w+$w/2.0-12.0 0*$w+$w/2.0-12.0)"/>
+ <def id="CV21_INPUT" xlink:href="#input" transform="translate(0*$w+$w/2.0-12.0 1*$w+$w/2.0-12.0)"/>
+ <def id="CV31_INPUT" xlink:href="#input" transform="translate(0*$w+$w/2.0-12.0 2*$w+$w/2.0-12.0)"/>
+ <def id="CV41_INPUT" xlink:href="#input" transform="translate(0*$w+$w/2.0-12.0 3*$w+$w/2.0-12.0)"/>
+
+ <def id="CV12_INPUT" xlink:href="#input" transform="translate(1*$w+$w/2.0-12.0 0*$w+$w/2.0-12.0)"/>
+ <def id="CV22_INPUT" xlink:href="#input" transform="translate(1*$w+$w/2.0-12.0 1*$w+$w/2.0-12.0)"/>
+ <def id="CV32_INPUT" xlink:href="#input" transform="translate(1*$w+$w/2.0-12.0 2*$w+$w/2.0-12.0)"/>
+ <def id="CV42_INPUT" xlink:href="#input" transform="translate(1*$w+$w/2.0-12.0 3*$w+$w/2.0-12.0)"/>
+
+ <def id="CV13_INPUT" xlink:href="#input" transform="translate(2*$w+$w/2.0-12.0 0*$w+$w/2.0-12.0)"/>
+ <def id="CV23_INPUT" xlink:href="#input" transform="translate(2*$w+$w/2.0-12.0 1*$w+$w/2.0-12.0)"/>
+ <def id="CV33_INPUT" xlink:href="#input" transform="translate(2*$w+$w/2.0-12.0 2*$w+$w/2.0-12.0)"/>
+ <def id="CV43_INPUT" xlink:href="#input" transform="translate(2*$w+$w/2.0-12.0 3*$w+$w/2.0-12.0)"/>
+
+ <def id="CV14_INPUT" xlink:href="#input" transform="translate(3*$w+$w/2.0-12.0 0*$w+$w/2.0-12.0)"/>
+ <def id="CV24_INPUT" xlink:href="#input" transform="translate(3*$w+$w/2.0-12.0 1*$w+$w/2.0-12.0)"/>
+ <def id="CV34_INPUT" xlink:href="#input" transform="translate(3*$w+$w/2.0-12.0 2*$w+$w/2.0-12.0)"/>
+ <def id="CV44_INPUT" xlink:href="#input" transform="translate(3*$w+$w/2.0-12.0 3*$w+$w/2.0-12.0)"/>
+ </g>
+
+ <!-- <polyline class="guide" points="0,0 0,380" stroke-width="1" stroke="#0f0" transform="translate(10+0*$w+$w/2.0 0)" /> -->
+ <!-- <polyline class="guide" points="0,0 0,380" stroke-width="1" stroke="#0f0" transform="translate(10+1*$w+$w/2.0 0)" /> -->
+ <!-- <polyline class="guide" points="0,0 0,380" stroke-width="1" stroke="#0f0" transform="translate(10+2*$w+$w/2.0 0)" /> -->
+ <!-- <polyline class="guide" points="0,0 0,380" stroke-width="1" stroke="#0f0" transform="translate(10+3*$w+$w/2.0 0)" /> -->
+ </g>
+</module>
diff --git a/res/Matrix44Cvm-dark.svg b/res/Matrix44Cvm-dark.svg
Binary files differ.
diff --git a/res/Matrix44Cvm-lowcontrast.svg b/res/Matrix44Cvm-lowcontrast.svg
Binary files differ.
diff --git a/res/Matrix44Cvm.svg b/res/Matrix44Cvm.svg
Binary files differ.
diff --git a/src/AddrSeq.hpp b/src/AddrSeq.hpp
@@ -114,7 +114,7 @@ struct AddrSeq : AddrSeqBase {
}
};
- AddrSeq() : AddrSeqBase(AddrSeqRegistry::registry()) {
+ AddrSeq() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<StepsParamQuantity>(STEPS_PARAM, 1.0f, 8.0f, 8.0f, "Steps");
configParam(DIRECTION_PARAM, 0.0f, 1.0f, 1.0f, "Direction");
diff --git a/src/AddrSeqX.hpp b/src/AddrSeqX.hpp
@@ -39,7 +39,7 @@ struct AddrSeqX : AddrSeqXBase, OutputRange {
NUM_LIGHTS
};
- AddrSeqX() : AddrSeqXBase(AddrSeqRegistry::registry()) {
+ AddrSeqX() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<OutputRangeParamQuantity>(OUT1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1", " V");
configParam<OutputRangeParamQuantity>(OUT2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2", " V");
diff --git a/src/AddrSeq_shared.hpp b/src/AddrSeq_shared.hpp
@@ -9,9 +9,7 @@ extern Model* modelAddrSeqX;
namespace bogaudio {
-struct AddrSeqExpanderMessage : ExpanderMessage {
- int baseID = -1;
- int position = -1;
+struct AddrSeqExpanderMessage : ChainableExpanderMessage {
float rangeOffset = 0.0f;
float rangeScale = 10.0f;
};
diff --git a/src/Matrix44.cpp b/src/Matrix44.cpp
@@ -1,6 +1,31 @@
#include "Matrix44.hpp"
+void Matrix44::elementsChanged() {
+ // base-class caller holds lock on _elements.
+ Input** cvs = NULL;
+ Param** mutes = NULL;
+ for (int i = 1, n = _elements.size(); i < n; ++i) {
+ auto e = _elements[i];
+ if (e->cvs) {
+ cvs = e->cvs;
+ }
+ if (e->mutes) {
+ mutes = e->mutes;
+ }
+ }
+ setCVInputs(cvs);
+ setMuteParams(mutes);
+}
+
+void Matrix44::processAlways(const ProcessArgs& args) {
+ if (expanderConnected()) {
+ Matrix44ExpanderMessage* te = toExpander();
+ te->baseID = _id;
+ te->position = 1;
+ }
+}
+
struct Matrix44Widget : KnobMatrixModuleWidget {
static constexpr int hp = 10;
diff --git a/src/Matrix44.hpp b/src/Matrix44.hpp
@@ -1,13 +1,12 @@
#pragma once
-#include "bogaudio.hpp"
-#include "matrix_base.hpp"
-
-extern Model* modelMatrix44;
+#include "Matrix44_shared.hpp"
namespace bogaudio {
-struct Matrix44 : KnobMatrixModule {
+typedef ChainableExpandableModule<Matrix44ExpanderMessage, Matrix44Element, 1, KnobMatrixModule> Matrix44Base;
+
+struct Matrix44 : Matrix44Base {
enum ParamsIds {
MIX11_PARAM,
MIX21_PARAM,
@@ -44,8 +43,9 @@ struct Matrix44 : KnobMatrixModule {
NUM_OUTPUTS
};
- Matrix44() : KnobMatrixModule(4, 4, MIX11_PARAM, IN1_INPUT, OUT1_OUTPUT) {
+ Matrix44() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configMatrixModule(4, 4, MIX11_PARAM, IN1_INPUT, OUT1_OUTPUT);
configParam(MIX11_PARAM, -1.0f, 1.0f, 0.0f, "Mix 1A", "%", 0.0f, 100.0f);
configParam(MIX21_PARAM, -1.0f, 1.0f, 0.0f, "Mix 2A", "%", 0.0f, 100.0f);
configParam(MIX31_PARAM, -1.0f, 1.0f, 0.0f, "Mix 3A", "%", 0.0f, 100.0f);
@@ -62,7 +62,14 @@ struct Matrix44 : KnobMatrixModule {
configParam(MIX24_PARAM, -1.0f, 1.0f, 0.0f, "Mix 2D", "%", 0.0f, 100.0f);
configParam(MIX34_PARAM, -1.0f, 1.0f, 0.0f, "Mix 3D", "%", 0.0f, 100.0f);
configParam(MIX44_PARAM, -1.0f, 1.0f, 0.0f, "Mix 4D", "%", 0.0f, 100.0f);
+
+ setLocalElements({new Matrix44Element(NULL, NULL)});
+ registerBase();
+ setExpanderModelPredicate([](Model* m) { return m == modelMatrix44Cvm; });
}
+
+ void elementsChanged() override;
+ void processAlways(const ProcessArgs& args) override;
};
} // namespace bogaudio
diff --git a/src/Matrix44Cvm.cpp b/src/Matrix44Cvm.cpp
@@ -0,0 +1,103 @@
+
+#include "Matrix44Cvm.hpp"
+#include "mixer.hpp"
+
+void Matrix44Cvm::processAlways(const ProcessArgs& args) {
+ int position = 0;
+ int baseID = 0;
+ if (baseConnected()) {
+ Matrix44ExpanderMessage* bm = fromBase();
+ baseID = bm->baseID;
+ position = bm->position;
+ }
+ setBaseIDAndPosition(baseID, position);
+
+ if (expanderConnected()) {
+ Matrix44ExpanderMessage* te = toExpander();
+ te->baseID = _baseID;
+ te->position = _position > 0 ? _position + 1 : 0;
+ }
+}
+
+struct Matrix44CvmWidget : BGModuleWidget {
+ static constexpr int hp = 10;
+
+ Matrix44CvmWidget(Matrix44Cvm* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+ setPanel(box.size, "Matrix44Cvm");
+ createScrews();
+
+ // generated by svg_widgets.rb
+ auto mute11ParamPosition = Vec(16.75, 60.75);
+ auto mute21ParamPosition = Vec(16.75, 93.25);
+ auto mute31ParamPosition = Vec(16.75, 125.75);
+ auto mute41ParamPosition = Vec(16.75, 158.25);
+ auto mute12ParamPosition = Vec(49.25, 60.75);
+ auto mute22ParamPosition = Vec(49.25, 93.25);
+ auto mute32ParamPosition = Vec(49.25, 125.75);
+ auto mute42ParamPosition = Vec(49.25, 158.25);
+ auto mute13ParamPosition = Vec(81.75, 60.75);
+ auto mute23ParamPosition = Vec(81.75, 93.25);
+ auto mute33ParamPosition = Vec(81.75, 125.75);
+ auto mute43ParamPosition = Vec(81.75, 158.25);
+ auto mute14ParamPosition = Vec(114.25, 60.75);
+ auto mute24ParamPosition = Vec(114.25, 93.25);
+ auto mute34ParamPosition = Vec(114.25, 125.75);
+ auto mute44ParamPosition = Vec(114.25, 158.25);
+
+ auto cv11InputPosition = Vec(14.25, 218.25);
+ auto cv21InputPosition = Vec(14.25, 250.75);
+ auto cv31InputPosition = Vec(14.25, 283.25);
+ auto cv41InputPosition = Vec(14.25, 315.75);
+ auto cv12InputPosition = Vec(46.75, 218.25);
+ auto cv22InputPosition = Vec(46.75, 250.75);
+ auto cv32InputPosition = Vec(46.75, 283.25);
+ auto cv42InputPosition = Vec(46.75, 315.75);
+ auto cv13InputPosition = Vec(79.25, 218.25);
+ auto cv23InputPosition = Vec(79.25, 250.75);
+ auto cv33InputPosition = Vec(79.25, 283.25);
+ auto cv43InputPosition = Vec(79.25, 315.75);
+ auto cv14InputPosition = Vec(111.75, 218.25);
+ auto cv24InputPosition = Vec(111.75, 250.75);
+ auto cv34InputPosition = Vec(111.75, 283.25);
+ auto cv44InputPosition = Vec(111.75, 315.75);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<SoloMuteButton>(mute11ParamPosition, module, Matrix44Cvm::MUTE11_PARAM));
+ addParam(createParam<SoloMuteButton>(mute21ParamPosition, module, Matrix44Cvm::MUTE21_PARAM));
+ addParam(createParam<SoloMuteButton>(mute31ParamPosition, module, Matrix44Cvm::MUTE31_PARAM));
+ addParam(createParam<SoloMuteButton>(mute41ParamPosition, module, Matrix44Cvm::MUTE41_PARAM));
+ addParam(createParam<SoloMuteButton>(mute12ParamPosition, module, Matrix44Cvm::MUTE12_PARAM));
+ addParam(createParam<SoloMuteButton>(mute22ParamPosition, module, Matrix44Cvm::MUTE22_PARAM));
+ addParam(createParam<SoloMuteButton>(mute32ParamPosition, module, Matrix44Cvm::MUTE32_PARAM));
+ addParam(createParam<SoloMuteButton>(mute42ParamPosition, module, Matrix44Cvm::MUTE42_PARAM));
+ addParam(createParam<SoloMuteButton>(mute13ParamPosition, module, Matrix44Cvm::MUTE13_PARAM));
+ addParam(createParam<SoloMuteButton>(mute23ParamPosition, module, Matrix44Cvm::MUTE23_PARAM));
+ addParam(createParam<SoloMuteButton>(mute33ParamPosition, module, Matrix44Cvm::MUTE33_PARAM));
+ addParam(createParam<SoloMuteButton>(mute43ParamPosition, module, Matrix44Cvm::MUTE43_PARAM));
+ addParam(createParam<SoloMuteButton>(mute14ParamPosition, module, Matrix44Cvm::MUTE14_PARAM));
+ addParam(createParam<SoloMuteButton>(mute24ParamPosition, module, Matrix44Cvm::MUTE24_PARAM));
+ addParam(createParam<SoloMuteButton>(mute34ParamPosition, module, Matrix44Cvm::MUTE34_PARAM));
+ addParam(createParam<SoloMuteButton>(mute44ParamPosition, module, Matrix44Cvm::MUTE44_PARAM));
+
+ addInput(createInput<Port24>(cv11InputPosition, module, Matrix44Cvm::CV11_INPUT));
+ addInput(createInput<Port24>(cv21InputPosition, module, Matrix44Cvm::CV21_INPUT));
+ addInput(createInput<Port24>(cv31InputPosition, module, Matrix44Cvm::CV31_INPUT));
+ addInput(createInput<Port24>(cv41InputPosition, module, Matrix44Cvm::CV41_INPUT));
+ addInput(createInput<Port24>(cv12InputPosition, module, Matrix44Cvm::CV12_INPUT));
+ addInput(createInput<Port24>(cv22InputPosition, module, Matrix44Cvm::CV22_INPUT));
+ addInput(createInput<Port24>(cv32InputPosition, module, Matrix44Cvm::CV32_INPUT));
+ addInput(createInput<Port24>(cv42InputPosition, module, Matrix44Cvm::CV42_INPUT));
+ addInput(createInput<Port24>(cv13InputPosition, module, Matrix44Cvm::CV13_INPUT));
+ addInput(createInput<Port24>(cv23InputPosition, module, Matrix44Cvm::CV23_INPUT));
+ addInput(createInput<Port24>(cv33InputPosition, module, Matrix44Cvm::CV33_INPUT));
+ addInput(createInput<Port24>(cv43InputPosition, module, Matrix44Cvm::CV43_INPUT));
+ addInput(createInput<Port24>(cv14InputPosition, module, Matrix44Cvm::CV14_INPUT));
+ addInput(createInput<Port24>(cv24InputPosition, module, Matrix44Cvm::CV24_INPUT));
+ addInput(createInput<Port24>(cv34InputPosition, module, Matrix44Cvm::CV34_INPUT));
+ addInput(createInput<Port24>(cv44InputPosition, module, Matrix44Cvm::CV44_INPUT));
+ }
+};
+
+Model* modelMatrix44Cvm = createModel<Matrix44Cvm, Matrix44CvmWidget>("Bogaudio-Matrix44Cvm", "MX44CVM", "CV and mutes expander for MATRIX44", "Mixer", "Expander", "Polyphonic");
diff --git a/src/Matrix44Cvm.hpp b/src/Matrix44Cvm.hpp
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "Matrix44_shared.hpp"
+
+namespace bogaudio {
+
+typedef ChainableExpanderModule<Matrix44ExpanderMessage, Matrix44Element, 1, BGModule> Matrix44CvmBase;
+
+struct Matrix44Cvm : Matrix44CvmBase {
+ enum ParamsIds {
+ MUTE11_PARAM,
+ MUTE21_PARAM,
+ MUTE31_PARAM,
+ MUTE41_PARAM,
+ MUTE12_PARAM,
+ MUTE22_PARAM,
+ MUTE32_PARAM,
+ MUTE42_PARAM,
+ MUTE13_PARAM,
+ MUTE23_PARAM,
+ MUTE33_PARAM,
+ MUTE43_PARAM,
+ MUTE14_PARAM,
+ MUTE24_PARAM,
+ MUTE34_PARAM,
+ MUTE44_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ CV11_INPUT,
+ CV21_INPUT,
+ CV31_INPUT,
+ CV41_INPUT,
+ CV12_INPUT,
+ CV22_INPUT,
+ CV32_INPUT,
+ CV42_INPUT,
+ CV13_INPUT,
+ CV23_INPUT,
+ CV33_INPUT,
+ CV43_INPUT,
+ CV14_INPUT,
+ CV24_INPUT,
+ CV34_INPUT,
+ CV44_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ NUM_OUTPUTS
+ };
+
+ Param** _mutes = NULL;
+ Input** _cvs = NULL;
+
+ Matrix44Cvm() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configParam(MUTE11_PARAM, 0.0f, 3.0f, 0.0f, "Mute 1A");
+ configParam(MUTE21_PARAM, 0.0f, 3.0f, 0.0f, "Mute 2A");
+ configParam(MUTE31_PARAM, 0.0f, 3.0f, 0.0f, "Mute 3A");
+ configParam(MUTE41_PARAM, 0.0f, 3.0f, 0.0f, "Mute 4A");
+ configParam(MUTE12_PARAM, 0.0f, 3.0f, 0.0f, "Mute 1B");
+ configParam(MUTE22_PARAM, 0.0f, 3.0f, 0.0f, "Mute 2B");
+ configParam(MUTE32_PARAM, 0.0f, 3.0f, 0.0f, "Mute 3B");
+ configParam(MUTE42_PARAM, 0.0f, 3.0f, 0.0f, "Mute 4B");
+ configParam(MUTE13_PARAM, 0.0f, 3.0f, 0.0f, "Mute 1C");
+ configParam(MUTE23_PARAM, 0.0f, 3.0f, 0.0f, "Mute 2C");
+ configParam(MUTE33_PARAM, 0.0f, 3.0f, 0.0f, "Mute 3C");
+ configParam(MUTE43_PARAM, 0.0f, 3.0f, 0.0f, "Mute 4C");
+ configParam(MUTE14_PARAM, 0.0f, 3.0f, 0.0f, "Mute 1D");
+ configParam(MUTE24_PARAM, 0.0f, 3.0f, 0.0f, "Mute 2D");
+ configParam(MUTE34_PARAM, 0.0f, 3.0f, 0.0f, "Mute 3D");
+ configParam(MUTE44_PARAM, 0.0f, 3.0f, 0.0f, "Mute 4D");
+
+ _mutes = new Param*[16];
+ _cvs = new Input*[16];
+ for (int i = 0; i < 16; ++i) {
+ _mutes[i] = ¶ms[MUTE11_PARAM + i];
+ _cvs[i] = &inputs[CV11_INPUT + i];
+ }
+ setLocalElements({new Matrix44Element(_mutes, _cvs)});
+ setBaseModelPredicate([](Model* m) { return m == modelMatrix44; });
+ }
+ virtual ~Matrix44Cvm() {
+ delete[] _mutes;
+ delete[] _cvs;
+ }
+
+ void processAlways(const ProcessArgs& args) override;
+};
+
+} // namespace bogaudio
diff --git a/src/Matrix44_shared.hpp b/src/Matrix44_shared.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "matrix_base.hpp"
+#include "expanders.hpp"
+
+extern Model* modelMatrix44;
+extern Model* modelMatrix44Cvm;
+
+namespace bogaudio {
+
+typedef ChainableExpanderMessage Matrix44ExpanderMessage;
+
+struct Matrix44Element {
+ Param** mutes;
+ Input** cvs;
+
+ Matrix44Element(
+ Param** mutes,
+ Input** cvs
+ )
+ : mutes(mutes)
+ , cvs(cvs)
+ {}
+};
+
+typedef ChainableRegistry<Matrix44Element, 1> Matrix44Registry;
+
+} // namespace bogaudio
diff --git a/src/Pgmr.hpp b/src/Pgmr.hpp
@@ -69,7 +69,7 @@ struct Pgmr : PgmrBase {
int _lastSteps[maxChannels] {};
rack::dsp::PulseGenerator _allPulseGens[maxChannels];
- Pgmr() : PgmrBase(PgmrRegistry::registry()) {
+ Pgmr() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam(DIRECTION_PARAM, 0.0f, 1.0f, 1.0f, "Forward");
configParam(SELECT_ON_CLOCK_PARAM, 0.0f, 1.0f, 0.0f, "Select on clock");
diff --git a/src/PgmrX.hpp b/src/PgmrX.hpp
@@ -55,7 +55,7 @@ struct PgmrX : PgmrXBase, OutputRange {
NUM_LIGHTS
};
- PgmrX() : PgmrXBase(PgmrRegistry::registry()) {
+ PgmrX() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<OutputRangeParamQuantity>(CVA1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1A", " V");
configParam<OutputRangeParamQuantity>(CVB1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1B", " V");
diff --git a/src/Pgmr_shared.hpp b/src/Pgmr_shared.hpp
@@ -12,9 +12,7 @@ extern Model* modelPgmrX;
namespace bogaudio {
-struct PgmrExpanderMessage : ExpanderMessage {
- int baseID = -1;
- int position = -1;
+struct PgmrExpanderMessage : ChainableExpanderMessage {
float rangeOffset = 0.0f;
float rangeScale = 10.0f;
};
diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp
@@ -47,6 +47,7 @@
#include "Manual.hpp"
#include "Matrix18.hpp"
#include "Matrix44.hpp"
+#include "Matrix44Cvm.hpp"
#include "Matrix81.hpp"
#include "Matrix88.hpp"
#include "MegaGate.hpp"
@@ -188,6 +189,7 @@ void init(rack::Plugin *p) {
p->addModel(modelMatrix81);
p->addModel(modelMatrix18);
p->addModel(modelMatrix44);
+ p->addModel(modelMatrix44Cvm);
p->addModel(modelMatrix88);
p->addModel(modelSwitch81);
p->addModel(modelSwitch18);
diff --git a/src/expanders.hpp b/src/expanders.hpp
@@ -136,7 +136,10 @@ public:
void setElements(const std::vector<E*>& elements) {
std::lock_guard<SpinLock> lock(_elementsLock);
_elements = elements;
+ elementsChanged();
}
+
+ virtual void elementsChanged() {}
};
typedef Chainable ChainableExpander;
@@ -220,6 +223,11 @@ public:
}
};
+struct ChainableExpanderMessage : ExpanderMessage {
+ int baseID = -1;
+ int position = -1;
+};
+
template<class MESSAGE, class ELEMENT, int N, class BASE>
struct ChainableExpandableModule
: ExpandableModule<MESSAGE, BASE>
@@ -228,7 +236,9 @@ struct ChainableExpandableModule
ChainableRegistry<ELEMENT, N>& _registry;
int _id = -1;
- ChainableExpandableModule(ChainableRegistry<ELEMENT, N>& registry) : _registry(registry) {}
+ ChainableExpandableModule()
+ : _registry(ChainableRegistry<ELEMENT, N>::registry())
+ {}
virtual ~ChainableExpandableModule() {
_registry.deregisterBase(_id);
}
@@ -248,7 +258,9 @@ struct ChainableExpanderModule
int _baseID = -1;
int _position = -1;
- ChainableExpanderModule(ChainableRegistry<ELEMENT, N>& registry) : _registry(registry) {}
+ ChainableExpanderModule()
+ : _registry(ChainableRegistry<ELEMENT, N>::registry())
+ {}
virtual ~ChainableExpanderModule() {
_registry.deregisterExpander(_baseID, _position);
}
diff --git a/src/matrix_base.cpp b/src/matrix_base.cpp
@@ -41,6 +41,21 @@ void MatrixBaseModule::modulate() {
}
+void MatrixModule::configMatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID) {
+ assert(!_paramValues && !_sls && !_saturators && !_inActive);
+ _ins = ins;
+ _outs = outs;
+ _firstParamID = firstParamID;
+ _firstInputID = firstInputID;
+ _firstOutputID = firstOutputID;
+ assert(_ins <= maxN);
+ assert(_outs <= maxN);
+ _paramValues = new float[_ins * _outs] {};
+ _sls = new bogaudio::dsp::SlewLimiter[_ins * _outs];
+ _saturators = new Saturator[_outs * maxChannels];
+ _inActive = new bool[_ins] {};
+}
+
void MatrixModule::sampleRateChange() {
float sr = APP->engine->getSampleRate();
for (int i = 0, n = _ins * _outs; i < n; ++i) {
@@ -55,6 +70,16 @@ int MatrixModule::channels() {
void MatrixModule::modulate() {
MatrixBaseModule::modulate();
+ bool solo = false;
+ if (_muteParams) {
+ for (int i = 0, n = _ins * _outs; i < n; ++i) {
+ if (_muteParams[i]->getValue() > 1.5f) {
+ solo = true;
+ break;
+ }
+ }
+ }
+
int active = 0;
for (int i = 0; i < _ins; ++i) {
_inActive[i] = inputs[_firstInputID + i].isConnected();
@@ -64,7 +89,12 @@ void MatrixModule::modulate() {
for (int j = 0; j < _outs; ++j) {
int ii = j * _ins + i;
- _paramValues[ii] = _sls[ii].next(params[_firstParamID + ii].getValue());
+ float v = params[_firstParamID + ii].getValue();
+ if (_muteParams) {
+ bool muted = solo ? _muteParams[ii]->getValue() < 2.0f : _muteParams[ii]->getValue() > 0.5f;
+ v *= !muted;
+ }
+ _paramValues[ii] = _sls[ii].next(v);
}
}
@@ -86,7 +116,12 @@ void MatrixModule::processChannel(const ProcessArgs& args, int c) {
float out = 0.0f;
for (int j = 0; j < _ins; ++j) {
if (_inActive[j]) {
- out += in[j] * _paramValues[i * _ins + j];
+ int ii = i * _ins + j;
+ float cv = 1.0f;
+ if (_cvInputs && _cvInputs[ii]->isConnected()) {
+ cv = clamp(_cvInputs[ii]->getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+ out += in[j] * _paramValues[ii] * cv;
}
}
if (!_sum && _invActive > 0.0f) {
diff --git a/src/matrix_base.hpp b/src/matrix_base.hpp
@@ -30,11 +30,13 @@ struct MatrixBaseModuleWidget : BGModuleWidget {
struct MatrixModule : MatrixBaseModule {
static constexpr int maxN = 16;
- int _ins;
- int _outs;
- int _firstParamID;
- int _firstInputID;
- int _firstOutputID;
+ int _ins = 0;
+ int _outs = 0;
+ int _firstParamID = 0;
+ int _firstInputID = 0;
+ int _firstOutputID = 0;
+ Input** _cvInputs = NULL; // owned elsewhere.
+ Param** _muteParams = NULL; // owned elsewhere.
float* _paramValues = NULL;
bogaudio::dsp::SlewLimiter* _sls = NULL;
@@ -42,19 +44,9 @@ struct MatrixModule : MatrixBaseModule {
bool* _inActive = NULL;
float _invActive = 0.0f;
- MatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID)
- : _ins(ins)
- , _outs(outs)
- , _firstParamID(firstParamID)
- , _firstInputID(firstInputID)
- , _firstOutputID(firstOutputID)
- {
- assert(_ins <= maxN);
- assert(_outs <= maxN);
- _paramValues = new float[_ins * _outs] {};
- _sls = new bogaudio::dsp::SlewLimiter[_ins * _outs];
- _saturators = new Saturator[_outs * maxChannels];
- _inActive = new bool[_ins] {};
+ MatrixModule() {} // call configMatrixModule().
+ MatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID) {
+ configMatrixModule(ins, outs, firstParamID, firstInputID, firstOutputID);
}
virtual ~MatrixModule() {
delete[] _paramValues;
@@ -63,6 +55,9 @@ struct MatrixModule : MatrixBaseModule {
delete[] _inActive;
}
+ void configMatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID);
+ inline void setCVInputs(Input** cvs) { _cvInputs = cvs; }
+ inline void setMuteParams(Param** mutes) { _muteParams = mutes; }
void sampleRateChange() override;
int channels() override;
void modulate() override;
@@ -76,6 +71,7 @@ struct MatrixModuleWidget : MatrixBaseModuleWidget {
struct KnobMatrixModule : MatrixModule {
bool _indicatorKnobs = true;
+ KnobMatrixModule() {} // call configMatrixModule()
KnobMatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID)
: MatrixModule(ins, outs, firstParamID, firstInputID, firstOutputID)
{}