一 前记
音频信号处理中,限波器是一个常用的算法。这个算法难度不是很高,可用起来却坑很多。
二 源码解析
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 限波期会影响音质,所以用的时候的原则就是尽量少用或者不用。