带通FIR滤波器

4
我需要制作一个简单的带通音频滤波器。现在我使用了这个简单的C++类:http://www.cardinalpeak.com/blog/a-c-class-to-implement-low-pass-high-pass-and-band-pass-filters,它很好地截断了所需的频带。但是当我尝试以小步长更改上限或下限时,在某些极限值上,我会听到错误的结果-被衰减或偏移频率(与当前极限不对应)的声音。
用于计算冲激响应的函数:
void Filter::designBPF()
{
    int n;
    float mm;

    for(n = 0; n < m_num_taps; n++){
        mm = n - (m_num_taps - 1.0) / 2.0;
        if( mm == 0.0 ) m_taps[n] = (m_phi - m_lambda) / M_PI;
        else m_taps[n] = (   sin( mm * m_phi ) -
                             sin( mm * m_lambda )   ) / (mm * M_PI);
    }

    return;
}

在哪里

m_lambda = M_PI * Fl / (Fs/2);
m_phi = M_PI * Fu / (Fs/2);

Fs - 采样率 (44.100) Fl - 下限 Fu - 上限

还有一个简单的滤波函数:

float Filter::do_sample(float data_sample)
{
    int i;
    float result;

    if( m_error_flag != 0 ) return(0);

    for(i = m_num_taps - 1; i >= 1; i--){
        m_sr[i] = m_sr[i-1];
    }   
    m_sr[0] = data_sample;

    result = 0;
    for(i = 0; i < m_num_taps; i++) result += m_sr[i] * m_taps[i];

    return result;
}

我需要使用窗函数(如Blackman等)吗?如果需要,我该如何做呢? 我已经尝试将脉冲响应乘以Blackman窗口:

m_taps[n] *= 0.42 - 0.5 * cos(2.0 * M_PI * n / double(N - 1)) +
                0.08 * cos(4.0 * M_PI * n / double(N - 1));

但结果是错误的。我需要规范制表符吗?

我犹豫了,也许这个问题更与http://dsp.stackexchange.com/有关。 - Stephane Rolland
2个回答

1

我发现了一个很好的免费FIR滤波器实现:

http://www.iowahills.com/A7ExampleCodePage.html

...这个窗口FIR滤波器C代码有两个部分,第一部分是矩形窗口(低通、高通、带通或陷波)脉冲响应的计算。然后将窗口(Kaiser、Hanning等)应用于脉冲响应。有几种窗口可供选择...


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接