g723源码详细分析-18-丢包补偿
生活随笔
收集整理的這篇文章主要介紹了
g723源码详细分析-18-丢包补偿
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
g723對網絡丟包行為了一些處理
涉及的函數為Comp_Info Regen
Comp_Info:負責計算插值依據
它的四個參數
Word16 *Buff:激勵數組,包含之前的145個激勵
Word16 Olp:當前幀的基音周期
Word16 *Gain:輸入增益(歸一化的)
Word16 *ShGain:輸出增益的縮放位移
返回值是激勵插值的延后
現在來看Comp_Info函數
道先做一個歸一化處理,得到能量的歸一化所需要位移位數
??? /* Normalize the excitation */
??? *ShGain = Vec_Norm( Buff, (Word16) (PitchMax+Frame) ) ;
在基音周期附近(Olp-3,Olp+3)這個范圍內尋找自相關最大的120個樣點取值,
代碼片段如下:
??? for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) { //lsc 在基音周期附近搜索自相關最大的一個索引
??????? Acc0 = (Word32) 0 ;
??????? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
??????????????????????????????????? Buff[PitchMax+Frame-2*SubFrLen-i+j] ) ;
??????? if ( Acc0 > Acc1 ) {
??????????? Acc1 = Acc0 ;//lsc Acc1保存基音周延后自相關最大的
??????????? Indx = (Word16) i ;
??????? }
??? }
找出來的基音延后序列我們記錄 x[n-Indx]
?? ?
計算最后120個樣點的能量 Tenr 這個是x[n]的能量(最后120個樣點)
??? /* Compute target energy */ //lsc 計算最后120個樣點的能量
??? Acc0 = (Word32) 0 ;
??? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
??????????????????????????????????? Buff[PitchMax+Frame-2*SubFrLen+j] ) ;
??? Tenr = round( Acc0 ) ;
??? *Gain = Tenr;
?? ?
計算最佳基音延后的能量 Enr 這個是x[n-Indx]的能量(連續120個)
??? /* Compute best energy */ //lsc 計算基音周期延后的能量Acc0
??? Acc0 = (Word32) 0 ;
??? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j],
??????????????????????????? Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j] ) ;
得到能量以相基音延后的自相關之后,
就可以判斷x[n-Indx] x[n]的相似度了
x[n-Indx] x[n]相關,在代碼中是Ccr
(Enr * Tenr)/16 < Ccr^2 就認為這兩個序列是相關的,
當丟包時,插值依據就是x[n-Indx],否則取x[n]
代碼片段:
??? Ccr = round( Acc1 ) ;
??? if ( Ccr <= (Word16) 0 )
??????? return (Word16) 0 ;
??? Enr = round( Acc0 ) ;
??? Acc0 = L_mult( Enr, Tenr ) ;//lsc Enr 為基音周期最佳延后的能量 Tenr為最后120個樣點的能量
??? Acc0 = L_shr( Acc0, (Word16) 3 ) ;
??? Acc0 = L_msu( Acc0, Ccr, Ccr ) ;//lsc Ccr為最佳基音延遲自相關
??? if ( Acc0 < (Word32) 0 )//lsc Acc0小 說明相關性大 可能會作為插值的依據,否則插值的依據就是前面的120個點
??????? return Indx ;
??? else
??????? return (Word16) 0 ;
再來看Regen,它負責在出現丟包時,做插值
是否丟包,是由調用Decod時傳的一個參數crc來觸發
??????????? Regen( DataBuff, Temp, DecStat.InterIndx, DecStat.InterGain,
??????????????????????????????????????? DecStat.Ecount, &DecStat.Rseed ) ;
DecStat.InterIndx就是Comp_Info計算得到的基音延后Temp保存145個歷史解碼激勵,
DataBuff為輸出的插值激勵
其中DecStat.InterGain是由以前幀得到的
如果沒有丟包,取中間兩子幀的平均,
丟包則按0.75的衰減取值
??????? /*
??????? * In case of no erasure, update the interpolation gain memory.
??????? * Otherwise compute the interpolation gain (Text: Section 3.10)
??????? */
??????? if ( DecStat.Ecount == (Word16) 0 ) {
??????????? DecStat.InterGain = add( Line.Sfs[SubFrames-2].Mamp,
??????????????????????????????????????????? Line.Sfs[SubFrames-1].Mamp ) ;
??????????? DecStat.InterGain = shr( DecStat.InterGain, (Word16) 1 ) ;//lsc 取中間兩幀增益的平均,作為丟包時的插值增益
??????????? DecStat.InterGain = FcbkGainTable[DecStat.InterGain] ;
??????? }
??????? else
??????????? DecStat.InterGain = mult_r( DecStat.InterGain, (Word16) 0x6000 ) ;//lsc 丟包時,按0.75衰減
Regen的函數過程
如果錯誤次數超為6,則不做插值
錯誤次數小于6,按DecStat.InterIndx是否為0,
DecStat.InterIndx不為0,取相應的基音延后歷史激勵插值
??????????? /* Voiced case */
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? Buff[PitchMax+i] = Buff[PitchMax-(int)Lag+i] ;//lsc 利用基音延后,構造一個周期激勵
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? DataBuff[i] = Buff[PitchMax+i] = mult( Buff[PitchMax+i],
??????????????????????????? (Word16) 0x6000 ) ;//lsc 做一個0.75的衰減
?????????????????????????? ?
如果為0,認為處于清音段,用隨機激勵插值
??????????? /* Unvoiced case */
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? DataBuff[i] = mult( Gain, Rand_lbc( Sd ) ) ;//lsc 模擬一個隨機激勵
??????????? /* Clear buffer to reset memory */
??????????? for ( i = 0 ; i < Frame+PitchMax ; i ++ )
??????????????? Buff[i] = (Word16) 0 ;
下一章節將分析基音后置濾波與共振峰后置濾波
????????????????????????????????????????????? 林紹川
????????????????????????????????????????????? 2012.01.16于杭州
涉及的函數為Comp_Info Regen
Comp_Info:負責計算插值依據
它的四個參數
Word16 *Buff:激勵數組,包含之前的145個激勵
Word16 Olp:當前幀的基音周期
Word16 *Gain:輸入增益(歸一化的)
Word16 *ShGain:輸出增益的縮放位移
返回值是激勵插值的延后
現在來看Comp_Info函數
道先做一個歸一化處理,得到能量的歸一化所需要位移位數
??? /* Normalize the excitation */
??? *ShGain = Vec_Norm( Buff, (Word16) (PitchMax+Frame) ) ;
在基音周期附近(Olp-3,Olp+3)這個范圍內尋找自相關最大的120個樣點取值,
代碼片段如下:
??? for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) { //lsc 在基音周期附近搜索自相關最大的一個索引
??????? Acc0 = (Word32) 0 ;
??????? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
??????????????????????????????????? Buff[PitchMax+Frame-2*SubFrLen-i+j] ) ;
??????? if ( Acc0 > Acc1 ) {
??????????? Acc1 = Acc0 ;//lsc Acc1保存基音周延后自相關最大的
??????????? Indx = (Word16) i ;
??????? }
??? }
找出來的基音延后序列我們記錄 x[n-Indx]
?? ?
計算最后120個樣點的能量 Tenr 這個是x[n]的能量(最后120個樣點)
??? /* Compute target energy */ //lsc 計算最后120個樣點的能量
??? Acc0 = (Word32) 0 ;
??? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
??????????????????????????????????? Buff[PitchMax+Frame-2*SubFrLen+j] ) ;
??? Tenr = round( Acc0 ) ;
??? *Gain = Tenr;
?? ?
計算最佳基音延后的能量 Enr 這個是x[n-Indx]的能量(連續120個)
??? /* Compute best energy */ //lsc 計算基音周期延后的能量Acc0
??? Acc0 = (Word32) 0 ;
??? for ( j = 0 ; j < 2*SubFrLen ; j ++ )
??????? Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j],
??????????????????????????? Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j] ) ;
得到能量以相基音延后的自相關之后,
就可以判斷x[n-Indx] x[n]的相似度了
x[n-Indx] x[n]相關,在代碼中是Ccr
(Enr * Tenr)/16 < Ccr^2 就認為這兩個序列是相關的,
當丟包時,插值依據就是x[n-Indx],否則取x[n]
代碼片段:
??? Ccr = round( Acc1 ) ;
??? if ( Ccr <= (Word16) 0 )
??????? return (Word16) 0 ;
??? Enr = round( Acc0 ) ;
??? Acc0 = L_mult( Enr, Tenr ) ;//lsc Enr 為基音周期最佳延后的能量 Tenr為最后120個樣點的能量
??? Acc0 = L_shr( Acc0, (Word16) 3 ) ;
??? Acc0 = L_msu( Acc0, Ccr, Ccr ) ;//lsc Ccr為最佳基音延遲自相關
??? if ( Acc0 < (Word32) 0 )//lsc Acc0小 說明相關性大 可能會作為插值的依據,否則插值的依據就是前面的120個點
??????? return Indx ;
??? else
??????? return (Word16) 0 ;
再來看Regen,它負責在出現丟包時,做插值
是否丟包,是由調用Decod時傳的一個參數crc來觸發
??????????? Regen( DataBuff, Temp, DecStat.InterIndx, DecStat.InterGain,
??????????????????????????????????????? DecStat.Ecount, &DecStat.Rseed ) ;
DecStat.InterIndx就是Comp_Info計算得到的基音延后Temp保存145個歷史解碼激勵,
DataBuff為輸出的插值激勵
其中DecStat.InterGain是由以前幀得到的
如果沒有丟包,取中間兩子幀的平均,
丟包則按0.75的衰減取值
??????? /*
??????? * In case of no erasure, update the interpolation gain memory.
??????? * Otherwise compute the interpolation gain (Text: Section 3.10)
??????? */
??????? if ( DecStat.Ecount == (Word16) 0 ) {
??????????? DecStat.InterGain = add( Line.Sfs[SubFrames-2].Mamp,
??????????????????????????????????????????? Line.Sfs[SubFrames-1].Mamp ) ;
??????????? DecStat.InterGain = shr( DecStat.InterGain, (Word16) 1 ) ;//lsc 取中間兩幀增益的平均,作為丟包時的插值增益
??????????? DecStat.InterGain = FcbkGainTable[DecStat.InterGain] ;
??????? }
??????? else
??????????? DecStat.InterGain = mult_r( DecStat.InterGain, (Word16) 0x6000 ) ;//lsc 丟包時,按0.75衰減
Regen的函數過程
如果錯誤次數超為6,則不做插值
錯誤次數小于6,按DecStat.InterIndx是否為0,
DecStat.InterIndx不為0,取相應的基音延后歷史激勵插值
??????????? /* Voiced case */
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? Buff[PitchMax+i] = Buff[PitchMax-(int)Lag+i] ;//lsc 利用基音延后,構造一個周期激勵
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? DataBuff[i] = Buff[PitchMax+i] = mult( Buff[PitchMax+i],
??????????????????????????? (Word16) 0x6000 ) ;//lsc 做一個0.75的衰減
?????????????????????????? ?
如果為0,認為處于清音段,用隨機激勵插值
??????????? /* Unvoiced case */
??????????? for ( i = 0 ; i < Frame ; i ++ )
??????????????? DataBuff[i] = mult( Gain, Rand_lbc( Sd ) ) ;//lsc 模擬一個隨機激勵
??????????? /* Clear buffer to reset memory */
??????????? for ( i = 0 ; i < Frame+PitchMax ; i ++ )
??????????????? Buff[i] = (Word16) 0 ;
下一章節將分析基音后置濾波與共振峰后置濾波
????????????????????????????????????????????? 林紹川
????????????????????????????????????????????? 2012.01.16于杭州
總結
以上是生活随笔為你收集整理的g723源码详细分析-18-丢包补偿的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue前端框架快速入门
- 下一篇: Oracle集合类型