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

📄 dec_util.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
 *
 * Returns:
 *    32 bit result
 */
Word32 D_UTIL_mpy_32_16(Word16 hi, Word16 lo, Word16 n)
{
   Word32 L_32;

   L_32 = hi * n;
   L_32 += (lo * n) >> 15;

   return(L_32 << 1);
}


/*
 * D_UTIL_mpy_32
 *
 * Parameters:
 *    hi1         I: hi part of first number
 *    lo1         I: lo part of first number
 *    hi2         I: hi part of second number
 *    lo2         I: lo part of second number
 *
 * Function:
 *    Multiply two 32 bit integers (DPF). The result is divided by 2^31
 *
 *    L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1
 *
 * Returns:
 *    32 bit result
 */
Word32 D_UTIL_mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
{
   Word32 L_32;

   L_32 = hi1 * hi2;
   L_32 += (hi1 * lo2) >> 15;
   L_32 += (lo1 * hi2) >> 15;

   return(L_32 << 1);
}

/*
 * D_UTIL_saturate
 *
 * Parameters:
 *    inp        I: 32-bit number
 *
 * Function:
 *    Saturation to 16-bit number
 *
 * Returns:
 *    16-bit number
 */
Word16 D_UTIL_saturate(Word32 inp)
{
  Word16 out;
  if ((inp < MAX_16) & (inp > MIN_16))
  {
     out = (Word16)inp;
  }
  else
  {
     if (inp > 0)
     {
        out = MAX_16;
     }
     else
     {
        out = MIN_16;
     }
  }

  return(out);
}

/*
 * D_UTIL_signal_up_scale
 *
 * Parameters:
 *    x         I/O: signal to scale
 *    lg          I: size of x[]
 *    exp         I: exponent: x = round(x << exp)
 *
 * Function:
 *    Scale signal up to get maximum of dynamic.
 *
 * Returns:
 *    32 bit result
 */
void D_UTIL_signal_up_scale(Word16 x[], Word16 lg, Word16 exp)
{
    Word32 i, tmp;

    for (i = 0; i < lg; i++)
    {
       tmp = x[i] << exp;
       x[i] = D_UTIL_saturate(tmp);
    }

    return;
}


/*
 * D_UTIL_signal_down_scale
 *
 * Parameters:
 *    x         I/O: signal to scale
 *    lg          I: size of x[]
 *    exp         I: exponent: x = round(x << exp)
 *
 * Function:
 *    Scale signal up to get maximum of dynamic.
 *
 * Returns:
 *    32 bit result
 */
void D_UTIL_signal_down_scale(Word16 x[], Word16 lg, Word16 exp)
{
   Word32 i, tmp;

   for(i = 0; i < lg; i++)
   {
      tmp = x[i] << 16;
      tmp = tmp >> exp;
      x[i] = (Word16)((tmp + 0x8000) >> 16);
   }

   return;
}


/*
 * D_UTIL_deemph_32
 *
 * Parameters:
 *    x_hi           I: input signal (bit31..16)
 *    x_lo           I: input signal (bit15..4)
 *    y              O: output signal (x16)
 *    mu             I: (Q15) deemphasis factor
 *    L              I: vector size
 *    mem          I/O: memory (y[-1])
 *
 * Function:
 *    Filtering through 1/(1-mu z^-1)
 *
 * Returns:
 *    void
 */
static void D_UTIL_deemph_32(Word16 x_hi[], Word16 x_lo[], Word16 y[],
                             Word16 mu, Word16 L, Word16 *mem)
{
   Word32 i, fac;
   Word32 tmp;

   fac = mu >> 1;   /* Q15 --> Q14 */

   /* L_tmp = hi<<16 + lo<<4 */
   tmp = (x_hi[0] << 12) + x_lo[0];
   tmp = (tmp << 6) + (*mem * fac);
   tmp = (tmp + 0x2000) >> 14;
   y[0] = D_UTIL_saturate(tmp);

   for(i = 1; i < L; i++)
   {
      tmp = (x_hi[i] << 12) + x_lo[i];
      tmp = (tmp << 6) + (y[i - 1] * fac);
      tmp = (tmp + 0x2000) >> 14;
      y[i] = D_UTIL_saturate(tmp);
   }

   *mem = y[L - 1];

   return;
}


/*
 * D_UTIL_synthesis_32
 *
 * Parameters:
 *    a              I: LP filter coefficients
 *    m              I: order of LP filter
 *    exc            I: excitation
 *    Qnew           I: exc scaling = 0(min) to 8(max)
 *    sig_hi         O: synthesis high
 *    sig_lo         O: synthesis low
 *    lg             I: size of filtering
 *
 * Function:
 *    Perform the synthesis filtering 1/A(z).
 *
 * Returns:
 *    void
 */
static void D_UTIL_synthesis_32(Word16 a[], Word16 m, Word16 exc[],
                                Word16 Qnew, Word16 sig_hi[], Word16 sig_lo[],
                                Word16 lg)
{
   Word32 i, j, a0;
   Word32 tmp, tmp2;

   a0 = a[0] >> (4 + Qnew);   /* input / 16 and >>Qnew */

   /* Do the filtering. */
   for(i = 0; i < lg; i++)
   {
      tmp = 0;

      for(j = 1; j <= m; j++)
      {
         tmp -= sig_lo[i - j] * a[j];
      }

      tmp = tmp >> (15 - 4);   /* -4 : sig_lo[i] << 4 */

      tmp2 = exc[i] * a0;

      for(j = 1; j <= m; j++)
      {
         tmp2 -= sig_hi[i - j] * a[j];
      }

      tmp += tmp2 << 1;

      /* sig_hi = bit16 to bit31 of synthesis */
      sig_hi[i] = (Word16)(tmp >> 13);

      /* sig_lo = bit4 to bit15 of synthesis */
      sig_lo[i] = (Word16)((tmp  >> 1) - (sig_hi[i] * 4096));
   }

   return;
}


/*
 * D_UTIL_hp50_12k8
 *
 * Parameters:
 *    signal       I/O: signal
 *    lg             I: lenght of signal
 *    mem          I/O: filter memory [6]
 *
 * Function:
 *    2nd order high pass filter with cut off frequency at 50 Hz.
 *
 *    Algorithm:
 *
 *    y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
 *                     + a[1]*y[i-1] + a[2]*y[i-2];
 *
 *    b[3] = {0.989501953f, -1.979003906f, 0.989501953f};
 *    a[3] = {1.000000000F,  1.978881836f,-0.966308594f};
 *
 *
 * Returns:
 *    void
 */
static void D_UTIL_hp50_12k8(Word16 signal[], Word16 lg, Word16 mem[])
{
   Word32 i, L_tmp;
   Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;

   y2_hi = mem[0];
   y2_lo = mem[1];
   y1_hi = mem[2];
   y1_lo = mem[3];
   x0 = mem[4];
   x1 = mem[5];

   for(i = 0; i < lg; i++)
   {
      x2 = x1;
      x1 = x0;
      x0 = signal[i];

      /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2]  */
      /* + a[1]*y[i-1] + a[2] * y[i-2];  */
      L_tmp = 8192L;   /* rounding to maximise precision */
      L_tmp = L_tmp + (y1_lo * 16211);
      L_tmp = L_tmp + (y2_lo * (-8021));
      L_tmp = L_tmp >> 14;
      L_tmp = L_tmp + (y1_hi * 32422);
      L_tmp = L_tmp + (y2_hi * (-16042));
      L_tmp = L_tmp + (x0 * 8106);
      L_tmp = L_tmp + (x1 * (-16212));
      L_tmp = L_tmp + (x2 * 8106);
      L_tmp = L_tmp << 2;  /* coeff Q11 --> Q14 */
      y2_hi = y1_hi;
      y2_lo = y1_lo;
      D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);
      L_tmp = (L_tmp + 0x4000) >> 15;   /* coeff Q14 --> Q15 with saturation */
      signal[i] = D_UTIL_saturate(L_tmp);

   }
   mem[0] = y2_hi;
   mem[1] = y2_lo;
   mem[2] = y1_hi;
   mem[3] = y1_lo;
   mem[4] = x0;
   mem[5] = x1;

   return;
}


/*
 * D_UTIL_interpol
 *
 * Parameters:
 *    x           I: input vector
 *    fir         I: filter coefficient
 *    frac        I: fraction (0..resol)
 *    up_samp     I: resolution
 *    nb_coef     I: number of coefficients
 *
 * Function:
 *    Fractional interpolation of signal at position (frac/up_samp)
 *
 * Returns:
 *    result of interpolation
 */
Word16 D_UTIL_interpol(Word16 *x, Word16 const *fir, Word16 frac,
                       Word16 resol, Word16 nb_coef)
{
   Word32 i, k;
   Word32 sum;

   x = x - nb_coef + 1;
   sum = 0L;

   for(i = 0, k = ((resol - 1) - frac); i < 2 * nb_coef; i++,
      k = (Word16)(k + resol))
   {
      sum = sum + (x[i] * fir[k]);
   }

   if((sum < 536846336) & (sum > -536879104))
   {
      sum = (sum + 0x2000) >> 14;
   }
   else if(sum > 536846336)
   {
      sum = 32767;
   }
   else
   {
      sum = -32768;
   }

   return((Word16)sum);   /* saturation can occur here */
}


/*
 * D_UTIL_up_samp
 *
 * Parameters:
 *    res_d          I: signal to upsampling
 *    res_u          O: upsampled output
 *    L_frame        I: length of output
 *
 * Function:
 *    Upsampling
 *
 * Returns:
 *    void
 */
static void D_UTIL_up_samp(Word16 *sig_d, Word16 *sig_u, Word16 L_frame)
{
   Word32 pos, i, j;
   Word16 frac;

   pos = 0;   /* position with 1/5 resolution */

   for(j = 0; j < L_frame; j++)
   {
      i = (pos * INV_FAC5) >> 15;   /* integer part = pos * 1/5 */
      frac = (Word16)(pos - ((i << 2) + i));   /* frac = pos - (pos/5)*5   */
      sig_u[j] = D_UTIL_interpol(&sig_d[i], D_ROM_fir_up, frac, FAC5, NB_COEF_UP);
      pos = pos + FAC4;   /* position + 4/5 */
   }

   return;
}


/*
 * D_UTIL_oversamp_16k
 *
 * Parameters:
 *    sig12k8        I: signal to oversampling
 *    lg             I: length of input
 *    sig16k         O: oversampled signal
 *    mem          I/O: memory (2*12)
 *
 * Function:
 *    Oversampling from 12.8kHz to 16kHz
 *
 * Returns:
 *    void
 */
static void D_UTIL_oversamp_16k(Word16 sig12k8[], Word16 lg, Word16 sig16k[],
                                Word16 mem[])
{
   Word16 lg_up;
   Word16 signal[L_SUBFR + (2 * NB_COEF_UP)];

   memcpy(signal, mem, (2 * NB_COEF_UP) * sizeof(Word16));
   memcpy(signal + (2 * NB_COEF_UP), sig12k8, lg * sizeof(Word16));
   lg_up = (Word16)(((lg * UP_FAC) >> 15) << 1);
   D_UTIL_up_samp(signal + NB_COEF_UP, sig16k, lg_up);
   memcpy(mem, signal + lg, (2 * NB_COEF_UP) * sizeof(Word16));

   return;
}


/*
 * D_UTIL_hp400_12k8
 *
 * Parameters:
 *    signal       I/O: signal
 *    lg             I: lenght of signal
 *    mem          I/O: filter memory [6]
 *
 * Function:
 *    2nd order high pass filter with cut off frequency at 400 Hz.
 *
 *    Algorithm:
 *
 *    y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
 *                     + a[1]*y[i-1] + a[2]*y[i-2];
 *
 *    b[3] = {0.893554687, -1.787109375,  0.893554687};
 *    a[3] = {1.000000000,  1.787109375, -0.864257812};
 *
 *
 * Returns:
 *    void
 */
void D_UTIL_hp400_12k8(Word16 signal[], Word16 lg, Word16 mem[])
{

   Word32 i, L_tmp;
   Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;

   y2_hi = mem[0];
   y2_lo = mem[1];
   y1_hi = mem[2];
   y1_lo = mem[3];
   x0 = mem[4];
   x1 = mem[5];

   for(i = 0; i < lg; i++)
   {
      x2 = x1;
      x1 = x0;

⌨️ 快捷键说明

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