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

📄 sp_enc.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
      if ( r[0] < 1.0F )
         r[0] = 1.0F;

      /*
       * Levinson Durbin
       */
      Levinson( old_A, r, &a[MP1 * 3], rc );
   }
   else {
      /*
       * Autocorrelations
       */
      Autocorr( x, r, window_200_40 );

      /*
       * a 60 Hz bandwidth expansion is used by lag windowing
       * the auto-correlations. Further, auto-correlation[0] is
       * multiplied by the white noise correction factor 1.0001
       * which is equivalent to adding a noise floor at -40 dB.
       */
      for ( i = 1; i <= M; i++ ) {
         r[i] = r[i] * lag_wind[i - 1];
      }
      r[0] *= 1.0001F;

      if ( r[0] < 1.0F )
         r[0] = 1.0F;

      /*
       * Levinson Durbin
       */
      Levinson( old_A, r, &a[MP1 * 3], rc );
   }
}


/*
 * Chebps
 *
 *
 * Parameters:
 *    x                 I: Cosine value for the freqency given
 *    f                 I: angular freqency
 * Function:
 *    Evaluates the Chebyshev polynomial series
 *
 * Returns:
 *    result of polynomial evaluation
 */
static Float32 Chebps( Float32 x, Float32 f[] )
{
   Float32 b0, b1, b2, x2;
   Word32 i;


   x2 = 2.0F * x;
   b2 = 1.0F;
   b1 = x2 + f[1];

   for ( i = 2; i < 5; i++ ) {
      b0 = x2 * b1 - b2 + f[i];
      b2 = b1;
      b1 = b0;
   }
   return( x * b1 - b2 + f[i] );
}


/*
 * Az_lsp
 *
 *
 * Parameters:
 *    a                 I: Predictor coefficients              [MP1]
 *    lsp               O: Line spectral pairs                 [M]
 *    old_lsp           I: Old lsp, in case not found 10 roots [M]
 *
 * Function:
 *    LP to LSP conversion
 *
 *    The LP filter coefficients A[], are converted to the line spectral pair
 *    (LSP) representation for quantization and interpolation purposes.
 *
 * Returns:
 *    void
 */
static void Az_lsp( Float32 a[], Float32 lsp[], Float32 old_lsp[] )
{
   Word32 i, j, nf, ip;
   Float32 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
   Float32 y;
   Float32 *coef;
   Float32 f1[6], f2[6];


   /*
    *  find the sum and diff. pol. F1(z) and F2(z)
    */
   f1[0] = 1.0F;
   f2[0] = 1.0F;

   for ( i = 0; i < ( NC ); i++ ) {
      f1[i + 1] = a[i + 1] +a[M - i] - f1[i];
      f2[i + 1] = a[i + 1] -a[M - i] + f2[i];
   }
   f1[NC] *= 0.5F;
   f2[NC] *= 0.5F;

   /*
    * find the LSPs using the Chebychev pol. evaluation
    */
   nf = 0;   /* number of found frequencies */
   ip = 0;   /* indicator for f1 or f2 */
   coef = f1;
   xlow = grid[0];
   ylow = Chebps( xlow, coef );
   j = 0;

   while ( ( nf < M ) && ( j < 60 ) ) {
      j++;
      xhigh = xlow;
      yhigh = ylow;
      xlow = grid[j];
      ylow = Chebps( xlow, coef );

      if ( ylow * yhigh <= 0 ) {
         /* divide 4 times the interval */
         for ( i = 0; i < 4; i++ ) {
            xmid = ( xlow + xhigh ) * 0.5F;
            ymid = Chebps( xmid, coef );

            if ( ylow * ymid <= 0.0F ) {
               yhigh = ymid;
               xhigh = xmid;
            }
            else {
               ylow = ymid;
               xlow = xmid;
            }
         }

         /*
          * Linear interpolation
          * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow)
          */
         y = yhigh - ylow;

         if ( y == 0 ) {
            xint = xlow;
         }
         else {
            y = ( xhigh - xlow ) / ( yhigh - ylow );
            xint = xlow - ylow * y;
         }
         lsp[nf] = xint;
         xlow = xint;
         nf++;

         if ( ip == 0 ) {
            ip = 1;
            coef = f2;
         }
         else {
            ip = 0;
            coef = f1;
         }
         ylow = Chebps( xlow, coef );
      }
   }

   /* Check if M roots found */
   if ( nf < M ) {
      memcpy( lsp, old_lsp, M <<2 );
   }
   return;
}


/*
 * Get_lsp_pol
 *
 *
 * Parameters:
 *    lsp                 I: line spectral frequencies
 *    f                   O: polynomial F1(z) or F2(z)
 *
 * Function:
 *    Find the polynomial F1(z) or F2(z) from the LSPs.
 *
 *    F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
 *             i=0,2,4,6,8
 *    F2(z) = product   ( 1 - 2 lsp[i] z^-1 + z^-2 )
 *             i=1,3,5,7,9
 *
 *    where lsp[] is the LSP vector in the cosine domain.
 *
 *    The expansion is performed using the following recursion:
 *
 *    f[0] = 1
 *    b = -2.0 * lsp[0]
 *    f[1] = b
 *    for i=2 to 5 do
 *       b = -2.0 * lsp[2*i-2];
 *       f[i] = b*f[i-1] + 2.0*f[i-2];
 *       for j=i-1 down to 2 do
 *          f[j] = f[j] + b*f[j-1] + f[j-2];
 *       f[1] = f[1] + b;
 *
 * Returns:
 *    void
 */
static void Get_lsp_pol( Float32 *lsp, Float32 *f )
{
   Word32 i, j;
   Float32 T0;


   f[0] = 1.0F;
   f[1] = -2.0F * lsp[0];

   for ( i = 2; i <= 5; i++ ) {
      T0 = -2.0F * lsp[2 * i - 2];
      f[i] = ( Float32 )( T0 * f[i - 1] +2.0F * f[i - 2] );

      for ( j = i - 1; j >= 2; j-- ) {
         f[j] = f[j] + T0 * f[j - 1] +f[j - 2];
      }
      f[1] = f[1] + T0;
   }
   return;
}


/*
 * Lsp_Az
 *
 *
 * Parameters:
 *    lsp                 I: Line spectral frequencies
 *    a                   O: Predictor coefficients
 *
 * Function:
 *    Converts from the line spectral pairs (LSP) to LP coefficients,
 *    for a 10th order filter.
 *
 * Returns:
 *    void
 */
static void Lsp_Az( Float32 lsp[], Float32 a[] )
{
   Float32 f1[6], f2[6];
   Word32 i, j;


   Get_lsp_pol( &lsp[0], f1 );
   Get_lsp_pol( &lsp[1], f2 );

   for ( i = 5; i > 0; i-- ) {
      f1[i] += f1[i - 1];
      f2[i] -= f2[i - 1];
   }
   a[0] = 1;

   for ( i = 1, j = 10; i <= 5; i++, j-- ) {
      a[i] = ( Float32 )( ( f1[i] + f2[i] ) * 0.5F );
      a[j] = ( Float32 )( ( f1[i] - f2[i] ) * 0.5F );
   }
   return;
}


/*
 * Int_lpc_1and3_2
 *
 *
 * 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:
 *    Interpolation of the LPC parameters. Same as the Int_lpc
 *    function but we do not recompute Az() for subframe 2 and
 *	   4 because it is already available.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1and3_2( Float32 lsp_old[], Float32 lsp_mid[], Float32
      lsp_new[], Float32 az[] )
{
   Float32 lsp[M];
   Word32 i;


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

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

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

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


/*
 * Lsp_lsf
 *
 *
 * Parameters:
 *    lsp               I: LSP vector
 *    lsf               O: LSF vector
 *
 * Function:
 *    Transformation lsp to lsf, LPC order M
 *
 * Returns:
 *    void
 */
static void Lsp_lsf( Float32 lsp[], Float32 lsf[] )
{
   Word32 i;


   for ( i = 0; i < M; i++ ) {
      lsf[i] = ( Float32 )( acos( lsp[i] )*SCALE_LSP_FREQ );
   }
   return;
}


/*
 * Lsf_wt
 *
 *
 * Parameters:
 *    lsf               I: LSF vector
 *    wf                O: square of weighting factors
 *
 * Function:
 *    Compute LSF weighting factors
 *
 * Returns:
 *    void
 */
static void Lsf_wt( Float32 *lsf, Float32 *wf )
{
   Float32 temp;
   Word32 i;


   wf[0] = lsf[1];

   for ( i = 1; i < 9; i++ ) {
      wf[i] = lsf[i + 1] -lsf[i - 1];
   }
   wf[9] = 4000.0F - lsf[8];

   for ( i = 0; i < 10; i++ ) {
      if ( wf[i] < 450.0F ) {
         temp = 3.347F - SLOPE1_WGHT_LSF * wf[i];
      }
      else {
         temp = 1.8F - SLOPE2_WGHT_LSF * ( wf[i] - 450.0F );
      }
      wf[i] = temp * temp;
   }
   return;
}


/*
 * Vq_subvec
 *
 *
 * Parameters:
 *    lsf_r1            I: 1st LSF residual vector
 *    lsf_r2            I: 2nd LSF residual vector
 *    dico              I: quantization codebook
 *    wf1               I: 1st LSF weighting factors
 *    wf2               I: 2nd LSF weighting factors
 *    dico_size         I: size of quantization codebook
 * Function:
 *    Quantization of a 4 dimensional subvector
 *
 * Returns:
 *    index             quantization index
 */
static Word16 Vq_subvec( Float32 *lsf_r1, Float32 *lsf_r2, const Float32 *dico,
      Float32 *wf1, Float32 *wf2, Word16 dico_size )
{
   Float64 temp, dist, dist_min;
   const Float32 *p_dico;
   Word32 i, index = 0;


   dist_min = DBL_MAX;
   p_dico = dico;

   for ( i = 0; i < dico_size; i++ ) {
      temp = lsf_r1[0] - *p_dico++;
      dist = temp * temp * wf1[0];
      temp = lsf_r1[1] - *p_dico++;
      dist += temp * temp * wf1[1];
      temp = lsf_r2[0] - *p_dico++;
      dist += temp * temp * wf2[0];
      temp = lsf_r2[1] - *p_dico++;
      dist += temp * temp * wf2[1];

      if ( dist < dist_min ) {
         dist_min = dist;
         index = i;
      }
   }

   /* Reading the selected vector */
   p_dico = &dico[index << 2];
   lsf_r1[0] = *p_dico++;
   lsf_r1[1] = *p_dico++;
   lsf_r2[0] = *p_dico++;
   lsf_r2[1] = *p_dico++;
   return( Word16 )index;
}


/*
 * Vq_subvec_s
 *
 *
 * Parameters:
 *    lsf_r1            I: 1st LSF residual vector
 *    lsf_r2            I: 2nd LSF residual vector
 *    dico              I: quantization codebook
 *    wf1               I: 1st LSF weighting factors
 *    wf2               I: 2nd LSF weighting factors
 *    dico_size         I: size of quantization codebook
 * Function:
 *    Quantization of a 4 dimensional subvector with a signed codebook
 *
 * Returns:
 *    index             quantization index
 */
static Word16 Vq_subvec_s( Float32 *lsf_r1, Float32 *lsf_r2, const Float32 *dico
      , Float32 *wf1, Float32 *wf2, Word16 dico_size )
{
   Float64 dist_min, dist1, dist2, temp1, temp2;
   const Float32 *p_dico;
   Word32 i, index = 0;
   Word16 sign = 0;


   dist_min = DBL_MAX;
   p_dico = dico;

   for ( i = 0; i < dico_size; i++ ) {
      temp1 = lsf_r1[0] - *p_dico;
      temp2 = lsf_r1[0] + *p_dico++;
      dist1 = temp1 * temp1 * wf1[0];
      dist2 = temp2 * temp2 * wf1[0];
      temp1 = lsf_r1[1] - *p_dico;
      temp2 = lsf_r1[1] + *p_dico++;
      dist1 += temp1 * temp1 * wf1[1];
      dist2 += temp2 * temp2 * wf1[1];
      temp1 = lsf_r2[0] - *p_dico;
      temp2 = lsf_r2[0] + *p_dico++;
      dist1 += temp1 * temp1 * wf2[0];
      dist2 += temp2 * temp2 * wf2[0];
      temp1 = lsf_r2[1] - *p_dico;
      temp2 = lsf_r2[1] + *p_dico++;
      dist1 += temp1 * temp1 * wf2[1];
      dist2 += temp2 * temp2 * wf2[1];

      if ( dist1 < dist_min ) {
         dist_min = dist1;
         index = i;
         sign = 0;
      }

      if ( dist2 < dist_min ) {
         dist_min = dist2;
         index = i;
         sign = 1;
      }
   }

   /* Reading the selected vector */
   p_dico = &dico[index << 2];

   if ( sign == 0 ) {
      lsf_r1[0] = *p_dico++;
      lsf_r1[1] = *p_dico++;
      lsf_r2[0] = *p_dico++;
      lsf_r2[1] = *p_dico++;
   }
   else {
      lsf_r1[0] = -( *p_dico++ );
      lsf_r1[1] = -( *p_dico++ );
      lsf_r2[0] = -( *p_dico++ );
      lsf_r2[1] = -( *p_dico++ );
   }
   index = index << 1;
   index = index + sign;
   return( Word16 )index;
}


/*
 * Reorder_lsf
 *
 *
 * Parameters:
 *    lsf               B: vector of LSFs
 *    min_dist          I: minimum required distance
 *
 * Function:
 *    Make sure that the LSFs are properly ordered and to keep a certain minimum
 *    distance between adjacent LSFs. LPC order = M.
 *

⌨️ 快捷键说明

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