bmc0 / dsp

An audio processing program with an interactive mode.
ISC License
219 stars 31 forks source link

lowpass_1 have very flat magnitude response (compared to 2-pole lowpass) for higher frequencies (checked 11025Hz for 44100Hz) #67

Closed richardpl closed 3 months ago

richardpl commented 3 months ago

Similar bugs probably present in other 1-pole variants.

bmc0 commented 3 months ago

Not really a bug. It's due to the discretization method used for the first order low pass (impulse invariance).

richardpl commented 3 months ago

Hmm, but isn't this variant in code just 0-zeros realization?

bmc0 commented 3 months ago

Apologies, what I wrote in my previous reply is incorrect. It's the same as the standard exponentially weighted moving average filter, which has the difference equation y[n] = a*x[n] + (1-a)*y[n-1]. The transfer function is H(z) = a / (1-(1-a)z^-1). Other signal processing software I've looked at (SoX, for example) uses the same difference equation for first order lowpass filters, so that's what I chose to implement.

One could instead use the bilinear transform to discretize the continuous-time transfer function, which forces the magnitude to be zero at fs/2. Perhaps some other software uses this approach.

richardpl commented 3 months ago

Maybe those here could be of use: https://dsp.stackexchange.com/questions/93446/first-order-filters-in-direct-form-i-rbj-cookbook Depending on what end goal of filter implementation would be. It could stay as is currently but I just wondered if it makes sense to (also) use something else than those SoX variants of 1st order. Also adding 1st order allpass... might be beneficial.

bmc0 commented 3 months ago

Thinking about it more, I agree that it would be useful to have the bilinear transform version available. Thanks for the link; that will save me some time looking for the formulae or trying to derive them myself.

bmc0 commented 3 months ago

Added in commit c2ae387.