C 如何级联两个二阶巴特沃斯滤波器

C 如何级联两个二阶巴特沃斯滤波器,c,matlab,audio,signal-processing,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

我已经计算出了二阶低通和高通巴特沃斯滤波器的系数

系数如下所示。我正在实现这个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; 
我现在要做一个四阶林威茨-莱利交叉。我知道这是两个巴特沃斯的级联。我不太确定该怎么办。我只是把系数相乘吗?我走对了吗?如果有人被打扰,我的系数看起来还好吗?他们在matlab中绘制得很好。

为什么不使用

  • :如果你能负担得起(不是免费的)
  • 如果您准备好尝试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]))
为什么不使用

  • :如果你能负担得起(不是免费的)
  • 如果您准备好尝试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]))

为了创建一个四阶高通(分别为低通)Linkwitz-Riley滤波器,必须级联两个相同的二阶高通(分别为低通)Butterworth滤波器

对于滤波器多项式,它意味着:

巴特沃斯过滤器:

h = b0 + b1.X + b2.X**2 / a0 + a1.X + a2.X**2
Linkwitz-Riley过滤器:

h' = h**2
因此,如果您的实现允许,您可以简单地平方巴特沃斯过滤器

如果要获得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)
    

为了创建一个四阶高通(分别为低通)Linkwitz-Riley滤波器,必须级联两个相同的二阶高通(分别为低通)Butterworth滤波器

对于滤波器多项式,它意味着:

巴特沃斯过滤器:

h = b0 + b1.X + b2.X**2 / a0 + a1.X + a2.X**2
Linkwitz-Riley过滤器:

h' = h**2
因此,如果您的实现允许,您可以简单地平方巴特沃斯过滤器

如果要获得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)
    

    • 罗比的评论是正确的

      首先,为了创建Linkwitz-Riley过滤器(同样适用于低通或高通),必须级联两个相同的过滤器,如Apree所述。现在,这和RawBean的评论一起意味着你必须卷积系数。这可以分别针对分子和分母进行,最终结果将对应于您正在寻找的Linkwitz-Riley系数的分子和分母系数


      如果你看一看Apree的例子,卷积函数被用来计算最终的系数。你可以很好地使用这个代码片段来获取你的系数,如果实现是一个静态交叉过滤器,你甚至可以对它们进行硬编码。

      RawBean在他的评论中是正确的

      首先,为了创建Linkwitz-Riley过滤器(同样适用于低通或高通),必须级联两个相同的过滤器,如Apree所述。现在,这和RawBean的评论一起意味着你必须卷积系数。这可以分别针对分子和分母进行,最终结果将对应于您正在寻找的Linkwitz-Riley系数的分子和分母系数


      如果你看一看Apree的例子,卷积函数被用来计算最终的系数。你可以很好地使用这个代码片段来获得系数,如果实现是静态交叉滤波器,你甚至可以对它们进行硬编码。

      我可以补充一点,我使用了双线性变换来获得这些系数。我不认为你可以乘系数,你可以乘频率空间中的传递函数。或者你可以把你的信号按顺序通过它们。但这不就是先衰减高频然后再衰减低频吗?是的。这不是你想要的吗?要基本上创建一个带通滤波器?这就是级联LPF和HPF将要做的。。。您确定要级联它们吗?在交叉网络中,这两个筛选器不是级联的。相反,相同的信号并行应用于两个滤波器。每个滤波器的输出分别提供高频和低频(每个将被发送到不同的扬声器)。例如,我可以加上,我用双线性变换得到这些系数。我不认为你可以乘以系数,你可以乘以频率空间中的传递函数。或者你可以把你的信号按顺序通过它们。但这不就是先衰减高频然后再衰减低频吗?是的。这不是你想要的吗?要基本上创建一个带通滤波器?这就是级联LPF和HPF将要做的。。。您确定要级联它们吗?在交叉网络中,这两个筛选器不是级联的。相反,相同的信号并行应用于两个滤波器。每个滤波器的输出分别提供高频和低频(每个将被发送到不同的扬声器)。例如,我正在做