BogaudioModules

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

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:
Mplugin.json | 11+++++++++++
Ares-src/CmpDist-src.svg | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/CmpDist.svg | 0
Asrc/CmpDist.cpp | 197+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/CmpDist.hpp | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 2++
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);