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

📄 sp_enc.c

📁 FIXPOINT
💻 C
📖 第 1 页 / 共 4 页
字号:

/*
 * Int_lpc_1and3
 *
 *
 * Parameters:
 *    lsp_old        I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_mid        I: LSP vector at the 2nd subframe of present frame [M]
 *    lsp_new        I: LSP vector at the 4th subframe of present frame [M]
 *    az             O: interpolated LP parameters in subframes 1 and 3
 *                                                                [AZ_SIZE]
 *
 * Function:
 *    Interpolates the LSPs and converts to LPC parameters
 *    to get a different LP filter in each subframe.
 *
 *    The 20 ms speech frame is divided into 4 subframes.
 *    The LSPs are quantized and transmitted at the 2nd and
 *    4th subframes (twice per frame) and interpolated at the
 *    1st and 3rd subframe.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1and3( Float32 lsp_old[], Float32 lsp_mid[], Float32 lsp_new
      [], Float32 az[] )
{
   Word32 i;
   Float32 lsp[M];


   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_mid[i] + lsp_old[i] ) * 0.5F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 2 */
   Lsp_Az( lsp_mid, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_mid[i] + lsp_new[i] ) * 0.5F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 4 */
   Lsp_Az( lsp_new, az );
   return;
}


/*
 * Int_lpc_1to3_2
 *
 *
 * Parameters:
 *    lsp_old           I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_new           I: LSP vector at the 4th subframe of present frame [M]
 *    az                O: interpolated LP parameters in subframes 1, 2 and 3
 *                                                                   [AZ_SIZE]
 *
 * Function:
 *    Interpolation of the LPC parameters.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1to3_2( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
   Float32 lsp[M];
   Word32 i;


   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
      lsp[i + 1] = lsp_new[i + 1] *0.25F + lsp_old[i + 1] *0.75F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
      lsp[i + 1] = ( lsp_old[i + 1] +lsp_new[i+1] )*0.5F;
   }

   /* Subframe 2 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
      lsp[i + 1] = lsp_old[i + 1] *0.25F + lsp_new[i + 1] *0.75F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   return;
}


/*
 * Int_lpc_1to3
 *
 *
 * Parameters:
 *    lsp_old           I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_new           I: LSP vector at the 4th subframe of present frame [M]
 *    az                O: interpolated LP parameters in all subframes
 *                                                                   [AZ_SIZE]
 *
 * Function:
 *    Interpolates the LSPs and converts to LPC parameters to get a different
 *    LP filter in each subframe.
 *
 *    The 20 ms speech frame is divided into 4 subframes.
 *    The LSPs are quantized and transmitted at the 4th
 *    subframes (once per frame) and interpolated at the
 *    1st, 2nd and 3rd subframe.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1to3( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
   Float32 lsp[M];
   Word32 i;


   for ( i = 0; i < M; i++ ) {
      lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
   }

   /* Subframe 2 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 4 */
   Lsp_Az( lsp_new, az );
   return;
}


/*
 * lsp
 *
 *
 * Parameters:
 *    req_mode          I: requested mode
 *    used_mode         I: used mode
 *    lsp_old           B: old LSP vector
 *    lsp_old_q         B: old quantized LSP vector
 *    past_rq           B: past quantized residual
 *    az                B: interpolated LP parameters
 *    azQ               O: quantization interpol. LP parameters
 *    lsp_new           O: new lsp vector
 *    anap              O: analysis parameters
 *
 * Function:
 *    From A(z) to lsp. LSP quantization and interpolation
 *
 * Returns:
 *    void
 */
static void lsp(int req_mode, int used_mode, Float32 *lsp_old,
      Float32 *lsp_old_q, Float32 *past_rq, Float32 az[], Float32 azQ[], Float32
      lsp_new[], Word16 **anap )
{
   Float32 lsp_new_q[M];   /* LSPs at 4th subframe */
   Float32 lsp_mid[M], lsp_mid_q[M];   /* LSPs at 2nd subframe */
   Word32 pred_init_i;   /* init index for MA prediction in DTX mode */


   if ( req_mode == MR122 ) {
      Az_lsp( &az[MP1], lsp_mid, lsp_old );
      Az_lsp( &az[MP1 * 3], lsp_new, lsp_mid );

      /*
       * Find interpolated LPC parameters in all subframes
       * (both quantized and unquantized).
       * The interpolated parameters are in array A_t[] of size (M+1)*4
       * and the quantized interpolated parameters are in array Aq_t[]
       */
      Int_lpc_1and3_2( lsp_old, lsp_mid, lsp_new, az );

      if ( used_mode != MRDTX ) {
         /* LSP quantization (lsp_mid[] and lsp_new[] jointly quantized) */
         Q_plsf_5( past_rq, lsp_mid, lsp_new, lsp_mid_q, lsp_new_q, *anap );
         Int_lpc_1and3( lsp_old_q, lsp_mid_q, lsp_new_q, azQ );

         /* Advance analysis parameters pointer */
         ( *anap ) += 5;
      }
   }
   else {
      /* From A(z) to lsp */
      Az_lsp( &az[MP1 * 3], lsp_new, lsp_old );

      /*
       * Find interpolated LPC parameters in all subframes
       * (both quantized and unquantized).
       * The interpolated parameters are in array A_t[] of size (M+1)*4
       * and the quantized interpolated parameters are in array Aq_t[]
       */
      Int_lpc_1to3_2( lsp_old, lsp_new, az );

      /* LSP quantization */
      if ( used_mode != MRDTX ) {
         Q_plsf_3( req_mode, past_rq, lsp_new, lsp_new_q, *anap, &pred_init_i );
         Int_lpc_1to3( lsp_old_q, lsp_new_q, azQ );

         /* Advance analysis parameters pointer */
         ( *anap ) += 3;
      }
   }

   /* update the LSPs for the next frame */
   memcpy( lsp_old, lsp_new, M <<2 );
   memcpy( lsp_old_q, lsp_new_q, M <<2 );
}


/*
 * check_lsp
 *
 *
 * Parameters:
 *    count          B: counter for resonance
 *    lsp            B: LSP vector
 *
 * Function:
 *    Check the LSP's to detect resonances
 *
 *    Resonances in the LPC filter are monitored to detect possible problem
 *    areas where divergence between the adaptive codebook memories in
 *    the encoder and the decoder could cause unstable filters in areas
 *    with highly correlated continuos signals. Typically, this divergence
 *    is due to channel errors.
 *    The monitoring of resonance signals is performed using unquantized LSPs
 *    q(i), i = 1,...,10. The algorithm utilises the fact that LSPs are
 *    closely located at a peak in the spectrum. First, two distances,
 *    dist 1 and dist 2 ,are calculated in two different regions,
 *    defined as
 *
 *    dist1 = min[q(i) - q(i + 1)],  i = 4,...,8
 *    dist2 = min[q(i) - q(i + 1)],  i = 2,3
 *
 *    Either of these two minimum distance conditions must be fulfilled
 *    to classify the frame as a resonance frame and increase the resonance
 *    counter.
 *
 *    if(dist1 < TH1) || if (dist2 < TH2)
 *       counter++
 *    else
 *       counter = 0
 *
 *    TH1 = 0.046
 *    TH2 = 0.018, q(2) > 0.98
 *    TH2 = 0.024, 0.93 < q(2) <= 0.98
 *    TH2 = 0.018, otherwise
 *
 *    12 consecutive resonance frames are needed to indicate possible
 *    problem conditions, otherwise the LSP_flag is cleared.
 *
 * Returns:
 *    resonance flag
 */
static Word16 check_lsp( Word16 *count, Float32 *lsp )
{
   Float32 dist, dist_min1, dist_min2, dist_th;
   Word32 i;


   /*
    * Check for a resonance:
    * Find minimum distance between lsp[i] and lsp[i+1]
    */
   dist_min1 = FLT_MAX;

   for ( i = 3; i < 8; i++ ) {
      dist = lsp[i] - lsp[i + 1];

      if ( dist < dist_min1 ) {
         dist_min1 = dist;
      }
   }
   dist_min2 = FLT_MAX;

   for ( i = 1; i < 3; i++ ) {
      dist = lsp[i] - lsp[i + 1];

      if ( dist < dist_min2 ) {
         dist_min2 = dist;
      }
   }

   if ( lsp[1] > 0.98F ) {
      dist_th = 0.018F;
   }
   else if ( lsp[1] > 0.93F ) {
      dist_th = 0.024F;
   }
   else {
      dist_th = 0.034F;
   }

   if ( ( dist_min1 < 0.046F ) || ( dist_min2 < dist_th ) ) {
      *count += 1;
   }
   else {
      *count = 0;
   }

   /* Need 12 consecutive frames to set the flag */
   if ( *count >= 12 ) {
      *count = 12;
      return 1;
   }
   else {
      return 0;
   }
}


/*
 * Weight_Ai
 *
 *
 * Parameters:
 *    a                 I: LPC coefficients                    [M+1]
 *    fac               I: Spectral expansion factors.         [M+1]
 *    a_exp             O: Spectral expanded LPC coefficients  [M+1]
 *
 * Function:
 *    Spectral expansion of LP coefficients
 *
 * Returns:
 *    void
 */
static void Weight_Ai( Float32 a[], const Float32 fac[], Float32 a_exp[] )
{
   Word32 i;


   a_exp[0] = a[0];

   for ( i = 1; i <= M; i++ ) {
      a_exp[i] = a[i] * fac[i - 1];
   }
   return;
}


/*
 * Residu
 *
 *
 * Parameters:
 *    a                 I: prediction coefficients
 *    x                 I: speech signal
 *    y                 O: residual signal
 *
 * Function:
 *    Computes the LTP residual signal.
 *
 * Returns:
 *    void
 */
static void Residu( Float32 a[], Float32 x[], Float32 y[] )
{
   Float32 s;
   Word32 i;


   for ( i = 0; i < L_SUBFR; i += 4 ) {
      s = x[i] * a[0];
      s += x[i - 1] *a[1];
      s += x[i - 2] * a[2];
      s += x[i - 3] * a[3];
      s += x[i - 4] * a[4];
      s += x[i - 5] * a[5];
      s += x[i - 6] * a[6];
      s += x[i - 7] * a[7];
      s += x[i - 8] * a[8];
      s += x[i - 9] * a[9];
      s += x[i - 10] * a[10];
      y[i] = s;
      s = x[i + 1] *a[0];
      s += x[i] * a[1];
      s += x[i - 1] *a[2];
      s += x[i - 2] * a[3];
      s += x[i - 3] * a[4];
      s += x[i - 4] * a[5];
      s += x[i - 5] * a[6];
      s += x[i - 6] * a[7];
      s += x[i - 7] * a[8];
      s += x[i - 8] * a[9];
      s += x[i - 9] * a[10];
      y[i + 1] = s;
      s = x[i + 2] * a[0];
      s += x[i + 1] *a[1];
      s += x[i] * a[2];
      s += x[i - 1] *a[3];
      s += x[i - 2] * a[4];
      s += x[i - 3] * a[5];
      s += x[i - 4] * a[6];
      s += x[i - 5] * a[7];
      s += x[i - 6] * a[8];
      s += x[i - 7] * a[9];
      s += x[i - 8] * a[10];
      y[i + 2] = s;
      s = x[i + 3] * a[0];
      s += x[i + 2] * a[1];
      s += x[i + 1] *a[2];
      s += x[i] * a[3];
      s += x[i - 1] *a[4];
      s += x[i - 2] * a[5];
      s += x[i - 3] * a[6];
      s += x[i - 4] * a[7];
      s += x[i - 5] * a[8];
      s += x[i - 6] * a[9];
      s += x[i - 7] * a[10];
      y[i + 3] = s;
   }
   return;
}


/*
 * Syn_filt
 *
 *
 * Parameters:
 *    a                 I: prediction coefficients [M+1]
 *    x                 I: input signal
 *    y                 O: output signal
 *    mem               B: memory associated with this filtering
 *    update            I: 0=no update, 1=update of memory.
 *
 * Function:
 *    Perform synthesis filtering through 1/A(z).
 *
 * Returns:
 *    void
 */
static void Syn_filt( Float32 a[], Float32 x[], Float32 y[], Float32 mem[], Word16 update )
{
#define Fixed_point_mode
#ifdef Fixed_point_mode
   Float32 sum;
   Float32 tmp[50];
   Float32 *yy;
   Word32 i, j;
   Word16 A[11]; //For Fixed_point a[]
   Word32 X[40]; //For Fixed_point x[]
#else
   Float64 tmp[50];
   Float64 sum;
   Float64 *yy;
   Word32 i, j;
#endif

#ifdef Fixed_point_mode
   //======= truncate a[] ========= total 16 bits, 俱计=3 bits, 

⌨️ 快捷键说明

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