如何级联两个二阶butterworth滤波器

时间:2014-02-05 11:53:48

标签: c matlab audio signal-processing

我已经计算出二阶低通和高通滤波器滤波器的系数。

系数如下。我正在实施这个C.

float cutoff = 600.00f * M_PI * 2;
float c = 2.0f / sampleRate;
float q = sqrt(2.0f)/2.0f;

g_a1LP = (2.0f * pow(c, 2.0f) - (2.0f * pow(cutoff, 2.0f))) / (pow(c, 2.0f) + ((cutoff*c)/q) + pow(cutoff, 2.0f));

g_a2LP = -(pow(c, 2.0f)  + pow(cutoff, 2.0f) - (cutoff*c)/q ) / (pow(c, 2.0f) + ((cutoff*c)/q) + pow(cutoff, 2.0f));

g_b0LP = 1.0f;
g_b1LP = 2.0f;
g_b2LP = 1.0f; 

g_a1HP = (2.0f - (2.0f * pow(cutoff, 2.0f))/ pow(c, 2.0f)) / (1.0f + (2.0f/sqrt(2.0f)) * (1.0f/c) * cutoff + (pow(cutoff, 2.0f) / pow(c, 2.0f)));

g_a2HP = -(1.0f - (2.0f/sqrt(2.0f) * 1.0f/c * cutoff) + pow(cutoff, 2.0f)/pow(c, 2.0f)) / (1.0f + (2.0f/sqrt(2.0f)) * (1.0f/c) * cutoff + (pow(cutoff, 2.0f) / pow(c, 2.0f)));

g_b0HP = 1.0;
g_b1HP = -2.0;
g_b2HP = 1.0; 

我现在必须制作一个4阶Linkwitz-Riley交叉。我知道这是两个卡斯沃思的级联。我不太清楚我应该怎么做。我只是将系数相乘吗?我是在正确的轨道上吗?如果有人受到打扰,我的系数看起来不错吗?他们在matlab中绘制得很好。

3 个答案:

答案 0 :(得分:2)

为了创建一个四阶高通(相应的低通)Linkwitz-Riley滤波器,你必须级联2 相同的二阶高通(相应的低通) Butterworth过滤器。

使用过滤器多项式,意味着:

Butterworth过滤器:

h = b0 + b1.X + b2.X**2 / a0 + a1.X + a2.X**2

Linkwitz-Riley过滤器:

h' = h**2

因此,如果您的实现允许,您可以简单地对Butterworth滤波器进行平方。

如果您想拥有Linkwitz-Riley数字滤波器系数,您可以:

  • 通过开发以下等式找到它们:

    (b0 + b1.X + b2.X**2) ** 2 = (b0' + b1'.X + b2'.X**2 + b3'.X**3 + b4'.X**4)
    

    它会给你5个系数b0' ...... b4'作为b0 ... b3(以及类似a0' ... a4'作为a0 ... a3的函数)的函数,您可以在代码中实现。

  • 使用Matlab或Python

    这是Python中使用scipy.signal的一个示例函数,它返回数字滤波器的分子和分母Linkwitz-Riley系数。

    import scipy.signal as sig
    def linkril(filter_order, w_center, btype='lowpass', analog=False):
       butter_order = int(filter_order / 2.)
       numbut, denbut = sig.butter(butter_order, w_center,
                               btype = btype, analog=analog)
       num = np.convolve(numbut, numbut)
       den = np.convolve(denbut, denbut)
       return(num, den)
    

答案 1 :(得分:1)

为什么不使用

  • Matlab:如果你负担得起(不是免费的)
  • SciPy如果您准备尝试使用Python(免费)

他们建议在Python的两行代码中执行此类操作

from scipy.signal import butter
# generate the coefficients (discrete time) of a 4 order butterworth bandpass filter, where low cutoff frequency is 0.3 the Nyquist frequency and the high cutoff is 0.4 the Nyquist frequency
butter(4, [0.3, 0.4], 'band')

这将输出以下系数:

>>> (array([  4.16599204e-04,   0.00000000e+00,  -1.66639682e-03,
     3.25816475e-19,   2.49959523e-03,  -3.25816475e-19,
    -1.66639682e-03,   0.00000000e+00,   4.16599204e-04]), array([  1.        ,  -3.30057727,   7.28008314, -10.20570426,
    10.95189946,  -8.30658348,   4.82226759,  -1.77664475,   0.43826514]))

答案 2 :(得分:0)

RawBean在他的评论中是对的...

首先,要创建Linkwitz Riley滤波器(低通或高通都一样),您必须将两个 相同 滤波器级联,例如Aporee提到的。现在,这与RawBean的注释一起意味着您必须对系数进行卷积。可以分别对分子和分母完成此操作,最终结果将与您要查找的Linkwitz-Riley系数的分子和分母系数相对应。

如果您看一下Aporee的示例,则可以使用卷积函数来计算最终系数。您可以很好地使用此代码段来获取系数,并且如果实现将是静态交叉滤波器,则甚至可以对其进行硬编码。