BogaudioModules

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

commit 4d22573c18ac69771ff4a3bb8123807b8aceab2a
parent 18552e82e450ddd6699214de3468a8f7537c8927
Author: Matt Demanett <matt@demanett.net>
Date:   Wed,  8 Jul 2020 15:18:41 -0400

Change around PEQ6 and PEQ14 such that the base module has band outputs, while EF outputs are moved to an expander; lesh out PEQ14XV; shelve PEQ14XR for now.

Diffstat:
Mplugin.json | 28++++++++--------------------
Mres-src/PEQ14-src.svg | 82+++++++++++++++++++++++++++++++++++--------------------------------------------
Ares-src/PEQ14XF-src.svg | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dres-src/PEQ14XO-src.svg | 89-------------------------------------------------------------------------------
Mres-src/PEQ14XR-src.svg | 49++++++++++++++++++++++++++++++++++++++++++++++++-
Mres-src/PEQ14XV-src.svg | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mres-src/PEQ6-src.svg | 60++++++++++++++++++++++++++++--------------------------------
Ares-src/PEQ6XF-src.svg | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dres-src/PEQ6XO-src.svg | 63---------------------------------------------------------------
Mres/PEQ14.svg | 0
Ares/PEQ14XF.svg | 0
Dres/PEQ14XO.svg | 0
Mres/PEQ14XR.svg | 0
Mres/PEQ14XV.svg | 0
Mres/PEQ6.svg | 0
Ares/PEQ6XF.svg | 0
Dres/PEQ6XO.svg | 0
Msrc/PEQ14.cpp | 114+++++++++++++++++++++++++++----------------------------------------------------
Msrc/PEQ14.hpp | 36+++++++++++++++---------------------
Asrc/PEQ14XF.cpp | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PEQ14XF.hpp | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/PEQ14XO.cpp | 85-------------------------------------------------------------------------------
Dsrc/PEQ14XO.hpp | 44--------------------------------------------
Msrc/PEQ14XR.cpp | 54++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/PEQ14XR.hpp | 16+++++++++++++---
Msrc/PEQ14XV.cpp | 139++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/PEQ14XV.hpp | 46+++++++++++++++++++++++++++++++++++++++-------
Msrc/PEQ14_shared.hpp | 5+----
Msrc/PEQ6.cpp | 79++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/PEQ6.hpp | 19++++++++-----------
Asrc/PEQ6XF.cpp | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PEQ6XF.hpp | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/PEQ6XO.cpp | 59-----------------------------------------------------------
Dsrc/PEQ6XO.hpp | 35-----------------------------------
Msrc/PEQ6_shared.hpp | 12++++--------
Msrc/bogaudio.cpp | 10+++++-----
Msrc/parametric_eq.cpp | 12++++++++++++
Msrc/parametric_eq.hpp | 9+++++++++
38 files changed, 1242 insertions(+), 680 deletions(-)

diff --git a/plugin.json b/plugin.json @@ -184,10 +184,10 @@ ] }, { - "slug": "Bogaudio-PEQ6XO", - "name": "PEQ6XO", - "description": "PEQ6 band outputs expander", - "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#peq6xo", + "slug": "Bogaudio-PEQ6XF", + "name": "PEQ6XF", + "description": "PEQ6 envelope followers expander", + "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#peq6xf", "tags": [ "Filter", "Expander", @@ -206,10 +206,10 @@ ] }, { - "slug": "Bogaudio-PEQ14XO", - "name": "PEQ14XO", - "description": "PEQ14 band outputs expander", - "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#peq14xo", + "slug": "Bogaudio-PEQ14XF", + "name": "PEQ14XF", + "description": "PEQ14 envelope followers expander", + "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#peq14xf", "tags": [ "Filter", "Expander", @@ -229,18 +229,6 @@ ] }, { - "slug": "Bogaudio-PEQ14XR", - "name": "PEQ14XR", - "description": "PEQ14 resynthesizer expander", - "manualUrl": "https://github.com/bogaudio/BogaudioModules/blob/master/README.md#peq14xr", - "tags": [ - "Filter", - "Vocoder", - "Expander", - "Polyphonic" - ] - }, - { "slug": "Bogaudio-DADSRH", "name": "DADSR(H)", "description": "Advanced envelope generator", diff --git a/res-src/PEQ14-src.svg b/res-src/PEQ14-src.svg @@ -153,46 +153,36 @@ <rect width="3.0" height="3" fill="#ddd" transform="translate(24 -5)" /> </g> - <g transform="translate(6.5 30)"> - <!-- <rect width="62" height="40" fill="#f0f" transform="translate(0 0)" /> --> - <use id="EF_RESPONSE_PARAM" xlink:href="#knob-smallest" transform="translate(40.5 8)" /> - <use xlink:href="#knobguide-mintick" transform="translate(28.5 -4)" /> - <text font-size="5pt" letter-spacing="1px" transform="translate(34.5 36)">EF-RSP</text> - <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(0 5)" /> - <use id="EF_RESPONSE_INPUT" xlink:href="#input" transform="translate(3 8)" /> - <!-- <rect width="62" height="17" fill="#0f0" transform="translate(0 40)" /> --> - </g> - - <g transform="translate(6.5 85.5)"> + <g transform="translate(6.5 48)"> <!-- <rect width="62" height="40" fill="#f0f" transform="translate(0 0)" /> --> <use id="FREQUENCY_CV_PARAM" xlink:href="#knob-smallest" transform="translate(40.5 11)" /> <use xlink:href="#knobguide-centertick" transform="translate(28.5 -1)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(40 37)">FCV</text> <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(0 5)" /> <use id="FREQUENCY_CV_INPUT" xlink:href="#input" transform="translate(3 8)" /> - <!-- <rect width="62" height="17" fill="#0f0" transform="translate(0 40)" /> --> + <!-- <rect width="62" height="25" fill="#0f0" transform="translate(0 40)" /> --> </g> - <g transform="translate(6.5 141.5)"> + <g transform="translate(6.5 113)"> <!-- <rect width="62" height="40" fill="#f0f" transform="translate(0 0)" /> --> <use id="BANDWIDTH_PARAM" xlink:href="#knob-smallest" transform="translate(40.5 8)" /> <use xlink:href="#knobguide-mintick" transform="translate(28.5 -4)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(42.5 37)">BW</text> <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(0 5)" /> <use id="BANDWIDTH_INPUT" xlink:href="#input" transform="translate(3 8)" /> - <!-- <rect width="62" height="17" fill="#0f0" transform="translate(0 40)" /> --> + <!-- <rect width="62" height="25" fill="#0f0" transform="translate(0 40)" /> --> </g> - <g transform="translate(17.5 197)"> + <g transform="translate(17.5 179)"> <!-- <rect width="40" height="23" fill="#f0f" transform="translate(0 0)" /> --> <text font-size="5pt" letter-spacing="1px" transform="translate(0 8.5)">CH1-LP</text> <use id="LP_PARAM" xlink:href="#button-small" transform="translate(31 1)" /> <text font-size="5pt" letter-spacing="0.5px" transform="translate(-3 20.5)">CH14-HP</text> <use id="HP_PARAM" xlink:href="#button-small" transform="translate(31 13)" /> - <!-- <rect width="62" height="17" fill="#0f0" transform="translate(0 23)" /> --> + <!-- <rect width="62" height="25" fill="#0f0" transform="translate(0 23)" /> --> </g> - <g transform="translate(18.5 235.5)"> + <g transform="translate(18.5 227)"> <!-- <rect width="38" height="35" fill="#f0f" transform="translate(0 0)" /> --> <text font-size="5pt" letter-spacing="1px" transform="translate(5 34.5) rotate(-90)">FCV RNG</text> <use id="FMOD_RELATIVE_LIGHT" xlink:href="#light-small" transform="translate(10 1)" /> @@ -200,7 +190,7 @@ <use id="FMOD_FULL_LIGHT" xlink:href="#light-small" transform="translate(10 14)" /> <text font-size="5pt" letter-spacing="0.5px" transform="translate(18.5 19.7)">FULL</text> <use id="FMOD_PARAM" xlink:href="#button-small" transform="translate(14 25)" /> - <!-- <rect width="62" height="17" fill="#0f0" transform="translate(0 35)" /> --> + <!-- <rect width="62" height="25" fill="#0f0" transform="translate(0 35)" /> --> </g> <g transform="translate(5.5 287)"> @@ -236,8 +226,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV1_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF1_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT1_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -259,8 +249,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV2_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF2_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT2_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -282,8 +272,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV3_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -305,8 +295,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV4_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF4_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT4_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -328,8 +318,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV5_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF5_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT5_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -351,8 +341,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV6_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF6_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT6_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -374,8 +364,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV7_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF7_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT7_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -397,8 +387,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV8_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF8_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT8_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -420,8 +410,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV9_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF9_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT9_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -443,8 +433,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV10_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF10_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT10_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -466,8 +456,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV11_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF11_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT11_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -489,8 +479,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV12_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF12_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT12_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -512,8 +502,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV13_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF13_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT13_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -535,8 +525,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV14_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF14_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT14_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> </svg> diff --git a/res-src/PEQ14XF-src.svg b/res-src/PEQ14XF-src.svg @@ -0,0 +1,140 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="75" + height="380" + viewBox="0 0 75 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="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-centertick" viewBox="0 0 40px 40px"> + <g transform="translate(20 20)"> + <g transform="rotate(-90) 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(20)" /> + <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(-20)" /> + <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="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 74,1 74,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 74.5,0.5 74.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 75,0 75,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <text class="title" x="20" y="14" font-size="7pt" letter-spacing="1px">PEQ14XF</text> + <g transform="translate(25 374)"> + <text class="brand" font-size="6.5pt" letter-spacing="2px">BGA</text> + <rect width="2" height="2" fill="#ddd" transform="translate(11.5 -4)" /> + </g> + + <g transform="translate(-2.5 24)"> + <use id="DAMP_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-mintick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 33)">DAMP</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="DAMP_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + </g> + + <g transform="translate(32.5 23.5)"> + <use id="GAIN_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(11.5 33)">GAIN</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="GAIN_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + </g> + + <g transform="translate(5.5 108)"> + <rect width="64" height="260" rx="5" fill="#bbb" transform="translate(0 -10)" /> + + <text font-size="5pt" letter-spacing="2px" transform="translate(27 0)">EF</text> + <use id="EF1_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">1</text> + <use id="EF2_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">2</text> + <use id="EF3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 105)">3</text> + <use id="EF4_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 140)">4</text> + <use id="EF5_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 175)">5</text> + <use id="EF6_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 210)">6</text> + <use id="EF7_OUTPUT" xlink:href="#output" transform="translate(5 213)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 245)">7</text> + + <g transform="translate(31 0)"> + <use id="EF8_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">8</text> + <use id="EF9_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">9</text> + <use id="EF10_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">10</text> + <use id="EF11_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 140)">11</text> + <use id="EF12_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 175)">12</text> + <use id="EF13_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 210)">13</text> + <use id="EF14_OUTPUT" xlink:href="#output" transform="translate(5 213)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 245)">14</text> + </g> + </g> + + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(18.75 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(37.5 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(56.25 0)" /> --> +</svg> diff --git a/res-src/PEQ14XO-src.svg b/res-src/PEQ14XO-src.svg @@ -1,89 +0,0 @@ -<svg - version="1.1" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - width="75" - height="380" - viewBox="0 0 75 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="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 74,1 74,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> - <polyline points="0.5,0.5 74.5,0.5 74.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> - <polyline points="0,0 75,0 75,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> - - <text class="title" x="20" y="14" font-size="7pt" letter-spacing="1px">PEQ14XO</text> - <!-- <text class="title" x="15" y="17" font-size="9pt" letter-spacing="3px" transform="translate(75 -8) rotate(90)">PEQ14-XO</text> --> - <g transform="translate(25 374)"> - <text class="brand" font-size="6.5pt" letter-spacing="2px">BGA</text> - <rect width="2" height="2" fill="#ddd" transform="translate(11.5 -4)" /> - </g> - - <g transform="translate(5.5 40)"> - <rect width="64" height="260" rx="5" fill="#bbb" transform="translate(0 -10)" /> - - <text font-size="5pt" letter-spacing="2px" transform="translate(6 0)">BAND OUTS</text> - <use id="BAND1_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">1</text> - <use id="BAND2_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">2</text> - <use id="BAND3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 105)">3</text> - <use id="BAND4_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 140)">4</text> - <use id="BAND5_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 175)">5</text> - <use id="BAND6_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 210)">6</text> - <use id="BAND7_OUTPUT" xlink:href="#output" transform="translate(5 213)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 245)">7</text> - - <g transform="translate(31 0)"> - <use id="BAND8_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">8</text> - <use id="BAND9_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">9</text> - <use id="BAND10_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 105)">10</text> - <use id="BAND11_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 140)">11</text> - <use id="BAND12_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 175)">12</text> - <use id="BAND13_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 210)">13</text> - <use id="BAND14_OUTPUT" xlink:href="#output" transform="translate(5 213)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 245)">14</text> - </g> - </g> -</svg> diff --git a/res-src/PEQ14XR-src.svg b/res-src/PEQ14XR-src.svg @@ -23,6 +23,38 @@ </style> <defs> + <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-centertick" viewBox="0 0 40px 40px"> + <g transform="translate(20 20)"> + <g transform="rotate(-90) 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(20)" /> + <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(-20)" /> + <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="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" /> @@ -44,12 +76,27 @@ <polyline points="0,0 75,0 75,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> <text class="title" x="20" y="14" font-size="7pt" letter-spacing="1px">PEQ14XR</text> - <!-- <text class="title" x="15" y="17" font-size="9pt" letter-spacing="3px" transform="translate(75 -8) rotate(90)">PEQ14-XO</text> --> <g transform="translate(25 374)"> <text class="brand" font-size="6.5pt" letter-spacing="2px">BGA</text> <rect width="2" height="2" fill="#ddd" transform="translate(11.5 -4)" /> </g> + <g transform="translate(-2.5 24)"> + <use id="DAMP_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-mintick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 33)">DAMP</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="DAMP_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + </g> + + <g transform="translate(32.5 23.5)"> + <use id="GAIN_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(11.5 33)">GAIN</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="GAIN_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + </g> + <g transform="translate(20.5 318)"> <rect width="34" height="42" rx="5" fill="#bbb" /> <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 4)" /> diff --git a/res-src/PEQ14XV-src.svg b/res-src/PEQ14XV-src.svg @@ -23,6 +23,67 @@ </style> <defs> + <symbol id="knob-medium" viewBox="0 0 26px 26px"> + <g transform="translate(13 13)"> + <polyline points="-3,0 3,0" stroke-width="1" stroke="#00f" /> + <polyline points="0,-3 0,3" stroke-width="1" stroke="#00f" /> + <circle cx="0" cy="0" r="12.5" stroke-width="1" stroke="#00f" fill="none" /> + </g> + </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-transpose" viewBox="0 0 45px 45px"> + <g transform="translate(22.5 22.5)"> + <text font-size="5.0pt" transform="rotate(-240) translate(18 0) rotate(240) translate(-3.5 2)">-2</text> + <text font-size="5.0pt" transform="rotate(-165) translate(18 0) rotate(165) translate(-3 2)">-1</text> + <text font-size="5.0pt" transform="rotate(-90) translate(18 0) rotate(90) translate(-2 3)">0</text> + <text font-size="5.0pt" transform="rotate(-15) translate(18 0) rotate(15) translate(-2 2)">1</text> + <text font-size="5.0pt" transform="rotate(60) translate(18 0) rotate(-60) translate(-2 2)">2</text> + + <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-208.75) translate(15 0)" /> + <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-133.75) translate(15 0)" /> + <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(-46.25) translate(15 0)" /> + <polyline points="0,0 2.5,0" stroke-width="0.3" stroke="#333" transform="rotate(28.75) translate(15 0)" /> + </g> + </symbol> + + <symbol id="knobguide-centertick" viewBox="0 0 40px 40px"> + <g transform="translate(20 20)"> + <g transform="rotate(-90) 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(20)" /> + <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(-20)" /> + <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="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="button-small" viewBox="0 0 9px 9px"> + <g transform="translate(4.5 4.5)"> + <circle r="4" stroke-width="1" stroke="#00f" fill="#f00" /> + </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" /> @@ -44,19 +105,79 @@ <polyline points="0,0 75,0 75,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> <text class="title" x="20" y="14" font-size="7pt" letter-spacing="1px">PEQ14XV</text> - <!-- <text class="title" x="15" y="17" font-size="9pt" letter-spacing="3px" transform="translate(75 -8) rotate(90)">PEQ14-XO</text> --> <g transform="translate(25 374)"> <text class="brand" font-size="6.5pt" letter-spacing="2px">BGA</text> <rect width="2" height="2" fill="#ddd" transform="translate(11.5 -4)" /> </g> - <g transform="translate(5.5 318)"> - <rect width="64" height="40" rx="5" fill="#fafafa" /> - <rect width="32" height="40" rx="5" fill="#bbb" transform="translate(32)" /> - <rect width="10" height="40" fill="#bbb" transform="translate(32)" /> - <use id="IN_INPUT" xlink:href="#input" transform="translate(3.5 4)" /> - <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(35.5 4)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(11 36)">IN</text> - <text font-size="6pt" letter-spacing="2px" transform="translate(37 36)">OUT</text> + <text font-size="6pt" letter-spacing="1.5px" transform="translate(9 30)">FOLLOWERS</text> + + <g transform="translate(-2.5 34)"> + <use id="EF_DAMP_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-mintick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(10 33)">DAMP</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="EF_DAMP_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + </g> + + <g transform="translate(32.5 34)"> + <use id="EF_GAIN_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 6)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 -6)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(11.5 33)">GAIN</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="EF_GAIN_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> + <!-- <rect width="75" height="17" fill="#f0f" transform="translate(-32.5 66)" /> --> </g> + + <g transform="translate(0 119)"> + <text font-size="6pt" letter-spacing="1.5px" transform="translate(8 2)">TRANSPOSE</text> + <use id="TRANSPOSE_PARAM" xlink:href="#knob-medium" transform="translate(24.5 13)" /> + <use xlink:href="#knobguide-transpose" transform="translate(15 3.5)" /> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(22.5 47)" /> + <use id="TRANSPOSE_INPUT" xlink:href="#input" transform="translate(25.5 50)" /> + <!-- <rect width="75" height="17" fill="#f0f" transform="translate(0 77)" /> --> + </g> + + <g transform="translate(0 212)"> + <text font-size="6pt" letter-spacing="1.5px" transform="translate(18 5)">OUTPUT</text> + + <use id="OUTPUT_GAIN_PARAM" xlink:href="#knob-smallest" transform="translate(12 15)" /> + <use xlink:href="#knobguide-mintick" transform="translate(0 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(9 42)">GAIN</text> + + <use id="BAND14_MIX_PARAM" xlink:href="#knob-smallest" transform="translate(47 15)" /> + <use xlink:href="#knobguide-mintick" transform="translate(35 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(44 42)">B14D</text> + + <g transform="translate(10 51)"> + <text font-size="5pt" letter-spacing="0.5px" transform="translate(0 6)">B1</text> + <use id="BAND1_ENABLE_PARAM" xlink:href="#button-small" transform="translate(9.5 -1)" /> + </g> + + <g transform="translate(47.5 51)"> + <text font-size="5pt" letter-spacing="0.5px" transform="translate(-5 6)">B14</text> + <use id="BAND14_ENABLE_PARAM" xlink:href="#button-small" transform="translate(9.5 -1)" /> + </g> + + <!-- <rect width="75" height="17" fill="#f0f" transform="translate(0 56)" /> --> + </g> + + <g transform="translate(5.5 287)"> + <rect width="64" height="73" rx="5" fill="#bbb" /> + <rect width="32" height="36.5" rx="5" fill="#fafafa" /> + <rect width="32" height="10" fill="#fafafa" transform="translate(0 26.5)" /> + <rect width="10" height="36.5" fill="#fafafa" transform="translate(22 0)" /> + <use id="IN_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 35)">IN</text> + <use id="ODDS_OUTPUT" xlink:href="#output" transform="translate(35 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(38.5 35)">ODD</text> + <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 70)">OUT</text> + <use id="EVENS_OUTPUT" xlink:href="#output" transform="translate(35 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(36 70)">EVEN</text> + </g> + + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(18.75 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(37.5 0)" /> --> + <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(56.25 0)" /> --> </svg> diff --git a/res-src/PEQ6-src.svg b/res-src/PEQ6-src.svg @@ -157,29 +157,25 @@ <!-- <polyline points="0,0 315,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(0 24)" /> --> <!-- <polyline points="0,0 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(22.5 0)" /> --> - <g transform="translate(0 20)"> - <use id="EF_RESPONSE_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 8)" /> - <use xlink:href="#knobguide-mintick" transform="translate(2.5 -4)" /> - <text font-size="5pt" letter-spacing="1px" transform="translate(8.5 36)">EF-RSP</text> + <g transform="translate(0 40)"> + <!-- <rect width="37" height="66" fill="#f0f" transform="translate(0 0)" /> --> + <use id="FREQUENCY_CV_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 7)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 -5)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(14 33)">FCV</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="FREQUENCY_CV_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> </g> - <g transform="translate(0 58)"> - <use id="FREQUENCY_CV_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 11)" /> - <use xlink:href="#knobguide-centertick" transform="translate(2.5 -1)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(14 37)">FCV</text> - <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 40)" /> - <use id="FREQUENCY_CV_INPUT" xlink:href="#input" transform="translate(10.5 43)" /> + <g transform="translate(0 124)"> + <!-- <rect width="37" height="66" fill="#f0f" transform="translate(0 0)" /> --> + <use id="BANDWIDTH_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 5)" /> + <use xlink:href="#knobguide-mintick" transform="translate(2.5 -7)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(16.5 33)">BW</text> + <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 36)" /> + <use id="BANDWIDTH_INPUT" xlink:href="#input" transform="translate(10.5 39)" /> </g> - <g transform="translate(0 133)"> - <use id="BANDWIDTH_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 8)" /> - <use xlink:href="#knobguide-mintick" transform="translate(2.5 -4)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(16.5 37)">BW</text> - <rect width="30" height="30" rx="5" fill="#fafafa" transform="translate(7.5 40)" /> - <use id="BANDWIDTH_INPUT" xlink:href="#input" transform="translate(10.5 43)" /> - </g> - - <g transform="translate(2 211)"> + <g transform="translate(2 209)"> <!-- <rect width="40" height="23" fill="#f0f" transform="translate(2.5 0)" /> --> <text font-size="5pt" letter-spacing="1px" transform="translate(2.5 8.5)">CH1-LP</text> <use id="LP_PARAM" xlink:href="#button-small" transform="translate(33.5 1)" /> @@ -187,7 +183,7 @@ <use id="HP_PARAM" xlink:href="#button-small" transform="translate(33.5 13)" /> </g> - <g transform="translate(6 243)"> + <g transform="translate(6 242)"> <!-- <rect width="37" height="35" fill="#f0f" transform="translate(0 0)" /> --> <text font-size="5pt" letter-spacing="1px" transform="translate(5 34.5) rotate(-90)">FCV RNG</text> <use id="FMOD_RELATIVE_LIGHT" xlink:href="#light-small" transform="translate(10 1)" /> @@ -225,8 +221,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV1_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF1_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT1_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -248,8 +244,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV2_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF2_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT2_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -271,8 +267,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV3_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -294,8 +290,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV4_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF4_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT4_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -317,8 +313,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV5_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF5_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT5_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> @@ -340,8 +336,8 @@ <text font-size="5pt" letter-spacing="2px" transform="translate(3.5 35)">LEVEL</text> <use id="FREQUENCY_CV6_INPUT" xlink:href="#input" transform="translate(5 38)" /> <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 70)">FCV</text> - <use id="EF6_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(12 105)">EF</text> + <use id="OUT6_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8 105)">OUT</text> </g> </g> </svg> diff --git a/res-src/PEQ6XF-src.svg b/res-src/PEQ6XF-src.svg @@ -0,0 +1,107 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="45" + height="380" + viewBox="0 0 45 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="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-centertick" viewBox="0 0 40px 40px"> + <g transform="translate(20 20)"> + <g transform="rotate(-90) 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(20)" /> + <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(-20)" /> + <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="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="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 44,1 44,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 45,0 45,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <g transform="rotate(-90) translate(-376 13)"> + <text class="title" font-size="7pt" letter-spacing="2.5px">PEQ6XF</text> + <g transform="translate(0 12)"> + <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text> + <rect width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)" /> + </g> + </g> + + <g transform="translate(0 24)"> + <use id="DAMP_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 8)" /> + <use xlink:href="#knobguide-mintick" transform="translate(2.5 -4)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(12 0)">DAMP</text> + </g> + + <g transform="translate(0 63)"> + <use id="GAIN_PARAM" xlink:href="#knob-smallest" transform="translate(14.5 8)" /> + <use xlink:href="#knobguide-centertick" transform="translate(2.5 -4)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(13 0)">GAIN</text> + </g> + + <g transform="translate(5.5 104)"> + <rect width="34" height="225" rx="5" fill="#bbb" transform="translate(0 -10)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 0)">EF</text> + <use id="EF1_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">1</text> + <use id="EF2_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">2</text> + <use id="EF3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 105)">3</text> + <use id="EF4_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 140)">4</text> + <use id="EF5_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 175)">5</text> + <use id="EF6_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(15 210)">6</text> + </g> +</svg> diff --git a/res-src/PEQ6XO-src.svg b/res-src/PEQ6XO-src.svg @@ -1,63 +0,0 @@ -<svg - version="1.1" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - width="45" - height="380" - viewBox="0 0 45 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="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 44,1 44,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> - <polyline points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> - <polyline points="0,0 45,0 45,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> - - <g transform="rotate(-90) translate(-376 13)"> - <text class="title" font-size="7pt" letter-spacing="2.5px">PEQ6-XO</text> - <g transform="translate(0 12)"> - <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text> - <rect width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)" /> - </g> - </g> - - <g transform="translate(5.5 40)"> - <rect width="34" height="225" rx="5" fill="#bbb" transform="translate(0 -10)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(8.5 0)">OUT</text> - <use id="BAND1_OUTPUT" xlink:href="#output" transform="translate(5 3)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 35)">1</text> - <use id="BAND2_OUTPUT" xlink:href="#output" transform="translate(5 38)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 70)">2</text> - <use id="BAND3_OUTPUT" xlink:href="#output" transform="translate(5 73)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 105)">3</text> - <use id="BAND4_OUTPUT" xlink:href="#output" transform="translate(5 108)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 140)">4</text> - <use id="BAND5_OUTPUT" xlink:href="#output" transform="translate(5 143)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 175)">5</text> - <use id="BAND6_OUTPUT" xlink:href="#output" transform="translate(5 178)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(15 210)">6</text> - </g> -</svg> diff --git a/res/PEQ14.svg b/res/PEQ14.svg Binary files differ. diff --git a/res/PEQ14XF.svg b/res/PEQ14XF.svg Binary files differ. diff --git a/res/PEQ14XO.svg b/res/PEQ14XO.svg Binary files differ. diff --git a/res/PEQ14XR.svg b/res/PEQ14XR.svg Binary files differ. diff --git a/res/PEQ14XV.svg b/res/PEQ14XV.svg Binary files differ. diff --git a/res/PEQ6.svg b/res/PEQ6.svg Binary files differ. diff --git a/res/PEQ6XF.svg b/res/PEQ6XF.svg Binary files differ. diff --git a/res/PEQ6XO.svg b/res/PEQ6XO.svg Binary files differ. diff --git a/src/PEQ14.cpp b/src/PEQ14.cpp @@ -5,9 +5,6 @@ void PEQ14::sampleRateChange() { float sr = APP->engine->getSampleRate(); for (int c = 0; c < _channels; ++c) { _engines[c]->setSampleRate(sr); - for (int i = 0; i < 14; ++i) { - _efs[c][i].setSampleRate(sr); - } } } @@ -43,9 +40,6 @@ void PEQ14::addChannel(int c) { void PEQ14::removeChannel(int c) { delete _engines[c]; _engines[c] = NULL; - for (int i = 0; i < 14; ++i) { - _efs[c][i].reset(); - } } void PEQ14::modulate() { @@ -60,20 +54,6 @@ void PEQ14::modulate() { e.setFrequencyMode(_fullFrequencyMode); e.modulate(); } - - float response = params[EF_RESPONSE_PARAM].getValue(); - if (_response != response) { - _response = response; - for (int c = 0; c < _channels; ++c) { - float r = _response; - if (inputs[EF_RESPONSE_INPUT].isConnected()) { - r *= clamp(inputs[EF_RESPONSE_INPUT].getPolyVoltage(c) / 10.f, 0.0f, 1.0f); - } - for (int i = 0; i < 14; ++i) { - _efs[c][i].setSensitivity(r); - } - } - } } void PEQ14::processAlways(const ProcessArgs& args) { @@ -81,7 +61,7 @@ void PEQ14::processAlways(const ProcessArgs& args) { outputs[ODDS_OUTPUT].setChannels(_channels); outputs[EVENS_OUTPUT].setChannels(_channels); for (int i = 0; i < 14; ++i) { - outputs[EF1_OUTPUT + i].setChannels(_channels); + outputs[OUT1_OUTPUT + i].setChannels(_channels); } std::fill(_rmsSums, _rmsSums + 14, 0.0f); } @@ -91,14 +71,12 @@ void PEQ14::processChannel(const ProcessArgs& args, int c) { float out = e.next(inputs[IN_INPUT].getVoltage(c), _rmsSums); outputs[OUT_OUTPUT].setVoltage(out, c); - float levels[14]; float oddOut = 0.0f; float evenOut = 0.0f; for (int i = 0; i < 14; ++i) { oddOut += e.outs[i] * (float)(i % 2 == 0 || (i == 13 && _highMode == MultimodeFilter::HIGHPASS_MODE)); evenOut += e.outs[i] * (float)(i % 2 == 1 || (i == 0 && _lowMode == MultimodeFilter::LOWPASS_MODE)); - levels[i] = scaleEF(_efs[c][i].next(e.outs[i]), e.frequencies[i]); - outputs[EF1_OUTPUT + i].setVoltage(levels[i], c); + outputs[OUT1_OUTPUT + i].setVoltage(e.outs[i], c); } outputs[ODDS_OUTPUT].setVoltage(oddOut, c); outputs[EVENS_OUTPUT].setVoltage(evenOut, c); @@ -108,22 +86,12 @@ void PEQ14::processChannel(const ProcessArgs& args, int c) { m->valid = true; std::copy(e.outs, e.outs + 14, m->outs[c]); std::copy(e.frequencies, e.frequencies + 14, m->frequencies[c]); - std::copy(levels, levels + 14, m->levels[c]); m->bandwidths[c] = e.bandwidth; m->lowLP = _lowMode == MultimodeFilter::LOWPASS_MODE; m->highHP = _highMode == MultimodeFilter::HIGHPASS_MODE; } } -float PEQ14::scaleEF(float ef, float frequency) { - float bandwidth = 2.0 * params[BANDWIDTH_PARAM].getValue(); - float minf = std::max(0.0f, powf(2.0f, -bandwidth) * frequency); - float maxf = std::min(PEQChannel::maxFrequency, powf(2.0f, bandwidth) * frequency); - float scale = (maxf - minf) / PEQChannel::maxFrequency; - scale = 1.0f / scale; - return scale * ef; -} - void PEQ14::postProcessAlways(const ProcessArgs& args) { for (int i = 0; i < 14; ++i) { _rms[i] = _rmsSums[i] * _inverseChannels; @@ -153,12 +121,11 @@ struct PEQ14Widget : ModuleWidget { addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365))); // generated by svg_widgets.rb - auto efResponseParamPosition = Vec(47.0, 38.0); - auto frequencyCvParamPosition = Vec(47.0, 96.5); - auto bandwidthParamPosition = Vec(47.0, 149.5); - auto lpParamPosition = Vec(48.5, 198.0); - auto hpParamPosition = Vec(48.5, 210.0); - auto fmodParamPosition = Vec(32.5, 260.5); + auto frequencyCvParamPosition = Vec(47.0, 59.0); + auto bandwidthParamPosition = Vec(47.0, 121.0); + auto lpParamPosition = Vec(48.5, 180.0); + auto hpParamPosition = Vec(48.5, 192.0); + auto fmodParamPosition = Vec(32.5, 252.0); auto level1ParamPosition = Vec(87.5, 28.0); auto frequency1ParamPosition = Vec(88.5, 184.0); auto frequencyCv1ParamPosition = Vec(88.5, 224.0); @@ -202,9 +169,8 @@ struct PEQ14Widget : ModuleWidget { auto frequency14ParamPosition = Vec(660.5, 184.0); auto frequencyCv14ParamPosition = Vec(660.5, 224.0); - auto efResponseInputPosition = Vec(9.5, 38.0); - auto frequencyCvInputPosition = Vec(9.5, 93.5); - auto bandwidthInputPosition = Vec(9.5, 149.5); + auto frequencyCvInputPosition = Vec(9.5, 56.0); + auto bandwidthInputPosition = Vec(9.5, 121.0); auto inInputPosition = Vec(10.5, 290.0); auto level1InputPosition = Vec(84.5, 255.0); auto frequencyCv1InputPosition = Vec(84.5, 290.0); @@ -238,26 +204,25 @@ struct PEQ14Widget : ModuleWidget { auto oddsOutputPosition = Vec(40.5, 290.0); auto outOutputPosition = Vec(10.5, 325.0); auto evensOutputPosition = Vec(40.5, 325.0); - auto ef1OutputPosition = Vec(84.5, 325.0); - auto ef2OutputPosition = Vec(128.5, 325.0); - auto ef3OutputPosition = Vec(172.5, 325.0); - auto ef4OutputPosition = Vec(216.5, 325.0); - auto ef5OutputPosition = Vec(260.5, 325.0); - auto ef6OutputPosition = Vec(304.5, 325.0); - auto ef7OutputPosition = Vec(348.5, 325.0); - auto ef8OutputPosition = Vec(392.5, 325.0); - auto ef9OutputPosition = Vec(436.5, 325.0); - auto ef10OutputPosition = Vec(480.5, 325.0); - auto ef11OutputPosition = Vec(524.5, 325.0); - auto ef12OutputPosition = Vec(568.5, 325.0); - auto ef13OutputPosition = Vec(612.5, 325.0); - auto ef14OutputPosition = Vec(656.5, 325.0); + auto out1OutputPosition = Vec(84.5, 325.0); + auto out2OutputPosition = Vec(128.5, 325.0); + auto out3OutputPosition = Vec(172.5, 325.0); + auto out4OutputPosition = Vec(216.5, 325.0); + auto out5OutputPosition = Vec(260.5, 325.0); + auto out6OutputPosition = Vec(304.5, 325.0); + auto out7OutputPosition = Vec(348.5, 325.0); + auto out8OutputPosition = Vec(392.5, 325.0); + auto out9OutputPosition = Vec(436.5, 325.0); + auto out10OutputPosition = Vec(480.5, 325.0); + auto out11OutputPosition = Vec(524.5, 325.0); + auto out12OutputPosition = Vec(568.5, 325.0); + auto out13OutputPosition = Vec(612.5, 325.0); + auto out14OutputPosition = Vec(656.5, 325.0); - auto fmodRelativeLightPosition = Vec(28.5, 236.5); - auto fmodFullLightPosition = Vec(28.5, 249.5); + auto fmodRelativeLightPosition = Vec(28.5, 228.0); + auto fmodFullLightPosition = Vec(28.5, 241.0); // end generated by svg_widgets.rb - addParam(createParam<Knob16>(efResponseParamPosition, module, PEQ14::EF_RESPONSE_PARAM)); addParam(createParam<Knob16>(frequencyCvParamPosition, module, PEQ14::FREQUENCY_CV_PARAM)); addParam(createParam<Knob16>(bandwidthParamPosition, module, PEQ14::BANDWIDTH_PARAM)); addParam(createParam<IndicatorButtonGreen9>(lpParamPosition, module, PEQ14::LP_PARAM)); @@ -306,7 +271,6 @@ struct PEQ14Widget : ModuleWidget { addParam(createParam<Knob16>(frequency14ParamPosition, module, PEQ14::FREQUENCY14_PARAM)); addParam(createParam<Knob16>(frequencyCv14ParamPosition, module, PEQ14::FREQUENCY_CV14_PARAM)); - addInput(createInput<Port24>(efResponseInputPosition, module, PEQ14::EF_RESPONSE_INPUT)); addInput(createInput<Port24>(frequencyCvInputPosition, module, PEQ14::FREQUENCY_CV_INPUT)); addInput(createInput<Port24>(bandwidthInputPosition, module, PEQ14::BANDWIDTH_INPUT)); addInput(createInput<Port24>(inInputPosition, module, PEQ14::IN_INPUT)); @@ -342,20 +306,20 @@ struct PEQ14Widget : ModuleWidget { addOutput(createOutput<Port24>(oddsOutputPosition, module, PEQ14::ODDS_OUTPUT)); addOutput(createOutput<Port24>(outOutputPosition, module, PEQ14::OUT_OUTPUT)); addOutput(createOutput<Port24>(evensOutputPosition, module, PEQ14::EVENS_OUTPUT)); - addOutput(createOutput<Port24>(ef1OutputPosition, module, PEQ14::EF1_OUTPUT)); - addOutput(createOutput<Port24>(ef2OutputPosition, module, PEQ14::EF2_OUTPUT)); - addOutput(createOutput<Port24>(ef3OutputPosition, module, PEQ14::EF3_OUTPUT)); - addOutput(createOutput<Port24>(ef4OutputPosition, module, PEQ14::EF4_OUTPUT)); - addOutput(createOutput<Port24>(ef5OutputPosition, module, PEQ14::EF5_OUTPUT)); - addOutput(createOutput<Port24>(ef6OutputPosition, module, PEQ14::EF6_OUTPUT)); - addOutput(createOutput<Port24>(ef7OutputPosition, module, PEQ14::EF7_OUTPUT)); - addOutput(createOutput<Port24>(ef8OutputPosition, module, PEQ14::EF8_OUTPUT)); - addOutput(createOutput<Port24>(ef9OutputPosition, module, PEQ14::EF9_OUTPUT)); - addOutput(createOutput<Port24>(ef10OutputPosition, module, PEQ14::EF10_OUTPUT)); - addOutput(createOutput<Port24>(ef11OutputPosition, module, PEQ14::EF11_OUTPUT)); - addOutput(createOutput<Port24>(ef12OutputPosition, module, PEQ14::EF12_OUTPUT)); - addOutput(createOutput<Port24>(ef13OutputPosition, module, PEQ14::EF13_OUTPUT)); - addOutput(createOutput<Port24>(ef14OutputPosition, module, PEQ14::EF14_OUTPUT)); + addOutput(createOutput<Port24>(out1OutputPosition, module, PEQ14::OUT1_OUTPUT)); + addOutput(createOutput<Port24>(out2OutputPosition, module, PEQ14::OUT2_OUTPUT)); + addOutput(createOutput<Port24>(out3OutputPosition, module, PEQ14::OUT3_OUTPUT)); + addOutput(createOutput<Port24>(out4OutputPosition, module, PEQ14::OUT4_OUTPUT)); + addOutput(createOutput<Port24>(out5OutputPosition, module, PEQ14::OUT5_OUTPUT)); + addOutput(createOutput<Port24>(out6OutputPosition, module, PEQ14::OUT6_OUTPUT)); + addOutput(createOutput<Port24>(out7OutputPosition, module, PEQ14::OUT7_OUTPUT)); + addOutput(createOutput<Port24>(out8OutputPosition, module, PEQ14::OUT8_OUTPUT)); + addOutput(createOutput<Port24>(out9OutputPosition, module, PEQ14::OUT9_OUTPUT)); + addOutput(createOutput<Port24>(out10OutputPosition, module, PEQ14::OUT10_OUTPUT)); + addOutput(createOutput<Port24>(out11OutputPosition, module, PEQ14::OUT11_OUTPUT)); + addOutput(createOutput<Port24>(out12OutputPosition, module, PEQ14::OUT12_OUTPUT)); + addOutput(createOutput<Port24>(out13OutputPosition, module, PEQ14::OUT13_OUTPUT)); + addOutput(createOutput<Port24>(out14OutputPosition, module, PEQ14::OUT14_OUTPUT)); addChild(createLight<SmallLight<GreenLight>>(fmodRelativeLightPosition, module, PEQ14::FMOD_RELATIVE_LIGHT)); addChild(createLight<SmallLight<GreenLight>>(fmodFullLightPosition, module, PEQ14::FMOD_FULL_LIGHT)); diff --git a/src/PEQ14.hpp b/src/PEQ14.hpp @@ -6,7 +6,6 @@ namespace bogaudio { struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { enum ParamsIds { - EF_RESPONSE_PARAM, FREQUENCY_CV_PARAM, BANDWIDTH_PARAM, LP_PARAM, @@ -58,7 +57,6 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { }; enum InputsIds { - EF_RESPONSE_INPUT, FREQUENCY_CV_INPUT, BANDWIDTH_INPUT, IN_INPUT, @@ -97,20 +95,20 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { ODDS_OUTPUT, OUT_OUTPUT, EVENS_OUTPUT, - EF1_OUTPUT, - EF2_OUTPUT, - EF3_OUTPUT, - EF4_OUTPUT, - EF5_OUTPUT, - EF6_OUTPUT, - EF7_OUTPUT, - EF8_OUTPUT, - EF9_OUTPUT, - EF10_OUTPUT, - EF11_OUTPUT, - EF12_OUTPUT, - EF13_OUTPUT, - EF14_OUTPUT, + OUT1_OUTPUT, + OUT2_OUTPUT, + OUT3_OUTPUT, + OUT4_OUTPUT, + OUT5_OUTPUT, + OUT6_OUTPUT, + OUT7_OUTPUT, + OUT8_OUTPUT, + OUT9_OUTPUT, + OUT10_OUTPUT, + OUT11_OUTPUT, + OUT12_OUTPUT, + OUT13_OUTPUT, + OUT14_OUTPUT, NUM_OUTPUTS }; @@ -123,8 +121,6 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { PEQEngine* _engines[maxChannels] {}; float _rmsSums[14] {}; float _rms[14] {}; - RootMeanSquare _efs[maxChannels][14]; - float _response = -1.0f; MultimodeFilter::Mode _lowMode = MultimodeFilter::LOWPASS_MODE; MultimodeFilter::Mode _highMode = MultimodeFilter::HIGHPASS_MODE; bool _fullFrequencyMode = false; @@ -132,7 +128,6 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { PEQ14() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); float levelDefault = fabsf(PEQChannel::minDecibels) / (PEQChannel::maxDecibels - PEQChannel::minDecibels); - configParam(EF_RESPONSE_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); configParam(FREQUENCY_CV_PARAM, -1.0f, 1.0f, 0.0f, "Global frequency CV attenuation", "%", 0.0f, 100.0f); configParam(BANDWIDTH_PARAM, 0.0f, 1.0f, 0.11f, "Bandwidth", "%", 0.0f, 100.0f); configParam(LP_PARAM, 0.0f, 1.0f, 1.0f, "Channel 1 LP/BP"); @@ -181,7 +176,7 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { configParam<ScaledSquaringParamQuantity<(int)PEQChannel::maxFrequency>>(FREQUENCY14_PARAM, 0.0f, 1.0f, 0.5873670f, "Channel 6 frequency", " HZ"); configParam(FREQUENCY_CV14_PARAM, -1.0f, 1.0f, 1.0f, "Channel 6 frequency CV attenuation", "%", 0.0f, 100.0f); - setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); + setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); } void sampleRateChange() override; @@ -192,7 +187,6 @@ struct PEQ14 : ExpandableModule<PEQ14ExpanderMessage, BGModule> { void modulate() override; void processAlways(const ProcessArgs& args) override; void processChannel(const ProcessArgs& args, int c) override; - float scaleEF(float ef, float frequency); void postProcessAlways(const ProcessArgs& args) override; }; diff --git a/src/PEQ14XF.cpp b/src/PEQ14XF.cpp @@ -0,0 +1,155 @@ + +#include "PEQ14XF.hpp" + +void PEQ14XF::sampleRateChange() { + float sr = APP->engine->getSampleRate(); + for (int c = 0; c < _channels; ++c) { + for (int i = 0; i < 14; ++i) { + _engines[c]->efs[i].setSampleRate(sr); + } + } +} + +void PEQ14XF::addChannel(int c) { + _engines[c] = new Engine(); + float sr = APP->engine->getSampleRate(); + for (int i = 0; i < 14; ++i) { + _engines[c]->efs[i].setSampleRate(sr); + } +} + +void PEQ14XF::removeChannel(int c) { + delete _engines[c]; + _engines[c] = NULL; +} + +void PEQ14XF::modulateChannel(int c) { + Engine& e = *_engines[c]; + + float response = params[DAMP_PARAM].getValue(); + if (inputs[DAMP_INPUT].isConnected()) { + response *= clamp(inputs[DAMP_INPUT].getPolyVoltage(c) / 10.f, 0.0f, 1.0f); + } + if (e.response != response) { + e.response = response; + for (int i = 0; i < 14; ++i) { + _engines[c]->efs[i].setSensitivity(e.response); + } + } + + float db = clamp(params[GAIN_PARAM].getValue(), -1.0f, 1.0f); + if (inputs[GAIN_INPUT].isConnected()) { + db *= clamp(inputs[GAIN_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + } + if (db < 0.0f) { + db = -db * efGainMinDecibels; + } + else { + db *= std::min(12.0f, efGainMaxDecibels); + } + e.gain.setLevel(db); +} + +void PEQ14XF::processAll(const ProcessArgs& args) { + for (int i = 0; i < 14; ++i) { + outputs[EF1_OUTPUT + i].setChannels(_channels); + } + + _baseMessage = NULL; + if (baseConnected()) { + _baseMessage = fromBase(); + } + + if (expanderConnected()) { + if (_baseMessage) { + // *toExpander() = *_baseMessage; + _baseMessage->copyTo(toExpander()); + } + else { + toExpander()->reset(); + } + } +} + +void PEQ14XF::processChannel(const ProcessArgs& args, int c) { + if (_baseMessage && _baseMessage->valid) { + Engine& e = *_engines[c]; + for (int i = 0; i < 14; ++i) { + float out = e.efs[i].next(_baseMessage->outs[c][i]); + out = scaleEF(out, _baseMessage->frequencies[c][i], _baseMessage->bandwidths[c]); + out = e.gain.next(out); + out = _saturator.next(out); + outputs[EF1_OUTPUT + i].setVoltage(out, c); + } + } + else { + for (int i = 0; i < 14; ++i) { + outputs[EF1_OUTPUT + i].setVoltage(0.0f, c); + } + } +} + +struct PEQ14XFWidget : ModuleWidget { + static constexpr int hp = 5; + + PEQ14XFWidget(PEQ14XF* 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/PEQ14XF.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto dampParamPosition = Vec(12.0, 30.0); + auto gainParamPosition = Vec(47.0, 29.5); + + auto dampInputPosition = Vec(8.0, 63.0); + auto gainInputPosition = Vec(43.0, 62.5); + + auto ef1OutputPosition = Vec(10.5, 111.0); + auto ef2OutputPosition = Vec(10.5, 146.0); + auto ef3OutputPosition = Vec(10.5, 181.0); + auto ef4OutputPosition = Vec(10.5, 216.0); + auto ef5OutputPosition = Vec(10.5, 251.0); + auto ef6OutputPosition = Vec(10.5, 286.0); + auto ef7OutputPosition = Vec(10.5, 321.0); + auto ef8OutputPosition = Vec(41.5, 111.0); + auto ef9OutputPosition = Vec(41.5, 146.0); + auto ef10OutputPosition = Vec(41.5, 181.0); + auto ef11OutputPosition = Vec(41.5, 216.0); + auto ef12OutputPosition = Vec(41.5, 251.0); + auto ef13OutputPosition = Vec(41.5, 286.0); + auto ef14OutputPosition = Vec(41.5, 321.0); + // end generated by svg_widgets.rb + + addParam(createParam<Knob16>(dampParamPosition, module, PEQ14XF::DAMP_PARAM)); + addParam(createParam<Knob16>(gainParamPosition, module, PEQ14XF::GAIN_PARAM)); + + addInput(createInput<Port24>(dampInputPosition, module, PEQ14XF::DAMP_INPUT)); + addInput(createInput<Port24>(gainInputPosition, module, PEQ14XF::GAIN_INPUT)); + + addOutput(createOutput<Port24>(ef1OutputPosition, module, PEQ14XF::EF1_OUTPUT)); + addOutput(createOutput<Port24>(ef2OutputPosition, module, PEQ14XF::EF2_OUTPUT)); + addOutput(createOutput<Port24>(ef3OutputPosition, module, PEQ14XF::EF3_OUTPUT)); + addOutput(createOutput<Port24>(ef4OutputPosition, module, PEQ14XF::EF4_OUTPUT)); + addOutput(createOutput<Port24>(ef5OutputPosition, module, PEQ14XF::EF5_OUTPUT)); + addOutput(createOutput<Port24>(ef6OutputPosition, module, PEQ14XF::EF6_OUTPUT)); + addOutput(createOutput<Port24>(ef7OutputPosition, module, PEQ14XF::EF7_OUTPUT)); + addOutput(createOutput<Port24>(ef8OutputPosition, module, PEQ14XF::EF8_OUTPUT)); + addOutput(createOutput<Port24>(ef9OutputPosition, module, PEQ14XF::EF9_OUTPUT)); + addOutput(createOutput<Port24>(ef10OutputPosition, module, PEQ14XF::EF10_OUTPUT)); + addOutput(createOutput<Port24>(ef11OutputPosition, module, PEQ14XF::EF11_OUTPUT)); + addOutput(createOutput<Port24>(ef12OutputPosition, module, PEQ14XF::EF12_OUTPUT)); + addOutput(createOutput<Port24>(ef13OutputPosition, module, PEQ14XF::EF13_OUTPUT)); + addOutput(createOutput<Port24>(ef14OutputPosition, module, PEQ14XF::EF14_OUTPUT)); + } +}; + +Model* modelPEQ14XF = createModel<PEQ14XF, PEQ14XFWidget>("Bogaudio-PEQ14XF", "PEQ14XF", "PEQ14 envelope followers expander", "Filter", "Expander", "Polyphonic"); diff --git a/src/PEQ14XF.hpp b/src/PEQ14XF.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include "PEQ14_shared.hpp" + +namespace bogaudio { + +struct PEQ14XF : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, PEQXFBase>> { + enum ParamsIds { + DAMP_PARAM, + GAIN_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + DAMP_INPUT, + GAIN_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + EF1_OUTPUT, + EF2_OUTPUT, + EF3_OUTPUT, + EF4_OUTPUT, + EF5_OUTPUT, + EF6_OUTPUT, + EF7_OUTPUT, + EF8_OUTPUT, + EF9_OUTPUT, + EF10_OUTPUT, + EF11_OUTPUT, + EF12_OUTPUT, + EF13_OUTPUT, + EF14_OUTPUT, + NUM_OUTPUTS + }; + + struct Engine { + RootMeanSquare efs[14]; + float response = -1.0f; + Amplifier gain; + }; + + Engine* _engines[maxChannels] {}; + Saturator _saturator; + PEQ14ExpanderMessage* _baseMessage = NULL; + + PEQ14XF() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(DAMP_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); + configParam<EFGainParamQuantity>(GAIN_PARAM, -1.0f, 1.0f, 0.0f, "Envelope follower gain", " dB"); + + setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); + setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); + } + + void sampleRateChange() override; + void addChannel(int c) override; + void removeChannel(int c) override; + void modulateChannel(int c) override; + void processAll(const ProcessArgs& args) override; + void processChannel(const ProcessArgs& args, int c) override; +}; + +} // namespace bogaudio diff --git a/src/PEQ14XO.cpp b/src/PEQ14XO.cpp @@ -1,85 +0,0 @@ - -#include "PEQ14XO.hpp" - -void PEQ14XO::processAll(const ProcessArgs& args) { - for (int i = 0; i < 14; ++i) { - outputs[BAND1_OUTPUT + i].setChannels(_channels); - } - - if (expanderConnected()) { - if (baseConnected()) { - // *toExpander() = *fromBase(); - fromBase()->copyTo(toExpander()); - } - else { - toExpander()->reset(); - } - } -} - -void PEQ14XO::processChannel(const ProcessArgs& args, int c) { - if (baseConnected()) { - float* outs = fromBase()->outs[c]; - for (int i = 0; i < 14; ++i) { - outputs[BAND1_OUTPUT + i].setVoltage(outs[i], c); - } - } - else { - for (int i = 0; i < 14; ++i) { - outputs[BAND1_OUTPUT + i].setVoltage(0.0f, c); - } - } -} - -struct PEQ14XOWidget : ModuleWidget { - static constexpr int hp = 5; - - PEQ14XOWidget(PEQ14XO* 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/PEQ14XO.svg"))); - addChild(panel); - } - - addChild(createWidget<ScrewSilver>(Vec(0, 0))); - addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); - - // generated by svg_widgets.rb - auto band1OutputPosition = Vec(10.5, 43.0); - auto band2OutputPosition = Vec(10.5, 78.0); - auto band3OutputPosition = Vec(10.5, 113.0); - auto band4OutputPosition = Vec(10.5, 148.0); - auto band5OutputPosition = Vec(10.5, 183.0); - auto band6OutputPosition = Vec(10.5, 218.0); - auto band7OutputPosition = Vec(10.5, 253.0); - auto band8OutputPosition = Vec(41.5, 43.0); - auto band9OutputPosition = Vec(41.5, 78.0); - auto band10OutputPosition = Vec(41.5, 113.0); - auto band11OutputPosition = Vec(41.5, 148.0); - auto band12OutputPosition = Vec(41.5, 183.0); - auto band13OutputPosition = Vec(41.5, 218.0); - auto band14OutputPosition = Vec(41.5, 253.0); - // end generated by svg_widgets.rb - - addOutput(createOutput<Port24>(band1OutputPosition, module, PEQ14XO::BAND1_OUTPUT)); - addOutput(createOutput<Port24>(band2OutputPosition, module, PEQ14XO::BAND2_OUTPUT)); - addOutput(createOutput<Port24>(band3OutputPosition, module, PEQ14XO::BAND3_OUTPUT)); - addOutput(createOutput<Port24>(band4OutputPosition, module, PEQ14XO::BAND4_OUTPUT)); - addOutput(createOutput<Port24>(band5OutputPosition, module, PEQ14XO::BAND5_OUTPUT)); - addOutput(createOutput<Port24>(band6OutputPosition, module, PEQ14XO::BAND6_OUTPUT)); - addOutput(createOutput<Port24>(band7OutputPosition, module, PEQ14XO::BAND7_OUTPUT)); - addOutput(createOutput<Port24>(band8OutputPosition, module, PEQ14XO::BAND8_OUTPUT)); - addOutput(createOutput<Port24>(band9OutputPosition, module, PEQ14XO::BAND9_OUTPUT)); - addOutput(createOutput<Port24>(band10OutputPosition, module, PEQ14XO::BAND10_OUTPUT)); - addOutput(createOutput<Port24>(band11OutputPosition, module, PEQ14XO::BAND11_OUTPUT)); - addOutput(createOutput<Port24>(band12OutputPosition, module, PEQ14XO::BAND12_OUTPUT)); - addOutput(createOutput<Port24>(band13OutputPosition, module, PEQ14XO::BAND13_OUTPUT)); - addOutput(createOutput<Port24>(band14OutputPosition, module, PEQ14XO::BAND14_OUTPUT)); - } -}; - -Model* modelPEQ14XO = createModel<PEQ14XO, PEQ14XOWidget>("Bogaudio-PEQ14XO", "PEQ14XO", "PEQ14 band outputs expander", "Filter", "Expander", "Polyphonic"); diff --git a/src/PEQ14XO.hpp b/src/PEQ14XO.hpp @@ -1,44 +0,0 @@ -#pragma once - -#include "PEQ14_shared.hpp" - -namespace bogaudio { - -struct PEQ14XO : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, BGModule>> { - enum ParamsIds { - NUM_PARAMS - }; - - enum InputsIds { - NUM_INPUTS - }; - - enum OutputsIds { - BAND1_OUTPUT, - BAND2_OUTPUT, - BAND3_OUTPUT, - BAND4_OUTPUT, - BAND5_OUTPUT, - BAND6_OUTPUT, - BAND7_OUTPUT, - BAND8_OUTPUT, - BAND9_OUTPUT, - BAND10_OUTPUT, - BAND11_OUTPUT, - BAND12_OUTPUT, - BAND13_OUTPUT, - BAND14_OUTPUT, - NUM_OUTPUTS - }; - - PEQ14XO() { - config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); - setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); - setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); - } - - void processAll(const ProcessArgs& args) override; - void processChannel(const ProcessArgs& args, int c) override; -}; - -} // namespace bogaudio diff --git a/src/PEQ14XR.cpp b/src/PEQ14XR.cpp @@ -4,6 +4,7 @@ void PEQ14XR::Engine::setSampleRate(float sr) { for (int i = 0; i < 14; ++i) { oscillators[i].setSampleRate(sr); + efs[i].setSampleRate(sr); } } @@ -24,6 +25,33 @@ void PEQ14XR::removeChannel(int c) { _engines[c] = NULL; } +void PEQ14XR::modulateChannel(int c) { + Engine& e = *_engines[c]; + + float response = params[DAMP_PARAM].getValue(); + if (inputs[DAMP_INPUT].isConnected()) { + response *= clamp(inputs[DAMP_INPUT].getPolyVoltage(c) / 10.f, 0.0f, 1.0f); + } + if (e.response != response) { + e.response = response; + for (int i = 0; i < 14; ++i) { + _engines[c]->efs[i].setSensitivity(e.response); + } + } + + float db = clamp(params[GAIN_PARAM].getValue(), -1.0f, 1.0f); + if (inputs[GAIN_INPUT].isConnected()) { + db *= clamp(inputs[GAIN_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + } + if (db < 0.0f) { + db = -db * efGainMinDecibels; + } + else { + db *= std::min(12.0f, efGainMaxDecibels); + } + e.efGain.setLevel(db); +} + void PEQ14XR::processAlways(const ProcessArgs& args) { outputs[OUT_OUTPUT].setChannels(_channels); @@ -50,12 +78,14 @@ void PEQ14XR::processChannel(const ProcessArgs& args, int c) { for (int i = 0; i < 14; ++i) { e.oscillators[i].setFrequency(_baseMessage->frequencies[c][i]); - float db = _baseMessage->levels[c][i]; - db *= 0.2f; - db = std::max(0.0f, std::min(1.0f, db)); - db = 1.0f - db; - db *= Amplifier::minDecibels; - e.amplifiers[i].setLevel(db); + float level = e.efs[i].next(_baseMessage->outs[c][i]); + level = scaleEF(level, _baseMessage->frequencies[c][i], _baseMessage->bandwidths[c]); + level = e.efGain.next(level); + level *= 0.1f; + level = std::max(0.0f, std::min(1.0f, level)); + level = 1.0f - level; + level *= Amplifier::minDecibels; + e.amplifiers[i].setLevel(level); out += e.amplifiers[i].next(e.oscillators[i].next()); } @@ -84,9 +114,21 @@ struct PEQ14XRWidget : ModuleWidget { addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); // generated by svg_widgets.rb + auto dampParamPosition = Vec(12.0, 30.0); + auto gainParamPosition = Vec(47.0, 29.5); + + auto dampInputPosition = Vec(8.0, 63.0); + auto gainInputPosition = Vec(43.0, 62.5); + auto outOutputPosition = Vec(25.5, 322.0); // end generated by svg_widgets.rb + addParam(createParam<Knob16>(dampParamPosition, module, PEQ14XR::DAMP_PARAM)); + addParam(createParam<Knob16>(gainParamPosition, module, PEQ14XR::GAIN_PARAM)); + + addInput(createInput<Port24>(dampInputPosition, module, PEQ14XR::DAMP_INPUT)); + addInput(createInput<Port24>(gainInputPosition, module, PEQ14XR::GAIN_INPUT)); + addOutput(createOutput<Port24>(outOutputPosition, module, PEQ14XR::OUT_OUTPUT)); } }; diff --git a/src/PEQ14XR.hpp b/src/PEQ14XR.hpp @@ -5,12 +5,16 @@ namespace bogaudio { -struct PEQ14XR : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, BGModule>> { +struct PEQ14XR : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, PEQXFBase>> { enum ParamsIds { + DAMP_PARAM, + GAIN_PARAM, NUM_PARAMS }; enum InputsIds { + DAMP_INPUT, + GAIN_INPUT, NUM_INPUTS }; @@ -36,6 +40,9 @@ struct PEQ14XR : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14Expa BandOscillator oscillators[14]; Amplifier amplifiers[14]; + RootMeanSquare efs[14]; + float response = -1.0f; + Amplifier efGain; void setSampleRate(float sr); }; @@ -46,14 +53,17 @@ struct PEQ14XR : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14Expa PEQ14XR() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(DAMP_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); + configParam<EFGainParamQuantity>(GAIN_PARAM, -1.0f, 1.0f, 0.0f, "Envelope follower gain", " dB"); - setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); - setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); + setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); + setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); } void sampleRateChange() override; void addChannel(int c) override; void removeChannel(int c) override; + void modulateChannel(int c) override; void processAlways(const ProcessArgs& args) override; void processChannel(const ProcessArgs& args, int c) override; }; diff --git a/src/PEQ14XV.cpp b/src/PEQ14XV.cpp @@ -1,5 +1,6 @@ #include "PEQ14XV.hpp" +#include "dsp/pitch.hpp" PEQ14XV::Engine::Engine() { filters[0] = new MultimodeFilter8(); @@ -15,12 +16,22 @@ PEQ14XV::Engine::~Engine() { } } +void PEQ14XV::Engine::setSampleRate(float sr) { + for (int i = 0; i < 14; ++i) { + efs[i].setSampleRate(sr); + } +} + void PEQ14XV::sampleRateChange() { _sampleRate = APP->engine->getSampleRate(); + for (int c = 0; c < _channels; ++c) { + _engines[c]->setSampleRate(_sampleRate); + } } void PEQ14XV::addChannel(int c) { _engines[c] = new Engine(); + _engines[c]->setSampleRate(APP->engine->getSampleRate()); } void PEQ14XV::removeChannel(int c) { @@ -28,8 +39,57 @@ void PEQ14XV::removeChannel(int c) { _engines[c] = NULL; } +void PEQ14XV::modulate() { + float outGain = clamp(params[OUTPUT_GAIN_PARAM].getValue(), 0.0f, 1.0f); + outGain *= maxOutputGain; + _outputGain.setLevel(outGain); + + float b14Mix = clamp(params[BAND14_MIX_PARAM].getValue(), 0.0f, 1.0f); + b14Mix = 1.0f - b14Mix; + b14Mix *= Amplifier::minDecibels; + _band14Mix.setLevel(b14Mix); + + _band1Enable = params[BAND1_ENABLE_PARAM].getValue() > 0.5f; + _band14Enable = params[BAND14_ENABLE_PARAM].getValue() > 0.5f; +} + +void PEQ14XV::modulateChannel(int c) { + Engine& e = *_engines[c]; + + float response = params[EF_DAMP_PARAM].getValue(); + if (inputs[EF_DAMP_INPUT].isConnected()) { + response *= clamp(inputs[EF_DAMP_INPUT].getPolyVoltage(c) / 10.f, 0.0f, 1.0f); + } + if (e.response != response) { + e.response = response; + for (int i = 0; i < 14; ++i) { + _engines[c]->efs[i].setSensitivity(e.response); + } + } + + float db = clamp(params[EF_GAIN_PARAM].getValue(), -1.0f, 1.0f); + if (inputs[EF_GAIN_INPUT].isConnected()) { + db *= clamp(inputs[EF_GAIN_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + } + if (db < 0.0f) { + db = -db * efGainMinDecibels; + } + else { + db *= std::min(12.0f, efGainMaxDecibels); + } + e.efGain.setLevel(db); + + float transpose = clamp(params[TRANSPOSE_PARAM].getValue(), -1.0f, 1.0f); + if (inputs[TRANSPOSE_INPUT].isConnected()) { + transpose *= clamp(inputs[TRANSPOSE_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + } + e.transposeSemitones = 24.0f * transpose; +} + void PEQ14XV::processAlways(const ProcessArgs& args) { outputs[OUT_OUTPUT].setChannels(_channels); + outputs[ODDS_OUTPUT].setChannels(_channels); + outputs[EVENS_OUTPUT].setChannels(_channels); _baseMessage = NULL; if (baseConnected()) { @@ -52,6 +112,8 @@ void PEQ14XV::processChannel(const ProcessArgs& args, int c) { Engine& e = *_engines[c]; float in = inputs[IN_INPUT].getPolyVoltage(c); float out = 0.0f; + float odds = 0.0f; + float evens = 0.0f; for (int i = 0; i < 14; ++i) { auto mode = MultimodeFilter::BANDPASS_MODE; int poles = 4; @@ -66,29 +128,56 @@ void PEQ14XV::processChannel(const ProcessArgs& args, int c) { poles = 12; bandwidth = MultimodeFilter::minQbw; } + float f = _baseMessage->frequencies[c][i]; + if (e.transposeSemitones > 0.01f || e.transposeSemitones < -0.01f) { + f = frequencyToSemitone(f); + f += e.transposeSemitones; + f = semitoneToFrequency(f); + } + if (f < MultimodeFilter::minFrequency || f > MultimodeFilter::maxFrequency) { + continue; + } + e.filters[i]->setParams( _sampleRate, MultimodeFilter::BUTTERWORTH_TYPE, poles, mode, - _baseMessage->frequencies[c][i], + f, bandwidth, MultimodeFilter::PITCH_BANDWIDTH_MODE ); - float db = _baseMessage->levels[c][i]; - db *= 0.2f; - db = std::max(0.0f, std::min(1.0f, db)); - db = 1.0f - db; - db *= Amplifier::minDecibels; - e.amplifiers[i].setLevel(db); - - out += e.amplifiers[i].next(e.filters[i]->next(in)); + float level = e.efs[i].next(_baseMessage->outs[c][i]); + level = scaleEF(level, _baseMessage->frequencies[c][i], _baseMessage->bandwidths[c]); + level = e.efGain.next(level); + level *= 0.1f; + level = std::max(0.0f, std::min(1.0f, level)); + level = 1.0f - level; + level *= Amplifier::minDecibels; + e.amplifiers[i].setLevel(level); + + float o = e.amplifiers[i].next(e.filters[i]->next(in)); + o = _outputGain.next(o); + out += (float)((i != 0 || _band1Enable) && (i != 13 || _band14Enable)) * o; + odds += (float)(i % 2 == 0 && (i != 0 || _band1Enable)) * o; + evens += (float)(i % 2 == 1 && (i != 13 || _band14Enable)) * o; } + + float band14raw = _baseMessage->outs[c][13]; + band14raw = _band14Mix.next(band14raw); + out += band14raw; + odds += band14raw; + evens += band14raw; + outputs[OUT_OUTPUT].setVoltage(_saturator.next(out), c); + outputs[ODDS_OUTPUT].setVoltage(_saturator.next(odds), c); + outputs[EVENS_OUTPUT].setVoltage(_saturator.next(evens), c); } else { outputs[OUT_OUTPUT].setVoltage(0.0f, c); + outputs[ODDS_OUTPUT].setVoltage(0.0f, c); + outputs[EVENS_OUTPUT].setVoltage(0.0f, c); } } @@ -110,14 +199,40 @@ struct PEQ14XVWidget : ModuleWidget { addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); // generated by svg_widgets.rb - auto inInputPosition = Vec(9.0, 322.0); - - auto outOutputPosition = Vec(41.0, 322.0); + auto efDampParamPosition = Vec(12.0, 40.0); + auto efGainParamPosition = Vec(47.0, 40.0); + auto transposeParamPosition = Vec(24.5, 132.0); + auto outputGainParamPosition = Vec(12.0, 227.0); + auto band14MixParamPosition = Vec(47.0, 227.0); + auto band1EnableParamPosition = Vec(19.5, 262.0); + auto band14EnableParamPosition = Vec(57.0, 262.0); + + auto efDampInputPosition = Vec(8.0, 73.0); + auto efGainInputPosition = Vec(43.0, 73.0); + auto transposeInputPosition = Vec(25.5, 169.0); + auto inInputPosition = Vec(10.5, 290.0); + + auto oddsOutputPosition = Vec(40.5, 290.0); + auto outOutputPosition = Vec(10.5, 325.0); + auto evensOutputPosition = Vec(40.5, 325.0); // end generated by svg_widgets.rb + addParam(createParam<Knob16>(efDampParamPosition, module, PEQ14XV::EF_DAMP_PARAM)); + addParam(createParam<Knob16>(efGainParamPosition, module, PEQ14XV::EF_GAIN_PARAM)); + addParam(createParam<Knob26>(transposeParamPosition, module, PEQ14XV::TRANSPOSE_PARAM)); + addParam(createParam<Knob16>(outputGainParamPosition, module, PEQ14XV::OUTPUT_GAIN_PARAM)); + addParam(createParam<Knob16>(band14MixParamPosition, module, PEQ14XV::BAND14_MIX_PARAM)); + addParam(createParam<IndicatorButtonGreen9>(band1EnableParamPosition, module, PEQ14XV::BAND1_ENABLE_PARAM)); + addParam(createParam<IndicatorButtonGreen9>(band14EnableParamPosition, module, PEQ14XV::BAND14_ENABLE_PARAM)); + + addInput(createInput<Port24>(efDampInputPosition, module, PEQ14XV::EF_DAMP_INPUT)); + addInput(createInput<Port24>(efGainInputPosition, module, PEQ14XV::EF_GAIN_INPUT)); + addInput(createInput<Port24>(transposeInputPosition, module, PEQ14XV::TRANSPOSE_INPUT)); addInput(createInput<Port24>(inInputPosition, module, PEQ14XV::IN_INPUT)); + addOutput(createOutput<Port24>(oddsOutputPosition, module, PEQ14XV::ODDS_OUTPUT)); addOutput(createOutput<Port24>(outOutputPosition, module, PEQ14XV::OUT_OUTPUT)); + addOutput(createOutput<Port24>(evensOutputPosition, module, PEQ14XV::EVENS_OUTPUT)); } }; diff --git a/src/PEQ14XV.hpp b/src/PEQ14XV.hpp @@ -1,48 +1,80 @@ #pragma once #include "PEQ14_shared.hpp" -#include "dsp/filters/multimode.hpp" namespace bogaudio { -struct PEQ14XV : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, BGModule>> { +struct PEQ14XV : ExpanderModule<PEQ14ExpanderMessage, ExpandableModule<PEQ14ExpanderMessage, PEQXFBase>> { enum ParamsIds { + EF_DAMP_PARAM, + EF_GAIN_PARAM, + TRANSPOSE_PARAM, + OUTPUT_GAIN_PARAM, + BAND14_MIX_PARAM, + BAND1_ENABLE_PARAM, + BAND14_ENABLE_PARAM, NUM_PARAMS }; enum InputsIds { + EF_DAMP_INPUT, + EF_GAIN_INPUT, + TRANSPOSE_INPUT, IN_INPUT, NUM_INPUTS }; enum OutputsIds { + ODDS_OUTPUT, OUT_OUTPUT, + EVENS_OUTPUT, NUM_OUTPUTS }; struct Engine { MultimodeFilter* filters[14] {}; - Amplifier amplifiers[14]; + Amplifier amplifiers[14]; + RootMeanSquare efs[14]; + float response = -1.0f; + Amplifier efGain; + float transposeSemitones = 0.0f; - Engine(); - ~Engine(); + Engine(); + ~Engine(); + + void setSampleRate(float sr); }; + static constexpr float maxOutputGain = 24.0f; + float _sampleRate = 1000.0f; Engine* _engines[maxChannels] {}; + Amplifier _outputGain; + Amplifier _band14Mix; + bool _band1Enable = true; + bool _band14Enable = true; Saturator _saturator; PEQ14ExpanderMessage* _baseMessage = NULL; PEQ14XV() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(EF_DAMP_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); + configParam<EFGainParamQuantity>(EF_GAIN_PARAM, -1.0f, 1.0f, 0.0f, "Envelope follower gain", " dB"); + configParam(TRANSPOSE_PARAM, -1.0f, 1.0f, 0.0f, "Transpose", " semitones", 0.0f, 24.0f); + configParam(OUTPUT_GAIN_PARAM, 0.0f, 1.0f, 0.0f, "Output gain", " dB", 0.0f, maxOutputGain); + configParam<AmplifierParamQuantity>(BAND14_MIX_PARAM, 0.0f, 1.0f, 0.0f, "Band 14 audio mix"); + configParam(BAND1_ENABLE_PARAM, 0.0f, 1.0f, 1.0f, "Band 1 enable"); + configParam(BAND14_ENABLE_PARAM, 0.0f, 1.0f, 1.0f, "Band 14 enable"); - setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); - setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XO || m == modelPEQ14XR || m == modelPEQ14XV; }); + setBaseModelPredicate([](Model* m) { return m == modelPEQ14 || m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); + setExpanderModelPredicate([](Model* m) { return m == modelPEQ14XF || m == modelPEQ14XR || m == modelPEQ14XV; }); } void sampleRateChange() 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; }; diff --git a/src/PEQ14_shared.hpp b/src/PEQ14_shared.hpp @@ -5,7 +5,7 @@ #include "parametric_eq.hpp" extern Model* modelPEQ14; -extern Model* modelPEQ14XO; +extern Model* modelPEQ14XF; extern Model* modelPEQ14XR; extern Model* modelPEQ14XV; @@ -15,7 +15,6 @@ struct PEQ14ExpanderMessage : ExpanderMessage { bool valid = false; float outs[BGModule::maxChannels][14]; float frequencies[BGModule::maxChannels][14]; - float levels[BGModule::maxChannels][14]; float bandwidths[BGModule::maxChannels]; bool lowLP = false; bool highHP = false; @@ -29,7 +28,6 @@ struct PEQ14ExpanderMessage : ExpanderMessage { const int n = BGModule::maxChannels * 14; std::fill((float*)outs, (float*)outs + n, 0.0f); std::fill((float*)frequencies, (float*)frequencies + n, 0.0f); - std::fill((float*)levels, (float*)levels + n, 0.0f); std::fill((float*)bandwidths, (float*)bandwidths + BGModule::maxChannels, 0.0f); lowLP = false; highHP = false; @@ -40,7 +38,6 @@ struct PEQ14ExpanderMessage : ExpanderMessage { const int n = BGModule::maxChannels * 14; std::copy((float*)outs, (float*)outs + n, (float*)o->outs); std::copy((float*)frequencies, (float*)frequencies + n, (float*)o->frequencies); - std::copy((float*)levels, (float*)levels + n, (float*)o->levels); std::copy((float*)bandwidths, (float*)bandwidths + BGModule::maxChannels, (float*)o->bandwidths); o->lowLP = lowLP; o->highHP = highHP; diff --git a/src/PEQ6.cpp b/src/PEQ6.cpp @@ -5,9 +5,6 @@ void PEQ6::sampleRateChange() { float sr = APP->engine->getSampleRate(); for (int c = 0; c < _channels; ++c) { _engines[c]->setSampleRate(sr); - for (int i = 0; i < 6; ++i) { - _efs[c][i].setSampleRate(sr); - } } } @@ -43,9 +40,6 @@ void PEQ6::addChannel(int c) { void PEQ6::removeChannel(int c) { delete _engines[c]; _engines[c] = NULL; - for (int i = 0; i < 6; ++i) { - _efs[c][i].reset(); - } } void PEQ6::modulate() { @@ -60,36 +54,33 @@ void PEQ6::modulate() { e.setFrequencyMode(_fullFrequencyMode); e.modulate(); } - - float response = params[EF_RESPONSE_PARAM].getValue(); - if (_response != response) { - _response = response; - for (int c = 0; c < _channels; ++c) { - for (int i = 0; i < 6; ++i) { - _efs[c][i].setSensitivity(_response); - } - } - } } void PEQ6::processAlways(const ProcessArgs& args) { outputs[OUT_OUTPUT].setChannels(_channels); for (int i = 0; i < 6; ++i) { - outputs[EF1_OUTPUT + i].setChannels(_channels); + outputs[OUT1_OUTPUT + i].setChannels(_channels); } std::fill(_rmsSums, _rmsSums + 6, 0.0f); + + _expanderMessage = NULL; + if (expanderConnected()) { + _expanderMessage = toExpander(); + } } void PEQ6::processChannel(const ProcessArgs& args, int c) { PEQEngine& e = *_engines[c]; float out = e.next(inputs[IN_INPUT].getVoltage(c), _rmsSums); outputs[OUT_OUTPUT].setVoltage(out, c); - if (expanderConnected()) { - std::copy(e.outs, e.outs + 6, toExpander()->outs[c]); + for (int i = 0; i < 6; ++i) { + outputs[OUT1_OUTPUT + i].setVoltage(e.outs[i], c); } - for (int i = 0; i < 6; ++i) { - outputs[EF1_OUTPUT + i].setVoltage(2.0f * _efs[c][i].next(e.outs[i]), c); + if (_expanderMessage) { + std::copy(e.outs, e.outs + 6, _expanderMessage->outs[c]); + std::copy(e.frequencies, e.frequencies + 6, _expanderMessage->frequencies[c]); + _expanderMessage->bandwidths[c] = e.bandwidth; } } @@ -122,12 +113,11 @@ struct PEQ6Widget : ModuleWidget { addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365))); // generated by svg_widgets.rb - auto efResponseParamPosition = Vec(14.5, 28.0); - auto frequencyCvParamPosition = Vec(14.5, 69.0); - auto bandwidthParamPosition = Vec(14.5, 141.0); - auto lpParamPosition = Vec(35.5, 212.0); - auto hpParamPosition = Vec(35.5, 224.0); - auto fmodParamPosition = Vec(20.0, 268.0); + auto frequencyCvParamPosition = Vec(14.5, 47.0); + auto bandwidthParamPosition = Vec(14.5, 129.0); + auto lpParamPosition = Vec(35.5, 210.0); + auto hpParamPosition = Vec(35.5, 222.0); + auto fmodParamPosition = Vec(20.0, 267.0); auto level1ParamPosition = Vec(58.5, 28.0); auto frequency1ParamPosition = Vec(59.5, 184.0); auto frequencyCv1ParamPosition = Vec(59.5, 224.0); @@ -147,8 +137,8 @@ struct PEQ6Widget : ModuleWidget { auto frequency6ParamPosition = Vec(284.5, 183.0); auto frequencyCv6ParamPosition = Vec(284.5, 224.0); - auto frequencyCvInputPosition = Vec(10.5, 101.0); - auto bandwidthInputPosition = Vec(10.5, 176.0); + auto frequencyCvInputPosition = Vec(10.5, 79.0); + auto bandwidthInputPosition = Vec(10.5, 163.0); auto inInputPosition = Vec(10.5, 290.0); auto level1InputPosition = Vec(55.5, 255.0); auto frequencyCv1InputPosition = Vec(55.5, 290.0); @@ -164,18 +154,17 @@ struct PEQ6Widget : ModuleWidget { auto frequencyCv6InputPosition = Vec(280.5, 290.0); auto outOutputPosition = Vec(10.5, 325.0); - auto ef1OutputPosition = Vec(55.5, 325.0); - auto ef2OutputPosition = Vec(100.5, 325.0); - auto ef3OutputPosition = Vec(145.5, 325.0); - auto ef4OutputPosition = Vec(190.5, 325.0); - auto ef5OutputPosition = Vec(235.5, 325.0); - auto ef6OutputPosition = Vec(280.5, 325.0); - - auto fmodRelativeLightPosition = Vec(16.0, 244.0); - auto fmodFullLightPosition = Vec(16.0, 257.0); + auto out1OutputPosition = Vec(55.5, 325.0); + auto out2OutputPosition = Vec(100.5, 325.0); + auto out3OutputPosition = Vec(145.5, 325.0); + auto out4OutputPosition = Vec(190.5, 325.0); + auto out5OutputPosition = Vec(235.5, 325.0); + auto out6OutputPosition = Vec(280.5, 325.0); + + auto fmodRelativeLightPosition = Vec(16.0, 243.0); + auto fmodFullLightPosition = Vec(16.0, 256.0); // end generated by svg_widgets.rb - addParam(createParam<Knob16>(efResponseParamPosition, module, PEQ6::EF_RESPONSE_PARAM)); addParam(createParam<Knob16>(frequencyCvParamPosition, module, PEQ6::FREQUENCY_CV_PARAM)); addParam(createParam<Knob16>(bandwidthParamPosition, module, PEQ6::BANDWIDTH_PARAM)); addParam(createParam<IndicatorButtonGreen9>(lpParamPosition, module, PEQ6::LP_PARAM)); @@ -217,12 +206,12 @@ struct PEQ6Widget : ModuleWidget { addInput(createInput<Port24>(frequencyCv6InputPosition, module, PEQ6::FREQUENCY_CV6_INPUT)); addOutput(createOutput<Port24>(outOutputPosition, module, PEQ6::OUT_OUTPUT)); - addOutput(createOutput<Port24>(ef1OutputPosition, module, PEQ6::EF1_OUTPUT)); - addOutput(createOutput<Port24>(ef2OutputPosition, module, PEQ6::EF2_OUTPUT)); - addOutput(createOutput<Port24>(ef3OutputPosition, module, PEQ6::EF3_OUTPUT)); - addOutput(createOutput<Port24>(ef4OutputPosition, module, PEQ6::EF4_OUTPUT)); - addOutput(createOutput<Port24>(ef5OutputPosition, module, PEQ6::EF5_OUTPUT)); - addOutput(createOutput<Port24>(ef6OutputPosition, module, PEQ6::EF6_OUTPUT)); + addOutput(createOutput<Port24>(out1OutputPosition, module, PEQ6::OUT1_OUTPUT)); + addOutput(createOutput<Port24>(out2OutputPosition, module, PEQ6::OUT2_OUTPUT)); + addOutput(createOutput<Port24>(out3OutputPosition, module, PEQ6::OUT3_OUTPUT)); + addOutput(createOutput<Port24>(out4OutputPosition, module, PEQ6::OUT4_OUTPUT)); + addOutput(createOutput<Port24>(out5OutputPosition, module, PEQ6::OUT5_OUTPUT)); + addOutput(createOutput<Port24>(out6OutputPosition, module, PEQ6::OUT6_OUTPUT)); addChild(createLight<SmallLight<GreenLight>>(fmodFullLightPosition, module, PEQ6::FMOD_FULL_LIGHT)); addChild(createLight<SmallLight<GreenLight>>(fmodRelativeLightPosition, module, PEQ6::FMOD_RELATIVE_LIGHT)); diff --git a/src/PEQ6.hpp b/src/PEQ6.hpp @@ -6,7 +6,6 @@ namespace bogaudio { struct PEQ6 : ExpandableModule<PEQ6ExpanderMessage, BGModule> { enum ParamsIds { - EF_RESPONSE_PARAM, FREQUENCY_CV_PARAM, BANDWIDTH_PARAM, LP_PARAM, @@ -54,12 +53,12 @@ struct PEQ6 : ExpandableModule<PEQ6ExpanderMessage, BGModule> { enum OutputsIds { OUT_OUTPUT, - EF1_OUTPUT, - EF2_OUTPUT, - EF3_OUTPUT, - EF4_OUTPUT, - EF5_OUTPUT, - EF6_OUTPUT, + OUT1_OUTPUT, + OUT2_OUTPUT, + OUT3_OUTPUT, + OUT4_OUTPUT, + OUT5_OUTPUT, + OUT6_OUTPUT, NUM_OUTPUTS }; @@ -72,14 +71,12 @@ struct PEQ6 : ExpandableModule<PEQ6ExpanderMessage, BGModule> { PEQEngine* _engines[maxChannels] {}; float _rmsSums[6] {}; float _rms[6] {}; - RootMeanSquare _efs[maxChannels][6]; - float _response = -1.0f; bool _fullFrequencyMode = false; + PEQ6ExpanderMessage* _expanderMessage = NULL; PEQ6() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); float levelDefault = fabsf(PEQChannel::minDecibels) / (PEQChannel::maxDecibels - PEQChannel::minDecibels); - configParam(EF_RESPONSE_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); configParam(FREQUENCY_CV_PARAM, -1.0f, 1.0f, 0.0f, "Global frequency CV attenuation", "%", 0.0f, 100.0f); configParam(BANDWIDTH_PARAM, 0.0f, 1.0f, 0.33f, "Bandwidth", "%", 0.0f, 100.0f); configParam(LP_PARAM, 0.0f, 1.0f, 1.0f, "Channel 1 LP/BP"); @@ -104,7 +101,7 @@ struct PEQ6 : ExpandableModule<PEQ6ExpanderMessage, BGModule> { configParam<ScaledSquaringParamQuantity<(int)PEQChannel::maxFrequency>>(FREQUENCY6_PARAM, 0.0f, 1.0f, 0.3535534f, "Channel 6 frequency", " HZ"); configParam(FREQUENCY_CV6_PARAM, -1.0f, 1.0f, 1.0f, "Channel 6 frequency CV attenuation", "%", 0.0f, 100.0f); - setExpanderModelPredicate([](Model* m) { return m == modelPEQ6XO; }); + setExpanderModelPredicate([](Model* m) { return m == modelPEQ6XF; }); } void sampleRateChange() override; diff --git a/src/PEQ6XF.cpp b/src/PEQ6XF.cpp @@ -0,0 +1,117 @@ + +#include "PEQ6XF.hpp" + +void PEQ6XF::sampleRateChange() { + float sr = APP->engine->getSampleRate(); + for (int c = 0; c < _channels; ++c) { + for (int i = 0; i < 6; ++i) { + _engines[c]->efs[i].setSampleRate(sr); + } + } +} + +void PEQ6XF::addChannel(int c) { + _engines[c] = new Engine(); + float sr = APP->engine->getSampleRate(); + for (int i = 0; i < 6; ++i) { + _engines[c]->efs[i].setSampleRate(sr); + } +} + +void PEQ6XF::removeChannel(int c) { + delete _engines[c]; + _engines[c] = NULL; +} + +void PEQ6XF::modulate() { + float response = params[DAMP_PARAM].getValue(); + if (_response != response) { + _response = response; + for (int c = 0; c < _channels; ++c) { + for (int i = 0; i < 6; ++i) { + _engines[c]->efs[i].setSensitivity(_response); + } + } + } + + float db = clamp(params[GAIN_PARAM].getValue(), -1.0f, 1.0f); + if (db < 0.0f) { + db = -db * efGainMinDecibels; + } + else { + db *= std::min(12.0f, efGainMaxDecibels); + } + _gain.setLevel(db); +} + +void PEQ6XF::processAll(const ProcessArgs& args) { + for (int i = 0; i < 6; ++i) { + outputs[EF1_OUTPUT + i].setChannels(_channels); + } + + _baseMessage = NULL; + if (baseConnected()) { + _baseMessage = fromBase(); + } +} + +void PEQ6XF::processChannel(const ProcessArgs& args, int c) { + if (_baseMessage) { + Engine& e = *_engines[c]; + for (int i = 0; i < 6; ++i) { + float out = e.efs[i].next(_baseMessage->outs[c][i]); + out = scaleEF(out, _baseMessage->frequencies[c][i], _baseMessage->bandwidths[c]); + out = _gain.next(out); + out = _saturator.next(out); + outputs[EF1_OUTPUT + i].setVoltage(out, c); + } + } + else { + for (int i = 0; i < 6; ++i) { + outputs[EF1_OUTPUT + i].setVoltage(0.0f, c); + } + } +} + +struct PEQ6XFWidget : ModuleWidget { + static constexpr int hp = 3; + + PEQ6XFWidget(PEQ6XF* 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/PEQ6XF.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto dampParamPosition = Vec(14.5, 32.0); + auto gainParamPosition = Vec(14.5, 71.0); + + auto ef1OutputPosition = Vec(10.5, 107.0); + auto ef2OutputPosition = Vec(10.5, 142.0); + auto ef3OutputPosition = Vec(10.5, 177.0); + auto ef4OutputPosition = Vec(10.5, 212.0); + auto ef5OutputPosition = Vec(10.5, 247.0); + auto ef6OutputPosition = Vec(10.5, 282.0); + // end generated by svg_widgets.rb + + addParam(createParam<Knob16>(dampParamPosition, module, PEQ6XF::DAMP_PARAM)); + addParam(createParam<Knob16>(gainParamPosition, module, PEQ6XF::GAIN_PARAM)); + + addOutput(createOutput<Port24>(ef1OutputPosition, module, PEQ6XF::EF1_OUTPUT)); + addOutput(createOutput<Port24>(ef2OutputPosition, module, PEQ6XF::EF2_OUTPUT)); + addOutput(createOutput<Port24>(ef3OutputPosition, module, PEQ6XF::EF3_OUTPUT)); + addOutput(createOutput<Port24>(ef4OutputPosition, module, PEQ6XF::EF4_OUTPUT)); + addOutput(createOutput<Port24>(ef5OutputPosition, module, PEQ6XF::EF5_OUTPUT)); + addOutput(createOutput<Port24>(ef6OutputPosition, module, PEQ6XF::EF6_OUTPUT)); + } +}; + +Model* modelPEQ6XF = createModel<PEQ6XF, PEQ6XFWidget>("Bogaudio-PEQ6XF", "PEQ6XF", "PEQ6 envelope followers expander", "Filter", "Expander", "Polyphonic"); diff --git a/src/PEQ6XF.hpp b/src/PEQ6XF.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include "PEQ6_shared.hpp" + +namespace bogaudio { + +struct PEQ6XF : ExpanderModule<PEQ6ExpanderMessage, PEQXFBase> { + enum ParamsIds { + DAMP_PARAM, + GAIN_PARAM, + NUM_PARAMS + }; + + enum InputsIds { + NUM_INPUTS + }; + + enum OutputsIds { + EF1_OUTPUT, + EF2_OUTPUT, + EF3_OUTPUT, + EF4_OUTPUT, + EF5_OUTPUT, + EF6_OUTPUT, + NUM_OUTPUTS + }; + + struct Engine { + RootMeanSquare efs[6]; + }; + + Engine* _engines[maxChannels] {}; + float _response = -1.0f; + Amplifier _gain; + Saturator _saturator; + PEQ6ExpanderMessage* _baseMessage = NULL; + + PEQ6XF() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + configParam(DAMP_PARAM, 0.0f, 1.0f, 0.3f, "Envelope follower response", "%", 0.0f, 100.0f); + configParam<EFGainParamQuantity>(GAIN_PARAM, -1.0f, 1.0f, 0.0f, "Envelope follower gain", " dB"); + + setBaseModelPredicate([](Model* m) { return m == modelPEQ6; }); + } + + void sampleRateChange() override; + void addChannel(int c) override; + void removeChannel(int c) override; + void modulate() override; + void processAll(const ProcessArgs& args) override; + void processChannel(const ProcessArgs& args, int c) override; +}; + +} // namespace bogaudio diff --git a/src/PEQ6XO.cpp b/src/PEQ6XO.cpp @@ -1,59 +0,0 @@ - -#include "PEQ6XO.hpp" - -void PEQ6XO::processAll(const ProcessArgs& args) { - for (int i = 0; i < 6; ++i) { - outputs[BAND1_OUTPUT + i].setChannels(_channels); - } -} - -void PEQ6XO::processChannel(const ProcessArgs& args, int c) { - if (baseConnected()) { - float* outs = fromBase()->outs[c]; - for (int i = 0; i < 6; ++i) { - outputs[BAND1_OUTPUT + i].setVoltage(outs[i], c); - } - } - else { - for (int i = 0; i < 6; ++i) { - outputs[BAND1_OUTPUT + i].setVoltage(0.0f, c); - } - } -} - -struct PEQ6XOWidget : ModuleWidget { - static constexpr int hp = 3; - - PEQ6XOWidget(PEQ6XO* 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/PEQ6XO.svg"))); - addChild(panel); - } - - addChild(createWidget<ScrewSilver>(Vec(0, 0))); - addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); - - // generated by svg_widgets.rb - auto band1OutputPosition = Vec(10.5, 43.0); - auto band2OutputPosition = Vec(10.5, 78.0); - auto band3OutputPosition = Vec(10.5, 113.0); - auto band4OutputPosition = Vec(10.5, 148.0); - auto band5OutputPosition = Vec(10.5, 183.0); - auto band6OutputPosition = Vec(10.5, 218.0); - // end generated by svg_widgets.rb - - addOutput(createOutput<Port24>(band1OutputPosition, module, PEQ6XO::BAND1_OUTPUT)); - addOutput(createOutput<Port24>(band2OutputPosition, module, PEQ6XO::BAND2_OUTPUT)); - addOutput(createOutput<Port24>(band3OutputPosition, module, PEQ6XO::BAND3_OUTPUT)); - addOutput(createOutput<Port24>(band4OutputPosition, module, PEQ6XO::BAND4_OUTPUT)); - addOutput(createOutput<Port24>(band5OutputPosition, module, PEQ6XO::BAND5_OUTPUT)); - addOutput(createOutput<Port24>(band6OutputPosition, module, PEQ6XO::BAND6_OUTPUT)); - } -}; - -Model* modelPEQ6XO = createModel<PEQ6XO, PEQ6XOWidget>("Bogaudio-PEQ6XO", "PEQ6XO", "PEQ6 band outputs expander", "Filter", "Expander", "Polyphonic"); diff --git a/src/PEQ6XO.hpp b/src/PEQ6XO.hpp @@ -1,35 +0,0 @@ -#pragma once - -#include "PEQ6_shared.hpp" - -namespace bogaudio { - -struct PEQ6XO : ExpanderModule<PEQ6ExpanderMessage, BGModule> { - enum ParamsIds { - NUM_PARAMS - }; - - enum InputsIds { - NUM_INPUTS - }; - - enum OutputsIds { - BAND1_OUTPUT, - BAND2_OUTPUT, - BAND3_OUTPUT, - BAND4_OUTPUT, - BAND5_OUTPUT, - BAND6_OUTPUT, - NUM_OUTPUTS - }; - - PEQ6XO() { - config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); - setBaseModelPredicate([](Model* m) { return m == modelPEQ6; }); - } - - void processAll(const ProcessArgs& args) override; - void processChannel(const ProcessArgs& args, int c) override; -}; - -} // namespace bogaudio diff --git a/src/PEQ6_shared.hpp b/src/PEQ6_shared.hpp @@ -5,18 +5,14 @@ #include "parametric_eq.hpp" extern Model* modelPEQ6; -extern Model* modelPEQ6XO; +extern Model* modelPEQ6XF; namespace bogaudio { struct PEQ6ExpanderMessage : ExpanderMessage { - float outs[BGModule::maxChannels][6]; - - PEQ6ExpanderMessage() { - for (int c = 0; c < BGModule::maxChannels; ++c) { - std::fill(outs[c], outs[c] + 6, 0.0f); - } - } + float outs[BGModule::maxChannels][6] {}; + float frequencies[BGModule::maxChannels][6] {}; + float bandwidths[BGModule::maxChannels] {}; }; } // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -58,9 +58,9 @@ #include "Pan.hpp" #include "PEQ.hpp" #include "PEQ6.hpp" -#include "PEQ6XO.hpp" +#include "PEQ6XF.hpp" #include "PEQ14.hpp" -#include "PEQ14XO.hpp" +#include "PEQ14XF.hpp" #include "PEQ14XR.hpp" #include "PEQ14XV.hpp" #include "Pgmr.hpp" @@ -129,11 +129,10 @@ void init(rack::Plugin *p) { p->addModel(modelEQS); p->addModel(modelPEQ); p->addModel(modelPEQ6); - p->addModel(modelPEQ6XO); + p->addModel(modelPEQ6XF); p->addModel(modelPEQ14); - p->addModel(modelPEQ14XO); + p->addModel(modelPEQ14XF); p->addModel(modelPEQ14XV); - p->addModel(modelPEQ14XR); p->addModel(modelDADSRH); p->addModel(modelDADSRHPlus); @@ -220,6 +219,7 @@ void init(rack::Plugin *p) { #ifdef EXPERIMENTAL p->addModel(modelLag); + p->addModel(modelPEQ14XR); #endif #ifdef TEST diff --git a/src/parametric_eq.cpp b/src/parametric_eq.cpp @@ -114,3 +114,15 @@ float PEQEngine::next(float sample, float* rmsSums) { } return _saturator.next(out); } + + +float PEQXFBase::scaleEF(float ef, float frequency, float bandwidth) { + bandwidth = (bandwidth - MultimodeFilter::minQbw) / (MultimodeFilter::maxQbw - MultimodeFilter::minQbw); + bandwidth *= MultimodeFilter::maxBWPitch; + float minf = std::max(0.0f, powf(2.0f, -bandwidth) * frequency); + float maxf = std::min(PEQChannel::maxFrequency, powf(2.0f, bandwidth) * frequency); + float scale = (2.0f * (maxf - minf)) / PEQChannel::maxFrequency; + scale = 1.0f / scale; + scale = sqrtf(scale); // FIXME: someday prove this is correct. + return 2.0f * scale * ef; +} diff --git a/src/parametric_eq.hpp b/src/parametric_eq.hpp @@ -1,6 +1,7 @@ #pragma once #include "bogaudio.hpp" +#include "filters/equalizer.hpp" #include "filters/multimode.hpp" #include "dsp/signal.hpp" @@ -142,4 +143,12 @@ struct PEQEngine { float next(float sample, float* rmsSums); }; +struct PEQXFBase : BGModule { + typedef EQParamQuantity EFGainParamQuantity; + static constexpr float efGainMinDecibels = Equalizer::cutDb; + static constexpr float efGainMaxDecibels = Equalizer::gainDb; + + float scaleEF(float ef, float frequency, float bandwidth); +}; + } // namespace bogaudio