美文网首页
5.IIR数字滤波器

5.IIR数字滤波器

作者: wit_yuan | 来源:发表于2019-05-03 23:53 被阅读0次

1.简介

在做音频eq的时候,iir滤波器是必不可少的,所以这节主要学习一下iir滤波器,当然,不会偏于理论,而是着重怎么用。

iir滤波器主要是用来处理信号的频率的,这是第一个最基本的认识。

摆一下基本的公式:

系统函数:

H(Z)=\frac{Y(Z)}{X(Z)}=\frac{\sum^{M}_{k=0}{b_kZ^{-k}}}{1-\sum^{N}_{k=1}{a_kZ^{-k}}}

差分方程:

y(n)=\sum^{N}_{k=1}{a_ky(n-k)} + \sum^{M}_{k=0}{b_kx(n-k)}

再来说一下该滤波器的结构:
a.直接I型
b.直接II型(典范型)
c.级联型
d.并联型

bcd三种类型都是从直接I型转化而来的,这是第二个最基本的认识。

iir滤波器对于叠加了噪声的信号,也就是信号和噪声的频谱相互混叠是无能为力的,这就是其用在eq上一个基本的原因,这是第三个最基本的认识。

具体再使用一个例子来表述如何使用该公式,由于使用matlab仿真条件下,反馈符号是负号,故需要将y代入一个负号。
假设是二阶滤波器,并且分子,分母如下:
b=[0.6,0.8,1.0]
a=[1,0.5,1.5]
样本点如下:
x=[1.0,2.5,1.5,0.5]
则计算一下输出值:
y(0)=-a_1*y(0-1)-a_2*y(0-2)+b_0*x(0)+b_1*x(0-1)+b_2*x(0-2)=0.6
y(1)=-a_1*y(1-1)-a_2*y(1-2)+b_0*x(1)+b_1*x(1-1)+b_2*x(1-2)=2.0
y(2)=-a_1*y(2-1)-a_2*y(2-2)+b_0*x(2)+b_1*x(2-1)+b_2*x(2-2)=2.0
y(3)=-a_1*y(3-1)-a_2*y(3-2)+b_0*x(3)+b_1*x(3-1)+b_2*x(3-2)=0

使用matlab编写上述程序,如下所示:

clc;
clear all;
format long;
b =  [0.6,0.8,1.0];
a = [1,0.5,1.5];
x = [1,2.5,1.5,0.5];
y=filter(b,a,x)

有一点要注意,在做dsp开发的时候,a,b的排序并不一定是按照[a_0,a_1,a_2],有可能是[a_2,a_1,a_0],这一点需要查看具体的API即可。

2.关于iir滤波器系数

可以使用matlab来计算出iir滤波器的系数,当然,也有其他的工具可以达成这样的功能,例如:一个直接计算的在线工具

3.二阶滤波器例子

3.1 简单的一段2阶滤波器

再来写一点例子程序,例如c代码:

void test_iir_raw()
{
    int i,j,k;
    int len = 4;
    float in[4]={0.0,0.1,0.2,0.3};
    float geq_para[5]={0.1,0.3,0.5,0,0};
    float a[3],b[3];
    float geq_state[2]={0.0};
    float geq_state_in[2]={0.0};
    float ym;
    float g=1.0;
    float tmpdata[4];

    a[0] = 1;
    a[1] = geq_para[1];
    a[2] = geq_para[2];
    b[0] = geq_para[0];
    b[1] = 0;
    b[2] = -b[0];

    for (k = 0; k < len; k++)
    {
        ym = geq_para[0] * (in[k] - geq_state_in[1]) - geq_para[2] * geq_state[1] - geq_para[1] * geq_state[0];
        geq_state[1] = geq_state[0];
        geq_state[0] = ym;
        geq_state_in[1] = geq_state_in[0];
        geq_state_in[0] = in[k];
        tmpdata[k] += ym * g;
    }
    for(i = 0 ; i < 4 ; i ++){
        printf("tmpdata:%f\n",tmpdata[i]);
    }
}

再例如matlab代码:

clc;
clear all;
format long;
b =  [0.1,  0,   -0.1];
a = [1,   0.3,   0.5];
xk=[0.0,0.1,0.2,0.3];
y=filter(b,a,xk)

可以很简单的分析到:

geq_state可以代表y(n)的临时变量.geq_state_in代表的是x(n)的临时变量.

我再给出结果:

tmpdata:0.000000
tmpdata:0.010000
tmpdata:0.017000
tmpdata:0.009900

最后,在说明一下本例子中的一个临时结果:

geq_state[0]=0.009900,geq_state[1]=0.017000
geq_state_in[0]=0.300000,geq_state_in[1]=0.200000

3.2 简单的二段2阶滤波器

这是一个并联的二阶滤波器,相当于一段音频做两次二阶滤波器效果,对应的是在每一个点上加上上一次做的结果值,我列出c代码:

void test_iir_raw()
{
    int i,j,k;
    int len = 4;
    float in[4]={0.0,0.1,0.2,0.3};
    float geq_para[GEQ_BANDS][5]={{0.1,0.3,0.5,0,0},{0.1,0.3,0.5,0,0}};
    float a[3],b[3];
    float geq_state[GEQ_BANDS][2]={0.0};
    float geq_state_in[GEQ_BANDS][2]={0.0};
    float ym;
    float g=1.0;
    float tmpdata[4];

    for(j = 0 ; j < GEQ_BANDS ; j ++){
        for (k = 0; k < len; k++)
        {
            ym = geq_para[j][0] * (in[k] - geq_state_in[j][1]) - geq_para[j][2] * geq_state[j][1] - geq_para[j][1] * geq_state[j][0];
            geq_state[j][1] = geq_state[j][0];
            geq_state[j][0] = ym;
            geq_state_in[j][1] = geq_state_in[j][0];
            geq_state_in[j][0] = in[k];
            tmpdata[k] += ym * g;
        }
    }

    for(i = 0 ; i < 4 ; i ++){
        printf("tmpdata:%f\n",tmpdata[i]);
    }
}

对应的matlab结果就是上次给出的值中每一项乘以2即可.至此,这个部分结束.

4.定点

首先给出biquad滤波器的差分函数形式:

y[n]=b0*x[n]+b1*x[n-1]+b2*x[n-2]-a1*y[n-1]-a2*y[n-2]

注意:
Matlab里的计算就是按照上面的式子计算的,但是STM32F4DSP库里的系数a1,a2是取反的。

再贴出来biquad滤波器的实现代码:

        for (k = 0; k < len; k++)
        {
            ym = geq_para[j][0] * (in[k] - geq_state_in[j][1]) - geq_para[j][2] * geq_state[j][1] - geq_para[j][1] * geq_state[j][0];
            geq_state[j][1] = geq_state[j][0];
            geq_state[j][0] = ym;
            geq_state_in[j][1] = geq_state_in[j][0];
            geq_state_in[j][0] = in[k];
            tmpdata[k] += ym * g;
        }

为了让定点化来的顺利,可以在第一步的时候只定点化ym,也就是说:

            geq_state[j][1] = geq_state[j][0];
            geq_state[j][0] = ym;
            geq_state_in[j][1] = geq_state_in[j][0];
            geq_state_in[j][0] = in[k];
            tmpdata[k] += ym * g;

这部分不变,而先将:

ym = geq_para[j][0] * (in[k] - geq_state_in[j][1]) - 
geq_para[j][2] * geq_state[j][1] - geq_para[j][1] * geq_state[j][0];

各个部分进行定点:

long long int tmp1 = geq_para[j][0] * (1 << 26);
long long int tmp2 = geq_para[j][2] * (1 << 26);
long long int tmp3 = geq_para[j][1] * (1 << 26);
tmp1 = (tmp1 * tmp0) >> 26;
tmp2 = (tmp2 * tmpp1) >> 26;
tmp3 = (tmp3 * tmpp2) >> 26;
ym = (tmp1 - tmp2 - tmp3)*1.0 / (1 << 26);

之后再将整体浮点数替换,从而真正实现定点化(64位)。为了方便移植到硬件上,还需要进一步定点化。

可以按照如下方法做进一步处理:

long long int tmp0 = (in[i][k])*(1 << 28) - geq_state_in_int[i][j][1];
long long int tmp1 = geq_para[j][0] * (1 << 26);
long long int tmp2 = geq_para[j][2] * (1 << 26);
long long int tmp3 = geq_para[j][1] * (1 << 26);

long long int tmpp1 = geq_state_int[i][j][1] ;
long long int tmpp2 = geq_state_int[i][j][0] ;

tmp1 = (tmp1 * tmp0) >> 26;
tmp2 = (tmp2 * tmpp1) >> 26;
tmp3 = (tmp3 * tmpp2) >> 26;

ym_int = tmp1 - tmp2 - tmp3;
geq_state_int[i][j][1] = geq_state_int[i][j][0];
geq_state_int[i][j][0] = ym_int;
geq_state_in_int[i][j][1] = geq_state_in_int[i][j][0];
geq_state_in_int[i][j][0] = in[i][k] * (1 << 28);
tmpdata_int[k] += ym_int * g;

相关文章

  • 5.IIR数字滤波器

    1.简介 在做音频eq的时候,iir滤波器是必不可少的,所以这节主要学习一下iir滤波器,当然,不会偏于理论,而是...

  • 2021-08-08

    浅谈频域数字滤波器[https://zhuanlan.zhihu.com/p/26194805] IIR数字滤波器...

  • 数字滤波器的基本结构

    数字滤波器结构的表示方法 功能:把输入序列通过一定的运算变换成输出序列本质:数字滤波器的滤波过程是一个计算过程 表...

  • FIR和IIR 滤波器

    两类数字滤波器是 有限脉冲响应(Finite Impulse Response, FIR) 无限脉冲响应(Infi...

  • 【原创】C++实现IIR数字滤波器(二)

    在上一篇文章中,我们讲到了C++实现IIR数字滤波器的理论模型及计算公式,以及实现了一个简单的带通滤波器提取交流信...

  • 【原创】C++实现IIR二阶数字滤波器(一)

    滤波器数学模型 如图Fig1所示,是IIR二阶数字滤波器的数学计算公式 转换到离散域,计算公式如下 滤波器系数计算...

  • Differences between four kinds o

    摘要:本文研究了低通、高通、带通、带阻模拟滤波器和数字滤波器的频率响应特性,单位脉冲响应以及零极点分布图,并定性解...

  • python制作数字滤波器

    在对数字序列进行滤波的过程中,我们发现对某些序列滤波后,在首端和尾端出现异常值(主要为异常大值)。具体的原因我还不...

  • matlab+vivado设计数字滤波器

    **这两个月在做数字信号处理方面的工作,也是从一个小白刚刚起步,这两天才把fir滤波器给跑通,写文记录下。希望大家...

  • MATLAB实现IIR数字滤波器设计及应用

    准备前的工作——一段收集来的代码 一、输入信号时域&频域图像(非声音信号,而是函数) https://blog.c...

网友评论

      本文标题:5.IIR数字滤波器

      本文链接:https://www.haomeiwen.com/subject/azdtoqtx.html