1. 陷波器去直流
speex采用数字陷波器去直流。数字陷波器去直流的基本原理就是在单位圆频率为0(即x轴正半轴与单位圆交点)的地方放置一个零点,并在接近零点的单位圆内放置一对共轭极点,这样即实现了去除直流分量的滤波作用;
公式如下所示:
极零图如下所示:
speex所用的系统函数为:
源码如下
static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride)
{
int i;
spx_word16_t den2;
#ifdef FIXED_POINT
den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius));
#else
den2 = radius*radius + .7*(1-radius)*(1-radius);
#endif
/*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/
for (i=0;i<len;i++)
{
spx_word16_t vin = in[i*stride];
spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15); /* out x(n)-2*x(n - 1) + x(n - 2) + 1.9640*y(n - 1) - 0.964*y(n - 2) */
#ifdef FIXED_POINT
mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1);
#else
mem[0] = mem[1] + 2*(-vin + radius*vout); /* save -2*x(n - 1) + x(n - 2) + 1.9640*y(n - 1) - 0.964*y(n - 2) */
#endif
mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout); /* save x(n - 2) - 0.964*y(n - 2) */
out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767); /* 补偿增益 */
}
}