⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g7231_exc_lbc.c

📁 G723.1语音压缩解压在tms320c54系列上的实现代码,本人已在CCS上仿真通过. 包含全部源代码,主函数请自已写(本人的就不奉送了:
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -