📄 g7231_exc_lbc.c
字号:
Word16 Np ;
Word16 Tv_tmp[G7231SubFrLen+4];
Word16 acelp_gain, acelp_sign, acelp_shift, acelp_pos;
Word16 offset, ipos, T0_acelp, gain_T0;
switch(G7231CodStat.WrkRate) {
case Rate63: {
Np = G7231Nb_puls[(int)Sfc] ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
Tv[i] = (Word16) 0 ;
if ( Sfs.Ppos >= G7231MaxPosTable[Sfc] )
return ;
j = G7231MaxPulseNum - (int) Np ;
Acc0 = Sfs.Ppos ;
for ( i = 0 ; i < G7231SubFrLen/G7231Sgrid ; i ++ ) {
Acc0 = G7231L_sub( Acc0, G7231CombinatorialTable[j][i] ) ;
if ( Acc0 < (Word32) 0 ) {
Acc0 = G7231L_add( Acc0, G7231CombinatorialTable[j][i] ) ;
j ++ ;
if ( (Sfs.Pamp & (1 << (G7231MaxPulseNum-j) )) != (Word16) 0 )
Tv[(int)Sfs.Grid + G7231Sgrid*i] = -G7231FcbkGainTable[Sfs.Mamp] ;
else
Tv[(int)Sfs.Grid + G7231Sgrid*i] = G7231FcbkGainTable[Sfs.Mamp] ;
if ( j == G7231MaxPulseNum )
break ;
}
}
if ( Sfs.Tran == (Word16) 1 )
G7231Gen_Trn( Tv, Tv, Olp ) ;
break;
}
case Rate53: {
for ( i = 0 ; i < G7231SubFrLen+4 ; i ++ )
Tv_tmp[i] = (Word16) 0 ;
acelp_gain = G7231FcbkGainTable[Sfs.Mamp];
acelp_shift = Sfs.Grid;
acelp_sign = Sfs.Pamp;
acelp_pos = (short) Sfs.Ppos;
offset = 0;
for(i=0; i<4; i++) {
ipos = (acelp_pos & (Word16)0x0007) ;
ipos = G7231shl(ipos,3) + acelp_shift + offset;
if( (acelp_sign & 1 )== 1) {
Tv_tmp[ipos] = acelp_gain;
}
else {
Tv_tmp[ipos] = -acelp_gain;
}
offset = G7231add(offset,2);
acelp_pos = G7231shr(acelp_pos, 3);
acelp_sign = G7231shr(acelp_sign,1);
}
for (i = 0; i < G7231SubFrLen; i++) Tv[i] = Tv_tmp[i];
T0_acelp = G7231search_T0( (Word16) (Olp-1+Sfs.AcLg), Sfs.AcGn,
&gain_T0);
if(T0_acelp <G7231SubFrLen-2) {
for (i = T0_acelp ; i < G7231SubFrLen; i++)
Tv[i] = G7231add(Tv[i], G7231mult(Tv[i-T0_acelp ], gain_T0));
}
break;
}
}
return;
}
void G7231Fcbk_Unpk_De( Word16 *Tv, G7231SFSDEF Sfs, Word16 Olp, Word16 Sfc )
{
int i,j ;
Word32 Acc0 ;
Word16 Np ;
Word16 Tv_tmp[G7231SubFrLen+4];
Word16 acelp_gain, acelp_sign, acelp_shift, acelp_pos;
Word16 offset, ipos, T0_acelp, gain_T0;
switch(G7231DecStat.WrkRate) {
case Rate63: {
Np = G7231Nb_puls[(int)Sfc] ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
Tv[i] = (Word16) 0 ;
if ( Sfs.Ppos >= G7231MaxPosTable[Sfc] )
return ;
j = G7231MaxPulseNum - (int) Np ;
Acc0 = Sfs.Ppos ;
for ( i = 0 ; i < G7231SubFrLen/G7231Sgrid ; i ++ ) {
Acc0 = G7231L_sub( Acc0, G7231CombinatorialTable[j][i] ) ;
if ( Acc0 < (Word32) 0 ) {
Acc0 = G7231L_add( Acc0, G7231CombinatorialTable[j][i] ) ;
j ++ ;
if ( (Sfs.Pamp & (1 << (G7231MaxPulseNum-j) )) != (Word16) 0 )
Tv[(int)Sfs.Grid + G7231Sgrid*i] = -G7231FcbkGainTable[Sfs.Mamp] ;
else
Tv[(int)Sfs.Grid + G7231Sgrid*i] = G7231FcbkGainTable[Sfs.Mamp] ;
if ( j == G7231MaxPulseNum )
break ;
}
}
if ( Sfs.Tran == (Word16) 1 )
G7231Gen_Trn( Tv, Tv, Olp ) ;
break;
}
case Rate53: {
for ( i = 0 ; i < G7231SubFrLen+4 ; i ++ )
Tv_tmp[i] = (Word16) 0 ;
acelp_gain = G7231FcbkGainTable[Sfs.Mamp];
acelp_shift = Sfs.Grid;
acelp_sign = Sfs.Pamp;
acelp_pos = (short) Sfs.Ppos;
offset = 0;
for(i=0; i<4; i++) {
ipos = (acelp_pos & (Word16)0x0007) ;
ipos = G7231shl(ipos,3) + acelp_shift + offset;
if( (acelp_sign & 1 )== 1) {
Tv_tmp[ipos] = acelp_gain;
}
else {
Tv_tmp[ipos] = -acelp_gain;
}
offset = G7231add(offset,2);
acelp_pos = G7231shr(acelp_pos, 3);
acelp_sign = G7231shr(acelp_sign,1);
}
for (i = 0; i < G7231SubFrLen; i++) Tv[i] = Tv_tmp[i];
T0_acelp = G7231search_T0( (Word16) (Olp-1+Sfs.AcLg), Sfs.AcGn,
&gain_T0);
if(T0_acelp <G7231SubFrLen-2) {
for (i = T0_acelp ; i < G7231SubFrLen; i++)
Tv[i] = G7231add(Tv[i], G7231mult(Tv[i-T0_acelp ], gain_T0));
}
break;
}
}
return;
}
void G7231Find_Acbk( Word16 *Tv, Word16 *ImpResp, Word16 *PrevExc, G7231LINEDEF
*Line, Word16 Sfc )
{
int i,j,k,l ;
Word32 Acc0,Acc1 ;
Word16 RezBuf[G7231SubFrLen+G7231ClPitchOrd-1] ;
Word16 FltBuf[G7231ClPitchOrd][G7231SubFrLen] ;
Word32 CorBuf[4*(2*G7231ClPitchOrd + G7231ClPitchOrd*(G7231ClPitchOrd-1)/2)] ;
Word32 *lPnt ;
Word16 CorVct[4*(2*G7231ClPitchOrd + G7231ClPitchOrd*(G7231ClPitchOrd-1)/2)] ;
Word16 *sPnt ;
Word16 Olp ;
Word16 Lid ;
Word16 Gid ;
Word16 Hb ;
Word16 Exp ;
Word16 Bound[2] ;
Word16 Lag1, Lag2;
Word16 off_filt;
Olp = (*Line).Olp[G7231shr(Sfc, (Word16) 1)] ;
Lid = (Word16) G7231Pstep ;
Gid = (Word16) 0 ;
Hb = (Word16) 3 + (Sfc & (Word16) 1 ) ;
if ( (Sfc & (Word16)1) == (Word16) 0 ) {
if ( Olp == (Word16) G7231PitchMin )
Olp = G7231add( Olp, (Word16) 1 ) ;
if ( Olp > (Word16) (G7231PitchMax-5) )
Olp = (Word16)(G7231PitchMax-5) ;
}
lPnt = CorBuf ;
for ( k = 0 ; k < (int) Hb ; k ++ ) {
G7231Get_Rez( RezBuf, PrevExc, (Word16)(Olp-(Word16)G7231Pstep+k) ) ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ ) {
Acc0 = (Word32) 0 ;
for ( j = 0 ; j <= i ; j ++ )
Acc0 = G7231L_mac( Acc0, RezBuf[G7231ClPitchOrd-1+j], ImpResp[i-j] ) ;
FltBuf[G7231ClPitchOrd-1][i] = G7231round( Acc0 ) ;
}
for ( i = G7231ClPitchOrd-2 ; i >= 0 ; i -- ) {
FltBuf[i][0] = G7231mult_r( RezBuf[i], (Word16) 0x2000 ) ;
for ( j = 1 ; j < G7231SubFrLen ; j ++ ) {
Acc0 = G7231L_deposit_h( FltBuf[i+1][j-1] ) ;
Acc0 = G7231L_mac( Acc0, RezBuf[i], ImpResp[j] ) ;
FltBuf[i][j] = G7231round( Acc0 ) ;
}
}
for ( i = 0 ; i < G7231ClPitchOrd ; i ++ ) {
Acc1 = (Word32) 0 ;
for ( j = 0 ; j < G7231SubFrLen ; j ++ ) {
Acc0 = G7231L_mult( Tv[j], FltBuf[i][j] ) ;
Acc1 = G7231L_add( Acc1, G7231L_shr( Acc0, (Word16) 1 ) ) ;
}
*lPnt ++ = G7231L_shl( Acc1, (Word16) 1 ) ;
}
for ( i = 0 ; i < G7231ClPitchOrd ; i ++ ) {
Acc1 = (Word32) 0 ;
for ( j = 0 ; j < G7231SubFrLen ; j ++ )
Acc1 = G7231L_mac( Acc1, FltBuf[i][j], FltBuf[i][j] ) ;
*lPnt ++ = Acc1 ;
}
for ( i = 1 ; i < G7231ClPitchOrd ; i ++ ) {
for ( j = 0 ; j < i ; j ++ ) {
Acc1 = (Word32) 0 ;
for ( l = 0 ; l < G7231SubFrLen ; l ++ ) {
Acc0 = G7231L_mult( FltBuf[i][l], FltBuf[j][l] ) ;
Acc1 = G7231L_add( Acc1, G7231L_shr( Acc0, (Word16) 1 ) ) ;
}
*lPnt ++ = G7231L_shl( Acc1, (Word16) 2 ) ;
}
}
}
Acc1 = (Word32) 0 ;
for ( i = 0 ; i < Hb*20 ; i ++ ) {
Acc0 = G7231L_abs(CorBuf[i]) ;
if ( Acc0 > Acc1 )
Acc1 = Acc0 ;
}
Exp = G7231norm_l( Acc1 ) ;
for ( i = 0 ; i < Hb*20 ; i ++ ) {
Acc0 = G7231L_shl( CorBuf[i], Exp ) ;
CorVct[i] = G7231round( Acc0 ) ;
}
Lag1 = Olp-(Word16)G7231Pstep;
Lag2 = Olp-(Word16)G7231Pstep+ Hb -(Word16)1;
off_filt = G7231Test_Err(Lag1, Lag2);
Bound[0] = G7231NbFilt085_min + G7231shl(off_filt,2);
if(Bound[0] > G7231NbFilt085) Bound[0] = G7231NbFilt085;
Bound[1] = G7231NbFilt170_min + G7231shl(off_filt,3);
if(Bound[1] > G7231NbFilt170) Bound[1] = G7231NbFilt170;
Acc1 = (Word32) 0 ;
for ( k = 0 ; k < (int) Hb ; k ++ ) {
l = 0 ;
if ( G7231CodStat.WrkRate == Rate63 ){
if ( (Sfc & (Word16) 1) == (Word16) 0 ) {
if ( (int)Olp-G7231Pstep+k >= G7231SubFrLen-2 )l ++ ;
}
else {
if ( (int)Olp >= G7231SubFrLen-2 ) l ++ ;
}
}
else {
l = 1;
}
sPnt = G7231AcbkGainTablePtr[l] ;
for ( i = 0 ; i < (int) Bound[l] ; i ++ )
{
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < 20 ; j ++ )
Acc0 = G7231L_add( Acc0, G7231L_shr( G7231L_mult(CorVct[k*20+j], *sPnt ++),
(Word16) 1 ) ) ;
if ( Acc0 > Acc1 )
{
Acc1 = Acc0 ;
Gid = (Word16) i ;
Lid = (Word16) k ;
}
}
}
if ( (Sfc & (Word16) 1 ) == (Word16) 0 ) {
Olp = Olp - (Word16) G7231Pstep + Lid ;
Lid = (Word16) G7231Pstep ;
}
(*Line).Sfs[Sfc].AcLg = Lid ;
(*Line).Sfs[Sfc].AcGn = Gid ;
(*Line).Olp[G7231shr(Sfc, (Word16) 1)] = Olp ;
G7231Decod_Acbk_En( RezBuf, PrevExc, Olp, Lid, Gid ) ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ ) {
Acc0 = G7231L_deposit_h( Tv[i] ) ;
Acc0 = G7231L_shr( Acc0, (Word16) 1 ) ;
for ( j = 0 ; j <= i ; j ++ )
Acc0 = G7231L_msu( Acc0, RezBuf[j], ImpResp[i-j] ) ;
Acc0 = G7231L_shl( Acc0, (Word16) 1 ) ;
Tv[i] = G7231round( Acc0 ) ;
}
return;
}
void G7231Get_Rez( Word16 *Tv, Word16 *PrevExc, Word16 Lag )
{
int i ;
for ( i = 0 ; i < G7231ClPitchOrd/2 ; i ++ )
Tv[i] = PrevExc[G7231PitchMax - (int) Lag - G7231ClPitchOrd/2 + i] ;
for ( i = 0 ; i < G7231SubFrLen+G7231ClPitchOrd/2 ; i ++ )
Tv[G7231ClPitchOrd/2+i] = PrevExc[G7231PitchMax - (int)Lag + i%(int)Lag] ;
return;
}
void G7231Decod_Acbk_En( Word16 *Tv, Word16 *PrevExc, Word16 Olp, Word16 Lid, Word16 Gid )
{
int i,j ;
Word32 Acc0 ;
Word16 RezBuf[G7231SubFrLen+G7231ClPitchOrd-1] ;
Word16 *sPnt ;
G7231Get_Rez( RezBuf, PrevExc, (Word16)(Olp - (Word16)G7231Pstep + Lid) ) ;
i = 0 ;
if ( G7231CodStat.WrkRate == Rate63 )
{
if ( Olp >= (Word16) (G7231SubFrLen-2) ) i ++ ;
}
else
{
i = 1;
}
sPnt = G7231AcbkGainTablePtr[i] ;
sPnt += (int)Gid*20 ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
{
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < G7231ClPitchOrd ; j ++ )
Acc0 = G7231L_mac( Acc0, RezBuf[i+j], sPnt[j] ) ;
Acc0 = G7231L_shl( Acc0, (Word16) 1 ) ;
Tv[i] = G7231round( Acc0 ) ;
}
return;
}
void G7231Decod_Acbk_De( Word16 *Tv, Word16 *PrevExc, Word16 Olp, Word16 Lid, Word16 Gid )
{
int i,j ;
Word32 Acc0 ;
Word16 RezBuf[G7231SubFrLen+G7231ClPitchOrd-1] ;
Word16 *sPnt ;
G7231Get_Rez( RezBuf, PrevExc, (Word16)(Olp - (Word16)G7231Pstep + Lid) ) ;
i = 0 ;
if ( G7231DecStat.WrkRate == Rate63 )
{
if ( Olp >= (Word16) (G7231SubFrLen-2) ) i ++ ;
}
else
{
i = 1;
}
sPnt = G7231AcbkGainTablePtr[i] ;
sPnt += (int)Gid*20 ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
{
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < G7231ClPitchOrd ; j ++ )
Acc0 = G7231L_mac( Acc0, RezBuf[i+j], sPnt[j] ) ;
Acc0 = G7231L_shl( Acc0, (Word16) 1 ) ;
Tv[i] = G7231round( Acc0 ) ;
}
return;
}
Word16 G7231Comp_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 = G7231Vec_Norm( Buff, (Word16) (G7231PitchMax+G7231Frame) ) ;
if ( Olp > (Word16) (G7231PitchMax-3) )
Olp = (Word16) (G7231PitchMax-3) ;
Indx = Olp ;
Acc1 = (Word32) 0 ;
for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) {
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < 2*G7231SubFrLen ; j ++ )
Acc0 = G7231L_mac( Acc0, Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen+j],
Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen-i+j] ) ;
if ( Acc0 > Acc1 ) {
Acc1 = Acc0 ;
Indx = (Word16) i ;
}
}
/* Compute target energy */
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < 2*G7231SubFrLen ; j ++ )
Acc0 = G7231L_mac( Acc0, Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen+j],
Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen+j] ) ;
Tenr = G7231round( Acc0 ) ;
*Gain = Tenr;
/* Compute best energy */
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < 2*G7231SubFrLen ; j ++ )
Acc0 = G7231L_mac( Acc0, Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen-(int)Indx+j],
Buff[G7231PitchMax+G7231Frame-2*G7231SubFrLen-(int)Indx+j] ) ;
Ccr = G7231round( Acc1 ) ;
if ( Ccr <= (Word16) 0 )
return (Word16) 0 ;
Enr = G7231round( Acc0 ) ;
Acc0 = G7231L_mult( Enr, Tenr ) ;
Acc0 = G7231L_shr( Acc0, (Word16) 3 ) ;
Acc0 = G7231L_msu( Acc0, Ccr, Ccr ) ;
if ( Acc0 < (Word32) 0 )
return Indx ;
else
return (Word16) 0 ;
}
void G7231Regen( Word16 *DataBuff, Word16 *Buff, Word16 Lag, Word16 Gain, Word16 Ecount, Word16 *Sd )
{
int i ;
/* Test for clearing */
if ( Ecount >= (Word16) G7231ErrMaxNum ) {
for ( i = 0 ; i < G7231Frame ; i ++ )
DataBuff[i] = (Word16) 0 ;
for ( i = 0 ; i < G7231Frame+G7231PitchMax ; i ++ )
Buff[i] = (Word16) 0 ;
}
else {
/* Interpolate accordingly to the voicing estimation */
if ( Lag != (Word16) 0 ) {
/* Voiced case */
for ( i = 0 ; i < G7231Frame ; i ++ )
Buff[G7231PitchMax+i] = Buff[G7231PitchMax-(int)Lag+i] ;
for ( i = 0 ; i < G7231Frame ; i ++ )
DataBuff[i] = Buff[G7231PitchMax+i] = G7231mult( Buff[G7231PitchMax+i],
(Word16) 0x6000 ) ;
}
else {
/* Unvoiced case */
for ( i = 0 ; i < G7231Frame ; i ++ )
DataBuff[i] = G7231mult( Gain, G7231Rand_lbc( Sd ) ) ;
/* Clear buffer to reset memory */
for ( i = 0 ; i < G7231Frame+G7231PitchMax ; i ++ )
Buff[i] = (Word16) 0 ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -