C语言源码的陷波器设计及调试总结

发布时间 2023-12-08 10:47:20作者: 虚生
一 前记
音频信号处理中,限波器是一个常用的算法。这个算法难度不是很高,可用起来却坑很多。
二 源码解析
1 滤波器的核心函数,这里注意两点,一个是带宽不能太宽了,太宽了杀伤力太大了,容易出问题。另外一个就是滤波器的阶数非常重要,假如想滤波宽度尽量窄一些,那就阶数尽量高一些。
/************************************************************************
*  IIR陷波器(直接II型/典范型)
*  参数列表:
*        short ch:滤波通道,0-17
*        int   xn:滤波输入
*        float fnotch:陷波频率,Hz
*        float bw:    带宽,Hz(eg:50Hz±1Hz,BW=2Hz )    
*        float fs:    采样率,Hz
*        short init:  是否初始化陷波器(1:初始化,0:不初始化)
*  输出:
*        滤波输出(若ch超出范围,或者fs,bw,fnotch不合理,返回-1)
* 说明: 陷波器个数由ch决定,每个陷波器相互独立,因此需要单独初始化;
************************************************************************/
int AzIIRNotchFilter(short ch,int xn, float fnotch,float bw, float fs, short init)
{
    float y0;
    float Fn;
    float BW;

    if (ch<0 || ch>=AZ_CH_NUM)return -1;
    if (bw<=0 || fs<=0 || fnotch<=0 || fs<=fnotch*2 || fnotch-bw/2<=0)return -1;

    Fn = fnotch/(fs/2);
    BW = bw/(fs/2);
    if (init)
    {
        AzInitNotchByChannel(ch,Fn,BW);
    }

//     fNotchBuf[ch][0]=(float)xn*fCoefA[ch][0]-fCoefA[ch][1]*fNotchBuf[ch][1]-fCoefA[ch][2]*fNotchBuf[ch][2];
    fNotchBuf[ch][0]=(float)xn-fCoefA[ch][1]*fNotchBuf[ch][1]-fCoefA[ch][2]*fNotchBuf[ch][2];
    y0=fCoefB[ch][0]*fNotchBuf[ch][0]+fCoefB[ch][1]*fNotchBuf[ch][1]+fCoefB[ch][2]*fNotchBuf[ch][2];
    fNotchBuf[ch][2]=fNotchBuf[ch][1];
    fNotchBuf[ch][1]=fNotchBuf[ch][0];

    return (int)y0;
}
三 效果展示
一个1k的正玄波处理前如下所示:
 
 
过了这个滤波器之后如下所示:
 
这样看可以得出这个限波器还是非常有价值的。
四 总结备忘
1 限波期会影响音质,所以用的时候的原则就是尽量少用或者不用。