4
$\begingroup$

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

$\endgroup$
3
  • 1
    $\begingroup$ 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. $\endgroup$ Commented Dec 25, 2022 at 17:23
  • $\begingroup$ @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 dsp.stackexchange.com/questions/85733/…) (sorry I earlier thought it was your thread in question). $\endgroup$
    – Juha P
    Commented Dec 27, 2022 at 8:24
  • $\begingroup$ You can get quite good match against definition by using MIM method to build 3rd order LPF and BLT method for biquad HPF: postimg.cc/XBj59mhz $\endgroup$
    – Juha P
    Commented Dec 29, 2022 at 8:07

3 Answers 3

4
$\begingroup$

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

$\endgroup$
5
  • $\begingroup$ 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? $\endgroup$
    – BugraKezan
    Commented Dec 25, 2022 at 15:54
  • $\begingroup$ A C weighting filter is undefined above 20 kHz., so anything above this isn't really relevant. What sample rates do you need ? $\endgroup$
    – Hilmar
    Commented Dec 25, 2022 at 16:36
  • $\begingroup$ I need 96kHz and 48kHz. Can't Matlab generate coef.s for the filters? I also need to convert my A-Weighting filter $\endgroup$
    – BugraKezan
    Commented Dec 26, 2022 at 7:38
  • $\begingroup$ @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 se.mathworks.com/matlabcentral/fileexchange?q=a-weighting )? $\endgroup$
    – Juha P
    Commented Dec 26, 2022 at 8:12
  • $\begingroup$ @JuhaP, I did tried that but a there was a significant difference at HF. I'll post a ss $\endgroup$
    – BugraKezan
    Commented Dec 26, 2022 at 11:15
3
$\begingroup$

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 ;)

$\endgroup$
2
  • $\begingroup$ 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? $\endgroup$
    – BugraKezan
    Commented Dec 25, 2022 at 15:55
  • $\begingroup$ 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 $\endgroup$
    – Jdip
    Commented Dec 25, 2022 at 16:23
2
$\begingroup$

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)+r*c(3)));
b(1)=(d(1)+r*(d(2)+r*d(3)))*invc;
b(2)=2.0*(d(1)-r^2*d(3))*invc;
b(3)=(d(1)-r*(d(2)-r*d(3)))*invc;
a(1)=1;
a(2)=2.0*(c(1)-r^2*c(3))*invc;
a(3)=(c(1)-r*(c(2)-r*c(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

$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – BugraKezan
    Commented Dec 25, 2022 at 15:55
  • $\begingroup$ I've edited my original post with this functions results $\endgroup$
    – BugraKezan
    Commented Dec 26, 2022 at 11:18
  • $\begingroup$ 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. $\endgroup$ Commented Dec 26, 2022 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.