Airwindows CONSOLE8: Mac/Windows/Linux/Pi AU/VST
-
- KVRian
- Topic Starter
- 1479 posts since 7 Apr, 2007 from Bellows Falls, VT
-
- KVRian
- 1119 posts since 4 Jan, 2007
Some formulas are using different nomenclature for the biquad. Either all need to have to have either "a1=1-b" or "b0=1-a1" and only be different on the other term. After that the should sound equal, the only difference will be the cutoff frequency changing mapping between method.antoineportes wrote: Tue Feb 21, 2023 11:13 am This might save some time as well if you (or anyone) plan(s) on experimenting with odd orders, here is a JSFX that compares the three exponential moving average algorithms (in mono):
Again, my code, no copyright.Code: Select all
desc:0im's filtering: 2 modes 1 pole desc:exponential moving average filter slider1:HP=0<0,1,1{Lo-pass,Hi-pass}>Mode slider2:freqHz=20000<20,20000,.1:log>Cutoff (Hz) slider3:algo=0<0,2,1{neat,decent,cheap}>Algorithm @init Ts=1/srate; nyquist.safe=srate*.49; @slider HP=max(0,min((HP|0),1)); freqHz=max(20,min(freqHz,nyquist.safe)); algo=max(0,min((algo|0),2)); w0=freqHz*2*$pi*Ts; //ALGORITHM 0 "neat" algo==0?( //source: https://tttapa.github.io/Pages/Mathematics/Systems-and-Control-Theory/Digital-filters/Exponential%20Moving%20Average/Exponential-Moving-Average.html calb0=cos(w0)-2; //thanks Tale! b0=sqrt(sqr(calb0)-1)+calb0+1; a1=1-b0; ); //ALGORITHM 1 "decent" algo==1?( //source: https://www.earlevel.com/main/2012/12/15/a-one-pole-filter/ ////a & b are at each other's place in the original a1=exp(-w0); b0=1-a1; ); //ALGORITHM 2 "cheap" algo==2?( //source: https://en.wikipedia.org/wiki/Low-pass_filter#Simple_infinite_impulse_response_filter) b0=w0/(w0+1); a1=1-b0; ); @sample yn=b0*spl0+a1*yn; !HP?( spl0=yn; ):( spl0-=yn; ); spl1=spl0;
-
- KVRian
- 1119 posts since 4 Jan, 2007
None of those seem to have prewarping. See "the art of VA filter design" by Vadim Zavalishin . You have 1 poles there. https://www.discodsp.net/VAFilterDesign_2.1.2.pdf
- KVRer
- 20 posts since 26 Aug, 2022
b0 and a1 are at each other place in the "decent" algorithm, indeed — it seems shamefully obvious now!
About the pre-warping, even though it never gets mentioned in the sources I've used, I assumed it was silently taken care of. Turns out it wasn't; that explains weird behaviours at high frequencies.
Thanks a lot for spotting those two and for the link you've provided @rafa1981. (I was looking for a way to implement 1-pole shelves, you've made my day!)
About the pre-warping, even though it never gets mentioned in the sources I've used, I assumed it was silently taken care of. Turns out it wasn't; that explains weird behaviours at high frequencies.
Thanks a lot for spotting those two and for the link you've provided @rafa1981. (I was looking for a way to implement 1-pole shelves, you've made my day!)
Working-class filter design (GitHub)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
- KVRer
- 20 posts since 26 Aug, 2022
@jinxtigr Thanks!
So I've used the book and here's my attempt to a virtual RC (1-pole) low-pass filter. I'm quite amazed by the precision of its cutoff (I've entered values manually and checked the resulting curves in the Bertom Analyser). I've reduced the number of computations as much as I could, the code is ridiculously short and the process negligible on CPU — this appears to be the perfect digital one-pole filter.
@rafa1981 thanks again, this book is incredible.
JSFX:
So I've used the book and here's my attempt to a virtual RC (1-pole) low-pass filter. I'm quite amazed by the precision of its cutoff (I've entered values manually and checked the resulting curves in the Bertom Analyser). I've reduced the number of computations as much as I could, the code is ridiculously short and the process negligible on CPU — this appears to be the perfect digital one-pole filter.
@rafa1981 thanks again, this book is incredible.
JSFX:
Code: Select all
desc:hopefuly my ultimate one-pole filter
//source: Vadim Zavalishin "The Art of VA filter design", Chapter 2: "Analog 1-pole filters"
slider1:cutoffHz=20000<20,20000,.1:log=547.72>Cutoff (Hz)
@init
Ts=1/srate;
@slider
g=tan($pi*cutoffHz*Ts);
GG=g/(1+g);
@sample
v=(spl0-s)*GG;
spl0=v+s;
s=spl0+v;
spl1=spl0;Working-class filter design (GitHub)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
-
- KVRian
- Topic Starter
- 1479 posts since 7 Apr, 2007 from Bellows Falls, VT
Very cool! I will probably try to simplify it even more by taking the cutoff-related calculations out of it to see what it does with just 0-1 valuesantoineportes wrote: Sun Apr 23, 2023 8:47 pmI've reduced the number of computations as much as I could, the code is ridiculously short and the process negligible on CPU — this appears to be the perfect digital one-pole filter.
Also, remember for tone color purposes we often want the weird behaviors at high frequencies. Things like transformers and tape machines have truly weird behaviors at all sorts of frequencies
- KVRer
- 20 posts since 26 Aug, 2022
Zero to one sounds like Airwindows indeed, you'll get a digital guitar tone pot.
In the meantime, I've updated it. There are now four modes (LP, HP, Low/High shelf).
In the meantime, I've updated it. There are now four modes (LP, HP, Low/High shelf).
Code: Select all
desc:hopefuly my ultimate one-pole filter
//source: Vadim Zavalishin "The Art of VA filter design", Chapter 2: "Analog 1-pole filters"
slider1:mode=0<0,3,1{Low-Pass,High-Pass,Low Shelf,High Shelf}>Mode
slider2:cutoffHz=20000<20,20000,.1:log=547.72>Cutoff (Hz)
slider3:gainDB=0<-36,36,.01:exp=0>Gain (dB)
@init
Ts=1/srate;
@slider
HP=mode&1;
shelf=mode>1;
g=tan($pi*cutoffHz*Ts);
GG=g/(1+g);
gain=10^(gainDB*.05)-1;
@sample
x=spl0;
v=(x-s)*GG;
y=v+s;
s=y+v;
HP?y=x-y;
shelf?spl0+=gain*y:spl0=y;
spl1=spl0;
Are you suggesting to purposely not pre-warp filters as a treble softening effect? Feels like a cheat code!
Working-class filter design (GitHub)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
Monetize THIS (Bandcamp)
"Man vergilt einem Lehrer schlecht, wenn man immer nur der Schüler bleibt." — Friedrich Nietzsche (Ecce homo)
-
- KVRian
- 1119 posts since 4 Jan, 2007
Then you will get different behaviors at different samplerates. Not desirable. Easy fix is resampling to run at a fixed sample rate.jinxtigr wrote: Mon Apr 24, 2023 12:44 amVery cool! I will probably try to simplify it even more by taking the cutoff-related calculations out of it to see what it does with just 0-1 valuesantoineportes wrote: Sun Apr 23, 2023 8:47 pmI've reduced the number of computations as much as I could, the code is ridiculously short and the process negligible on CPU — this appears to be the perfect digital one-pole filter.
Also, remember for tone color purposes we often want the weird behaviors at high frequencies. Things like transformers and tape machines have truly weird behaviors at all sorts of frequencies![]()
