📄 exc_lbc.c
字号:
for ( j = 1 ; j < SubFrLen ; j ++ ) { Acc0 = L_deposit_h( FltBuf[i+1][j-1] ) ; Acc0 = L_mac( Acc0, RezBuf[i], ImpResp[j] ) ; FltBuf[i][j] = round( Acc0 ) ; } } /* Compute the cross with the signal */ for ( i = 0 ; i < ClPitchOrd ; i ++ ) { Acc1 = (Word32) 0 ; for ( j = 0 ; j < SubFrLen ; j ++ ) { Acc0 = L_mult( Tv[j], FltBuf[i][j] ) ; Acc1 = L_add( Acc1, L_shr( Acc0, (Word16) 1 ) ) ; } *lPnt ++ = L_shl( Acc1, (Word16) 1 ) ; } /* Compute the energies */ for ( i = 0 ; i < ClPitchOrd ; i ++ ) { Acc1 = (Word32) 0 ; for ( j = 0 ; j < SubFrLen ; j ++ ) Acc1 = L_mac( Acc1, FltBuf[i][j], FltBuf[i][j] ) ; *lPnt ++ = Acc1 ; } /* Compute the between crosses */ for ( i = 1 ; i < ClPitchOrd ; i ++ ) { for ( j = 0 ; j < i ; j ++ ) { Acc1 = (Word32) 0 ; for ( l = 0 ; l < SubFrLen ; l ++ ) { Acc0 = L_mult( FltBuf[i][l], FltBuf[j][l] ) ; Acc1 = L_add( Acc1, L_shr( Acc0, (Word16) 1 ) ) ; } *lPnt ++ = L_shl( Acc1, (Word16) 2 ) ; } } } /* Find Max and normalize */ Acc1 = (Word32) 0 ; for ( i = 0 ; i < Hb*20 ; i ++ ) { Acc0 = L_abs(CorBuf[i]) ; if ( Acc0 > Acc1 ) Acc1 = Acc0 ; } Exp = norm_l( Acc1 ) ; /* Convert to shorts */ for ( i = 0 ; i < Hb*20 ; i ++ ) { Acc0 = L_shl( CorBuf[i], Exp ) ; CorVct[i] = round( Acc0 ) ; } /* Test potential error */ Lag1 = Olp-(Word16)Pstep; Lag2 = Olp-(Word16)Pstep+ Hb -(Word16)1; off_filt = Test_Err(Lag1, Lag2); Bound[0] = NbFilt085_min + shl(off_filt,2); if(Bound[0] > NbFilt085) Bound[0] = NbFilt085; Bound[1] = NbFilt170_min + shl(off_filt,3); if(Bound[1] > NbFilt170) Bound[1] = NbFilt170; /* Init the search loop */ Acc1 = (Word32) 0 ; for ( k = 0 ; k < (int) Hb ; k ++ ) { /* Select Quantization tables */ l = 0 ; if ( WrkRate == Rate63 ){ if ( (Sfc & (Word16) 1) == (Word16) 0 ) { if ( (int)Olp-Pstep+k >= SubFrLen-2 )l ++ ; } else { if ( (int)Olp >= SubFrLen-2 ) l ++ ; } } else { l = 1; } sPnt = AcbkGainTablePtr[l] ; for ( i = 0 ; i < (int) Bound[l] ; i ++ ) { Acc0 = (Word32) 0 ; for ( j = 0 ; j < 20 ; j ++ ) Acc0 = L_add( Acc0, L_shr( L_mult(CorVct[k*20+j], *sPnt ++),(Word16) 1 ) ) ; if ( Acc0 > Acc1 ) { Acc1 = Acc0 ; Gid = (Word16) i ; Lid = (Word16) k ; } } } /* Modify Olp for even sub frames */ if ( (Sfc & (Word16) 1 ) == (Word16) 0 ) { Olp = Olp - (Word16) Pstep + Lid ; Lid = (Word16) Pstep ; } /* Save Gains and Olp */ (*Line).Sfs[Sfc].AcLg = Lid ; (*Line).Sfs[Sfc].AcGn = Gid ; (*Line).Olp[shr(Sfc, (Word16) 1)] = Olp ; /* Decode the Acbk contribution and subtract it */ Decod_Acbk( RezBuf, PrevExc, Olp, Lid, Gid ) ; for ( i = 0 ; i < SubFrLen ; i ++ ) { Acc0 = L_deposit_h( Tv[i] ) ; Acc0 = L_shr( Acc0, (Word16) 1 ) ; for ( j = 0 ; j <= i ; j ++ ) Acc0 = L_msu( Acc0, RezBuf[j], ImpResp[i-j] ) ; Acc0 = L_shl( Acc0, (Word16) 1 ) ; Tv[i] = round( Acc0 ) ; } return;}/***** Function: Get_Rez()**** Description: Gets delayed contribution from the previous excitation** vector.**** Links to text: Sections 2.14, 2.18 & 3.4**** Arguments:**** Word16 *Tv delayed excitation** Word16 *PrevExc Previous excitation vector** Word16 Lag Closed loop pitch lag**** Outputs:**** Word16 *Tv delayed excitation**** Return value: None***/void Get_Rez( Word16 *Tv, Word16 *PrevExc, Word16 Lag ){ int i ; for ( i = 0 ; i < ClPitchOrd/2 ; i ++ ) Tv[i] = PrevExc[PitchMax - (int) Lag - ClPitchOrd/2 + i] ; for ( i = 0 ; i < SubFrLen+ClPitchOrd/2 ; i ++ ) Tv[ClPitchOrd/2+i] = PrevExc[PitchMax - (int)Lag + i%(int)Lag] ; return;}/***** Function: Decod_Acbk()**** Description: Computes the adaptive codebook contribution from the previous** excitation vector.** With the gain index, the closed loop pitch lag, the jitter** which when added to this pitch lag gives the actual closed** loop value, and after having selected the proper codebook,** the pitch contribution is reconstructed using the previous** excitation buffer.**** Links to text: Sections 2.14, 2.18 & 3.4**** Arguments:**** Word16 *Tv Reconstructed excitation vector** Word16 *PrevExc Previous excitation vector** Word16 Olp closed-loop pitch period** Word16 Lid Jitter around pitch period** Word16 Gid Gain vector index in 5- dimensional** adaptive gain vector codebook**** Outputs:**** Word16 *Tv Reconstructed excitation vector**** Return value: None***/void Decod_Acbk( Word16 *Tv, Word16 *PrevExc, Word16 Olp, Word16 Lid,Word16 Gid ){ int i,j ; Word32 Acc0 ; Word16 RezBuf[SubFrLen+ClPitchOrd-1] ; Word16 *sPnt ; Get_Rez( RezBuf, PrevExc, (Word16)(Olp - (Word16)Pstep + Lid) ) ; /* Select Quantization tables */ i = 0 ; if ( WrkRate == Rate63 ) { if ( Olp >= (Word16) (SubFrLen-2) ) i ++ ; } else { i = 1; } sPnt = AcbkGainTablePtr[i] ; sPnt += (int)Gid*20 ; for ( i = 0 ; i < SubFrLen ; i ++ ) { Acc0 = (Word32) 0 ; for ( j = 0 ; j < ClPitchOrd ; j ++ ) Acc0 = L_mac( Acc0, RezBuf[i+j], sPnt[j] ) ; Acc0 = L_shl( Acc0, (Word16) 1 ) ; Tv[i] = round( Acc0 ) ; } return;}/***** Function: Comp_Info()**** Description: Voiced/unvoiced classifier.** It is based on a cross correlation maximization over the** last 120 samples of the frame and with an index varying** around the decoded pitch lag (from L-3 to L+3). Then the** prediction gain is tested to declare the frame voiced or** unvoiced.**** Links to text: Section 3.10.2**** Arguments:**** Word16 *Buff decoded excitation** Word16 Olp Decoded pitch lag**** Outputs: None**** Return value:**** Word16 Estimated pitch value*/Word16 Comp_Info( Word16 *Buff, Word16 Olp, Word16 *Gain, Word16 *ShGain){ int i,j ; Word32 Acc0,Acc1 ; Word16 Tenr ; Word16 Ccr,Enr ; Word16 Indx ; /* Normalize the excitation */ *ShGain = Vec_Norm( Buff, (Word16) (PitchMax+Frame) ) ; if ( Olp > (Word16) (PitchMax-3) ) Olp = (Word16) (PitchMax-3) ; Indx = Olp ; Acc1 = (Word32) 0 ; for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) { 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 ; Indx = (Word16) i ; } } /* Compute target energy */ 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; /* Compute best energy */ 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] ) ; Ccr = round( Acc1 ) ; if ( Ccr <= (Word16) 0 ) return (Word16) 0 ; Enr = round( Acc0 ) ; Acc0 = L_mult( Enr, Tenr ) ; Acc0 = L_shr( Acc0, (Word16) 3 ) ; Acc0 = L_msu( Acc0, Ccr, Ccr ) ; if ( Acc0 < (Word32) 0 ) return Indx ; else return (Word16) 0 ;}/***** Function: Regen()**** Description: Performs residual interpolation depending of the frame** classification.** If the frame is previously declared unvoiced, the excitation** is regenerated using a random number generator. Otherwise** a periodic excitation is generated with the period** previously found.**** Links to text: Section 3.10.2**** Arguments:**** Word16 *DataBuff current subframe decoded excitation** Word16 *Buff past decoded excitation** Word16 Lag Decoded pitch lag from previous frame** Word16 Gain Interpolated gain from previous frames** Word16 Ecount Number of erased frames** Word16 *Sd Random number used in unvoiced cases**** Outputs:**** Word16 *DataBuff current subframe decoded excitation** Word16 *Buff updated past excitation**** Return value: None***/void Regen( Word16 *DataBuff, Word16 *Buff, Word16 Lag, Word16 Gain,Word16 Ecount, Word16 *Sd ){ int i ; /* Test for clearing */ if ( Ecount >= (Word16) ErrMaxNum ) { for ( i = 0 ; i < Frame ; i ++ ) DataBuff[i] = (Word16) 0 ; for ( i = 0 ; i < Frame+PitchMax ; i ++ ) Buff[i] = (Word16) 0 ; } else { /* Interpolate accordingly to the voicing estimation */ if ( Lag != (Word16) 0 ) { /* Voiced case */ for ( i = 0 ; i < Frame ; i ++ ) Buff[PitchMax+i] = Buff[PitchMax-(int)Lag+i] ; for ( i = 0 ; i < Frame ; i ++ ) DataBuff[i] = Buff[PitchMax+i] = mult( Buff[PitchMax+i], (Word16) 0x6000 ) ; } else { /* Unvoiced case */ for ( i = 0 ; i < Frame ; i ++ ) DataBuff[i] = mult( Gain, Rand_lbc( Sd ) ) ; /* Clear buffer to reset memory */ for ( i = 0 ; i < Frame+PitchMax ; i ++ ) Buff[i] = (Word16) 0 ; } } return;}/***** Function: Comp_Lpf()**** Description: Computes pitch postfilter parameters.** The pitch postfilter lag is first derived (Find_B** and Find_F). Then, the one that gives the largest** contribution is used to calculate the gains (Get_Ind).****** Links to text: Section 3.6**** Arguments:**** Word16 *Buff decoded excitation** Word16 Olp Decoded pitch lag** Word16 Sfc Subframe index**** Outputs:****** Return value:**** PFDEF Pitch postfilter parameters: PF.Gain Pitch Postfilter gain** PF.ScGn Pitch Postfilter scaling gain** PF.Indx Pitch postfilter lag*/PFDEF Comp_Lpf( Word16 *Buff, Word16 Olp, Word16 Sfc ){ int i,j ; PFDEF Pf ; Word32 Lcr[5] ; Word16 Scr[5] ; Word16 Bindx, Findx ; Word16 Exp ; Word32 Acc0,Acc1 ; /* Initialize */ Pf.Indx = (Word16) 0 ; Pf.Gain = (Word16) 0 ; Pf.ScGn = (Word16) 0x7fff ; /* Find both indices */ Bindx = Find_B( Buff, Olp, Sfc ) ; Findx = Find_F( Buff, Olp, Sfc ) ; /* Combine the results */ if ( (Bindx == (Word16) 0) && (Findx == (Word16) 0) ) return Pf ; /* Compute target energy */ Acc0 = (Word32) 0 ; for ( j = 0 ; j < SubFrLen ; j ++ ) Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j], Buff[PitchMax+(int)Sfc*SubFrLen+j] ) ; Lcr[0] = Acc0 ; if ( Bindx != (Word16) 0 ) { Acc0 = (Word32) 0 ; Acc1 = (Word32) 0 ; for ( j = 0 ; j < SubFrLen ; j ++ ) { Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j], Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j] ) ; Acc1 = L_mac( Acc1, Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j], Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j] ) ; } Lcr[1] = Acc0 ; Lcr[2] = Acc1 ; } else { Lcr[1] = (Word32) 0 ; Lcr[2] = (Word32) 0 ; } if ( Findx != (Word16) 0 ) { Acc0 = (Word32) 0 ; Acc1 = (Word32) 0 ; for ( j = 0 ; j < SubFrLen ; j ++ ) { Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j], Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j] ) ; Acc1 = L_mac( Acc1, Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j], Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j] ) ; } Lcr[3] = Acc0 ; Lcr[4] = Acc1 ; } else { Lcr[3] = (Word32) 0 ; Lcr[4] = (Word32) 0 ; } /* Normalize and convert to shorts */ Acc1 = 0L ; for ( i = 0 ; i < 5 ; i ++ ) { Acc0 = Lcr[i] ; if ( Acc0 > Acc1 ) Acc1 = Acc0 ; } Exp = norm_l( Acc1 ) ; for ( i = 0 ; i < 5 ; i ++ ) { Acc0 = L_shl( Lcr[i], Exp ) ; Scr[i] = extract_h( Acc0 ) ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -