commit 6f7b9602b70a2673b1cb4273ea5f5b2505ea27e3
parent 233abf243323efd198b0db1a0e755618050f08f2
Author: Matt Demanett <matt@demanett.net>
Date: Sun, 19 Jul 2020 20:37:12 -0400
CMPDIST: comparator-based distorition. #123
Diffstat:
6 files changed, 566 insertions(+), 0 deletions(-)
diff --git a/plugin.json b/plugin.json
@@ -606,6 +606,17 @@
]
},
{
+ "slug": "Bogaudio-CmpDist",
+ "name": "CMPDIST",
+ "description": "Comparator-based distortion",
+ "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#cmpdist",
+ "tags": [
+ "Distortion",
+ "Effect",
+ "Polyphonic"
+ ]
+ },
+ {
"slug": "Bogaudio-OneEight",
"name": "1:8",
"description": "8-channel multiplexer & sequential switch",
diff --git a/res-src/CmpDist-src.svg b/res-src/CmpDist-src.svg
@@ -0,0 +1,272 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="150"
+ height="380"
+ viewBox="0 0 150 380"
+>
+ <style>
+ text {
+ fill: #333;
+ font-family: 'Roboto', sans-serif;
+ font-weight: bold;
+ }
+ text.title {
+ font-family: 'Comfortaa', sans-serif;
+ font-weight: normal;
+ }
+ text.brand {
+ font-family: 'Audiowide', sans-serif;
+ font-weight: bold;
+ }
+ </style>
+
+ <defs>
+ <symbol id="knob29" viewBox="0 0 45px 45px">
+ <g transform="translate(22.5 22.5)">
+ <polyline points="-5,0 5,0" stroke-width="1" stroke="#00f" />
+ <polyline points="0,-5 0,5" stroke-width="1" stroke="#00f" />
+ <circle cx="0" cy="0" r="14" stroke-width="1" stroke="#00f" fill="none" />
+ </g>
+ </symbol>
+
+ <symbol id="knob-smallest" viewBox="0 0 16px 16px">
+ <g transform="translate(8 8)">
+ <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f" />
+ <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f" />
+ <circle r="7.5" stroke-width="1" stroke="#00f" fill="none" />
+ </g>
+ </symbol>
+
+ <symbol id="knobguide-attenuverter" viewBox="0 0 45px 45px">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="7pt" transform="rotate(-240) translate(20 0) rotate(240) translate(-1.2 2.2)">-</text>
+
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-225) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-210) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-195) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-180) translate(17 0)" />
+ <polyline points="0,0 3.5,0" stroke-width="1" stroke="#333" transform="rotate(-165) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-150) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-135) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-120) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-105) translate(17 0)" />
+
+ <text font-size="5pt" transform="rotate(-90) translate(20 0) rotate(90) translate(-1.9 3)">0</text>
+
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-75) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-60) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-45) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-30) translate(17 0)" />
+ <polyline points="0,0 3.5,0" stroke-width="1" stroke="#333" transform="rotate(-15) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(0) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(15) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(30) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(45) translate(17 0)" />
+
+ <text font-size="5pt" transform="rotate(60) translate(20 0) rotate(-60) translate(-2 2)">+</text>
+ </g>
+ </symbol>
+
+ <symbol id="knobguide-window" viewBox="0 0 45px 45px">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="5.0pt" transform="rotate(-240) translate(20 0) rotate(240) translate(-1.9 2.2)">0</text>
+
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-210) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-180) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-150) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-120) translate(17 0)" />
+
+ <polyline points="0,0 3.5,0" stroke-width="1" stroke="#333" transform="rotate(-90) translate(17 0)" />
+
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-60) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-30) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(0) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(30) translate(17 0)" />
+
+ <text font-size="5.0pt" transform="rotate(60) translate(20 0) rotate(-60) translate(-4 2.2)">10</text>
+ </g>
+ </symbol>
+
+ <symbol id="knobguide-drywet29" viewBox="0 0 45px 45px">
+ <g transform="translate(22.5 22.5)">
+ <text font-size="5pt" transform="rotate(-240) translate(20 0) rotate(240) translate(-2.5 3)">D</text>
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-210) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-180) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-150) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-120) translate(17 0)" />
+ <polyline points="0,0 4.5,0" stroke-width="1" stroke="#333" transform="rotate(-90) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-60) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-30) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(0) translate(17 0)" />
+ <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(30) translate(17 0)" />
+ <text font-size="5pt" transform="rotate(60) translate(20 0) rotate(-60) translate(-2 3)">W</text>
+ </g>
+ </symbol>
+
+ <symbol id="knobguide-mintick" viewBox="0 0 40px 40px">
+ <g transform="translate(20 20)">
+ <g transform="rotate(-240) translate(10 0)">
+ <polyline points="0,0 4,0" stroke-width="1" stroke="#333" />
+ </g>
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(0)" />
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 1 12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(43)" />
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(0)" />
+ <path d="M 0 -12.5 A 12.5 12.5 0 0 0 -12.5 0" stroke="#333" stroke-width="0.5" stroke-linecap="round" fill="none" transform="rotate(-43)" />
+ </g>
+ </symbol>
+
+ <symbol id="input" viewBox="0 0 24px 24px">
+ <g transform="translate(12 12)">
+ <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#0f0" fill="#0f0" />
+ <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#0f0" fill="none" />
+ </g>
+ </symbol>
+
+ <symbol id="output" viewBox="0 0 24px 24px">
+ <g transform="translate(12 12)">
+ <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#f00" fill="#f00" />
+ <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#f00" fill="none" />
+ </g>
+ </symbol>
+ </defs>
+
+ <rect width="100%" height="100%" fill="#ddd" />
+ <polyline points="1,1 149,1 149,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" />
+ <polyline points="0.5,0.5 149.5,0.5 149.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" />
+ <polyline points="0,0 150,0 150,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" />
+
+ <!-- <rect width="30" height="20" fill="#0f0" transform="translate(0 0)" /> -->
+ <!-- <rect width="30" height="20" fill="#0f0" transform="translate(120 0)" /> -->
+ <text class="title" x="26" y="19" font-size="12pt" letter-spacing="3.5px">CMPDIST</text>
+ <g transform="translate(35.5 374)">
+ <text class="brand" font-size="8pt" letter-spacing="2px">BOGAUDIO</text>
+ <rect width="3.0" height="3" fill="#ddd" transform="translate(24 -5)" />
+ </g>
+
+ <!-- <rect width="150" height="14" fill="#0f0" transform="translate(0 80)" /> -->
+ <!-- <rect width="150" height="14" fill="#0f0" transform="translate(0 145)" /> -->
+ <!-- <rect width="150" height="14" fill="#0f0" transform="translate(0 211)" /> -->
+
+ <g transform="translate(6 35)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(3.5 0)">A SCALE</text>
+ <use id="A_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-attenuverter" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(52.5 35)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(4 0)">WINDOW</text>
+ <use id="WINDOW_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-window" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(99 35)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(3.5 0)">B SCALE</text>
+ <use id="B_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-attenuverter" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(6 100)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(6.5 0)">GT MIX</text>
+ <use id="GT_MIX_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-attenuverter" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(52.5 100)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(6.5 0)">EQ MIX</text>
+ <use id="EQ_MIX_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-attenuverter" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(99 100)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(7 0)">LT MIX</text>
+ <use id="LT_MIX_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-attenuverter" transform="translate(0 3)" />
+ </g>
+
+ <!-- <polyline points="0,0 0,350" stroke="#0f0" stroke-width="1" fill="none" transform="translate(28.5 0)" /> -->
+ <!-- <polyline points="0,0 0,350" stroke="#0f0" stroke-width="1" fill="none" transform="translate(121.5 0)" /> -->
+ <!-- <polyline points="0,0 150,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(0 190.5)" /> -->
+
+ <g transform="translate(52.5 165)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(2.5 0)">DRY/WET</text>
+ <use id="DRY_WET_PARAM" xlink:href="#knob29" transform="translate(0 3)" />
+ <use xlink:href="#knobguide-drywet29" transform="translate(0 3)" />
+ </g>
+
+ <g transform="translate(20.5 182.5)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(-6 -9)">A DRY</text>
+ <use id="A_DRY_PARAM" xlink:href="#knob-smallest" transform="translate(0 0)" />
+ <use xlink:href="#knobguide-mintick" transform="translate(-12.5 -12)" />
+ </g>
+
+ <g transform="translate(113.5 182.5)">
+ <text font-size="6pt" letter-spacing="1px" transform="translate(-6 -9)">B DRY</text>
+ <use id="B_DRY_PARAM" xlink:href="#knob-smallest" transform="translate(0 0)" />
+ <use xlink:href="#knobguide-mintick" transform="translate(-12.5 -12)" />
+ </g>
+
+ <g transform="translate(0 225)">
+ <rect width="130" height="135" rx="5" fill="#fafafa" transform="translate(10 0)" />
+ <rect width="65" height="91" rx="5" fill="#bbb" transform="translate(75 44)" />
+ <rect width="10" height="8" fill="#bbb" transform="translate(75 44)" />
+ <rect width="10" height="8" fill="#bbb" transform="translate(130 44)" />
+ <rect width="10" height="8" fill="#bbb" transform="translate(75 127)" />
+
+ <g transform="translate(12 0)">
+ <use id="GT_MIX_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(5 40)">GTM</text>
+ </g>
+ <g transform="translate(44 0)">
+ <use id="LT_MIX_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(6 40)">LTM</text>
+ </g>
+ <g transform="translate(76 0)">
+ <use id="WINDOW_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="0.5px" transform="translate(1.5 40)">WNDW</text>
+ </g>
+ <g transform="translate(108 0)">
+ <use id="DRY_WET_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(6 40)">D/W</text>
+ </g>
+
+ <g transform="translate(0 44)">
+ <g transform="translate(12 0)">
+ <use id="A_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(5 40)">A IN</text>
+ </g>
+ <g transform="translate(44 0)">
+ <use id="A_SCALE_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(1.5 40)">A SCL</text>
+ </g>
+ <g transform="translate(76 0)">
+ <use id="GT_OUTPUT" xlink:href="#output" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="2px" transform="translate(8 40)">GT</text>
+ </g>
+ <g transform="translate(108 0)">
+ <use id="LT_OUTPUT" xlink:href="#output" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="2px" transform="translate(9.5 40)">LT</text>
+ </g>
+
+ <g transform="translate(10 44)">
+ <g transform="translate(2 0)">
+ <use id="B_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(5 40)">B IN</text>
+ </g>
+ <g transform="translate(34 0)">
+ <use id="B_SCALE_INPUT" xlink:href="#input" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(1.5 40)">B SCL</text>
+ </g>
+ <g transform="translate(66 0)">
+ <use id="EQ_OUTPUT" xlink:href="#output" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="2px" transform="translate(9 40)">EQ</text>
+ </g>
+ <g transform="translate(98 0)">
+ <use id="MIX_OUTPUT" xlink:href="#output" transform="translate(3 5)" />
+ <text font-size="6pt" letter-spacing="2px" transform="translate(6 40)">MIX</text>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/res/CmpDist.svg b/res/CmpDist.svg
Binary files differ.
diff --git a/src/CmpDist.cpp b/src/CmpDist.cpp
@@ -0,0 +1,197 @@
+
+#include "CmpDist.hpp"
+
+bool CmpDist::active() {
+ return (
+ outputs[MIX_OUTPUT].isConnected() ||
+ outputs[GT_OUTPUT].isConnected() ||
+ outputs[EQ_OUTPUT].isConnected() ||
+ outputs[LT_OUTPUT].isConnected()
+ );
+}
+
+int CmpDist::channels() {
+ return inputs[A_INPUT].getChannels();
+}
+
+void CmpDist::addChannel(int c) {
+ _engines[c] = new Engine();
+}
+
+void CmpDist::removeChannel(int c) {
+ delete _engines[c];
+ _engines[c] = NULL;
+}
+
+void CmpDist::modulate() {
+ float aLevel = clamp(params[A_DRY_PARAM].getValue(), 0.0f, 1.0f);
+ aLevel = 1.0f - aLevel;
+ aLevel *= Amplifier::minDecibels;
+ _aDryAmplifier.setLevel(aLevel);
+
+ float bLevel = clamp(params[B_DRY_PARAM].getValue(), 0.0f, 1.0f);
+ bLevel = 1.0f - bLevel;
+ bLevel *= Amplifier::minDecibels;
+ _bDryAmplifier.setLevel(bLevel);
+}
+
+void CmpDist::modulateChannel(int c) {
+ Engine& e = *_engines[c];
+
+ e.aScale = clamp(params[A_PARAM].getValue(), -1.0f, 1.0f);
+ if (inputs[A_SCALE_INPUT].isConnected()) {
+ e.aScale *= clamp(inputs[A_SCALE_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+ e.bScale = clamp(params[B_PARAM].getValue(), -1.0f, 1.0f);
+ if (inputs[B_SCALE_INPUT].isConnected()) {
+ e.bScale *= clamp(inputs[B_SCALE_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+
+ e.window = clamp(params[WINDOW_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[WINDOW_INPUT].isConnected()) {
+ e.window *= clamp(inputs[WINDOW_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f);
+ }
+ e.window *= 10.0f;
+
+ e.gtMix = clamp(params[GT_MIX_PARAM].getValue(), -1.0f, 1.0f);
+ if (inputs[GT_MIX_INPUT].isConnected()) {
+ e.gtMix *= clamp(inputs[GT_MIX_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+ e.eqMix = clamp(params[EQ_MIX_PARAM].getValue(), -1.0f, 1.0f);
+ e.ltMix = clamp(params[LT_MIX_PARAM].getValue(), -1.0f, 1.0f);
+ if (inputs[LT_MIX_INPUT].isConnected()) {
+ e.ltMix *= clamp(inputs[LT_MIX_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+
+ float dw = clamp(params[DRY_WET_PARAM].getValue(), -1.0f, 1.0f);
+ if (inputs[DRY_WET_INPUT].isConnected()) {
+ e.ltMix *= clamp(inputs[DRY_WET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
+ }
+ e.dryWet.setParams(dw, 0.9f, false);
+}
+
+void CmpDist::processAlways(const ProcessArgs& args) {
+ outputs[GT_OUTPUT].setChannels(_channels);
+ outputs[EQ_OUTPUT].setChannels(_channels);
+ outputs[LT_OUTPUT].setChannels(_channels);
+ outputs[MIX_OUTPUT].setChannels(_channels);
+}
+
+void CmpDist::processChannel(const ProcessArgs& args, int c) {
+ const float v = 5.0f;
+ Engine& e = *_engines[c];
+
+ float a = v;
+ if (inputs[A_INPUT].isConnected()) {
+ a = inputs[A_INPUT].getPolyVoltage(c);
+ }
+ a *= e.aScale;
+ float b = v;
+ if (inputs[B_INPUT].isConnected()) {
+ b = inputs[B_INPUT].getPolyVoltage(c);
+ }
+ b *= e.bScale;
+
+ float gt = 0.0f;
+ float eq = 0.0f;
+ float lt = 0.0f;
+ if (fabsf(a - b) <= e.window) {
+ gt = -v;
+ eq = v;
+ lt = -v;
+ }
+ else if (a > b) {
+ gt = v;
+ eq = -v;
+ lt = -v;
+ }
+ else {
+ gt = -v;
+ eq = -v;
+ lt = v;
+ }
+ lt = -lt;
+
+ float dry = _aDryAmplifier.next(a) + _bDryAmplifier.next(b);
+ float wet = e.gtMix*gt + e.eqMix*eq + e.ltMix*lt;
+ float mix = e.dryWet.next(dry, wet);
+ outputs[GT_OUTPUT].setVoltage(gt, c);
+ outputs[EQ_OUTPUT].setVoltage(eq, c);
+ outputs[LT_OUTPUT].setVoltage(lt, c);
+ outputs[MIX_OUTPUT].setVoltage(mix, c);
+}
+
+struct CmpDistWidget : ModuleWidget {
+ static constexpr int hp = 10;
+
+ CmpDistWidget(CmpDist* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+
+ {
+ SvgPanel *panel = new SvgPanel();
+ panel->box.size = box.size;
+ panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CmpDist.svg")));
+ addChild(panel);
+ }
+
+ addChild(createWidget<ScrewSilver>(Vec(0, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(0, 365)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365)));
+
+ // generated by svg_widgets.rb
+ auto aParamPosition = Vec(14.0, 46.0);
+ auto windowParamPosition = Vec(60.5, 46.0);
+ auto bParamPosition = Vec(107.0, 46.0);
+ auto gtMixParamPosition = Vec(14.0, 111.0);
+ auto eqMixParamPosition = Vec(60.5, 111.0);
+ auto ltMixParamPosition = Vec(107.0, 111.0);
+ auto dryWetParamPosition = Vec(60.5, 176.0);
+ auto aDryParamPosition = Vec(20.5, 182.5);
+ auto bDryParamPosition = Vec(113.5, 182.5);
+
+ auto gtMixInputPosition = Vec(15.0, 230.0);
+ auto ltMixInputPosition = Vec(47.0, 230.0);
+ auto windowInputPosition = Vec(79.0, 230.0);
+ auto dryWetInputPosition = Vec(111.0, 230.0);
+ auto aInputPosition = Vec(15.0, 274.0);
+ auto aScaleInputPosition = Vec(47.0, 274.0);
+ auto bInputPosition = Vec(15.0, 318.0);
+ auto bScaleInputPosition = Vec(47.0, 318.0);
+
+ auto ltMixOutputPosition = Vec(79.0, 230.0);
+ auto gtOutputPosition = Vec(79.0, 274.0);
+ auto ltOutputPosition = Vec(111.0, 274.0);
+ auto eqOutputPosition = Vec(79.0, 318.0);
+ auto mixOutputPosition = Vec(111.0, 318.0);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<Knob29>(aParamPosition, module, CmpDist::A_PARAM));
+ addParam(createParam<Knob29>(windowParamPosition, module, CmpDist::WINDOW_PARAM));
+ addParam(createParam<Knob29>(bParamPosition, module, CmpDist::B_PARAM));
+ addParam(createParam<Knob29>(gtMixParamPosition, module, CmpDist::GT_MIX_PARAM));
+ addParam(createParam<Knob29>(eqMixParamPosition, module, CmpDist::EQ_MIX_PARAM));
+ addParam(createParam<Knob29>(ltMixParamPosition, module, CmpDist::LT_MIX_PARAM));
+ addParam(createParam<Knob29>(dryWetParamPosition, module, CmpDist::DRY_WET_PARAM));
+ addParam(createParam<Knob16>(aDryParamPosition, module, CmpDist::A_DRY_PARAM));
+ addParam(createParam<Knob16>(bDryParamPosition, module, CmpDist::B_DRY_PARAM));
+
+ addInput(createInput<Port24>(gtMixInputPosition, module, CmpDist::GT_MIX_INPUT));
+ addInput(createInput<Port24>(ltMixInputPosition, module, CmpDist::LT_MIX_INPUT));
+ addInput(createInput<Port24>(windowInputPosition, module, CmpDist::WINDOW_INPUT));
+ addInput(createInput<Port24>(dryWetInputPosition, module, CmpDist::DRY_WET_INPUT));
+ addInput(createInput<Port24>(aInputPosition, module, CmpDist::A_INPUT));
+ addInput(createInput<Port24>(aScaleInputPosition, module, CmpDist::A_SCALE_INPUT));
+ addInput(createInput<Port24>(bInputPosition, module, CmpDist::B_INPUT));
+ addInput(createInput<Port24>(bScaleInputPosition, module, CmpDist::B_SCALE_INPUT));
+
+ addOutput(createOutput<Port24>(ltMixOutputPosition, module, CmpDist::LT_MIX_OUTPUT));
+ addOutput(createOutput<Port24>(gtOutputPosition, module, CmpDist::GT_OUTPUT));
+ addOutput(createOutput<Port24>(ltOutputPosition, module, CmpDist::LT_OUTPUT));
+ addOutput(createOutput<Port24>(eqOutputPosition, module, CmpDist::EQ_OUTPUT));
+ addOutput(createOutput<Port24>(mixOutputPosition, module, CmpDist::MIX_OUTPUT));
+ }
+};
+
+Model* modelCmpDist = createModel<CmpDist, CmpDistWidget>("Bogaudio-CmpDist", "CMPDIST", "Comparator-based distortion", "Distortion", "Effect", "Polyphonic");
diff --git a/src/CmpDist.hpp b/src/CmpDist.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+extern Model* modelCmpDist;
+
+using namespace bogaudio::dsp;
+
+namespace bogaudio {
+
+struct CmpDist : BGModule {
+ enum ParamsIds {
+ A_PARAM,
+ WINDOW_PARAM,
+ B_PARAM,
+ GT_MIX_PARAM,
+ EQ_MIX_PARAM,
+ LT_MIX_PARAM,
+ DRY_WET_PARAM,
+ A_DRY_PARAM,
+ B_DRY_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ GT_MIX_INPUT,
+ LT_MIX_INPUT,
+ WINDOW_INPUT,
+ DRY_WET_INPUT,
+ A_INPUT,
+ A_SCALE_INPUT,
+ B_INPUT,
+ B_SCALE_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ LT_MIX_OUTPUT,
+ GT_OUTPUT,
+ LT_OUTPUT,
+ EQ_OUTPUT,
+ MIX_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ struct Engine {
+ float aScale = 0.0f;
+ float bScale = 0.0f;
+ float window = 0.0f;
+ float gtMix = 0.0f;
+ float eqMix = 0.0f;
+ float ltMix = 0.0f;
+ CrossFader dryWet;
+ };
+
+ Engine* _engines[maxChannels] {};
+ Amplifier _aDryAmplifier;
+ Amplifier _bDryAmplifier;
+
+ CmpDist() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configParam(A_PARAM, -1.0f, 1.0f, 1.0f, "A scaling", "%", 0.0f, 100.0f);
+ configParam(WINDOW_PARAM, 0.0f, 1.0f, 0.25f, "Window", " V", 0.0f, 10.0f);
+ configParam(B_PARAM, -1.0f, 1.0f, 0.0f, "B scaling", "%", 0.0f, 100.0f);
+ configParam(GT_MIX_PARAM, -1.0f, 1.0f, 1.0f, "Greater-than mix", "%", 0.0f, 100.0f);
+ configParam(EQ_MIX_PARAM, -1.0f, 1.0f, 0.0f, "Equal mix", "%", 0.0f, 100.0f);
+ configParam(LT_MIX_PARAM, -1.0f, 1.0f, 1.0f, "Less-than mix", "%", 0.0f, 100.0f);
+ configParam(DRY_WET_PARAM, -1.0f, 1.0f, 0.0f, "Dry/wet mix", "%", 0.0f, 100.0f);
+ configParam<AmplifierParamQuantity>(A_DRY_PARAM, 0.0f, 1.0f, 1.0f, "A dry level");
+ configParam<AmplifierParamQuantity>(B_DRY_PARAM, 0.0f, 1.0f, 1.0f, "B dry level");
+ }
+
+ bool active() override;
+ int channels() override;
+ void addChannel(int c) override;
+ void removeChannel(int c) override;
+ void modulate() override;
+ void modulateChannel(int c) override;
+ void processAlways(const ProcessArgs& args) override;
+ void processChannel(const ProcessArgs& args, int c) override;
+};
+
+} // namespace bogaudio
diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp
@@ -16,6 +16,7 @@
#include "Bool.hpp"
#include "Clpr.hpp"
#include "Cmp.hpp"
+#include "CmpDist.hpp"
#include "CVD.hpp"
#include "DADSRH.hpp"
#include "DADSRHPlus.hpp"
@@ -175,6 +176,7 @@ void init(rack::Plugin *p) {
p->addModel(modelClpr);
p->addModel(modelLmtr);
p->addModel(modelNsgt);
+ p->addModel(modelCmpDist);
p->addModel(modelOneEight);
p->addModel(modelEightOne);