diff --git a/Makefile b/Makefile
index a13b536..35d2db4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
SLUG = Bidoo
-VERSION = 0.5.18
+VERSION = 0.5.19
FLAGS = -I./pffft -DPFFFT_SIMD_DISABLE
-SOURCES = $(wildcard src/*.cpp src/dep/audiofile/*cpp src/dep/pffft/*c)
+SOURCES = $(wildcard src/*.cpp src/dep/audiofile/*cpp src/dep/pffft/*c src/dep/filters/*cpp)
DISTRIBUTABLES += $(wildcard LICENSE*) res
diff --git a/README.md b/README.md
index 2b22f1d..f861803 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Bidoo's plugins for [VCVRack](https://vcvrack.com)
-![Version](https://img.shields.io/badge/version-0.5.18-green.svg?style=flat-square)
+![Version](https://img.shields.io/badge/version-0.5.19-green.svg?style=flat-square)
![License](https://img.shields.io/badge/license-BSD3-blue.svg?style=flat-square)
![Language](https://img.shields.io/badge/language-C++-yellow.svg?style=flat-square)
@@ -13,11 +13,16 @@ You can find information on that plugins pack in the [wiki](https://github.com/s
## Last changes
-0.5.18
+0.5.19
-lIMbO
+lIMbO the 4th order ladder filter has a second mode i.e. "non linear". In that mode the GAIN control is no more a gain on the output but a gain on the tanh() that introduces non linearity.
+
+pErCO is a step in my journey across filters. To achieve the next plugin I needed a BP filter so I tried this approach. The result is a very simple 1st order LP, BP, HP filter.
+
+ziNC is the plugin I wanted to do with filters. It is a 16 band vocoder. I started this plugin with pErCO's BP but I needed more selective filters so I finally used 4 poles BP.
+If you are interested in filter design and more generally in dsp I recommend that website http://www.earlevel.com.
+Controls are gains for the 16 bands. Attack and Decay for the envelop follower and gain stages for MODulator, CARRier and OUTput.
-lIMbO is a ladder LPF. Based on Will Pirkle's courses & Vadim Zavalishin's book.
## License
diff --git a/images/pack.png b/images/pack.png
index 9bf74ce..1006e70 100644
Binary files a/images/pack.png and b/images/pack.png differ
diff --git a/res/LIMBO.svg b/res/LIMBO.svg
index e5e2020..e419258 100644
--- a/res/LIMBO.svg
+++ b/res/LIMBO.svg
@@ -78,7 +78,7 @@
+ style="opacity:0.08;fill:#000000;stroke-width:0.17951877" />
@@ -90,23 +90,23 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:125%;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
aria-label="bId°°">
@@ -115,23 +115,23 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:125%;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
aria-label="lIMbO">
@@ -148,15 +148,15 @@
transform="rotate(-179.84442)"
aria-label="OUT">
@@ -174,11 +174,11 @@
transform="rotate(-179.84442)"
aria-label="IN">
@@ -188,138 +188,194 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
aria-label="FREQ">
+ id="path914"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 6.6290871,35.181533 q 0.107487,0.02756 0.1832791,0.10473 0.075792,0.07579 0.1887912,0.304547 l 0.2797417,0.562239 H 6.9818649 l -0.2452908,-0.51952 q -0.106109,-0.221864 -0.1915473,-0.285254 -0.08406,-0.06477 -0.2204862,-0.06477 H 6.0585793 v 0.869542 H 5.7788375 v -2.057411 h 0.5732639 q 0.3389974,0 0.5195204,0.152963 0.180523,0.152962 0.180523,0.44235 0,0.20395 -0.1116211,0.333485 -0.110243,0.128158 -0.3114366,0.157097 z m -0.5705078,-0.85714 v 0.73036 h 0.3045464 q 0.1998155,0 0.2976563,-0.08957 0.097841,-0.08957 0.097841,-0.27423 0,-0.177767 -0.1047309,-0.271474 -0.1033529,-0.09508 -0.3017904,-0.09508 z" />
+ id="path916"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 7.5509946,34.095638 h 1.2209419 v 0.234267 H 7.8293583 v 0.609093 h 0.901237 v 0.234266 h -0.901237 v 0.745519 h 0.9687609 v 0.234266 H 7.5509946 Z" />
+ id="path918"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 10.371839,34.165918 v 0.282498 q -0.12678,-0.0813 -0.254937,-0.122645 -0.1267798,-0.04134 -0.2563153,-0.04134 -0.1970595,0 -0.3114367,0.09233 -0.1143772,0.09095 -0.1143772,0.246669 0,0.136426 0.074414,0.208084 0.075792,0.07166 0.2811198,0.119889 l 0.1460721,0.03307 q 0.2893883,0.06752 0.4216793,0.212218 0.132292,0.144694 0.132292,0.394119 0,0.293522 -0.181901,0.447862 -0.181901,0.154341 -0.5291667,0.154341 -0.144694,0 -0.2907661,-0.03169 -0.146072,-0.03032 -0.2935221,-0.09233 v -0.296278 q 0.1584744,0.100597 0.2990343,0.14745 0.1419379,0.04685 0.2852539,0.04685 0.2108398,0 0.3279727,-0.09371 0.117134,-0.09509 0.117134,-0.264584 0,-0.15434 -0.08131,-0.235644 -0.07993,-0.0813 -0.2797414,-0.125402 L 9.7145095,35.213225 Q 9.4278776,35.148455 9.298342,35.017544 9.1688064,34.88663 9.1688064,34.666144 q 0,-0.275607 0.1846571,-0.440972 0.1860352,-0.166743 0.4933377,-0.166743 0.1185113,0 0.2494248,0.02756 0.130914,0.02618 0.275608,0.07993 z" />
+ id="path921"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 22.029788,35.983555 q -0.111621,0.103352 -0.252181,0.157096 -0.139181,0.05237 -0.30179,0.05237 -0.391363,0 -0.609093,-0.279741 -0.21773,-0.28112 -0.21773,-0.78686 0,-0.504362 0.220486,-0.785482 0.220486,-0.282498 0.613227,-0.282498 0.129536,0 0.248047,0.03721 0.118511,0.03583 0.228755,0.110243 v 0.285254 q -0.111622,-0.106109 -0.228755,-0.155718 -0.117133,-0.05099 -0.248047,-0.05099 -0.271473,0 -0.407899,0.21084 -0.135048,0.209462 -0.135048,0.631142 0,0.42857 0.130914,0.635275 0.132292,0.205328 0.405143,0.205328 0.09233,0 0.161231,-0.02067 0.07028,-0.02205 0.126779,-0.06752 V 35.32623 h -0.299034 v -0.228754 h 0.564995 z" />
+ id="path923"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 23.055049,34.340933 -0.293522,1.052821 h 0.587044 z m -0.168121,-0.245291 h 0.33762 l 0.629763,2.057411 h -0.28801 l -0.151584,-0.536057 h -0.720714 l -0.148828,0.536057 h -0.28801 z" />
+ id="path925"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="M 24.180906,34.095642 H 25.3233 v 0.234267 h -0.431326 v 1.588878 H 25.3233 v 0.234266 h -1.142394 v -0.234266 h 0.431326 v -1.588878 h -0.431326 z" />
+ id="path927"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 25.793211,34.095642 h 0.352778 l 0.694531,1.693609 v -1.693609 h 0.268717 v 2.057411 H 26.75646 l -0.694532,-1.693609 v 1.693609 h -0.268717 z" />
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:125%;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ aria-label="F.MOD">
+ id="path930"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 4.1375941,51.445732 h 1.2112955 v 0.234267 H 4.4173358 v 0.606337 h 0.8447374 v 0.234266 H 4.4173358 v 0.982541 H 4.1375941 Z" />
+ id="path932"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 6.1881149,53.082842 h 0.3472656 v 0.420301 H 6.1881149 Z" />
+ id="path934"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 7.3305086,51.445732 h 0.3720703 l 0.3555338,1.047309 0.35829,-1.047309 H 8.789851 v 2.057411 H 8.5321579 V 51.685511 L 8.1655997,52.770027 H 7.9547599 L 7.5868237,51.685511 v 1.817632 H 7.3305086 Z" />
+ id="path936"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
+ d="m 10.156865,52.476505 q 0,-0.453375 -0.09371,-0.647678 -0.092328,-0.194303 -0.304546,-0.194303 -0.2108399,0 -0.3045465,0.194303 -0.092329,0.194303 -0.092329,0.647678 0,0.451996 0.092329,0.6463 0.093707,0.194303 0.3045465,0.194303 0.2122179,0 0.304546,-0.192925 0.09371,-0.194304 0.09371,-0.647678 z m 0.290766,0 q 0,0.537435 -0.170877,0.802018 -0.169498,0.264583 -0.518142,0.264583 -0.3486437,0 -0.5181424,-0.263205 -0.1694987,-0.263205 -0.1694987,-0.803396 0,-0.538813 0.1694987,-0.803396 0.1708768,-0.264584 0.5181424,-0.264584 0.348644,0 0.518142,0.264584 0.170877,0.264583 0.170877,0.803396 z" />
+
+ d="m 3.3642882,70.513237 h 1.2112955 v 0.234267 H 3.6440299 v 0.606336 h 0.8447374 v 0.234267 H 3.6440299 v 0.982541 H 3.3642882 Z" />
+ d="m 5.7882574,71.599131 q 0.1074869,0.02756 0.183279,0.104731 0.075792,0.07579 0.1887913,0.304547 l 0.2797417,0.562239 H 6.1410351 L 5.8957443,72.051128 Q 5.7896354,71.829264 5.704197,71.765874 5.6201367,71.701106 5.4837109,71.701106 H 5.2177495 v 0.869542 H 4.9380078 v -2.057411 h 0.5732639 q 0.3389974,0 0.5195204,0.152962 0.180523,0.152963 0.180523,0.442351 0,0.203949 -0.1116211,0.333485 -0.1102431,0.128157 -0.3114366,0.157096 z M 5.2177495,70.741992 v 0.73036 H 5.522296 q 0.1998155,0 0.2976562,-0.08957 0.097841,-0.08957 0.097841,-0.274229 0,-0.177767 -0.1047309,-0.271474 -0.1033528,-0.09508 -0.3017903,-0.09508 z" />
+ d="m 6.7101649,70.513237 h 1.2209418 v 0.234267 H 6.9885286 v 0.609093 h 0.901237 v 0.234266 h -0.901237 v 0.745519 h 0.9687609 v 0.234266 H 6.7101649 Z" />
+ d="m 9.0390496,72.607855 q -0.00965,0 -0.027561,0.0014 -0.017914,0.0014 -0.028939,0.0014 -0.3445095,0 -0.5153863,-0.264583 Q 8.297665,72.081445 8.297665,71.54401 q 0,-0.538813 0.1694987,-0.803397 0.1708768,-0.264583 0.5181424,-0.264583 0.3486437,0 0.5181423,0.264583 0.1708768,0.264584 0.1708768,0.803397 0,0.405143 -0.095085,0.65319 -0.093707,0.246669 -0.285254,0.345887 l 0.2756077,0.261828 -0.2080838,0.137804 z M 9.3835591,71.54401 q 0,-0.453375 -0.093707,-0.647678 -0.092329,-0.194304 -0.3045464,-0.194304 -0.2108399,0 -0.3045465,0.194304 -0.092329,0.194303 -0.092329,0.647678 0,0.451996 0.092329,0.6463 0.093707,0.194303 0.3045465,0.194303 0.2122179,0 0.3045464,-0.192925 0.093707,-0.194304 0.093707,-0.647678 z" />
+ d="m 14.032844,71.765185 q 0.107487,0.02756 0.183279,0.104731 0.07579,0.07579 0.188791,0.304546 l 0.279742,0.56224 h -0.299035 l -0.24529,-0.51952 q -0.106109,-0.221865 -0.191548,-0.285254 -0.08406,-0.06477 -0.220486,-0.06477 H 13.462336 V 72.7367 h -0.279742 v -2.057411 h 0.573264 q 0.338997,0 0.51952,0.152962 0.180523,0.152962 0.180523,0.44235 0,0.20395 -0.111621,0.333486 -0.110243,0.128157 -0.311436,0.157096 z m -0.570508,-0.85714 v 0.730361 h 0.304546 q 0.199816,0 0.297657,-0.08957 0.09784,-0.08957 0.09784,-0.27423 0,-0.177766 -0.104731,-0.271473 -0.103352,-0.09508 -0.30179,-0.09508 z" />
+ d="m 14.954751,70.679291 h 1.220942 v 0.234266 h -0.942578 v 0.609093 h 0.901237 v 0.234267 h -0.901237 v 0.745518 h 0.968761 v 0.234267 h -1.247125 z" />
+ d="m 17.775595,70.749571 v 0.282498 q -0.126779,-0.08131 -0.254937,-0.122646 -0.126779,-0.04134 -0.256315,-0.04134 -0.197059,0 -0.311436,0.09233 -0.114378,0.09095 -0.114378,0.246669 0,0.136425 0.07441,0.208083 0.07579,0.07166 0.281119,0.11989 l 0.146072,0.03307 q 0.289388,0.06752 0.42168,0.212217 0.132292,0.144694 0.132292,0.394119 0,0.293523 -0.181901,0.447863 -0.181901,0.15434 -0.529167,0.15434 -0.144694,0 -0.290766,-0.03169 -0.146072,-0.03032 -0.293522,-0.09233 v -0.296279 q 0.158474,0.100597 0.299034,0.147451 0.141938,0.04685 0.285254,0.04685 0.21084,0 0.327973,-0.09371 0.117133,-0.09508 0.117133,-0.264583 0,-0.15434 -0.0813,-0.235645 -0.07993,-0.0813 -0.279742,-0.125401 l -0.148828,-0.03445 q -0.286632,-0.06477 -0.416167,-0.195682 -0.129536,-0.130913 -0.129536,-0.351399 0,-0.275608 0.184657,-0.440972 0.186035,-0.166743 0.493338,-0.166743 0.118511,0 0.249425,0.02756 0.130913,0.02618 0.275607,0.07993 z" />
+ d="m 22.940492,72.567203 q -0.111621,0.103353 -0.252181,0.157097 -0.139182,0.05236 -0.30179,0.05236 -0.391363,0 -0.609093,-0.279742 -0.21773,-0.281119 -0.21773,-0.786859 0,-0.504362 0.220486,-0.785482 0.220486,-0.282498 0.613227,-0.282498 0.129536,0 0.248047,0.03721 0.118511,0.03583 0.228754,0.110243 v 0.285254 q -0.111621,-0.106109 -0.228754,-0.155718 -0.117133,-0.05099 -0.248047,-0.05099 -0.271474,0 -0.407899,0.21084 -0.135048,0.209462 -0.135048,0.631142 0,0.428569 0.130914,0.635275 0.132291,0.205328 0.405143,0.205328 0.09233,0 0.16123,-0.02067 0.07028,-0.02205 0.12678,-0.06752 V 71.90988 h -0.299035 v -0.228754 h 0.564996 z" />
+ d="m 23.965753,70.924582 -0.293523,1.052821 h 0.587045 z m -0.168121,-0.245291 h 0.337619 l 0.629764,2.057411 h -0.28801 l -0.151584,-0.536057 h -0.720714 l -0.148829,0.536057 h -0.28801 z" />
+ d="m 25.09161,70.679291 h 1.142393 v 0.234266 h -0.431326 v 1.588878 h 0.431326 v 0.234267 H 25.09161 v -0.234267 h 0.431326 V 70.913557 H 25.09161 Z" />
+ d="m 26.703915,70.679291 h 0.352777 l 0.694532,1.693609 v -1.693609 h 0.268717 v 2.057411 h -0.352778 l -0.694531,-1.693609 v 1.693609 h -0.268717 z" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/LIMBOtemp.svg b/res/LIMBOtemp.svg
index fd08f94..4a5e204 100644
--- a/res/LIMBOtemp.svg
+++ b/res/LIMBOtemp.svg
@@ -28,9 +28,9 @@
inkscape:window-height="1017"
id="namedview118"
showgrid="true"
- inkscape:zoom="1.1137255"
- inkscape:cx="-255.48368"
- inkscape:cy="298.63246"
+ inkscape:zoom="2.227451"
+ inkscape:cx="-15.814717"
+ inkscape:cy="134.24544"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
@@ -108,7 +108,7 @@
inkscape:connector-curvature="0" />
@@ -218,70 +218,112 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777766px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr;text-anchor:start;stroke-width:0.26458332px;">FREQ
RES
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px">RES
GAIN
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px">GAIN
F.CV
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px">F.MOD
FREQ
RES
GAIN
-
+ NON LIN
+ LIN
+
diff --git a/res/PERCO.svg b/res/PERCO.svg
new file mode 100644
index 0000000..75d67cd
--- /dev/null
+++ b/res/PERCO.svg
@@ -0,0 +1,339 @@
+
+
diff --git a/res/PERCOtemp.svg b/res/PERCOtemp.svg
new file mode 100644
index 0000000..879c693
--- /dev/null
+++ b/res/PERCOtemp.svg
@@ -0,0 +1,331 @@
+
+
diff --git a/res/ZINC.svg b/res/ZINC.svg
new file mode 100644
index 0000000..1177347
--- /dev/null
+++ b/res/ZINC.svg
@@ -0,0 +1,266 @@
+
+
diff --git a/res/ZINCtemp.svg b/res/ZINCtemp.svg
new file mode 100644
index 0000000..8cd004c
--- /dev/null
+++ b/res/ZINCtemp.svg
@@ -0,0 +1,272 @@
+
+
diff --git a/src/Bidoo.cpp b/src/Bidoo.cpp
index 7bf3ec5..8e67d36 100644
--- a/src/Bidoo.cpp
+++ b/src/Bidoo.cpp
@@ -25,4 +25,6 @@ void init(rack::Plugin *p) {
p->addModel(createModel("Bidoo", "clACos", "clACos oscillator", OSCILLATOR_TAG));
p->addModel(createModel("Bidoo", "baR", "bAR compressor", DYNAMICS_TAG));
p->addModel(createModel("Bidoo", "lIMbO", "lIMbO filter", FILTER_TAG));
+ p->addModel(createModel("Bidoo", "pErCO", "pErCO filter", FILTER_TAG));
+ p->addModel(createModel("Bidoo", "ziNC", "ziNC vocoder", EFFECT_TAG));
}
diff --git a/src/Bidoo.hpp b/src/Bidoo.hpp
index 251fa94..4f01285 100644
--- a/src/Bidoo.hpp
+++ b/src/Bidoo.hpp
@@ -91,3 +91,11 @@ struct BARWidget : ModuleWidget {
struct LIMBOWidget : ModuleWidget {
LIMBOWidget();
};
+
+struct PERCOWidget : ModuleWidget {
+ PERCOWidget();
+};
+
+struct ZINCWidget : ModuleWidget {
+ ZINCWidget();
+};
diff --git a/src/LIMBO.cpp b/src/LIMBO.cpp
index 0fdc667..89174f0 100644
--- a/src/LIMBO.cpp
+++ b/src/LIMBO.cpp
@@ -12,11 +12,16 @@ struct FilterStage
{
float mem = 0.0;
- float Filter(float sample, float freq, float smpRate)
+ float Filter(float sample, float freq, float smpRate, float gain, int mode)
{
float g = tan(pi*freq/smpRate);
float G = g/(1.0 + g);
- float out = (sample - mem) * G + mem;
+ float out;
+ if (mode == 0) {
+ out = (sample - mem) * G + mem;
+ } else {
+ out = (tanh(sample*gain)/tanh(gain) - mem) * G + mem;
+ }
mem = out + (sample - mem) * G ;
return out;
}
@@ -31,11 +36,15 @@ struct LadderFilter
float q;
float freq;
float smpRate;
+ int mode = 0;
+ float gain = 1;
- void setParams(float freq, float q, float smpRate) {
+ void setParams(float freq, float q, float smpRate, float gain, int mode) {
this->freq = freq;
this->q=q;
this->smpRate=smpRate;
+ this->mode = mode;
+ this->gain = gain;
}
float calcOutput(float sample)
@@ -48,7 +57,7 @@ struct LadderFilter
float S3 = stage3.mem/(1 + g);
float S4 = stage4.mem/(1 + g);
float S = G*G*G*S1 + G*G*S2 + G*S3 + S4;
- return stage4.Filter(stage3.Filter(stage2.Filter(stage1.Filter((sample - q*S)/(1 + q*G),freq,smpRate),freq,smpRate),freq,smpRate),freq,smpRate);
+ return stage4.Filter(stage3.Filter(stage2.Filter(stage1.Filter((sample - q*S)/(1 + q*G),freq,smpRate,gain,mode),freq,smpRate,gain,mode),freq,smpRate,gain,mode),freq,smpRate,gain,mode);
}
};
@@ -59,6 +68,7 @@ struct LIMBO : Module {
Q_PARAM,
CMOD_PARAM,
MUG_PARAM,
+ MODE_PARAM,
NUM_PARAMS
};
enum InputIds {
@@ -90,14 +100,14 @@ struct LIMBO : Module {
void LIMBO::step() {
float cfreq = pow(2,rescalef(clampf(params[CUTOFF_PARAM].value + params[CMOD_PARAM].value * inputs[CUTOFF_INPUT].value / 5,0,1),0,1,4.5,13));
float q = 3.5 * clampf(params[Q_PARAM].value + inputs[Q_INPUT].value / 5.0, 0.0, 1.0);
- lFilter.setParams(cfreq,q,engineGetSampleRate());
- rFilter.setParams(cfreq,q,engineGetSampleRate());
+ float g = pow(2,rescalef(clampf(params[MUG_PARAM].value + inputs[MUG_INPUT].value / 5,0,1),0,1,0,3));
+ int mode = (int)params[MODE_PARAM].value;
+ lFilter.setParams(cfreq,q,engineGetSampleRate(),g/3,mode);
+ rFilter.setParams(cfreq,q,engineGetSampleRate(),g/3,mode);
float inL = inputs[IN_L].value/5; //normalise to -1/+1 we consider VCV Rack standard is #+5/-5V on VCO1
float inR = inputs[IN_R].value/5;
- //filtering + makeup gain
- float g = clampf(params[MUG_PARAM].value + inputs[MUG_INPUT].value,1,10);
- inL = lFilter.calcOutput(inL)*5*g;
- inR = rFilter.calcOutput(inR)*5*g;
+ inL = lFilter.calcOutput(inL)*5*(mode == 0 ? g : 1);
+ inR = rFilter.calcOutput(inR)*5*(mode == 0 ? g : 1);
outputs[OUT_L].value = inL;
outputs[OUT_R].value = inR;
}
@@ -134,8 +144,9 @@ LIMBOWidget::LIMBOWidget() {
addParam(createParam(Vec(33, 61), module, LIMBO::CUTOFF_PARAM, 0, 1, 1));
addParam(createParam(Vec(12, 143), module, LIMBO::Q_PARAM, 0, 1, 0));
- addParam(createParam(Vec(71, 143), module, LIMBO::MUG_PARAM, 1, 10, 1));
+ addParam(createParam(Vec(71, 143), module, LIMBO::MUG_PARAM, 0, 1, 0));
addParam(createParam(Vec(12, 208), module, LIMBO::CMOD_PARAM, -1, 1, 0));
+ addParam(createParam(Vec(83, 217), module, LIMBO::MODE_PARAM, 0.0, 1.0, 0.0));
addInput(createInput(Vec(12, 280), module, LIMBO::CUTOFF_INPUT));
addInput(createInput(Vec(47, 280), module, LIMBO::Q_INPUT));
diff --git a/src/PERCO.cpp b/src/PERCO.cpp
new file mode 100644
index 0000000..a23aace
--- /dev/null
+++ b/src/PERCO.cpp
@@ -0,0 +1,128 @@
+// Based on Will Pirkle's courses & Vadim Zavalishin's book
+
+#include "Bidoo.hpp"
+#include "BidooComponents.hpp"
+#include "dsp/decimator.hpp"
+
+using namespace std;
+
+#define pi 3.14159265359
+
+
+struct MultiFilter
+{
+ float q;
+ float freq;
+ float smpRate;
+ float hp = 0,bp = 0,lp = 0,mem1 = 0,mem2 = 0;
+
+ void setParams(float freq, float q, float smpRate) {
+ this->freq = freq;
+ this->q=q;
+ this->smpRate=smpRate;
+ }
+
+ void calcOutput(float sample)
+ {
+ float g = tan(pi*freq/smpRate);
+ float R = 1.0/(2.0*q);
+ hp = (sample - (2.0*R + g)*mem1 - mem2)/(1.0 + 2.0*R*g + g*g);
+ bp = g*hp + mem1;
+ lp = g*bp + mem2;
+ mem1 = g*hp + bp;
+ mem2 = g*bp + lp;
+ }
+
+};
+
+struct PERCO : Module {
+ enum ParamIds {
+ CUTOFF_PARAM,
+ Q_PARAM,
+ CMOD_PARAM,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ IN,
+ CUTOFF_INPUT,
+ Q_INPUT,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ OUT_LP,
+ OUT_BP,
+ OUT_HP,
+ NUM_OUTPUTS
+ };
+ enum LightIds {
+ LEARN_LIGHT,
+ NUM_LIGHTS
+ };
+ MultiFilter filter;
+
+ PERCO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ }
+
+ void step() override;
+
+};
+
+void PERCO::step() {
+ float cfreq = pow(2,rescalef(clampf(params[CUTOFF_PARAM].value + params[CMOD_PARAM].value * inputs[CUTOFF_INPUT].value / 5,0,1),0,1,4.5,13));
+ float q = 10 * clampf(params[Q_PARAM].value + inputs[Q_INPUT].value / 5.0, 0.1, 1.0);
+ filter.setParams(cfreq,q,engineGetSampleRate());
+ float in = inputs[IN].value/5; //normalise to -1/+1 we consider VCV Rack standard is #+5/-5V on VCO1
+ //filtering
+ filter.calcOutput(in);
+ outputs[OUT_LP].value = filter.lp * 5;
+ outputs[OUT_HP].value = filter.hp * 5;
+ outputs[OUT_BP].value = filter.bp * 5;
+}
+
+struct PERCODisplay : TransparentWidget {
+ PERCO *module;
+ std::shared_ptr font;
+ PERCODisplay() {
+ font = Font::load(assetPlugin(plugin, "res/DejaVuSansMono.ttf"));
+ }
+
+ void draw(NVGcontext *vg) override {
+
+ }
+};
+
+PERCOWidget::PERCOWidget() {
+ PERCO *module = new PERCO();
+ setModule(module);
+ box.size = Vec(15*8, 380);
+
+ {
+ SVGPanel *panel = new SVGPanel();
+ panel->box.size = box.size;
+ panel->setBackground(SVG::load(assetPlugin(plugin, "res/PERCO.svg")));
+ addChild(panel);
+ }
+
+ PERCODisplay *display = new PERCODisplay();
+ display->module = module;
+ display->box.pos = Vec(5, 40);
+ display->box.size = Vec(110, 70);
+ addChild(display);
+
+ addParam(createParam(Vec(33, 61), module, PERCO::CUTOFF_PARAM, 0, 1, 1));
+ addParam(createParam(Vec(12, 143), module, PERCO::Q_PARAM, 0.1, 1, 0.1));
+ addParam(createParam(Vec(71, 143), module, PERCO::CMOD_PARAM, -1, 1, 0));
+
+ addInput(createInput(Vec(10, 276), module, PERCO::IN));
+ addInput(createInput(Vec(48, 276), module, PERCO::CUTOFF_INPUT));
+ addInput(createInput(Vec(85, 276), module, PERCO::Q_INPUT));
+
+ addOutput(createOutput(Vec(10, 320), module, PERCO::OUT_LP));
+ addOutput(createOutput(Vec(48, 320), module, PERCO::OUT_BP));
+ addOutput(createOutput(Vec(85, 320), module, PERCO::OUT_HP));
+
+ addChild(createScrew(Vec(15, 0)));
+ addChild(createScrew(Vec(box.size.x-30, 0)));
+ addChild(createScrew(Vec(15, 365)));
+ addChild(createScrew(Vec(box.size.x-30, 365)));
+}
diff --git a/src/ZINC.cpp b/src/ZINC.cpp
new file mode 100644
index 0000000..13b9499
--- /dev/null
+++ b/src/ZINC.cpp
@@ -0,0 +1,147 @@
+#include "Bidoo.hpp"
+#include "BidooComponents.hpp"
+#include "dsp/decimator.hpp"
+#include "dep/filters/biquad.h"
+
+using namespace std;
+
+#define BANDS 16
+
+struct ZINC : Module {
+ enum ParamIds {
+ BG_PARAM,
+ ATTACK_PARAM = BG_PARAM + BANDS,
+ DECAY_PARAM,
+ Q_PARAM,
+ GMOD_PARAM,
+ GCARR_PARAM,
+ G_PARAM,
+ SHAPE_PARAM,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ IN_MOD,
+ IN_CARR,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ OUT,
+ NUM_OUTPUTS
+ };
+ enum LightIds {
+ LEARN_LIGHT,
+ NUM_LIGHTS
+ };
+ Biquad* iFilter[2*BANDS];
+ Biquad* cFilter[2*BANDS];
+ float mem[BANDS] = {0};
+ float freq[BANDS] = {125,185,270,350,430,530,630,780,950,1150,1380,1680,2070,2780,3800,6400};
+ float peaks[BANDS] = {0};
+
+ ZINC() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ for(int i=0; i<2*BANDS; i++) {
+ iFilter[i] = new Biquad(bq_type_bandpass, freq[i%BANDS] / engineGetSampleRate(), 5, 6);
+ cFilter[i] = new Biquad(bq_type_bandpass, freq[i%BANDS] / engineGetSampleRate(), 5, 6);
+ }
+ }
+
+ void step() override;
+
+};
+
+void ZINC::step() {
+ float inM = inputs[IN_MOD].value/5;
+ float inC = inputs[IN_CARR].value/5;
+ const float slewMin = 0.001;
+ const float slewMax = 500.0;
+ const float shapeScale = 1/10.0;
+ float attack = params[ATTACK_PARAM].value;
+ float decay = params[DECAY_PARAM].value;
+ float slewAttack = slewMax * powf(slewMin / slewMax, attack);
+ float slewDecay = slewMax * powf(slewMin / slewMax, decay);
+ float out = 0.0;
+
+ for(int i=0; iprocess(iFilter[i]->process(inM*params[GMOD_PARAM].value)));
+ if (peak>coeff) {
+ coeff += slewAttack * shapeScale * (peak - coeff) / engineGetSampleRate();
+ if (coeff > peak)
+ coeff = peak;
+ }
+ else if (peak < coeff) {
+ coeff -= slewDecay * shapeScale * (coeff - peak) / engineGetSampleRate();
+ if (coeff < peak)
+ coeff = peak;
+ }
+ peaks[i]=peak;
+ mem[i]=coeff;
+ out += cFilter[i+BANDS]->process(cFilter[i]->process(inC*params[GCARR_PARAM].value)) * coeff * params[BG_PARAM+i].value;
+ }
+ outputs[OUT].value = out * 5 * params[G_PARAM].value;
+}
+
+struct ZINCDisplay : TransparentWidget {
+ ZINC *module;
+ std::shared_ptr font;
+
+ ZINCDisplay() {
+ font = Font::load(assetPlugin(plugin, "res/DejaVuSansMono.ttf"));
+ }
+
+ void draw(NVGcontext *vg) override {
+ nvgFontSize(vg, 10);
+ nvgFontFaceId(vg, font->handle);
+ nvgStrokeWidth(vg, 2);
+ nvgTextLetterSpacing(vg, -2);
+ nvgTextAlign(vg, NVG_ALIGN_CENTER);
+ static const int portX0[4] = {20, 63, 106, 149};
+ for (int i=0; ifreq[i]);
+ nvgFillColor(vg,nvgRGBA(rescalef(clampf(module->peaks[i],0,1),0,1,0,255), 0, 0, 255));
+ nvgText(vg, portX0[i%(BANDS/4)]+1, 35+43*(int)(i/4), fVal, NULL);
+ }
+ }
+};
+
+ZINCWidget::ZINCWidget() {
+ ZINC *module = new ZINC();
+ setModule(module);
+ box.size = Vec(15*13, 380);
+
+ {
+ SVGPanel *panel = new SVGPanel();
+ panel->box.size = box.size;
+ panel->setBackground(SVG::load(assetPlugin(plugin, "res/ZINC.svg")));
+ addChild(panel);
+ }
+
+ ZINCDisplay *display = new ZINCDisplay();
+ display->module = module;
+ display->box.pos = Vec(12, 12);
+ display->box.size = Vec(110, 70);
+ addChild(display);
+
+ static const float portX0[4] = {20, 63, 106, 149};
+
+ for (int i = 0; i < BANDS; i++) {
+ addParam( createParam(Vec(portX0[i%(BANDS/4)]-1, 50+43*(int)(i/4)), module, ZINC::BG_PARAM + i, 0, 2, 1));
+ }
+ addParam(createParam(Vec(portX0[0]+5, 230), module, ZINC::ATTACK_PARAM, 0.0, 0.25, 0.0));
+ addParam(createParam(Vec(portX0[1]+5, 230), module, ZINC::DECAY_PARAM, 0.0, 0.25, 0.0));
+ addParam(createParam(Vec(portX0[0]-1, 268), module, ZINC::GMOD_PARAM, 1, 10, 1));
+ addParam(createParam(Vec(portX0[1]-1, 268), module, ZINC::GCARR_PARAM, 1, 10, 1));
+ addParam(createParam(Vec(portX0[2]-1, 268), module, ZINC::G_PARAM, 1, 10, 1));
+
+
+ addInput(createInput(Vec(10, 320), module, ZINC::IN_MOD));
+ addInput(createInput(Vec(48, 320), module, ZINC::IN_CARR));
+
+ addOutput(createOutput(Vec(85, 320), module, ZINC::OUT));
+
+ addChild(createScrew(Vec(15, 0)));
+ addChild(createScrew(Vec(box.size.x-30, 0)));
+ addChild(createScrew(Vec(15, 365)));
+ addChild(createScrew(Vec(box.size.x-30, 365)));
+}
diff --git a/src/dep/filters/biquad.cpp b/src/dep/filters/biquad.cpp
new file mode 100644
index 0000000..2e54be9
--- /dev/null
+++ b/src/dep/filters/biquad.cpp
@@ -0,0 +1,165 @@
+//
+// Biquad.cpp
+//
+// Created by Nigel Redmon on 11/24/12
+// EarLevel Engineering: earlevel.com
+// Copyright 2012 Nigel Redmon
+//
+// For a complete explanation of the Biquad code:
+// http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
+//
+// License:
+//
+// This source code is provided as is, without warranty.
+// You may copy and distribute verbatim copies of this document.
+// You may modify and use this source code to create binary code
+// for your own purposes, free or commercial.
+//
+
+#include
+#include "Biquad.h"
+
+Biquad::Biquad() {
+ type = bq_type_lowpass;
+ a0 = 1.0;
+ a1 = a2 = b1 = b2 = 0.0;
+ Fc = 0.50;
+ Q = 0.707;
+ peakGain = 0.0;
+ z1 = z2 = 0.0;
+}
+
+Biquad::Biquad(int type, double Fc, double Q, double peakGainDB) {
+ setBiquad(type, Fc, Q, peakGainDB);
+ z1 = z2 = 0.0;
+}
+
+Biquad::~Biquad() {
+}
+
+void Biquad::setType(int type) {
+ this->type = type;
+ calcBiquad();
+}
+
+void Biquad::setQ(double Q) {
+ this->Q = Q;
+ calcBiquad();
+}
+
+void Biquad::setFc(double Fc) {
+ this->Fc = Fc;
+ calcBiquad();
+}
+
+void Biquad::setPeakGain(double peakGainDB) {
+ this->peakGain = peakGainDB;
+ calcBiquad();
+}
+
+void Biquad::setBiquad(int type, double Fc, double Q, double peakGainDB) {
+ this->type = type;
+ this->Q = Q;
+ this->Fc = Fc;
+ setPeakGain(peakGainDB);
+}
+
+void Biquad::calcBiquad(void) {
+ double norm;
+ double V = pow(10, fabs(peakGain) / 20.0);
+ double K = tan(M_PI * Fc);
+ switch (this->type) {
+ case bq_type_lowpass:
+ norm = 1 / (1 + K / Q + K * K);
+ a0 = K * K * norm;
+ a1 = 2 * a0;
+ a2 = a0;
+ b1 = 2 * (K * K - 1) * norm;
+ b2 = (1 - K / Q + K * K) * norm;
+ break;
+
+ case bq_type_highpass:
+ norm = 1 / (1 + K / Q + K * K);
+ a0 = 1 * norm;
+ a1 = -2 * a0;
+ a2 = a0;
+ b1 = 2 * (K * K - 1) * norm;
+ b2 = (1 - K / Q + K * K) * norm;
+ break;
+
+ case bq_type_bandpass:
+ norm = 1 / (1 + K / Q + K * K);
+ a0 = K / Q * norm;
+ a1 = 0;
+ a2 = -a0;
+ b1 = 2 * (K * K - 1) * norm;
+ b2 = (1 - K / Q + K * K) * norm;
+ break;
+
+ case bq_type_notch:
+ norm = 1 / (1 + K / Q + K * K);
+ a0 = (1 + K * K) * norm;
+ a1 = 2 * (K * K - 1) * norm;
+ a2 = a0;
+ b1 = a1;
+ b2 = (1 - K / Q + K * K) * norm;
+ break;
+
+ case bq_type_peak:
+ if (peakGain >= 0) { // boost
+ norm = 1 / (1 + 1/Q * K + K * K);
+ a0 = (1 + V/Q * K + K * K) * norm;
+ a1 = 2 * (K * K - 1) * norm;
+ a2 = (1 - V/Q * K + K * K) * norm;
+ b1 = a1;
+ b2 = (1 - 1/Q * K + K * K) * norm;
+ }
+ else { // cut
+ norm = 1 / (1 + V/Q * K + K * K);
+ a0 = (1 + 1/Q * K + K * K) * norm;
+ a1 = 2 * (K * K - 1) * norm;
+ a2 = (1 - 1/Q * K + K * K) * norm;
+ b1 = a1;
+ b2 = (1 - V/Q * K + K * K) * norm;
+ }
+ break;
+ case bq_type_lowshelf:
+ if (peakGain >= 0) { // boost
+ norm = 1 / (1 + sqrt(2) * K + K * K);
+ a0 = (1 + sqrt(2*V) * K + V * K * K) * norm;
+ a1 = 2 * (V * K * K - 1) * norm;
+ a2 = (1 - sqrt(2*V) * K + V * K * K) * norm;
+ b1 = 2 * (K * K - 1) * norm;
+ b2 = (1 - sqrt(2) * K + K * K) * norm;
+ }
+ else { // cut
+ norm = 1 / (1 + sqrt(2*V) * K + V * K * K);
+ a0 = (1 + sqrt(2) * K + K * K) * norm;
+ a1 = 2 * (K * K - 1) * norm;
+ a2 = (1 - sqrt(2) * K + K * K) * norm;
+ b1 = 2 * (V * K * K - 1) * norm;
+ b2 = (1 - sqrt(2*V) * K + V * K * K) * norm;
+ }
+ break;
+ case bq_type_highshelf:
+ if (peakGain >= 0) { // boost
+ norm = 1 / (1 + sqrt(2) * K + K * K);
+ a0 = (V + sqrt(2*V) * K + K * K) * norm;
+ a1 = 2 * (K * K - V) * norm;
+ a2 = (V - sqrt(2*V) * K + K * K) * norm;
+ b1 = 2 * (K * K - 1) * norm;
+ b2 = (1 - sqrt(2) * K + K * K) * norm;
+ }
+ else { // cut
+ norm = 1 / (V + sqrt(2*V) * K + K * K);
+ a0 = (1 + sqrt(2) * K + K * K) * norm;
+ a1 = 2 * (K * K - 1) * norm;
+ a2 = (1 - sqrt(2) * K + K * K) * norm;
+ b1 = 2 * (K * K - V) * norm;
+ b2 = (V - sqrt(2*V) * K + K * K) * norm;
+ }
+ break;
+ }
+
+ return;
+}
diff --git a/src/dep/filters/biquad.h b/src/dep/filters/biquad.h
new file mode 100644
index 0000000..6875e95
--- /dev/null
+++ b/src/dep/filters/biquad.h
@@ -0,0 +1,60 @@
+//
+// Biquad.h
+//
+// Created by Nigel Redmon on 11/24/12
+// EarLevel Engineering: earlevel.com
+// Copyright 2012 Nigel Redmon
+//
+// For a complete explanation of the Biquad code:
+// http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
+//
+// License:
+//
+// This source code is provided as is, without warranty.
+// You may copy and distribute verbatim copies of this document.
+// You may modify and use this source code to create binary code
+// for your own purposes, free or commercial.
+//
+
+#ifndef Biquad_h
+#define Biquad_h
+
+enum {
+ bq_type_lowpass = 0,
+ bq_type_highpass,
+ bq_type_bandpass,
+ bq_type_notch,
+ bq_type_peak,
+ bq_type_lowshelf,
+ bq_type_highshelf
+};
+
+class Biquad {
+public:
+ Biquad();
+ Biquad(int type, double Fc, double Q, double peakGainDB);
+ ~Biquad();
+ void setType(int type);
+ void setQ(double Q);
+ void setFc(double Fc);
+ void setPeakGain(double peakGainDB);
+ void setBiquad(int type, double Fc, double Q, double peakGain);
+ float process(float in);
+
+protected:
+ void calcBiquad(void);
+
+ int type;
+ double a0, a1, a2, b1, b2;
+ double Fc, Q, peakGain;
+ double z1, z2;
+};
+
+inline float Biquad::process(float in) {
+ double out = in * a0 + z1;
+ z1 = in * a1 + z2 - b1 * out;
+ z2 = in * a2 - b2 * out;
+ return out;
+}
+
+#endif // Biquad_h