📄 exc_lbc.c
字号:
/* 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 ) ;
//printf("%d , ",Exp);
//printf("\r\n");
/* 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 )
{
int i,j ;
Word32 Acc0,Acc1 ;
Word16 Tenr ;
Word16 Ccr,Enr ;
Word16 Indx ;
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 ) ;
/* 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 ) ;
}
/* Select the best pair */
if ( (Bindx != (Word16) 0) && ( Findx == (Word16) 0) )
Pf = Get_Ind( Bindx, Scr[0], Scr[1], Scr[2] ) ;
if ( (Bindx == (Word16) 0) && ( Findx != (Word16) 0) )
Pf = Get_Ind( Findx, Scr[0], Scr[3], Scr[4] ) ;
if ( (Bindx != (Word16) 0) && ( Findx != (Word16) 0) )
{
Exp = mult_r( Scr[1], Scr[1] ) ;
Acc0 = L_mult( Exp, Scr[4] ) ;
Exp = mult_r( Scr[3], Scr[3] ) ;
Acc1 = L_mult( Exp, Scr[2] ) ;
if ( Acc0 > Acc1 )
Pf = Get_Ind( Bindx, Scr[0], Scr[1], Scr[2] ) ;
else
Pf = Get_Ind( Findx, Scr[0], Scr[3], Scr[4] ) ;
}
return Pf ;
}
/*
**
** Function: Find_B()
**
** Description: Computes best pitch postfilter backward lag by
** backward cross correlation maximization around the
** decoded pitch lag
** of the subframe 0 (for subframes 0 & 1)
** of the subframe 2 (for subframes 2 & 3)
**
** Links to text: Section 3.6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -