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

📄 util_lbc.c

📁 语音编解码算法G.723.1的C语言算法原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
**
** Function:        Line_Unpk()
**
** Description:     unpacking of bitstream, gets coding parameters for a frame
**
** Links to text:   Section 4
**
** Arguments:
**
**  char   *Vinp        bitstream chars
**
** Outputs:
**
**  Word16 *VadAct
**
** Return value:
**
**  LINEDEF             coded parameters
**     Word16   Crc
**     Word32   LspId
**     Word16   Olp[SubFrames/2]
**     SFSDEF   Sfs[SubFrames]
**
*/
LINEDEF  Line_Unpk( char *Vinp, Word16 Crc )
{
    int   i  ;
    Word16  BitStream[192] ;
    Word16 *Bsp = BitStream ;
    Word16  FrType ;
    LINEDEF Line ;
    Word32  Temp ;
    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 first two bits */
    FrType = (Word16)Ser2Par( &Bsp, 2 ) ;

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

    if ( FrType == 2 )
	{
        /* Decode the SID frame */

        return Line ;
    }

    /*
        Decode the common information to both rates
    */

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

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

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

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

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

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

        Temp = Ser2Par( &Bsp, 12 ) ;

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

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

    if ( WrkRate == Rate63 )
	{

        /* Test if rate OK */
        if(FrType != 0)
		{
            fprintf(stderr, "Selected rate incompatible with bitstream file\n");
            exit(-1);
        }


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

        /* Decode 13 bit combined position index */
        Temp = Ser2Par( &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 ) + Ser2Par( &Bsp, 16 ) ;
        Line.Sfs[1].Ppos = ( Line.Sfs[1].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;
        Line.Sfs[2].Ppos = ( Line.Sfs[2].Ppos << 16 ) + Ser2Par( &Bsp, 16 ) ;
        Line.Sfs[3].Ppos = ( Line.Sfs[3].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;

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

    else
	{

        /* Test if rate OK */
        if(FrType != 1)
		{
            fprintf(stderr, "Selected rate incompatible with bitstream file\n");
            exit(-1);
        }

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

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

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

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

/*
**
** Function:        Comp_En()
**
** Description:     Compute energy of a subframe vector
**
** Links to text:
**
** Arguments:
**
**  Word16 *Dpnt
**
** Outputs:         None
**
** Return value:
**
**      Word32 energy
**
*/
Word32   Comp_En( Word16 *Dpnt )
{
   int   i ;
   Word32   Rez ;
   Word16   Temp[SubFrLen] ;

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

   Rez = (Word32) 0 ;
   for ( i = 0 ; i < SubFrLen ; i ++ )
      Rez = L_mac( Rez, Temp[i], Temp[i] ) ;

   return Rez ;
}

/*
**
** Function:        Sqrt_lbc()
**
** Description:     Square root computation
**
** Links to text:
**
** Arguments:
**
**  Word32 Num
**
** Outputs:     None
**
** Return value:
**
**  Word16 square root of num
**
*/
Word16   Sqrt_lbc( Word32 Num )
{
   int   i  ;

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

   Word32   Acc ;

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

      Acc = L_mult( add(Rez, Exp), add(Rez, Exp) ) ;
      if ( Num >= Acc )
         Rez = add( Rez, Exp ) ;

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

/*
**
** Function:        Rand_lbc()
**
** Description:     Generator of random numbers
**
** Links to text:   Section 3.10.2
**
** Arguments:
**
**  Word16 *p
**
** Outputs:
**
**  Word16 *p
**
** Return value:
**
**  Word16 random number
**
*/
Word16   Rand_lbc( Word16 *p )
{
   Word32   Temp ;

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

/*
**
** Function:        Scale()
**
** Description:     Postfilter gain scaling
**
** Links to text:   Section 3.9
**
** Arguments:
**
**  Word16 *Tv
**  Word32 Sen
**
**  Inputs:
**
**  Word16 DecStat.Gain
**
** Outputs:
**
**  Word16 *Tv
**
** Return value:    None
**
*/
void  Scale( Word16 *Tv, Word32 Sen )
{
   int   i ;

   Word32   Acc0,Acc1   ;
   Word16   Exp,SfGain  ;


   Acc0 = Sen ;
   Acc1 = Comp_En( Tv ) ;

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

      Exp = norm_l( Acc1 ) ;
      Acc1 = L_shl( Acc1, Exp ) ;

      SfGain = norm_l( Acc0 ) ;
      Acc0 = L_shl( Acc0, SfGain ) ;
      Acc0 = L_shr( Acc0, (Word16) 1 ) ;
      Exp = sub( Exp, SfGain ) ;
      Exp = add( Exp, (Word16) 1 ) ;
      Exp = sub( (Word16) 6, Exp ) ;
      if ( Exp < (Word16) 0 )
         Exp = (Word16) 0 ;

      SfGain = extract_h( Acc1 ) ;

      SfGain = div_l( Acc0, SfGain ) ;

      Acc0 = L_deposit_h( SfGain ) ;

      Acc0 = L_shr( Acc0, Exp ) ;

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

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

      /* Update gain */
      Acc0 = L_deposit_h( DecStat.Gain ) ;
      Acc0 = L_msu( Acc0, DecStat.Gain, (Word16) 0x0800 ) ;
      Acc0 = L_mac( Acc0, SfGain, (Word16) 0x0800 ) ;
      DecStat.Gain = round( Acc0 ) ;

      Exp = add( DecStat.Gain, shr( DecStat.Gain, (Word16) 4) ) ;

      Acc0 = L_mult( Tv[i], Exp ) ;
      Acc0 = L_shl( Acc0, (Word16) 4 ) ;
      Tv[i] = round( Acc0 ) ;
   }

   return;
}

⌨️ 快捷键说明

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