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

📄 g7231_util_lbc.c

📁 G723.1语音压缩解压在tms320c54系列上的实现代码,本人已在CCS上仿真通过. 包含全部源代码,主函数请自已写(本人的就不奉送了:
💻 C
字号:

#include "typedef.h"
#include "G7231_basop.h"
#include "G7231_cst_lbc.h"
#include "G7231_tab_lbc.h"
#include "G7231_lbccodec.h"
#include "G7231_coder.h"
#include "G7231_decod.h"
#include "G7231_util_lbc.h"
#include "intrindefs.h"

void  G7231Rem_Dc( Word16 *Dpnt )
{
    int   i  ;


    Word32   Acc0,Acc1 ;

    if ( G7231UseHp ) {
        for ( i = 0 ; i < G7231Frame ; i ++ ) {

            /* Do the Fir and scale by 2 */
            Acc0 = G7231L_mult( Dpnt[i], (Word16) 0x4000 ) ;
            Acc0 = G7231L_mac ( Acc0, G7231CodStat.HpfZdl, (Word16) 0xc000 ) ;
            G7231CodStat.HpfZdl = Dpnt[i] ;

            /* Do the Iir part */
            Acc1 = G7231L_mls( G7231CodStat.HpfPdl, (Word16) 0x7f00 ) ;
            Acc0 = G7231L_add( Acc0, Acc1 ) ;
            G7231CodStat.HpfPdl = Acc0 ;
            Dpnt[i] = G7231round(Acc0) ;
        }
    }
    else {
        for ( i = 0 ; i < G7231Frame ; i ++ )
            Dpnt[i] = G7231shr( Dpnt[i], (Word16) 1 ) ;
    }

    return;
}

Word16  G7231Vec_Norm( Word16 *Vect, Word16 Len )
{
    int   i  ;

    Word16  Acc0,Acc1   ;
    Word16  Exp   ;
    Word16  Rez ;
    Word32  Temp  ;

    static   short G7231ShiftTable[16] = {
      0x0001 ,
      0x0002 ,
      0x0004 ,
      0x0008 ,
      0x0010 ,
      0x0020 ,
      0x0040 ,
      0x0080 ,
      0x0100 ,
      0x0200 ,
      0x0400 ,
      0x0800 ,
      0x1000 ,
      0x2000 ,
      0x4000 ,
      0x7fff
   } ;

    /* Find absolute maximum */
    Acc1 = (Word16) 0 ;
    for ( i = 0 ; i < Len ; i ++ ) {
        Acc0 = G7231abs_s( Vect[i] ) ;
        if ( Acc0 > Acc1 )
            Acc1 = Acc0 ;
    }

    /* Get the shift count */
    Rez = G7231norm_s( Acc1 ) ;
    Exp = G7231ShiftTable[Rez] ;

    /* Normalize all the vector */
    for ( i = 0 ; i < Len ; i ++ ) {
        Temp = G7231L_mult( Exp, Vect[i] ) ;
        Temp = G7231L_shr( Temp, 4 ) ;
        Vect[i] = G7231extract_l( Temp ) ;
    }

    Rez = G7231sub( Rez, (Word16) 3) ;
    return Rez ;
}

void  G7231Mem_Shift( Word16 *PrevDat, Word16 *DataBuff )
{
    int   i  ;

    Word16   Dpnt[G7231Frame+G7231LpcFrame-G7231SubFrLen] ;

    /*  Form Buffer  */
    for ( i = 0 ; i < G7231LpcFrame-G7231SubFrLen ; i ++ )
        Dpnt[i] = PrevDat[i] ;
    for ( i = 0 ; i < G7231Frame ; i ++ )
        Dpnt[i+G7231LpcFrame-G7231SubFrLen] = DataBuff[i] ;

    /* Update PrevDat */
    for ( i = 0 ; i < G7231LpcFrame-G7231SubFrLen ; i ++ )
        PrevDat[i] = Dpnt[G7231Frame+i] ;

    /* Update DataBuff */
    for ( i = 0 ; i < G7231Frame ; i ++ )
        DataBuff[i] = Dpnt[(G7231LpcFrame-G7231SubFrLen)/2+i] ;

    return;
}

void    G7231Line_Pack( G7231LINEDEF *Line, char *Vout, Word16 Ftyp )
{
    int     i ;
    int     BitCount ;

    Word16  BitStream[192] ;
    Word16 *Bsp = BitStream ;
    Word32  Temp ;

    /* Clear the output vector */
    for ( i = 0 ; i < 24 ; i ++ )
        Vout[i] = 0 ;

 /*
  * Add the coder rate info and frame type info to the 2 msb
  * of the first word of the frame.
  * The signaling is as follows:
  *     Ftyp  WrkRate => X1X0
  *       1     Rate63     00  :   High Rate
  *       1     Rate53     01  :   Low  Rate
  *       2       x        10  :   Silence Insertion Descriptor frame
  *       0       x        11  :   Used only for simulation of
  *                                 untransmitted silence frames
  */
    switch (Ftyp) {

        case 0 : {
            Temp = 0x00000003L;
            break;
        }

        case 2 : {
            Temp = 0x00000002L;
            break;
        }

        default : {
            if ( G7231CodStat.WrkRate == Rate63 )
                Temp = 0x00000000L ;
            else
                Temp = 0x00000001L ;
            break;
        }
    }

    /* Serialize Control info */
    Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;


    /* Check for Speech/NonSpeech case */
    if ( Ftyp == 1 ) {

    /* 24 bit LspId */
    Temp = (*Line).LspId ;
    Bsp = G7231Par2Ser( Temp, Bsp, 24 ) ;

 /*
  * Do the part common to both rates
  */

        /* Adaptive code book lags */
        Temp = (Word32) (*Line).Olp[0] - (Word32) G7231PitchMin ;
        Bsp = G7231Par2Ser( Temp, Bsp, 7 ) ;

        Temp = (Word32) (*Line).Sfs[1].AcLg ;
        Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;

        Temp = (Word32) (*Line).Olp[1] - (Word32) G7231PitchMin ;
        Bsp = G7231Par2Ser( Temp, Bsp, 7 ) ;

        Temp = (Word32) (*Line).Sfs[3].AcLg ;
        Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;

        /* Write combined 12 bit index of all the gains */
        for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
            Temp = (*Line).Sfs[i].AcGn*G7231NumOfGainLev + (*Line).Sfs[i].Mamp ;
            if ( G7231CodStat.WrkRate == Rate63 )
                Temp += (Word32) (*Line).Sfs[i].Tran << 11 ;
            Bsp = G7231Par2Ser( Temp, Bsp, 12 ) ;
        }

        /* Write all the Grid indices */
        for ( i = 0 ; i < G7231SubFrames ; i ++ )
            *Bsp ++ = (*Line).Sfs[i].Grid ;

        /* High rate only part */
        if ( G7231CodStat.WrkRate == Rate63 ) {

            /* Write the reserved bit as 0 */
            *Bsp ++ = (Word16) 0 ;

            /* Write 13 bit combined position index */
            Temp = (*Line).Sfs[0].Ppos >> 16 ;
            Temp = Temp * 9 + ( (*Line).Sfs[1].Ppos >> 14) ;
            Temp *= 90 ;
            Temp += ((*Line).Sfs[2].Ppos >> 16) * 9 + ( (*Line).Sfs[3].Ppos >> 14 ) ;
            Bsp = G7231Par2Ser( Temp, Bsp, 13 ) ;

            /* Write all the pulse positions */
            Temp = (*Line).Sfs[0].Ppos & 0x0000ffffL ;
            Bsp = G7231Par2Ser( Temp, Bsp, 16 ) ;

            Temp = (*Line).Sfs[1].Ppos & 0x00003fffL ;
            Bsp = G7231Par2Ser( Temp, Bsp, 14 ) ;

            Temp = (*Line).Sfs[2].Ppos & 0x0000ffffL ;
            Bsp = G7231Par2Ser( Temp, Bsp, 16 ) ;

            Temp = (*Line).Sfs[3].Ppos & 0x00003fffL ;
            Bsp = G7231Par2Ser( Temp, Bsp, 14 ) ;

            /* Write pulse amplitudes */
            Temp = (Word32) (*Line).Sfs[0].Pamp ;
            Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;

            Temp = (Word32) (*Line).Sfs[1].Pamp ;
            Bsp = G7231Par2Ser( Temp, Bsp, 5 ) ;

            Temp = (Word32) (*Line).Sfs[2].Pamp ;
            Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;

            Temp = (Word32) (*Line).Sfs[3].Pamp ;
            Bsp = G7231Par2Ser( Temp, Bsp, 5 ) ;
        }

        /* Low rate only part */
        else {

            /* Write 12 bits of positions */
            for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
                Temp = (*Line).Sfs[i].Ppos ;
                Bsp = G7231Par2Ser( Temp, Bsp, 12 ) ;
            }

            /* Write 4 bit Pamps */
            for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
                Temp = (*Line).Sfs[i].Pamp ;
                Bsp = G7231Par2Ser( Temp, Bsp, 4 ) ;
            }
        }

    }

    else if(Ftyp == 2) {   /* SID frame */

        /* 24 bit LspId */
        Temp = (*Line).LspId ;
        Bsp = G7231Par2Ser( Temp, Bsp, 24 ) ;

        /* Do Sid frame gain */
        Temp = (Word32)(*Line).Sfs[0].Mamp ;
        Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;
    }

    /* Write out active frames */
    if ( Ftyp == 1 ) {
        if ( G7231CodStat.WrkRate == Rate63 )
            BitCount = 192 ;
        else
            BitCount = 160 ;
    }
    /* Non active frames */
    else if ( Ftyp == 2 )
        BitCount = 32 ;
    else
        BitCount = 2;

    for ( i = 0 ; i < BitCount ; i ++ )
        Vout[i>>3] ^= BitStream[i] << (i & 0x0007) ;

    return;
}

Word16* G7231Par2Ser( Word32 Inp, Word16 *Pnt, int BitNum )
{
    int i   ;
    Word16  Temp ;

    for ( i = 0 ; i < BitNum ; i ++ ) {
        Temp = (Word16) Inp & (Word16)0x0001 ;
        Inp >>= 1 ;
        *Pnt ++ = Temp ;
    }

    return Pnt ;
}

G7231LINEDEF  G7231Line_Unpk( char *Vinp, Word16 *Ftyp, Word16 Crc )
{
    int   i  ;
    Word16  BitStream[192] ;
    Word16 *Bsp = BitStream ;
    G7231LINEDEF Line ;
    Word32  Temp ;
    Word16  Info;
    Word16 Bound_AcGn;

    Line.Crc = Crc;
    if(Crc != 0) return Line;

    /* Unpack the byte info to BitStream vector */
    for ( i = 0 ; i < 192 ; i ++ )
        BitStream[i] = ( Vinp[i>>3] >> (i & (Word16)0x0007) ) & (Word16)1 ;

    /* Decode the frame type and rate info */
    Info = (Word16)G7231Ser2Par( &Bsp, 2 ) ;

    if ( Info == 3 ) {
        *Ftyp = 0;
        Line.LspId = 0L;    /* Dummy : to avoid Borland C3.1 warning */
        return Line;
    }

    /* Decode the LspId */
    Line.LspId = G7231Ser2Par( &Bsp, 24 ) ;

    if ( Info == 2 ) {
        /* Decode the Noise Gain */
        Line.Sfs[0].Mamp = (Word16)G7231Ser2Par( &Bsp, 6);
        *Ftyp = 2;
        return Line ;
    }

 /*
  * Decode the common information to both rates
  */
    *Ftyp = 1;

    /* Decode the bit-rate */
    G7231DecStat.WrkRate = (Info == 0) ? Rate63 : Rate53;

    /* Decode the adaptive codebook lags */
    Temp = G7231Ser2Par( &Bsp, 7 ) ;
    /* Test if forbidden code */
    if( Temp <= 123) {
        Line.Olp[0] = (Word16) Temp + (Word16)G7231PitchMin ;
    }
    else {
        /* transmission error */
        Line.Crc = 1;
        return Line ;
    }

    Line.Sfs[1].AcLg = (Word16) G7231Ser2Par( &Bsp, 2 ) ;

    Temp = G7231Ser2Par( &Bsp, 7 ) ;
    /* Test if forbidden code */
    if( Temp <= 123) {
        Line.Olp[1] = (Word16) Temp + (Word16)G7231PitchMin ;
    }
    else {
        /* transmission error */
        Line.Crc = 1;
        return Line ;
    }

    Line.Sfs[3].AcLg = (Word16) G7231Ser2Par( &Bsp, 2 ) ;

    Line.Sfs[0].AcLg = 1 ;
    Line.Sfs[2].AcLg = 1 ;

    /* Decode the combined gains accordingly to the rate */
    for ( i = 0 ; i < G7231SubFrames ; i ++ ) {

        Temp = G7231Ser2Par( &Bsp, 12 ) ;

        Line.Sfs[i].Tran = 0 ;
        Bound_AcGn = G7231NbFilt170 ;
        if ( (G7231DecStat.WrkRate == Rate63) && (Line.Olp[i>>1] < (G7231SubFrLen-2) ) ) {
            Line.Sfs[i].Tran = (Word16)(Temp >> 11) ;
            Temp &= 0x000007ffL ;
            Bound_AcGn = G7231NbFilt085 ;
        }
        Line.Sfs[i].AcGn = (Word16)(Temp / (Word16)G7231NumOfGainLev) ;
        if(Line.Sfs[i].AcGn < Bound_AcGn ) {
            Line.Sfs[i].Mamp = (Word16)(Temp % (Word16)G7231NumOfGainLev) ;
        }
        else {
            /* error detected */
            Line.Crc = 1;
            return Line ;
        }
    }

    /* Decode the grids */
    for ( i = 0 ; i < G7231SubFrames ; i ++ )
        Line.Sfs[i].Grid = *Bsp ++ ;

    if (Info == 0) {

        /* Skip the reserved bit */
        Bsp ++ ;

        /* Decode 13 bit combined position index */
        Temp = G7231Ser2Par( &Bsp, 13 ) ;
        Line.Sfs[0].Ppos = ( Temp/90 ) / 9 ;
        Line.Sfs[1].Ppos = ( Temp/90 ) % 9 ;
        Line.Sfs[2].Ppos = ( Temp%90 ) / 9 ;
        Line.Sfs[3].Ppos = ( Temp%90 ) % 9 ;

        /* Decode all the pulse positions */
        Line.Sfs[0].Ppos = ( Line.Sfs[0].Ppos << 16 ) + G7231Ser2Par( &Bsp, 16 ) ;
        Line.Sfs[1].Ppos = ( Line.Sfs[1].Ppos << 14 ) + G7231Ser2Par( &Bsp, 14 ) ;
        Line.Sfs[2].Ppos = ( Line.Sfs[2].Ppos << 16 ) + G7231Ser2Par( &Bsp, 16 ) ;
        Line.Sfs[3].Ppos = ( Line.Sfs[3].Ppos << 14 ) + G7231Ser2Par( &Bsp, 14 ) ;

        /* Decode pulse amplitudes */
        Line.Sfs[0].Pamp = (Word16)G7231Ser2Par( &Bsp, 6 ) ;
        Line.Sfs[1].Pamp = (Word16)G7231Ser2Par( &Bsp, 5 ) ;
        Line.Sfs[2].Pamp = (Word16)G7231Ser2Par( &Bsp, 6 ) ;
        Line.Sfs[3].Pamp = (Word16)G7231Ser2Par( &Bsp, 5 ) ;
    }

    else {

        /* Decode the positions */
        for ( i = 0 ; i < G7231SubFrames ; i ++ )
            Line.Sfs[i].Ppos = G7231Ser2Par( &Bsp, 12 ) ;

        /* Decode the amplitudes */
        for ( i = 0 ; i < G7231SubFrames ; i ++ )
            Line.Sfs[i].Pamp = (Word16)G7231Ser2Par( &Bsp, 4 ) ;
    }
   return Line ;
}

Word32  G7231Ser2Par( Word16 **Pnt, int Count )
{
    int     i ;
    Word32  Rez = 0L ;

    for ( i = 0 ; i < Count ; i ++ ) {
        Rez += (Word32) **Pnt << i ;
        (*Pnt) ++ ;
    }
    return Rez ;
}

Word32   G7231Comp_En( Word16 *Dpnt )
{
    int   i ;
    Word32   Rez ;
    Word16   Temp[G7231SubFrLen] ;

    for ( i = 0 ; i < G7231SubFrLen ; i ++ )
        Temp[i] = G7231shr( Dpnt[i], (Word16) 2 ) ;

    Rez = (Word32) 0 ;
    for ( i = 0 ; i < G7231SubFrLen ; i ++ )
        Rez = G7231L_mac( Rez, Temp[i], Temp[i] ) ;

    return Rez ;
}

Word16   G7231Sqrt_lbc( Word32 Num )
{
    int   i  ;

    Word16   Rez = (Word16) 0 ;
    Word16   Exp = (Word16) 0x4000 ;

    Word32   Acc ;

    for ( i = 0 ; i < 14 ; i ++ ) {

        Acc = G7231L_mult( G7231add(Rez, Exp), G7231add(Rez, Exp) ) ;
        if ( Num >= Acc )
            Rez = G7231add( Rez, Exp ) ;

        Exp = G7231shr( Exp, (Word16) 1 ) ;
    }
    return Rez ;
}

Word16   G7231Rand_lbc( Word16 *p )
{
    Word32   Temp ;

    Temp = G7231L_deposit_l( *p ) ;
    Temp &= (Word32) 0x0000ffff ;
    Temp = Temp*(Word32)521 + (Word32) 259 ;
    *p = G7231extract_l( Temp ) ;
    return G7231extract_l( Temp ) ;
}

void  G7231Scale( Word16 *Tv, Word32 Sen )
{
    int   i ;

    Word32   Acc0,Acc1   ;
    Word16   Exp,SfGain  ;


    Acc0 = Sen ;
    Acc1 = G7231Comp_En( Tv ) ;

    /* Normalize both */
    if ( (Acc1 != (Word32) 0) && (Acc0 != (Word32) 0 ) ) {

        Exp = G7231norm_l( Acc1 ) ;
        Acc1 = G7231L_shl( Acc1, Exp ) ;

        SfGain = G7231norm_l( Acc0 ) ;
        Acc0 = G7231L_shl( Acc0, SfGain ) ;
        Acc0 = G7231L_shr( Acc0, (Word16) 1 ) ;
        Exp = G7231sub( Exp, SfGain ) ;
        Exp = G7231add( Exp, (Word16) 1 ) ;
        Exp = G7231sub( (Word16) 6, Exp ) ;
        if ( Exp < (Word16) 0 )
            Exp = (Word16) 0 ;

        SfGain = G7231extract_h( Acc1 ) ;

        SfGain = G7231div_l( Acc0, SfGain ) ;

        Acc0 = G7231L_deposit_h( SfGain ) ;

        Acc0 = G7231L_shr( Acc0, Exp ) ;

        SfGain = G7231Sqrt_lbc( Acc0 ) ;
    }
    else
        SfGain = 0x1000 ;

    /* Filter the data */
    for ( i = 0 ; i < G7231SubFrLen ; i ++ ) {

        /* Update gain */
        Acc0 = G7231L_deposit_h( G7231DecStat.Gain ) ;
        Acc0 = G7231L_msu( Acc0, G7231DecStat.Gain, (Word16) 0x0800 ) ;
        Acc0 = G7231L_mac( Acc0, SfGain, (Word16) 0x0800 ) ;
        G7231DecStat.Gain = G7231round( Acc0 ) ;

        Exp = G7231add( G7231DecStat.Gain, G7231shr( G7231DecStat.Gain, (Word16) 4) ) ;

        Acc0 = G7231L_mult( Tv[i], Exp ) ;
        Acc0 = G7231L_shl( Acc0, (Word16) 4 ) ;
        Tv[i] = G7231round( Acc0 ) ;
    }

    return;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -