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

📄 dec_util.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
      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 + (y1_lo * 29280);
      L_tmp = L_tmp + (y2_lo * (-14160));
      L_tmp = (L_tmp >> 14);
      L_tmp = L_tmp + (y1_hi * 58560);
      L_tmp = L_tmp + (y2_hi * (-28320));
      L_tmp = L_tmp + (x0 * 1830);
      L_tmp = L_tmp + (x1 * (-3660));
      L_tmp = L_tmp + (x2 * 1830);
      L_tmp = (L_tmp << 1);   /* coeff Q12 --> Q13 */
      y2_hi = y1_hi;
      y2_lo = y1_lo;
      D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);

      /* signal is divided by 16 to avoid overflow in energy computation */
      signal[i] = (Word16)((L_tmp + 0x8000) >> 16);
   }
   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_synthesis
 *
 * Parameters:
 *    a              I: LP filter coefficients
 *    m              I: order of LP filter
 *    x              I: input signal
 *    y              O: output signal
 *    lg             I: size of filtering
 *    mem          I/O: initial filter states
 *    update_m       I: update memory flag
 *
 * Function:
 *    Perform the synthesis filtering 1/A(z).
 *
 * Returns:
 *    void
 */
static void D_UTIL_synthesis(Word16 a[], Word16 m, Word16 x[], Word16 y[],
                             Word16 lg, Word16 mem[], Word16 update)
{
   Word32 i, j, tmp;
   Word16 y_buf[L_SUBFR16k + M16k], a0;
   Word16 *yy;

   yy = &y_buf[m];

   /* copy initial filter states into synthesis buffer */
   memcpy(y_buf, mem, m * sizeof(Word16));

   a0 = (Word16)(a[0] >> 1);   /* input / 2 */

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

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

      y[i] = yy[i] = (Word16)((tmp + 0x800) >> 12);
   }

   /* Update memory if required */
   if(update)
   {
      memcpy(mem, &yy[lg - m], m * sizeof(Word16));
   }

   return;
}


/*
 * D_UTIL_bp_6k_7k
 *
 * Parameters:
 *    signal       I/O: signal
 *    lg             I: lenght of signal
 *    mem          I/O: filter memory [4]
 *
 * Function:
 *    15th order band pass 6kHz to 7kHz FIR filter.
 *
 * Returns:
 *    void
 */
void D_UTIL_bp_6k_7k(Word16 signal[], Word16 lg, Word16 mem[])
{
   Word32 x[L_SUBFR16k + (L_FIR - 1)];
   Word32 i, j, tmp;

   for(i = 0; i < (L_FIR - 1); i++)
   {
      x[i] = (Word16)mem[i];   /* gain of filter = 4 */
   }

   for(i = 0; i < lg; i++)
   {
      x[i + L_FIR - 1] = signal[i] >> 2;   /* gain of filter = 4 */
   }

   for(i = 0; i < lg; i++)
   {
      tmp = 0;

      for(j = 0; j < L_FIR; j++)
      {
         tmp += x[i + j] * D_ROM_fir_6k_7k[j];
      }

      signal[i] = (Word16)((tmp + 0x4000) >> 15);
   }

   for(i = 0; i < (L_FIR - 1); i++)
   {
      mem[i] = (Word16)x[lg + i];   /* gain of filter = 4 */
   }

   return;
}


/*
 * D_UTIL_hp_7k
 *
 * Parameters:
 *    signal          I/O: ISF vector
 *    lg                I: length of signal
 *    mem             I/O: memory (30)
 *
 * Function:
 *    15th order high pass 7kHz FIR filter
 *
 * Returns:
 *    void
 */
static void D_UTIL_hp_7k(Word16 signal[], Word16 lg, Word16 mem[])
{

   Word32 i, j, tmp;
   Word16 x[L_SUBFR16k + (L_FIR - 1)];

   memcpy(x, mem, (L_FIR - 1) * sizeof(Word16));
   memcpy(&x[L_FIR - 1], signal, lg * sizeof(Word16));

   for(i = 0; i < lg; i++)
   {
      tmp = 0;

      for(j = 0; j < L_FIR; j++)
      {
         tmp += x[i + j] * D_ROM_fir_7k[j];
      }

      signal[i] = (Word16)((tmp + 0x4000) >> 15);
   }

   memcpy(mem, x + lg, (L_FIR - 1) * sizeof(Word16));

   return;
}


/*
 * D_UTIL_Dec_synthesis
 *
 * Parameters:
 *    Aq             I: quantized Az
 *    exc            I: excitation at 12kHz
 *    Q_new          I: scaling performed on exc
 *    synth16k       O: 16kHz synthesis signal
 *    prms           I: parameters
 *    HfIsf        I/O: High frequency ISF:s
 *    mode           I: codec mode
 *    newDTXState    I: dtx state
 *    bfi            I: bad frame indicator
 *    st           I/O: State structure
 *
 * Function:
 *    Synthesis of signal at 16kHz with HF extension.
 *
 * Returns:
 *    void
 */
void D_UTIL_dec_synthesis(Word16 Aq[], Word16 exc[], Word16 Q_new,
                          Word16 synth16k[], Word16 prms, Word16 HfIsf[],
                          Word16 mode, Word16 newDTXState, Word16 bfi,
                          Decoder_State *st)
{
   Word32 tmp, i;
   Word16 exp;
   Word16 ener, exp_ener;
   Word32 fac;
   Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
   Word16 synth[L_SUBFR];
   Word16 HF[L_SUBFR16k];   /* High Frequency vector      */
   Word16 Ap[M16k + 1];
   Word16 HfA[M16k + 1];
   Word16 HF_corr_gain;
   Word16 HF_gain_ind;
   Word32 gain1, gain2;
   Word16 weight1, weight2;

   /*
    * Speech synthesis
    *
    * - Find synthesis speech corresponding to exc2[].
    * - Perform fixed deemphasis and hp 50hz filtering.
    * - Oversampling from 12.8kHz to 16kHz.
    */
   memcpy(synth_hi, st->mem_syn_hi, M * sizeof(Word16));
   memcpy(synth_lo, st->mem_syn_lo, M * sizeof(Word16));
   D_UTIL_synthesis_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
   memcpy(st->mem_syn_hi, synth_hi + L_SUBFR, M * sizeof(Word16));
   memcpy(st->mem_syn_lo, synth_lo + L_SUBFR, M * sizeof(Word16));
   D_UTIL_deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR,
      &(st->mem_deemph));
   D_UTIL_hp50_12k8(synth, L_SUBFR, st->mem_sig_out);
   D_UTIL_oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp);

   /*
    * HF noise synthesis
    *
    * - Generate HF noise between 5.5 and 7.5 kHz.
    * - Set energy of noise according to synthesis tilt.
    *     tilt > 0.8 ==> - 14 dB (voiced)
    *     tilt   0.5 ==> - 6 dB  (voiced or noise)
    *     tilt < 0.0 ==>   0 dB  (noise)
    */

   /* generate white noise vector */
   for(i = 0; i < L_SUBFR16k; i++)
   {
      HF[i] = (Word16)(D_UTIL_random(&(st->mem_seed2)) >> 3);
   }

   /* energy of excitation */
   D_UTIL_signal_down_scale(exc, L_SUBFR, 3);
   Q_new = (Word16)(Q_new - 3);
   ener = (Word16)(D_UTIL_dot_product12(exc, exc, L_SUBFR, &exp_ener) >> 16);
   exp_ener = (Word16)(exp_ener - (Q_new << 1));

   /* set energy of white noise to energy of excitation */
   tmp = (Word16)(D_UTIL_dot_product12(HF, HF, L_SUBFR16k, &exp) >> 16);

   if(tmp > ener)
   {
      tmp = tmp >> 1;   /* Be sure tmp < ener */
      exp = (Word16)(exp + 1);
   }

   tmp = (tmp << 15) / ener;

   if(tmp > 32767)
   {
      tmp = 32767;
   }

   tmp = tmp << 16;   /* result is normalized */
   exp = (Word16)(exp - exp_ener);
   D_UTIL_normalised_inverse_sqrt(&tmp, &exp);

   /* L_tmp x 2, L_tmp in Q31 */
   /* tmp = 2 x sqrt(ener_exc/ener_hf) */
   if(exp >= 0)
   {
      tmp = tmp >> (15 - exp);
   }
   else
   {
      tmp = tmp >> (-exp);
      tmp = tmp >> 15;
   }

   /* saturation */
   if(tmp > 0x7FFF)
   {
      tmp = 0x7FFF;
   }

   for(i = 0; i < L_SUBFR16k; i++)
   {
      HF[i] = (Word16)((HF[i] * tmp) >> 15);
   }

   /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
   D_UTIL_hp400_12k8(synth, L_SUBFR, st->mem_hp400);
   tmp = 0L;

   for(i = 0; i < L_SUBFR; i++)
   {
      tmp = tmp + (synth[i] * synth[i]);
   }

   tmp = (tmp << 1) + 1;
   exp = D_UTIL_norm_l(tmp);
   ener = (Word16)((tmp << exp) >> 16);   /* ener = r[0] */
   tmp = 0L;

   for(i = 1; i < L_SUBFR; i++)
   {
      tmp = tmp + (synth[i] * synth[i - 1]);
   }

   tmp = (tmp << 1) + 1;
   tmp = (tmp << exp) >> 16;   /* tmp = r[1] */

   if(tmp > 0)
   {
      fac = ((tmp << 15) / ener);

      if(fac > 32767)
      {
         fac = 32767;
      }
   }
   else
   {
      fac = 0;
   }

   /* modify energy of white noise according to synthesis tilt */
   gain1 = (32767 - fac);
   gain2 = ((32767 - fac) * 20480) >> 15;
   gain2 = (gain2 << 1);

   if(gain2 > 32767)
      gain2 = 32767;

   if(st->mem_vad_hist > 0)
   {
      weight1 = 0;
      weight2 = 32767;
   }
   else
   {
      weight1 = 32767;
      weight2 = 0;
   }

   tmp = (weight1 * gain1) >> 15;
   tmp = tmp + ((weight2 * gain2) >> 15);

   if(tmp != 0)
   {
      tmp = tmp + 1;
   }

   if(tmp < 3277)
   {
      tmp = 3277;   /* 0.1 in Q15 */
   }

   if((mode == MODE_24k) & (bfi == 0))
   {
      /* HF correction gain */
      HF_gain_ind = prms;
      HF_corr_gain = D_ROM_hp_gain[HF_gain_ind];

      /* HF gain */
      for(i = 0; i < L_SUBFR16k; i++)
      {
         HF[i] = (Word16)(((HF[i] * HF_corr_gain) >> 15) << 1);
      }
   }
   else
   {
      for(i = 0; i < L_SUBFR16k; i++)
      {
         HF[i] = (Word16)((HF[i] * tmp) >> 15);
      }
   }

   if((mode <= MODE_7k) & (newDTXState == SPEECH))
   {
      D_LPC_isf_extrapolation(HfIsf);
      D_LPC_isp_a_conversion(HfIsf, HfA, M16k);
      D_LPC_a_weight(HfA, Ap, 29491, M16k);   /* fac=0.9 */
      D_UTIL_synthesis(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
   }
   else
   {
      /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
      D_LPC_a_weight(Aq, Ap, 19661, M);   /* fac=0.6 */
      D_UTIL_synthesis(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1);
   }

   /* noise High Pass filtering (1ms of delay) */
   D_UTIL_bp_6k_7k(HF, L_SUBFR16k, st->mem_hf);

   if(mode == MODE_24k)
   {
      /* Low Pass filtering (7 kHz) */
      D_UTIL_hp_7k(HF, L_SUBFR16k, st->mem_hf3);
   }

   /* add filtered HF noise to speech synthesis */
   for(i = 0; i < L_SUBFR16k; i++)
   {
      tmp = (synth16k[i] + HF[i]);
      synth16k[i] = D_UTIL_saturate(tmp);
   }

   return;
}


/*
 * D_UTIL_preemph
 *
 * Parameters:
 *    x            I/O: signal
 *    mu             I: preemphasis factor
 *    lg             I: vector size
 *    mem          I/O: memory (x[-1])
 *
 * Function:
 *    Filtering through 1 - mu z^-1
 *
 *
 * Returns:
 *    void
 */
void D_UTIL_preemph(Word16 x[], Word16 mu, Word16 lg, Word16 *mem)
{
   Word32 i, L_tmp;
   Word16 temp;

   temp = x[lg - 1];

   for(i = lg - 1; i > 0; i--)
   {
      L_tmp = x[i] << 15;
      L_tmp = L_tmp - (x[i - 1] * mu);
      x[i] = (Word16)((L_tmp + 0x4000) >> 15);
   }

   L_tmp = x[0] << 15;
   L_tmp = L_tmp - (*mem * mu);
   x[0] = (Word16)((L_tmp + 0x4000) >> 15);
   *mem = temp;

   return;
}

⌨️ 快捷键说明

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