BogaudioModules

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

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:
MREADME-prerelease.md | 8+++++++-
Mplugin.json | 11+++++++++++
Ares-pp/Matrix44Cvm-dark-pp.svg | 360+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares-pp/Matrix44Cvm-lowcontrast-pp.svg | 360+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares-pp/Matrix44Cvm-pp.svg | 296+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares-src/Matrix44Cvm-src.svg | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/Matrix44Cvm-dark.svg | 0
Ares/Matrix44Cvm-lowcontrast.svg | 0
Ares/Matrix44Cvm.svg | 0
Msrc/AddrSeq.hpp | 2+-
Msrc/AddrSeqX.hpp | 2+-
Msrc/AddrSeq_shared.hpp | 4+---
Msrc/Matrix44.cpp | 25+++++++++++++++++++++++++
Msrc/Matrix44.hpp | 19+++++++++++++------
Asrc/Matrix44Cvm.cpp | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Matrix44Cvm.hpp | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Matrix44_shared.hpp | 29+++++++++++++++++++++++++++++
Msrc/Pgmr.hpp | 2+-
Msrc/PgmrX.hpp | 2+-
Msrc/Pgmr_shared.hpp | 4+---
Msrc/bogaudio.cpp | 2++
Msrc/expanders.hpp | 16++++++++++++++--
Msrc/matrix_base.cpp | 39+++++++++++++++++++++++++++++++++++++--
Msrc/matrix_base.hpp | 32++++++++++++++------------------
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] = &params[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) {}