打印
[开发资料]

二阶滤波器C代码实现

[复制链接]
316|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1988020566|  楼主 | 2022-9-11 20:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define PI 3.14159265358979323846
typedef double sample_t;

enum {
    BIQUAD_LOWPASS,
    BIQUAD_HIGHPASS,
    BIQUAD_BANDPASS_PEAK,
};

typedef struct
{
    sample_t a0, a1, a2, a3, a4;
    sample_t x1, x2, y1, y2;
}biquad_state;

// 计算滤波器的系数,2nd-order Butterworth: q_value=0.7071 ,2nd-order Chebyshev (ripple 1 dB): q_value=0.9565,2nd-order Thomson-Bessel:
// q_value=0.5773。带通滤波器的q_value = sqrt(f1*f2)/(f2-f1),fs是指信号的采样频率,fc为cutoff frequence 或者是centern frequenc(带通滤波器)
void filter_init(biquad_state *state, int type, int fs, float fc, float q_value)
{
    sample_t w0, sin_w0, cos_w0, alpha;
    sample_t b0, b1, b2, a0, a1, a2;

    w0 = 2 * PI * fc / fs;
    sin_w0 = sin(w0);
    cos_w0 = cos(w0);
    alpha = sin_w0 / (2.0 * q_value);

    switch(type)
    {
    case BIQUAD_LOWPASS:
        b0 = (1.0 - cos_w0) / 2.0;
        b1 = b0 * 2;
        b2 = b0;
        a0 = 1.0 + alpha;
        a1 = -2.0 * cos_w0;
        a2 = 1.0 - alpha;
        break;
    case BIQUAD_HIGHPASS:
        b0 = (1.0 + cos_w0) / 2.0;
        b1 = -b0 * 2;
        b2 = b0;
        a0 = 1.0 + alpha;
        a1 = -2.0 * cos_w0;
        a2 = 1.0 - alpha;
        break;
    case BIQUAD_BANDPASS_PEAK:
        b0 = alpha;
        b1 = 0.0;
        b2 = -alpha;
        a0 = 1.0 + alpha;
        a1 = -2.0 * cos_w0;
        a2 = 1.0 - alpha;
        break;
    }
    state->a0 = b0 / a0;
    state->a1 = b1 / a0;
    state->a2 = b2 / a0;
    state->a3 = a1 / a0;
    state->a4 = a2 / a0;
    state->x1 = state->x2 = 0.0;
    state->y1 = state->y2 = 0.0;
}

//biquard滤波
sample_t biquad(biquad_state *state, sample_t data)
{
    sample_t result = 0;
    result = state->a0 * data + state->a1 * state->x1 + state->a2 * state->x2 -  state->a3 * state->y1 - state->a4 * state->y2;
    state->x2 = state->x1;
    state->x1 = data;
    state->y2 = state->y1;
    state->y1 = result;
    return result;

}int main(int argc, char **argv) {
    biquad_state *stat = (biquad_state *) malloc(sizeof(biquad_state));
    int numbers = 1024;
    float fs = 1024;
    sample_t data[numbers], filter_data[numbers];
    float fc = 50;
    float q_value = 0.7071;
    int type = BIQUAD_LOWPASS;
    filter_init(stat, type, fs, fc, q_value);
    for (int i = 0; i <numbers; ++i)
    { 
        data[i] = 0.5 * (sin(2 * PI * 40 * i / fs) + cos(2 * PI * 150 * i / fs + PI / 4));
    }
    
    for (int i = 0; i <numbers; ++i)
    {
        filter_data[i] = biquad(stat, data[i]);
    }
    free(stat);
}      


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

381

主题

10425

帖子

6

粉丝