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

📄 enc_lpc.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
 *    void
 */
void E_LPC_a_isp_conversion(Float32 *a, Float32 *isp, Float32 *old_isp,
                            Word32 m)
{
   Float32 f1[(M >> 1) + 1], f2[M >> 1];
   Float32 *pf;
   Float32 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
   Word32 j, i, nf, ip, order, nc;

   nc = m >> 1;

   /*
    * find the sum and diff polynomials F1(z) and F2(z)
    *      F1(z) = [A(z) + z^m A(z^-1)]
    *      F2(z) = [A(z) - z^m A(z^-1)]/(1-z^-2)
    */

   for (i=0; i < nc; i++)
   {
      f1[i] = a[i] + a[m - i];
      f2[i] = a[i] - a[m - i];
   }

   f1[nc] = 2.0F * a[nc];

   /* divide by (1 - z^-2) */
   for (i = 2; i < nc; i++)
   {
      f2[i] += f2[i - 2];
   }

   /*
    * Find the ISPs (roots of F1(z) and F2(z) ) using the
    * Chebyshev polynomial evaluation.
    * The roots of F1(z) and F2(z) are alternatively searched.
    * We start by finding the first root of F1(z) then we switch
    * to F2(z) then back to F1(z) and so on until all roots are found.
    *
    *  - Evaluate Chebyshev pol. at E_ROM_grid polongs and check for sign change.
    *  - If sign change track the root by subdividing the Word32erval
    *    4 times and ckecking sign change.
    */

   nf=0;      /* number of found frequencies */
   ip=0;      /* flag to first polynomial   */

   pf = f1;  /* start with F1(z) */
   order = nc;

   xlow = E_ROM_grid[0];
   ylow = E_LPC_chebyshev(xlow, pf, nc);

   j = 0;

   while ( (nf < m - 1) && (j < NO_POINTS) )
   {
      j++;
      xhigh = xlow;
      yhigh = ylow;
      xlow = E_ROM_grid[j];
      ylow = E_LPC_chebyshev(xlow, pf, order);

      if (ylow * yhigh <= 0.0F)  /* if sign change new root exists */
      {
         j--;

         /* divide the Word32erval of sign change by NO_ITER */

         for (i = 0; i < NO_ITER; i++)
         {
            xmid = 0.5F * (xlow + xhigh);
            ymid = E_LPC_chebyshev(xmid, pf, order);

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

         /* linear interpolation for evaluating the root */

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

         isp[nf] = xint;    /* new root */
         nf++;

         ip = 1 - ip;                  /* flag to other polynomial    */
         pf = ip ? f2 : f1;            /* pointer to other polynomial */
         order = ip ? (nc - 1) : nc;   /* order of other polynomial   */

         xlow = xint;
         ylow = E_LPC_chebyshev(xlow, pf, order);
      }
   }

   isp[m - 1] = a[m];

   /*
    * Check if m-1 roots found
    * if not use the ISPs from previous frame
    */

   if (nf < m - 1)
   {
      for(i = 0; i < m; i++)
      {
         isp[i] = old_isp[i];
      }
   }

   return;
}

/*
 * E_LPC_isp_isf_conversion
 *
 * Parameters:
 *    isp            I: isp[m] (range: -1 <= val < 1) (Q15)
 *    isf            O: isf[m] normalized (range: 0 <= val <= 6400)
 *    m              I: LPC order
 *
 * Function:
 *    Transformation isp to isf
 *
 *    ISP are immitance spectral pair in cosine domain (-1 to 1).
 *    ISF are immitance spectral pair in frequency domain (0 to 6400).
 * Returns:
 *    energy of prediction error
 */
void E_LPC_isp_isf_conversion(Float32 isp[], Float32 isf[], Word32 m)
{
   Word32 i;

   /* convert ISPs to frequency domain 0..6400 */
   for(i = 0; i < (m - 1); i++)
   {
      isf[i] = (Float32)(acos(isp[i]) * SCALE1);
   }

   isf[m - 1] = (Float32)(acos(isp[m - 1]) * SCALE1 * 0.5F);

   return;
}

/*
 * E_LPC_stage1_isf_vq
 *
 * Parameters:
 *    x              I: ISF residual vector
 *    dico           I: quantisation codebook
 *    dim            I: dimension of vector
 *    dico_size      I: size of quantization codebook
 *    index          O: indices of survivors
 *    surv           I: number of survivor
 *
 * Function:
 *    1st stage VQ with split-by-2.
 *
 * Returns:
 *    void
 */
static void E_LPC_stage1_isf_vq(Float32 *x, const Float32 *E_ROM_dico,
                                Word32 dim, Word32 E_ROM_dico_size,
                                Word32 *index, Word32 surv)
{
   Float32 dist_min[N_SURV_MAX];
   Float32 dist, temp1, temp2;
   const Float32 *p_E_ROM_dico;
   Word32 i, j, k, l;

   for (i = 0; i < surv; i++)
   {
      dist_min[i] = 1.0e30F;
   }

   for (i = 0; i < surv; i++)
   {
      index[i] = i;
   }

   p_E_ROM_dico = E_ROM_dico;

   for (i = 0; i < E_ROM_dico_size; i++)
   {
      dist = x[0] - *p_E_ROM_dico++;
      dist *= dist;

      for (j = 1; j < dim; j += 2)
      {
         temp1 = x[j] - *p_E_ROM_dico++;
         temp2 = x[j + 1] - *p_E_ROM_dico++;
         dist += temp1 * temp1 + temp2 * temp2;
      }

      for (k = 0; k < surv; k++)
      {
         if (dist < dist_min[k])
         {
            for (l = surv - 1; l > k; l--)
            {
               dist_min[l] = dist_min[l - 1];
               index[l] = index[l - 1];
            }

            dist_min[k] = dist;
            index[k] = i;

            break;
         }
      }
   }

   return;
}

/*
 * E_LPC_isf_2s3s_quantise
 *
 * Parameters:
 *    isf1              I: ISF in the frequency domain (0..6400)
 *    isf_q             O: quantized ISF
 *    past_isfq       I/O: past ISF quantizer
 *    indice            O: quantisation indices (5 words)
 *    nb_surv           I: number of survivor (1, 2, 3 or 4)
 *
 * Function:
 *    Quantization of isf parameters with prediction. (36 bits)
 *
 *    The isf vector is quantized using two-stage VQ with split-by-2 in
 *    1st stage and split-by-3 in the second stage.
 * Returns:
 *    void
 */
void E_LPC_isf_2s3s_quantise(Float32 *isf1, Word16 *isf_q, Word16 *past_isfq,
                             Word32 *indice, Word32 nb_surv)
{
   Float32 isf[ORDER], isf_stage2[ORDER];
   Float32 temp, min_err, distance;
   Word32 surv1[N_SURV_MAX];     /* indices of survivors from 1st stage */
   Word32 tmp_ind[5];
   Word32 i, k;

   for (i = 0; i < ORDER; i++)
   {
      isf[i] = (Float32)((isf1[i] - E_ROM_f_mean_isf[i]) -
         F_MU * past_isfq[i] * 0.390625F);
   }

   E_LPC_stage1_isf_vq(&isf[0], E_ROM_dico1_isf, 9, SIZE_BK1, surv1, nb_surv);

   distance = 1.0e30F;

   for (k = 0; k < nb_surv; k++)
   {
      for (i = 0; i < 9; i++)
      {
         isf_stage2[i] = isf[i] - E_ROM_dico1_isf[i + surv1[k] * 9];
      }

      tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico21_isf_36b, 5,
         SIZE_BK21_36b, &min_err);
      temp = min_err;
      tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[5], E_ROM_dico22_isf_36b, 4,
         SIZE_BK22_36b, &min_err);
      temp += min_err;

      if (temp < distance)
      {
         distance = temp;
         indice[0] = surv1[k];

         for (i = 0; i < 2; i++)
         {
            indice[i + 2] = tmp_ind[i];
         }
      }
   }

   E_LPC_stage1_isf_vq(&isf[9], E_ROM_dico2_isf, 7, SIZE_BK2, surv1, nb_surv);

   distance = 1.0e30F;

   for (k = 0; k < nb_surv; k++)
   {
      for (i = 0; i < 7; i++)
      {
         isf_stage2[i] = isf[9 + i] - E_ROM_dico2_isf[i + surv1[k] * 7];
      }

      tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico23_isf_36b, 7,
         SIZE_BK23_36b, &min_err);
      temp = min_err;

      if (temp < distance)
      {
         distance = temp;
         indice[1] = surv1[k];
         indice[4]= tmp_ind[0];
      }
   }

   /* decoding the ISF */

   E_LPC_isf_2s3s_decode(indice, isf_q, past_isfq);

   return;
}

/*
 * E_LPC_isf_2s5s_quantise
 *
 * Parameters:
 *    isf1              I: ISF in the frequency domain (0..6400)
 *    isf_q             O: quantized ISF
 *    past_isfq       I/O: past ISF quantizer
 *    indice            O: quantisation indices (5 words)
 *    nb_surv           I: number of survivor (1, 2, 3 or 4)
 *
 * Function:
 *    Quantization of isf parameters with prediction. (46 bits)
 *
 *    The isf vector is quantized using two-stage VQ with split-by-2 in
 *    1st stage and split-by-5 in the second stage.
 * Returns:
 *    void
 */
void E_LPC_isf_2s5s_quantise(Float32 *isf1, Word16 *isf_q, Word16 *past_isfq,
                             Word32 *indice, Word32 nb_surv)
{
   Float32 isf[ORDER], isf_stage2[ORDER];
   Float32 temp, min_err, distance;
   Word32 surv1[N_SURV_MAX];     /* indices of survivors from 1st stage */
   Word32 tmp_ind[5];
   Word32 i, k;

   for (i=0; i<ORDER; i++)
   {
      isf[i] = (Float32)((isf1[i] - E_ROM_f_mean_isf[i]) -
         F_MU * past_isfq[i] * 0.390625F);
   }

   E_LPC_stage1_isf_vq(&isf[0], E_ROM_dico1_isf, 9, SIZE_BK1, surv1, nb_surv);

   distance = 1.0e30F;

   for (k = 0; k < nb_surv; k++)
   {
      for (i = 0; i < 9; i++)
      {
         isf_stage2[i] = isf[i] - E_ROM_dico1_isf[i + surv1[k] * 9];
      }

      tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico21_isf, 3,
         SIZE_BK21, &min_err);
      temp = min_err;
      tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[3], E_ROM_dico22_isf, 3,
         SIZE_BK22, &min_err);
      temp += min_err;
      tmp_ind[2] = E_LPC_isf_sub_vq(&isf_stage2[6], E_ROM_dico23_isf, 3,
         SIZE_BK23, &min_err);
      temp += min_err;

      if (temp < distance)
      {
         distance = temp;
         indice[0] = surv1[k];

         for (i = 0; i < 3; i++)
         {
            indice[i + 2] = tmp_ind[i];
         }
      }
   }

   E_LPC_stage1_isf_vq(&isf[9], E_ROM_dico2_isf, 7, SIZE_BK2, surv1, nb_surv);

   distance = 1.0e30F;

   for (k=0; k<nb_surv; k++)
   {
      for (i = 0; i < 7; i++)
      {
         isf_stage2[i] = isf[9+i] - E_ROM_dico2_isf[i+surv1[k]*7];
      }

      tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico24_isf, 3,
         SIZE_BK24, &min_err);
      temp = min_err;
      tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[3], E_ROM_dico25_isf, 4,
         SIZE_BK25, &min_err);
      temp += min_err;

      if (temp < distance)
      {
         distance = temp;
         indice[1] = surv1[k];

         for (i = 0; i < 2; i++)
         {
            indice[i + 5]= tmp_ind[i];
         }
      }
   }

   /* decoding the ISFs */
   E_LPC_isf_2s5s_decode(indice, isf_q, past_isfq);

   return;
}

⌨️ 快捷键说明

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