[开发资料] 二阶滤波器C代码实现

[复制链接]
 楼主| 1988020566 发表于 2022-9-11 20:32 | 显示全部楼层 |阅读模式
  1. #define PI 3.14159265358979323846
  2. typedef double sample_t;

  3. enum {
  4.     BIQUAD_LOWPASS,
  5.     BIQUAD_HIGHPASS,
  6.     BIQUAD_BANDPASS_PEAK,
  7. };

  8. typedef struct
  9. {
  10.     sample_t a0, a1, a2, a3, a4;
  11.     sample_t x1, x2, y1, y2;
  12. }biquad_state;

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

  19.     w0 = 2 * PI * fc / fs;
  20.     sin_w0 = sin(w0);
  21.     cos_w0 = cos(w0);
  22.     alpha = sin_w0 / (2.0 * q_value);

  23.     switch(type)
  24.     {
  25.     case BIQUAD_LOWPASS:
  26.         b0 = (1.0 - cos_w0) / 2.0;
  27.         b1 = b0 * 2;
  28.         b2 = b0;
  29.         a0 = 1.0 + alpha;
  30.         a1 = -2.0 * cos_w0;
  31.         a2 = 1.0 - alpha;
  32.         break;
  33.     case BIQUAD_HIGHPASS:
  34.         b0 = (1.0 + cos_w0) / 2.0;
  35.         b1 = -b0 * 2;
  36.         b2 = b0;
  37.         a0 = 1.0 + alpha;
  38.         a1 = -2.0 * cos_w0;
  39.         a2 = 1.0 - alpha;
  40.         break;
  41.     case BIQUAD_BANDPASS_PEAK:
  42.         b0 = alpha;
  43.         b1 = 0.0;
  44.         b2 = -alpha;
  45.         a0 = 1.0 + alpha;
  46.         a1 = -2.0 * cos_w0;
  47.         a2 = 1.0 - alpha;
  48.         break;
  49.     }
  50.     state->a0 = b0 / a0;
  51.     state->a1 = b1 / a0;
  52.     state->a2 = b2 / a0;
  53.     state->a3 = a1 / a0;
  54.     state->a4 = a2 / a0;
  55.     state->x1 = state->x2 = 0.0;
  56.     state->y1 = state->y2 = 0.0;
  57. }

  58. //biquard滤波
  59. sample_t biquad(biquad_state *state, sample_t data)
  60. {
  61.     sample_t result = 0;
  62.     result = state->a0 * data + state->a1 * state->x1 + state->a2 * state->x2 -  state->a3 * state->y1 - state->a4 * state->y2;
  63.     state->x2 = state->x1;
  64.     state->x1 = data;
  65.     state->y2 = state->y1;
  66.     state->y1 = result;
  67.     return result;

  68. }int main(int argc, char **argv) {
  69.     biquad_state *stat = (biquad_state *) malloc(sizeof(biquad_state));
  70.     int numbers = 1024;
  71.     float fs = 1024;
  72.     sample_t data[numbers], filter_data[numbers];
  73.     float fc = 50;
  74.     float q_value = 0.7071;
  75.     int type = BIQUAD_LOWPASS;
  76.     filter_init(stat, type, fs, fc, q_value);
  77.     for (int i = 0; i <numbers; ++i)
  78.     { 
  79.         data[i] = 0.5 * (sin(2 * PI * 40 * i / fs) + cos(2 * PI * 150 * i / fs + PI / 4));
  80.     }
  81.     
  82.     for (int i = 0; i <numbers; ++i)
  83.     {
  84.         filter_data[i] = biquad(stat, data[i]);
  85.     }
  86.     free(stat);
  87. }      


您需要登录后才可以回帖 登录 | 注册

本版积分规则

418

主题

10979

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部