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

📄 enc_main.c

📁 Linux 影片撥放解碼 Video DVD
💻 C
📖 第 1 页 / 共 3 页
字号:
             */
            i = T0 - T0_min;
            index = (Word16)(i * 4 + T0_frac);

            E_MAIN_parm_store(index, &prms);
         }
      }

      /*
       * Gain clipping test to avoid unstable synthesis on frame erasure
       */

      clip_gain = E_GAIN_clip_test(st->mem_gp_clip);

      /*
       * - find unity gain pitch excitation (adaptive codebook entry)
       *   with fractional interpolation.
       * - find filtered pitch exc. y1[]=exc[] convolved with h1[])
       * - compute pitch gain1
       */

      /* find pitch exitation */
      E_GAIN_adaptive_codebook_excitation(&exc[i_subfr], (Word16)T0, T0_frac, L_SUBFR + 1);

      if(*mode > MODE_9k)
      {

         E_UTIL_convolve(&exc[i_subfr], st->mem_q, h1, y1);

         gain1 = E_ACELP_xy1_corr(xn, y1, g_coeff);

         /* clip gain if necessary to avoid problem at decoder */
        if (clip_gain && (gain1 > 0.95))
        {
           gain1 = 0.95f;
        }

         /* find energy of new target xn2[] */
         E_ACELP_codebook_target_update(xn, dn, y1, gain1);
      }
      else
      {
         gain1 = 0.0F;
      }

      /*
       * - find pitch excitation filtered by 1st order LP filter.
       * - find filtered pitch exc. y2[]=exc[] convolved with h1[])
       * - compute pitch gain2
       */

      /* find pitch excitation with lp filter */
      for (i = 0; i < L_SUBFR; i++)
      {
         l_tmp = 5898 * exc[i - 1 + i_subfr];
         l_tmp += 20972 * exc[i + i_subfr];
         l_tmp += 5898 * exc[i + 1 + i_subfr];
         s_code[i] = (Word16)((l_tmp + 0x4000) >> 15);
      }

      E_UTIL_convolve(s_code, st->mem_q, h1, y2);

      gain2 = E_ACELP_xy1_corr(xn, y2, g_coeff2);

      /* clip gain if necessary to avoid problem at decoder */
      if (clip_gain && (gain2 > 0.95))
      {
         gain2 = 0.95F;
      }

      /* find energy of new target xn2[] */
      E_ACELP_codebook_target_update(xn, xn2, y2, gain2);

      /*
       * use the best prediction (minimise quadratic error).
       */

      select = 0;

      if (*mode > MODE_9k)
      {
         f_tmp = 0.0;
         for (i = 0; i < L_SUBFR; i++)
         {
            f_tmp += dn[i] * dn[i];
            f_tmp -= xn2[i] * xn2[i];
         }

         if (f_tmp < 0.1)
         {
            select = 1;
         }

         E_MAIN_parm_store(select, &prms);
      }

      if (select == 0)
      {
         /* use the lp filter for pitch excitation prediction */
         memcpy(&exc[i_subfr], s_code, L_SUBFR * sizeof(Word16));
         memcpy(y1, y2, L_SUBFR * sizeof(Float32));
         gain_pit = gain2;
         g_coeff[0] = g_coeff2[0];
         g_coeff[1] = g_coeff2[1];
      }
      else
      {
         /* no filter used for pitch excitation prediction */
         gain_pit = gain1;
         memcpy(xn2, dn, L_SUBFR * sizeof(Float32));        /* target vector for codebook search */
      }


      /*
       * - update target vector for codebook search
       * - scaling of cn[] to limit dynamic at 12 bits
       */
      for (i = 0; i < L_SUBFR; i ++)
      {
         cn[i] = (Float32)(cn[i] - gain_pit * exc[i_subfr + i] * pow(2, Q_new));
      }

      /*
       * - include fixed-gain pitch contribution into impulse resp. h1[]
       */
      f_tmp = 0.0F;
      E_UTIL_f_preemph(h1, (Float32)(st->mem_tilt_code / 32768.0), L_SUBFR, &f_tmp);

      if (T0_frac > 2)
      {
         T0++;
      }

      E_GAIN_f_pitch_sharpening(h1, T0);

      /*
       * - Correlation between target xn2[] and impulse response h1[]
       * - Innovative codebook search
       */
      E_ACELP_xh_corr(xn2, dn, h1);

      switch(*mode)
      {
      case MODE_7k:
         E_ACELP_2t(dn, cn, h1, s_code, y2, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         break;
      case MODE_9k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 20, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);

         break;
      case MODE_12k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 36, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);

         break;
      case MODE_14k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 44, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);

         break;
      case MODE_16k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 52, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);

         break;
      case MODE_18k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 64, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);
         E_MAIN_parm_store((Word16)indice[4], &prms);
         E_MAIN_parm_store((Word16)indice[5], &prms);
         E_MAIN_parm_store((Word16)indice[6], &prms);
         E_MAIN_parm_store((Word16)indice[7], &prms);

         break;
      case MODE_20k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 72, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);
         E_MAIN_parm_store((Word16)indice[4], &prms);
         E_MAIN_parm_store((Word16)indice[5], &prms);
         E_MAIN_parm_store((Word16)indice[6], &prms);
         E_MAIN_parm_store((Word16)indice[7], &prms);

         break;
      case MODE_23k:
      case MODE_24k:
         E_ACELP_4t(dn, cn, h1, s_code, y2, 88, *mode, indice);
         E_MAIN_parm_store((Word16)indice[0], &prms);
         E_MAIN_parm_store((Word16)indice[1], &prms);
         E_MAIN_parm_store((Word16)indice[2], &prms);
         E_MAIN_parm_store((Word16)indice[3], &prms);
         E_MAIN_parm_store((Word16)indice[4], &prms);
         E_MAIN_parm_store((Word16)indice[5], &prms);
         E_MAIN_parm_store((Word16)indice[6], &prms);
         E_MAIN_parm_store((Word16)indice[7], &prms);
         break;
      default:
         return -1;
      }

      /*
       * - Add the fixed-gain pitch contribution to code[].
       */
      s_tmp = 0;
      E_UTIL_preemph(s_code, st->mem_tilt_code, L_SUBFR, &s_tmp);

      E_GAIN_pitch_sharpening(s_code, (Word16)T0);

      E_ACELP_xy2_corr(xn, y1, y2, g_coeff);

      /*
       *  - Compute the fixed codebook gain
       *  - quantize fixed codebook gain
       */
      if (*mode <= MODE_9k)
      {
          index = (Word16)E_ACELP_gains_quantise(s_code, 6, gain_pit,
             &s_gain_pit, &L_gain_code, g_coeff, clip_gain, st->mem_gain_q);

         E_MAIN_parm_store(index, &prms);
      }
      else
      {
         index = (Word16)E_ACELP_gains_quantise(s_code, 7, gain_pit,
            &s_gain_pit, &L_gain_code, g_coeff, clip_gain, st->mem_gain_q);
         E_MAIN_parm_store(index, &prms);
      }

      /* find best scaling to perform on excitation (Q_new) */
      s_tmp = st->mem_subfr_q[0];
      for (i = 1; i < 4; i++)
      {
         if (st->mem_subfr_q[i] < s_tmp)
         {
            s_tmp = st->mem_subfr_q[i];
         }
      }

      /* limit scaling (Q_new) to Q_MAX */
      if (s_tmp > Q_MAX)
      {
         s_tmp = Q_MAX;
      }

      Q_new = 0;
      l_tmp = L_gain_code;                 /* L_gain_code in Q16 */

      while ((l_tmp < 0x08000000L) && (Q_new < s_tmp))
      {
         l_tmp = (l_tmp << 1);
         Q_new = Q_new + 1;
      }

      if (l_tmp < 0x7FFF7FFF)
      {
         /* scaled gain_code with Qnew */
         gain_code = (Word16)((l_tmp + 0x8000) >> 16);
      }
      else
      {
         gain_code = 32767;
      }

      if (Q_new > st->mem_q)
      {
         E_UTIL_signal_up_scale(exc + i_subfr - (PIT_MAX + L_INTERPOL),
            (Word16)(Q_new - st->mem_q));
      }
      else
      {
         E_UTIL_signal_down_scale(exc + i_subfr - (PIT_MAX + L_INTERPOL),
            PIT_MAX + L_INTERPOL + L_SUBFR, (Word16)(st->mem_q - Q_new));
      }
      st->mem_q = (Word16)Q_new;

      /* test quantized gain of pitch for pitch clipping algorithm */
      E_GAIN_clip_pit_test((Float32)(s_gain_pit * pow(2, -14)),
         st->mem_gp_clip);

      /*
       * Update parameters for the next subframe.
       * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
       */

      /* find voice factor in Q15 (1=voiced, -1=unvoiced) */
      memcpy(exc2, &exc[i_subfr], L_SUBFR * sizeof(Word16));

      E_UTIL_signal_down_scale(exc2, L_SUBFR, 3);

      voice_fac = E_GAIN_voice_factor(exc2, -3, s_gain_pit, s_code, gain_code);

      /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
      st->mem_tilt_code = (Word16)((voice_fac >> 2) + 8192);

      /*
       * - Update filter's memory "mem_w0" for finding the
       *   target vector in the next subframe.
       * - Find the total excitation
       * - Find synthesis speech to update mem_syn[].
       */
      memcpy(exc2, &exc[i_subfr], L_SUBFR * sizeof(Word16));

      st->mem_w0 = (Float32)((xn[L_SUBFR - 1] -
         ((s_gain_pit / 16384.0F) * y1[L_SUBFR - 1])) -
         (gain_code * pow(2, -st->mem_q) * y2[L_SUBFR - 1]));

      if (*mode == MODE_24k)
      {
         Q_new = -st->mem_q;

         for (i = 0; i < L_SUBFR; i++)
         {
            f_exc2[i_subfr + i] = (Float32)(exc[i_subfr + i] * pow(2, Q_new) * (s_gain_pit / 16384.0F));
         }
      }

      s_max = 1;
      for (i = 0; i < L_SUBFR; i++)
      {
         /* code in Q9, gain_pit in Q14 */
         l_tmp = gain_code * s_code[i];
         l_tmp = l_tmp << 5;
         l_tmp += exc[i + i_subfr] * s_gain_pit; /* gain_pit Q14 */
         l_tmp = (l_tmp + 0x2000) >> 14;

         if ((l_tmp > MIN_16) & (l_tmp < 32768))
         {
            exc[i + i_subfr] = (Word16)l_tmp;
            s_tmp = (Word16)abs(l_tmp);

            if (s_tmp > s_max)
            {
               s_max = s_tmp;
            }
         }
         else if (l_tmp > MAX_16)
         {
            exc[i + i_subfr] = MAX_16;
            s_max = MAX_16;
         }
         else
         {
            exc[i + i_subfr] = MIN_16;
            s_max = MAX_16;
         }
      }

      /* tmp = scaling possible according to max value of excitation */
      s_tmp = (Word16)((E_UTIL_norm_s(s_max) + st->mem_q) - 1);

      st->mem_subfr_q[3] = st->mem_subfr_q[2];
      st->mem_subfr_q[2] = st->mem_subfr_q[1];
      st->mem_subfr_q[1] = st->mem_subfr_q[0];
      st->mem_subfr_q[0] = s_tmp;

      Q_new = -st->mem_q;

      for (i = 0; i < L_SUBFR; i++)
      {
         f_exc[i + i_subfr] = (Float32)(exc[i + i_subfr] * pow(2, Q_new));
      }

      E_UTIL_synthesis(p_Aq, &f_exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);

      if(*mode >= MODE_24k)
      {
         /*
          * noise enhancer
          * --------------
          * - Enhance excitation on noise. (modify gain of code)
          *   If signal is noisy and LPC filter is stable, move gain
          *   of code 1.5 dB toward gain of code threshold.
          *   This decrease by 3 dB noise energy variation.
          */

         /* 1=unvoiced, 0=voiced */
         f_tmp = (Float32)(0.5 * (1.0 - (voice_fac / 32768.0)));
         fac = stab_fac * f_tmp;
         f_tmp = (Float32)(gain_code * pow(2, -st->mem_q));

         if(f_tmp < st->mem_gc_threshold)
         {
            f_tmp = (Float32)(f_tmp * 1.19);

            if(f_tmp > st->mem_gc_threshold)
            {
               f_tmp = st->mem_gc_threshold;
            }
         }
         else
         {
            f_tmp = (Float32)(f_tmp / 1.19);

            if(f_tmp < st->mem_gc_threshold)
            {
               f_tmp = st->mem_gc_threshold;
            }
         }

         st->mem_gc_threshold = f_tmp;
         f_tmp = (Float32)(((fac * f_tmp) + ((1.0 - fac) *
            (gain_code * pow(2, -st->mem_q)))) * 0.001953125F);

         for(i = 0; i < L_SUBFR; i++)
         {
            f_code[i] = (Float32)(s_code[i] * f_tmp);
         }

         /*
          * pitch enhancer
          * --------------
          * - Enhance excitation on voice. (HP filtering of code)
          *   On voiced signal, filtering of code by a smooth fir HP
          *   filter to decrease energy of code in low frequency.
          */

         /* 0.25=voiced, 0=unvoiced */
         f_tmp = (Float32)(0.125F * (1.0F + (voice_fac / 32768.0)));

         f_exc2[i_subfr] += f_code[0] - (f_tmp * f_code[1]);

         for(i = 1; i < L_SUBFR - 1; i++)
         {
            f_exc2[i + i_subfr] +=
               f_code[i] - (f_tmp * f_code[i - 1]) - (f_tmp * f_code[i + 1]);
         }

         f_exc2[i_subfr + L_SUBFR - 1] +=
            f_code[L_SUBFR - 1] - (f_tmp * f_code[L_SUBFR - 2]);

         corr_gain = (Word16)E_UTIL_enc_synthesis(p_Aq, &f_exc2[i_subfr],
            &f_speech16k[i_subfr * 5 /4], st);

         E_MAIN_parm_store(corr_gain, &prms);
      }

      p_A += (M + 1);
      p_Aq += (M + 1);
  }   /* end of subframe loop */

   /*
    * Update signal for next frame.
    * -> save past of speech[], wsp[] and exc[].
    */

   memmove(st->mem_speech, &st->mem_speech[L_FRAME], (L_TOTAL - L_FRAME) * sizeof(Float32));
   memmove(st->mem_wsp, &st->mem_wsp[L_FRAME / OPL_DECIM], (PIT_MAX / OPL_DECIM) * sizeof(Float32));
   memmove(st->mem_exc, &st->mem_exc[L_FRAME], (PIT_MAX + L_INTERPOL) * sizeof(Word16));

   return 0;
}

⌨️ 快捷键说明

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