4

I have IIR filter coefficients and zeroes, poles for that filters. But all filters are generated with 192kHz sample rate. I have no other info about filter properties such as Fc or filter type or Q.

Is there a way to regenerate new coefficients with different sample rates? Or any module in matlab / python?

Gain:
g = 0.08171341690434748

Zeros: z0 = 1.0 z1 = 1.0 z2 = 0.09485478100283842 z3 = -0.44667747990336809

Poles: p0 = 0.99929869236222657 p1 = 0.99935189324524132 p2 = 0.67410455633510369 p3 = 0.67410455630335042

Biquads: a1 = -1,673456449549 a2 = 0,673667664587 b0 = 3,024568847795 b1 = -1,673562057068 b2 = -1,351006790727

a1 = -1,673403248697
a2 = 0,673631801661 b0 = 0,027016550463 b1 = -0,029579199440 b2 = 0,002562648978

EDIT: I've tried Juha's function but there was a huge difference at C-Weighting filters;

Diff

BugraKezan
  • 87
  • 7
  • 1
    This is actually a pretty good question, one that I hadn't considered before. And, unlike FIR, there is no "standard" way to deal with it. I guess I would try factoring both numerator and denominator into zeros and poles. I would try to scale the relative resonant frequencies and time constants of each pole and zero so that they remain constant in physical time, given the new sample rate. – robert bristow-johnson Dec 25 '22 at 17:23
  • @BugraKezan, you should see same 'huge' difference in plot shown in Hilmar's answer. It's there because of nature of the bilinear transform method and the only way to get rid of that 'error' is to use some matching method for low pass filter implementation (like I use MIM in my A-Weighting filter implementation showed in Scipio's related thread here https://dsp.stackexchange.com/questions/85733/trying-to-implement-a-digital-a-frequency-filter) (sorry I earlier thought it was your thread in question). – Juha P Dec 27 '22 at 08:24
  • You can get quite good match against definition by using MIM method to build 3rd order LPF and BLT method for biquad HPF: https://postimg.cc/XBj59mhz – Juha P Dec 29 '22 at 08:07

3 Answers3

4

There is no standard way of doing this.

Your specific example is a "mild" bandpass filter with corner frequencies for about 32Hz and 7750 Hz. Unfortunately it's steeper than a first order and less steep than a second order BW filter, so it's not easy to replace with a "simple" IIR filter.

You can certainly do an inverse bilinear transform to convert into the S-plane and then another forward bilinear transform with the new sample rate. How well this works will depend on the sample rates.

Below there is an example of doing this for 96kHz and 48 kHz. Obviously there is some high frequency distortion but that's unavoidable if you change the sample rate drastically.

enter image description here

Hilmar
  • 44,604
  • 1
  • 32
  • 63
  • Actually it's a standard C-Weighting filter. So this HF distortions is not good for standards I guess. Do you know any other way to create C-Weighting filter with 2 or 3 IIR's? – BugraKezan Dec 25 '22 at 15:54
  • A C weighting filter is undefined above 20 kHz., so anything above this isn't really relevant. What sample rates do you need ? – Hilmar Dec 25 '22 at 16:36
  • I need 96kHz and 48kHz. Can't Matlab generate coef.s for the filters? I also need to convert my A-Weighting filter – BugraKezan Dec 26 '22 at 07:38
  • @BugraKezan, why not use my A-Weighting (given in your recent question thread) implementation for to build the filters for each sample-rate you need (that source code needs just little modifications so you get C-Weighting coefficients calculated too (see the difference in definition https://se.mathworks.com/matlabcentral/fileexchange?q=a-weighting )? – Juha P Dec 26 '22 at 08:12
  • @JuhaP, I did tried that but a there was a significant difference at HF. I'll post a ss – BugraKezan Dec 26 '22 at 11:15
3

There's no standard way to convert IIR filter coefficients for a different sampling rate than the one used to design the original filter.

However, you have all the information you need to design a new filter with your new sampling rate, since you have the gain, poles and zeros of your original filter. You can use that information to look at your filter's frequency response, figure out what your filter does, and go from there.

I did just that, and the filter in question is a combination of a 2nd order DC blocker and 2nd order low pass filter with cut-off $f_c \approx 8\,\text{KHz}$:

enter image description here

Just design a new filter with these specs. If you don't know filter design, that's a different question, which you can ask in a separate question ;)

Jdip
  • 5,980
  • 3
  • 7
  • 29
  • Actually it's a standard C-Weighting filter. So this HF distortions is not good for standards I guess. Do you know any other way to create C-Weighting filter with 2 or 3 IIR's? – BugraKezan Dec 25 '22 at 15:55
  • That’s even easier then. That’s a common filter, you can probably find SOS coefficients or at least design specs / methods for your sampling rate online. I think C-weighting is just a bandpass that should only let through 20 to 20kHz… surely you can design this easily – Jdip Dec 25 '22 at 16:23
2

Z->S->Z' should work well (as Hilmar suggests in his answer). If your discrete filter is biquad based on BLT (and not tweaked) then this (Octave) code should do the conversion:

function [b, a] = BiquadCoefficientConverter(b, a, inFS, outFS)

d(1)=b(1)+b(2)+b(3); d(2)=2.0(b(1)-b(3)); d(3)=b(1)-b(2)+b(3); c(1)=1+a(2)+a(3); c(2)=2.0(1.0-a(3)); c(3)=1.0-a(2)+a(3);

r=outFS/inFS;

invc=1/(c(1)+r(c(2)+rc(3))); b(1)=(d(1)+r(d(2)+rd(3)))invc; b(2)=2.0(d(1)-r^2d(3))invc; b(3)=(d(1)-r(d(2)-rd(3)))invc; a(1)=1; a(2)=2.0(c(1)-r^2c(3))invc; a(3)=(c(1)-r(c(2)-rc(3)))*invc;

Edit: Tried this function online Matlab using your two biquad sets as input and got coefficients for 48kHz filter:

a0 =  1.0
a1 = -1.121843
a2 =  0.124111
b0 =  6.435993
b1 = -1.122977
b2 = -5.310622

a0 = 1.0 a1 = -1.121631 a2 = 0.124084 b0 = 0.042738 b1 = -0.019846 b2 = -0.022892

enter image description here

Juha P
  • 917
  • 4
  • 12
  • Actually it's a standard C-Weighting filter. So this HF distortions is not good for standards I guess. Do you know any other way to create C-Weighting filter with 2 or 3 IIR's? – BugraKezan Dec 25 '22 at 15:55
  • I've edited my original post with this functions results – BugraKezan Dec 26 '22 at 11:18
  • This is the way to go (for BLT): $H(z)\rightarrow H\left(\frac{z^{-1}-\alpha}{1-\alpha z^{-1}}\right)$, with $\alpha=\frac{\sin(0.5(\omega_1-\omega_2))}{\sin(0.5(\omega_1+\omega_2))}$. After expansion you get the formulas in the function. This is for LP to LP. HP is similar, but BP and BS need a second order allpass. – a concerned citizen Dec 26 '22 at 19:22