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

📄 lsp.c

📁 语音编解码算法G.723.1的C语言算法原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      /*
       * Pack the result with the optimum index for this band
       */
      Rez = L_shl( Rez, (Word16) LspCbBits ) ;
      Rez = L_add( Rez, Indx ) ;
   }

   return Rez ;
}


/*
**
** Function:            Lsp_Inq()
**
** Description:     Performs inverse vector quantization of the
**          LSP frequencies.  The LSP vector is divided
**          into 3 sub-vectors, or bands, of dimension 3,
**          3, and 4.  Each band is inverse quantized
**          separately using a different VQ table.  Each
**          table has 256 entries, so each VQ index is 8
**          bits.  (Only the LSP vector for subframe 3 is
**          quantized per frame.)
**          
** Links to text:   Sections 2.6, 3.2
**
** Arguments:       
**
**  Word16 *Lsp     Empty buffer
**  Word16 PrevLsp[]    Quantized LSP frequencies from the previous frame 
**               (10 words)
**  Word32 LspId        Long word packed with the 3 VQ indices.  Band 0
**               corresponds to bits [23:16], band 1 corresponds
**               to bits [15:8], and band 2 corresponds to bits 
**               [7:0].
**  Word16 Crc      Frame erasure indicator
**
** Outputs:         
**
**  Word16 Lsp[]        Quantized LSP frequencies for current frame (10
**               words)
**
** Return value:         None
**
*/
void Lsp_Inq( Word16 *Lsp, Word16 *PrevLsp, Word32 LspId, Word16 Crc )
{
   int  i,j   ;

   Word16  *LspQntPnt  ;


   Word16   Scon  ;
   Word16   Lprd  ;

   Word16   Tmp   ;
   Flag     Test  ;


   /*
    * Check for frame erasure.  If a frame erasure has occurred, the
    * resulting VQ table entries are zero.  In addition, a different
    * fixed predictor and minimum frequency separation are used.  
    */
   if ( Crc == (Word16) 0 ) 
   {
      Scon = (Word16) 0x0100 ;
      Lprd = LspPrd0 ;
   }
   else
   {
      LspId = (Word32) 0 ;
      Scon = (Word16) 0x0200 ;
      Lprd = LspPrd1 ;
   }


   /* 
    * Inverse quantize the 10th-order LSP vector.  Each band is done
    * separately.  
    */
   for ( i = LspQntBands-1; i >= 0 ; i -- )
   {

     /* Get the VQ table entry corresponding to the transmitted index */
      Tmp = (Word16) ( LspId & (Word32) 0x000000ff ) ;
      LspId >>= 8 ;

      LspQntPnt = BandQntTable[i] ;

      for ( j = 0 ; j < BandInfoTable[i][1] ; j ++ )
         Lsp[BandInfoTable[i][0] + j] = LspQntPnt[Tmp*BandInfoTable[i][1] +j] ;
   }

   /* Subtract the DC component from the previous frame's quantized
      vector */
   for ( j = 0 ; j < LpcOrder ; j ++ )
      PrevLsp[j] = sub(PrevLsp[j], LspDcTable[j] ) ;

   /* Generate the prediction vector using a fixed first-order
      predictor based on the previous frame's (DC-free) quantized
      vector */
   for ( j = 0 ; j < LpcOrder ; j ++ ) 
   {
      Tmp = mult_r( PrevLsp[j], Lprd ) ;
      Lsp[j] = add( Lsp[j], Tmp ) ;
   }

   /* Add the DC component back to the previous quantized vector,
      which is needed in later routines */
   for ( j = 0 ; j < LpcOrder ; j ++ )
   {
      PrevLsp[j] = add( PrevLsp[j], LspDcTable[j] ) ;
      Lsp[j] = add( Lsp[j], LspDcTable[j] ) ;
   }


   /*
    * Perform a stability test on the quantized LSP frequencies.  This
    * test checks that the frequencies are ordered, with a minimum
    * separation between each.  If the test fails, the frequencies are
    * iteratively modified until the test passes.  If after 10
    * iterations the test has not passed, the previous frame's
    * quantized LSP vector is used.
    */
   for ( i = 0 ; i < LpcOrder ; i ++ ) 
   {

      /* Check the first frequency */
      if ( Lsp[0] < (Word16) 0x180 )
         Lsp[0] = (Word16) 0x180 ;

      /* Check the last frequency */
      if ( Lsp[LpcOrder-1] > (Word16) 0x7e00 )
         Lsp[LpcOrder-1] = (Word16) 0x7e00 ;

      /* Perform the modification */
      for ( j = 1 ; j < LpcOrder ; j ++ )
	  {

         Tmp = add( Scon, Lsp[j-1] ) ;
         Tmp = sub( Tmp, Lsp[j] ) ;
         if ( Tmp > (Word16) 0 ) 
		 {
            Tmp = shr( Tmp, (Word16) 1 ) ;
            Lsp[j-1] = sub( Lsp[j-1], Tmp ) ;
            Lsp[j] = add( Lsp[j], Tmp ) ;
		 }
	  }

      Test = False ;

      /* Test the modified frequencies for stability.  Break out of
         the loop if the frequencies are stable. */
      for ( j = 1 ; j < LpcOrder ; j ++ )
	  {
         Tmp = add( Lsp[j-1], Scon ) ;
         Tmp = sub( Tmp, (Word16) 4 ) ;
         Tmp = sub( Tmp, Lsp[j] ) ;
         if ( Tmp > (Word16) 0 )
            Test = True ;
	  }

      if ( Test == False )
         break ;
   }


   /*
    * Return the result of the stability check.  True = not stable,
    * False = stable.
    */
   if ( Test == True) 
   {
      for ( j = 0 ; j < LpcOrder ; j ++ )
         Lsp[j] = PrevLsp[j] ;
   }

   return;
}


/*
**
** Function:            Lsp_Int()
**
** Description:     Computes the quantized LPC coefficients for a
**          frame.  First the quantized LSP frequencies
**          for all subframes are computed by linear
**          interpolation.  These frequencies are then
**          transformed to quantized LPC coefficients.
**
** Links to text:   Sections 2.7, 3.3
**
** Arguments:       
**
**  Word16 *QntLpc      Empty buffer
**  Word16 CurrLsp[]    Quantized LSP frequencies for the current frame,
**               subframe 3 (10 words)
**  Word16 PrevLsp[]    Quantized LSP frequencies for the previous frame,
**               subframe 3 (10 words)
**
** Outputs:         
**
**  Word16 QntLpc[]     Quantized LPC coefficients for current frame, all
**               subframes (40 words)
**
** Return value:        None
** 
*/
void  Lsp_Int( Word16 *QntLpc, Word16 *CurrLsp, Word16 *PrevLsp )
{
   int   i,j   ;

   Word16   Tmp   ;
   Word16  *Dpnt  ;

   Word32   Acc0  ;


   /* 
    * Initialize the interpolation factor 
    */
   Tmp = (Word16) (MIN_16 / SubFrames ) ;

   Dpnt = QntLpc ;


   /*
    * Do for all subframes
    */
   for ( i = 0 ; i < SubFrames ; i ++ ) 
   {

     /* Compute the quantized LSP frequencies by linear interpolation
        of the frequencies from subframe 3 of the current and
        previous frames */
      for ( j = 0 ; j < LpcOrder ; j ++ ) 
	  {
         Acc0 = L_deposit_h( PrevLsp[j] ) ;
         Acc0 = L_mac( Acc0, Tmp, PrevLsp[j] ) ;
         Acc0 = L_msu( Acc0, Tmp, CurrLsp[j] ) ;
         Dpnt[j] = round( Acc0 ) ;
	  }

      /* Convert the quantized LSP frequencies to quantized LPC
         coefficients */
      LsptoA( Dpnt ) ;
      Dpnt += LpcOrder ;

      /* Update the interpolation factor */
      Tmp = add( Tmp, (Word16) (MIN_16 / SubFrames ) ) ;
   }
}


/*
**
** Function:            LsptoA()
**
** Description:     Converts LSP frequencies to LPC coefficients
**          for a subframe.  Sum and difference
**          polynomials are computed from the LSP
**          frequencies (which are the roots of these
**          polynomials).  The LPC coefficients are then
**          computed by adding the sum and difference
**          polynomials.
**          
** Links to text:   Sections 2.7, 3.3
**
** Arguments:       
**
**  Word16 Lsp[]        LSP frequencies (10 words)
**
** Outputs:         
**
**  Word16 Lsp[]        LPC coefficients (10 words)
**
** Return value:        None
** 
*/
void  LsptoA( Word16 *Lsp )
{
   int   i,j   ;

   Word32   Acc0,Acc1   ;
   Word16   Tmp ;

   Word32   P[LpcOrder/2+1] ;
   Word32   Q[LpcOrder/2+1] ;


   /*
    * Compute the cosines of the LSP frequencies by table lookup and
    * linear interpolation
    */
   for ( i = 0 ; i < LpcOrder ; i ++ ) 
   {

     /* Do the table lookup using bits [15:7] of the LSP frequency */
      j = (int) shr( Lsp[i], (Word16) 7 ) ;
      Acc0 = L_deposit_h( CosineTable[j] ) ;

      /* Do the linear interpolations using bits [6:0] of the LSP
         frequency */
      Tmp = sub(CosineTable[j+1], CosineTable[j] ) ;
      Acc0 = L_mac( Acc0, Tmp, add( shl( (Word16) (Lsp[i] & 0x007f) ,
                        (Word16)8 ), (Word16) 0x0080 ) ) ;
      Acc0 = L_shl( Acc0, (Word16) 1 ) ;
      Lsp[i] = negate( round( Acc0 ) ) ;
   }


   /*
    * Compute the sum and difference polynomials with the real roots
    * removed.  These are computed by polynomial multiplication as
    * follows.  Let the sum polynomial be P(z).  Define the elementary
    * polynomials P_i(z) = 1 - 2cos(w_i) z^{-1} + z^{-2}, for 1<=i<=
    * 5, where {w_i} are the LSP frequencies corresponding to the sum
    * polynomial.  Then P(z) = P_1(z)P_2(z)...P_5(z).  Similarly
    * the difference polynomial Q(z) = Q_1(z)Q_2(z)...Q_5(z).  
    */

   /* Initialize the arrays with the coefficients of the product
      P_1(z)P_2(z) and Q_1(z)Q_2(z).  Scale by 1/8. */
   P[0] = (Word32) 0x10000000L ;
   P[1] = L_mult( Lsp[0], (Word16) 0x2000 ) ;
   P[1] = L_mac( P[1], Lsp[2], (Word16) 0x2000 ) ;
   P[2] = L_mult( Lsp[0], Lsp[2] ) ;
   P[2] = L_shr( P[2], (Word16) 1 ) ;
   P[2] = L_add( P[2], (Word32) 0x20000000L ) ;

   Q[0] = (Word32) 0x10000000L ;
   Q[1] = L_mult( Lsp[1], (Word16) 0x2000 ) ;
   Q[1] = L_mac( Q[1], Lsp[3], (Word16) 0x2000 ) ;
   Q[2] = L_mult( Lsp[1], Lsp[3] ) ;
   Q[2] = L_shr( Q[2], (Word16) 1 ) ;
   Q[2] = L_add( Q[2], (Word32) 0x20000000L ) ;

   /* Compute the intermediate polynomials P_1(z)P_2(z)...P_i(z) and
      Q_1(z)Q_2(z)...Q_i(z), for i = 2, 3, 4.  Each intermediate
      polynomial is symmetric, so only the coefficients up to i+1 need
      by computed.  Scale by 1/2 each iteration for a total of 1/8. */
   for ( i = 2 ; i < LpcOrder/2 ; i ++ ) 
   {

     /* Compute coefficient (i+1) */
      Acc0 = P[i] ;
      Acc0 = L_mls( Acc0, Lsp[2*i+0] ) ;
      Acc0 = L_add( Acc0, P[i-1] ) ;
      P[i+1] = Acc0 ;

      Acc1 = Q[i] ;
      Acc1 = L_mls( Acc1, Lsp[2*i+1] ) ;
      Acc1 = L_add( Acc1, Q[i-1] ) ;
      Q[i+1] = Acc1 ;

     /* Compute coefficients i, i-1, ..., 2 */
      for ( j = i ; j >= 2 ; j -- ) 
	  {
         Acc0 = P[j-1] ;
         Acc0 = L_mls( Acc0, Lsp[2*i+0] ) ;
         Acc0 = L_add( Acc0, L_shr(P[j], (Word16) 1 ) ) ;
         Acc0 = L_add( Acc0, L_shr(P[j-2], (Word16) 1 ) ) ;
         P[j] = Acc0 ;

         Acc1 = Q[j-1] ;
         Acc1 = L_mls( Acc1, Lsp[2*i+1] ) ;
         Acc1 = L_add( Acc1, L_shr(Q[j], (Word16) 1 ) ) ;
         Acc1 = L_add( Acc1, L_shr(Q[j-2], (Word16) 1 ) ) ;
         Q[j] = Acc1 ;
	  }

     /* Compute coefficients 1, 0 */
      P[0] = L_shr( P[0], (Word16) 1 ) ;
      Q[0] = L_shr( Q[0], (Word16) 1 ) ;

      Acc0 = L_deposit_h( Lsp[2*i+0] ) ;
      Acc0 = L_shr( Acc0, (Word16) i ) ;
      Acc0 = L_add( Acc0, P[1] ) ;
      Acc0 = L_shr( Acc0, (Word16) 1 ) ;
      P[1] = Acc0 ;

      Acc1 = L_deposit_h( Lsp[2*i+1] ) ;
      Acc1 = L_shr( Acc1, (Word16) i ) ;
      Acc1 = L_add( Acc1, Q[1] ) ;
      Acc1 = L_shr( Acc1, (Word16) 1 ) ;
      Q[1] = Acc1 ;
   }


   /*
    * Convert the sum and difference polynomials to LPC coefficients
    * The LPC polynomial is the sum of the sum and difference
    * polynomials with the real zeros factored in: A(z) = 1/2 {P(z) (1
    * + z^{-1}) + Q(z) (1 - z^{-1})}.  The LPC coefficients are scaled
    * here by 16; the overall scale factor for the LPC coefficients
    * returned by this function is therefore 1/4.  
    */
   for ( i = 0 ; i < LpcOrder/2 ; i ++ )
   {
      Acc0 = P[i] ;
      Acc0 = L_add( Acc0, P[i+1] ) ;
      Acc0 = L_sub( Acc0, Q[i] ) ;
      Acc0 = L_add( Acc0, Q[i+1] ) ;
      Acc0 = L_shl( Acc0, (Word16) 3 ) ;
      Lsp[i] = negate( round( Acc0 ) ) ;

      Acc1 = P[i] ;
      Acc1 = L_add( Acc1, P[i+1] ) ;
      Acc1 = L_add( Acc1, Q[i] ) ;
      Acc1 = L_sub( Acc1, Q[i+1] ) ;
      Acc1 = L_shl( Acc1, (Word16) 3 ) ;
      Lsp[LpcOrder-1-i] = negate( round( Acc1 ) ) ;
   }

}


⌨️ 快捷键说明

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