现在来分析最后一块g723中最后一个未分析模块
共振峰后置滤波器
涉及函数 Spf Scale
观察itu 3.8 式49.3:
10
1 - Σ ai * λ1^i * z^(-i)
i=1
F(z)= --------------------------- (1 - 0.25 * k * z^(-i))
10
1 - Σ ai * λ2^i * z^(-i)
i=1
这个滤波器是由两部分组成
(1 - 0.25 * k * z^(-i)) 这一部分为倾斜补偿滤波器,
由k的取值可以起到那频谱倾斜度调节的作用,这一点会在本文下面进一步说明
别来看短时滤波部分,即
10
1 - Σ ai * λ1^i * z^(-i)
i=1
---------------------------
10
1 - Σ ai * λ2^i * z^(-i)
i=1
其中λ1=0.65 λ2=0.75
回顾共振峰感知加权滤波器,这两个值的大小正好是相反的(共振峰加权γ1=0.9 γ2=0.5)
共振峰感加权,目的是加强频谱中共振峰处的能量,但同时也会对波谷处的噪声,
共振峰后置滤波器就是要降低波谷处噪声
由于需要构造的稳定系统,可以想见,z^-1的系数应该要小于1,即ai*(λ2^i)必须不能大于1,
保险的办法,就是λ2不能大于1,又由于需要降低频谱波谷处的能量,
引入的调节因子λ1,自然就必须比λ2小
现在来看倾斜补偿滤波器:
(1 - 0.25 * k * z^(-i))
k的取值 见itu文档式49.1 49.2
根据柯西定理,我们很容易得出 -1 < k < 1
z用单位圆代入,可得到频谱幅度的表达式:
1+(0.25)^2 - 0.5*cos(x) k=1 时
1+(0.25)^2 + 0.5*cos(x) k=-1 时
很容易看出,当k=1时(意味着信号自关联性强,即信号低频能量很高),
倾斜补偿滤波器是将高频抬高,而将低频适当抑制
当k=-1时则正好相反
分析完公式的含义,代码基本是照本宣科了,Spf代码片段:
Word32 Spf( Word16 *Tv, Word16 *Lpc )
{
int i,j ;
Word32 Acc0,Acc1 ;
Word32 Sen ;
Word16 Tmp ;
Word16 Exp ;
Word16 FirCoef[LpcOrder] ;
Word16 IirCoef[LpcOrder] ;
Word16 TmpVect[SubFrLen] ;
//lsc 在频域内共振峰加强?? --- 感知加权是加强了共振峰附近的能量(可以从两个系数的比值看出),而此处应正好相反
/*
* Compute ARMA coefficients. Compute the jth FIR coefficient by
* multiplying the jth quantized LPC coefficient by (0.65)^j.
* Compute the jth IIR coefficient by multiplying the jth quantized
* LPC coefficient by (0.75)^j. This emphasizes the formants in
* the frequency response.
*/
for ( i = 0 ; i < LpcOrder ; i ++ ) {
FirCoef[i] = mult_r( Lpc[i], PostFiltZeroTable[i] ) ;
IirCoef[i] = mult_r( Lpc[i], PostFiltPoleTable[i] ) ;
}
/*
* Normalize the speech vector.
*/
for ( i = 0 ; i < SubFrLen ; i ++ )
TmpVect[i] = Tv[i] ;
Exp = Vec_Norm( TmpVect, (Word16) SubFrLen ) ;
/*
* Compute the first two autocorrelation coefficients R[0] and R[1]
*/
Acc0 = (Word32) 0 ;
Acc1 = L_mult( TmpVect[0], TmpVect[0] ) ;
for ( i = 1 ; i < SubFrLen ; i ++ ) {
Acc0 = L_mac( Acc0, TmpVect[i], TmpVect[i-1] ) ;
Acc1 = L_mac( Acc1, TmpVect[i], TmpVect[i] ) ;
}
/*
* Scale the energy for the later use.
*/
Sen = L_shr( Acc1, (Word16)(2*Exp + 4) ) ;//lsc 4 = 3 + 1 这里还原了解码信号的能量
/*
* Compute the first-order partial correlation coefficient of the
* input speech vector.
*/
Tmp = extract_h( Acc1 ) ;//lsc tmp能量的高16位
if ( Tmp != (Word16) 0 ) {
/* Compute first parkor */
Acc0 = L_shr( Acc0, (Word16) 1 ) ;
Acc1 = Acc0 ;
Acc0 = L_abs( Acc0 ) ;
Tmp = div_l( Acc0, Tmp ) ;
if ( Acc1 < (Word32) 0 )
Tmp = negate( Tmp ) ;
}
else
Tmp = (Word16) 0 ;
/*
* Compute the compensation filter parameter and update the memory
*/
//lsc 倾斜补偿滤波器,是一个"高通"滤波器,根据itu的算法 低频大约是0.5625 高频大约是 1.5625,大意是引入后置滤波后
//lsc 会造成频谱倾斜,即高频的能量被抑制了,需要加强,
//lsc 倾斜滤波器的"斜率"应该是根据共振峰所处的位置来调节的,
//lsc 可以看出k的取值就是 应该是 -1 1之间
//lsc 如果k是1 那么说明信号相邻之间的相关性极强,也就是说能量可能集中在低频,要平衡能量,此时会变成高通滤波
//lsc 如果k是-1, 说明信号相关性不强,也就是说能量可能集中在高频,为平衡能量,此时会变成低通滤波
Acc0 = L_deposit_h( DecStat.Park ) ;
Acc0 = L_msu( Acc0, DecStat.Park, (Word16) 0x2000 ) ;
Acc0 = L_mac( Acc0, Tmp, (Word16) 0x2000 ) ;
DecStat.Park = round( Acc0 ) ;
Tmp = mult( DecStat.Park, PreCoef ) ;
Tmp &= (Word16) 0xfffc ;
/*
* Do for all elements in the subframe
*/
for ( i = 0 ; i < SubFrLen ; i ++ ) {
/*
* Input the speech vector
*/
Acc0 = L_deposit_h( Tv[i] ) ;
Acc0 = L_shr( Acc0, (Word16) 2 ) ;
/*
* Formant postfilter
*/
/* FIR part */
for ( j = 0 ; j < LpcOrder ; j ++ )
Acc0 = L_msu( Acc0, FirCoef[j], DecStat.PostFirDl[j] ) ;
/* Update FIR memory */
for ( j = LpcOrder-1 ; j > 0 ; j -- )
DecStat.PostFirDl[j] = DecStat.PostFirDl[j-1] ;
DecStat.PostFirDl[0] = Tv[i] ;
/* IIR part */
for ( j = 0 ; j < LpcOrder ; j ++ )
Acc0 = L_mac( Acc0, IirCoef[j], DecStat.PostIirDl[j] ) ;
/* Update IIR memory */
for ( j = LpcOrder-1 ; j > 0 ; j -- )
DecStat.PostIirDl[j] = DecStat.PostIirDl[j-1] ;
Acc0 = L_shl( Acc0, (Word16) 2 ) ;
Acc1 = Acc0 ;
DecStat.PostIirDl[0] = round( Acc0 ) ;
/*
* Compensation filter
*/
Acc1 = L_mac( Acc1, DecStat.PostIirDl[1], Tmp ) ;
Tv[i] = round( Acc1 ) ;
}
return Sen ;
}
关于增益缩放问题,代码片段如下:
/* Do the gain scaling unit. (Text: Section 3.9) */
Scale( Dpnt, Senr ) ;//lsc 做共振峰感知加权后, 语音的能量会出现放大或者缩小,这里处理,补回去
公式见itu 3.9节的式50.
g723 done!
林绍川
2012.01.19于杭州
共振峰后置滤波器
涉及函数 Spf Scale
观察itu 3.8 式49.3:
10
1 - Σ ai * λ1^i * z^(-i)
i=1
F(z)= --------------------------- (1 - 0.25 * k * z^(-i))
10
1 - Σ ai * λ2^i * z^(-i)
i=1
这个滤波器是由两部分组成
(1 - 0.25 * k * z^(-i)) 这一部分为倾斜补偿滤波器,
由k的取值可以起到那频谱倾斜度调节的作用,这一点会在本文下面进一步说明
别来看短时滤波部分,即
10
1 - Σ ai * λ1^i * z^(-i)
i=1
---------------------------
10
1 - Σ ai * λ2^i * z^(-i)
i=1
其中λ1=0.65 λ2=0.75
回顾共振峰感知加权滤波器,这两个值的大小正好是相反的(共振峰加权γ1=0.9 γ2=0.5)
共振峰感加权,目的是加强频谱中共振峰处的能量,但同时也会对波谷处的噪声,
共振峰后置滤波器就是要降低波谷处噪声
由于需要构造的稳定系统,可以想见,z^-1的系数应该要小于1,即ai*(λ2^i)必须不能大于1,
保险的办法,就是λ2不能大于1,又由于需要降低频谱波谷处的能量,
引入的调节因子λ1,自然就必须比λ2小
现在来看倾斜补偿滤波器:
(1 - 0.25 * k * z^(-i))
k的取值 见itu文档式49.1 49.2
根据柯西定理,我们很容易得出 -1 < k < 1
z用单位圆代入,可得到频谱幅度的表达式:
1+(0.25)^2 - 0.5*cos(x) k=1 时
1+(0.25)^2 + 0.5*cos(x) k=-1 时
很容易看出,当k=1时(意味着信号自关联性强,即信号低频能量很高),
倾斜补偿滤波器是将高频抬高,而将低频适当抑制
当k=-1时则正好相反
分析完公式的含义,代码基本是照本宣科了,Spf代码片段:
Word32 Spf( Word16 *Tv, Word16 *Lpc )
{
int i,j ;
Word32 Acc0,Acc1 ;
Word32 Sen ;
Word16 Tmp ;
Word16 Exp ;
Word16 FirCoef[LpcOrder] ;
Word16 IirCoef[LpcOrder] ;
Word16 TmpVect[SubFrLen] ;
//lsc 在频域内共振峰加强?? --- 感知加权是加强了共振峰附近的能量(可以从两个系数的比值看出),而此处应正好相反
/*
* Compute ARMA coefficients. Compute the jth FIR coefficient by
* multiplying the jth quantized LPC coefficient by (0.65)^j.
* Compute the jth IIR coefficient by multiplying the jth quantized
* LPC coefficient by (0.75)^j. This emphasizes the formants in
* the frequency response.
*/
for ( i = 0 ; i < LpcOrder ; i ++ ) {
FirCoef[i] = mult_r( Lpc[i], PostFiltZeroTable[i] ) ;
IirCoef[i] = mult_r( Lpc[i], PostFiltPoleTable[i] ) ;
}
/*
* Normalize the speech vector.
*/
for ( i = 0 ; i < SubFrLen ; i ++ )
TmpVect[i] = Tv[i] ;
Exp = Vec_Norm( TmpVect, (Word16) SubFrLen ) ;
/*
* Compute the first two autocorrelation coefficients R[0] and R[1]
*/
Acc0 = (Word32) 0 ;
Acc1 = L_mult( TmpVect[0], TmpVect[0] ) ;
for ( i = 1 ; i < SubFrLen ; i ++ ) {
Acc0 = L_mac( Acc0, TmpVect[i], TmpVect[i-1] ) ;
Acc1 = L_mac( Acc1, TmpVect[i], TmpVect[i] ) ;
}
/*
* Scale the energy for the later use.
*/
Sen = L_shr( Acc1, (Word16)(2*Exp + 4) ) ;//lsc 4 = 3 + 1 这里还原了解码信号的能量
/*
* Compute the first-order partial correlation coefficient of the
* input speech vector.
*/
Tmp = extract_h( Acc1 ) ;//lsc tmp能量的高16位
if ( Tmp != (Word16) 0 ) {
/* Compute first parkor */
Acc0 = L_shr( Acc0, (Word16) 1 ) ;
Acc1 = Acc0 ;
Acc0 = L_abs( Acc0 ) ;
Tmp = div_l( Acc0, Tmp ) ;
if ( Acc1 < (Word32) 0 )
Tmp = negate( Tmp ) ;
}
else
Tmp = (Word16) 0 ;
/*
* Compute the compensation filter parameter and update the memory
*/
//lsc 倾斜补偿滤波器,是一个"高通"滤波器,根据itu的算法 低频大约是0.5625 高频大约是 1.5625,大意是引入后置滤波后
//lsc 会造成频谱倾斜,即高频的能量被抑制了,需要加强,
//lsc 倾斜滤波器的"斜率"应该是根据共振峰所处的位置来调节的,
//lsc 可以看出k的取值就是 应该是 -1 1之间
//lsc 如果k是1 那么说明信号相邻之间的相关性极强,也就是说能量可能集中在低频,要平衡能量,此时会变成高通滤波
//lsc 如果k是-1, 说明信号相关性不强,也就是说能量可能集中在高频,为平衡能量,此时会变成低通滤波
Acc0 = L_deposit_h( DecStat.Park ) ;
Acc0 = L_msu( Acc0, DecStat.Park, (Word16) 0x2000 ) ;
Acc0 = L_mac( Acc0, Tmp, (Word16) 0x2000 ) ;
DecStat.Park = round( Acc0 ) ;
Tmp = mult( DecStat.Park, PreCoef ) ;
Tmp &= (Word16) 0xfffc ;
/*
* Do for all elements in the subframe
*/
for ( i = 0 ; i < SubFrLen ; i ++ ) {
/*
* Input the speech vector
*/
Acc0 = L_deposit_h( Tv[i] ) ;
Acc0 = L_shr( Acc0, (Word16) 2 ) ;
/*
* Formant postfilter
*/
/* FIR part */
for ( j = 0 ; j < LpcOrder ; j ++ )
Acc0 = L_msu( Acc0, FirCoef[j], DecStat.PostFirDl[j] ) ;
/* Update FIR memory */
for ( j = LpcOrder-1 ; j > 0 ; j -- )
DecStat.PostFirDl[j] = DecStat.PostFirDl[j-1] ;
DecStat.PostFirDl[0] = Tv[i] ;
/* IIR part */
for ( j = 0 ; j < LpcOrder ; j ++ )
Acc0 = L_mac( Acc0, IirCoef[j], DecStat.PostIirDl[j] ) ;
/* Update IIR memory */
for ( j = LpcOrder-1 ; j > 0 ; j -- )
DecStat.PostIirDl[j] = DecStat.PostIirDl[j-1] ;
Acc0 = L_shl( Acc0, (Word16) 2 ) ;
Acc1 = Acc0 ;
DecStat.PostIirDl[0] = round( Acc0 ) ;
/*
* Compensation filter
*/
Acc1 = L_mac( Acc1, DecStat.PostIirDl[1], Tmp ) ;
Tv[i] = round( Acc1 ) ;
}
return Sen ;
}
关于增益缩放问题,代码片段如下:
/* Do the gain scaling unit. (Text: Section 3.9) */
Scale( Dpnt, Senr ) ;//lsc 做共振峰感知加权后, 语音的能量会出现放大或者缩小,这里处理,补回去
公式见itu 3.9节的式50.
g723 done!
林绍川
2012.01.19于杭州