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

📄 dec_gain.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      }
      else
      {
         gain_in = 32767;
      }
      exp = exp - i;
      /*
       * g0 = sqrt(gain_in/gain_out)
       */
      s = (gain_out << 15) / gain_in;
      s = s << (7 - exp);   /* s = gain_out / gain_in */
      s = D_UTIL_inverse_sqrt(s);
      g0 = ((s << 9) + 0x8000) >> 16;
   }
   /* sig_out(n) = gain(n) sig_out(n) */
   for(i = 0; i < l_trm; i++)
   {
      s = (sig_out[i] * g0) >> 13;
      sig_out[i] = D_UTIL_saturate(s);
   }
   return;
}
/*
 * D_GAIN_insert_lag
 *
 * Parameters:
 *    array        I/O: pitch lag history
 *    n              I: history size
 *    x              I: lag value
 *
 * Function:
 *    Insert lag into correct location
 *
 * Returns:
 *    void
 */
static void D_GAIN_insert_lag(Word16 array[], Word32 n, Word16 x)
{
   Word32 i;
   for(i = n - 1; i >= 0; i--)  
   {
      if(x < array[i])
      {
         array[i + 1] = array[i];
      }
      else
      {
         break;
      }
   }
   array[i + 1] = x;
}
/*
 * D_GAIN_sort_lag
 *
 * Parameters:
 *    array        I/O: pitch lag history
 *    n              I: history size
 *
 * Function:
 *    Sorting of the lag history
 *
 * Returns:
 *    void
 */
static void D_GAIN_sort_lag(Word16 array[], Word16 n)
{
   Word32 i;
   for(i = 0; i < n; i++)
   {
      D_GAIN_insert_lag(array, i, array[i]);
   }
}
/*
 * D_GAIN_lag_concealment_init
 *
 * Parameters:
 *    lag_hist       O: pitch lag history
 *
 * Function:
 *    Initialise lag history to 64
 *
 * Returns:
 *    void
 */
void D_GAIN_lag_concealment_init(Word16 lag_hist[])
{
   Word32 i;
   for(i = 0; i < L_LTPHIST; i++)
   {
      lag_hist[i] = 64;
   }
}   
/*
 * D_GAIN_lag_concealment
 *
 * Parameters:
 *    gain_hist         I: gain history
 *    lag_hist          I: pitch lag history
 *    T0                O: current lag
 *    old_T0            I: previous lag
 *    seed            I/O: seed for random
 *    unusable_frame    I: lost frame
 *
 * Function:
 *    Concealment of LTP lags during bad frames
 *
 * Returns:
 *    void
 */
void D_GAIN_lag_concealment(Word16 gain_hist[], Word16 lag_hist[],
                            Word32 *T0, Word16 *old_T0, Word16 *seed,
                            Word16 unusable_frame)
{
   Word32 i, lagDif, tmp, tmp2, D2, meanLag = 0;
   Word16 lag_hist2[L_LTPHIST] = {0};
   Word16 maxLag, minLag, lastLag;
   Word16 minGain, lastGain, secLastGain;
   Word16 D;
   /*
    * Is lag index such that it can be aplied directly
    * or does it has to be subtituted
    */
   lastGain = gain_hist[4];
   secLastGain = gain_hist[3];
   lastLag = lag_hist[0];
   /* SMALLEST history lag */
   minLag = lag_hist[0];
   for(i = 1; i < L_LTPHIST; i++)
   {
      if(lag_hist[i] < minLag)
      {
         minLag = lag_hist[i];
      }
   }
   /* BIGGEST history lag */
   maxLag = lag_hist[0];
   for(i = 1; i < L_LTPHIST; i++)
   {
      if(lag_hist[i] > maxLag)
      {
         maxLag = lag_hist[i];
      }
   }
   /* SMALLEST history gain */
   minGain = gain_hist[0];
   for(i = 1; i < L_LTPHIST; i++)
   {
      if(gain_hist[i] < minGain)
      {
         minGain = gain_hist[i];
      }
   }
   /* Difference between MAX and MIN lag */
   lagDif = maxLag - minLag;
   if(unusable_frame != 0)
   {
      /*
       * LTP-lag for RX_SPEECH_LOST
       * Recognition of the LTP-history
       */
      if((minGain > 8192) & (lagDif < 10))
      {
         *T0 = *old_T0;
      }
      else if((lastGain > 8192) && (secLastGain > 8192))
      {
         *T0 = lag_hist[0];
      }
      else  
      {                                                         
         /* 
          * SORT
          * The sorting of the lag history
          */
         for(i = 0; i < L_LTPHIST; i++)
         {
            lag_hist2[i] = lag_hist[i];
         }
         D_GAIN_sort_lag(lag_hist2, 5);
         /*
          * Lag is weighted towards bigger lags
          * and random variation is added
          */
         lagDif = (lag_hist2[4] - lag_hist2[2]);
         if(lagDif > 40)
         {
            lagDif = 40;
         }
         D = D_UTIL_random(seed);   /* D={-1, ...,1} */
         /* D2={-lagDif/2..lagDif/2} */
         tmp = lagDif >> 1;
         D2 = (tmp * D) >> 15;
         tmp = (lag_hist2[2] + lag_hist2[3]) + lag_hist2[4];
         *T0 = ((tmp * ONE_PER_3) >> 15) + D2;
      }
      /* New lag is not allowed to be bigger or smaller than last lag values */
      if(*T0 > maxLag)
      {
         *T0 = maxLag;
      }
      if(*T0 < minLag)
      {
         *T0 = minLag;
      }
   }
   else
   {
      /*
       * LTP-lag for RX_BAD_FRAME
       * MEAN lag
       */
      meanLag = 0;
      for(i = 0; i < L_LTPHIST; i++)
      {
         meanLag = meanLag + lag_hist[i];
      }
      meanLag = (meanLag * ONE_PER_LTPHIST) >> 15;
      tmp = *T0 - maxLag;
      tmp2 = *T0 - lastLag;
      if((lagDif < 10) & (*T0 > (minLag - 5)) & (tmp < 5))
      {
         *T0 = *T0;
      }
      else if((lastGain > 8192) & (secLastGain > 8192) & ((tmp2 > - 10)
         & (tmp2 < 10)))
      {
         *T0 = *T0;
      }
      else if((minGain < 6554) & (lastGain == minGain) & ((*T0 > minLag)
         & (*T0 < maxLag)))
      {
         *T0 = *T0;
      }
      else if((lagDif < 70) & (*T0 > minLag) & (*T0 < maxLag))
      {
         *T0 = *T0;
      }
      else if((*T0 > meanLag) & (*T0 < maxLag))
      {
         *T0 = *T0;
      }
      else
      {
         if((minGain > 8192) & (lagDif < 10))
         {
            *T0 = lag_hist[0];
         }
         else if((lastGain > 8192) & (secLastGain > 8192))
         {
            *T0 = lag_hist[0];
         }
         else
         {                                                                  
            /*
             * SORT
             * The sorting of the lag history
             */
            for(i = 0; i < L_LTPHIST; i++)
            {
               lag_hist2[i] = lag_hist[i];
            }
            D_GAIN_sort_lag(lag_hist2, 5);
            /*
             * Lag is weighted towards bigger lags
             * and random variation is added
             */
            lagDif = lag_hist2[4] - lag_hist2[2];
            if(lagDif > 40)
            {
               lagDif = 40;
            }
            D = D_UTIL_random(seed);   /* D={-1,.., 1} */
            /* D2={-lagDif/2..lagDif/2} */
            tmp = lagDif >> 1;
            D2 = (tmp * D) >> 15;
            tmp = (lag_hist2[2] + lag_hist2[3]) + lag_hist2[4];
            *T0 = ((tmp * ONE_PER_3) >> 15) + D2;
         }
         /*
          * New lag is not allowed to be bigger or
          * smaller than last lag values
          */    
         if(*T0 > maxLag)
         {
            *T0 = maxLag;
         }
         if(*T0 < minLag)
         {
            *T0 = minLag;
         }
      }
   }
}
/*
 * D_GAIN_adaptive_codebook_excitation
 *
 * Parameters:
 *    exc          I/O: excitation buffer
 *    T0             I: integer pitch lag
 *    frac           I: fraction of lag
 *
 * Function:
 *    Compute the result of Word32 term prediction with fractional
 *    interpolation of resolution 1/4.
 *
 * Returns:
 *    interpolated signal (adaptive codebook excitation)
 */
void D_GAIN_adaptive_codebook_excitation(Word16 exc[], Word32 T0, Word32 frac)
{
   Word32 i, j, k, sum;
   Word16 *x;
   x = &exc[ - T0];
   frac = -(frac);
   if(frac < 0)
   {
      frac = (frac + UP_SAMP);
      x--;
   }
   x = x - L_INTERPOL2 + 1;
   for(j = 0; j < L_SUBFR + 1; j++)
   {
      sum = 0L;
      for(i = 0, k = ((UP_SAMP - 1) - frac); i < 2 * L_INTERPOL2; i++,
         k += UP_SAMP)
      {
         sum += x[i] * D_ROM_inter4_2[k];
      }
      sum = (sum + 0x2000) >> 14;
      exc[j] = D_UTIL_saturate(sum);
      x++;
   }
   return;
}
/*
 * D_GAIN_pitch_sharpening
 *
 * Parameters:
 *    x            I/O: impulse response (or algebraic code)
 *    pit_lag        I: pitch lag
 *    sharp          I: (Q15) pitch sharpening factor
 *
 * Function:
 *    Performs Pitch sharpening routine for one subframe.
 *
 * Returns:
 *    void
 */
void D_GAIN_pitch_sharpening(Word16 *x, Word32 pit_lag, Word16 sharp)
{
   Word32 i;
   Word32 tmp;
   for(i = pit_lag; i < L_SUBFR; i++)   
   {
      tmp = x[i] << 15;
      tmp += x[i - pit_lag] * sharp;
      x[i] = (Word16)((tmp + 0x4000) >> 15);
   }
   return;
}
/*
 * D_GAIN_find_voice_factor
 *
 * Parameters:
 *    exc            I: pitch excitation
 *    Q_exc          I: exc format
 *    gain_pit       I: (Q14) gain of pitch
 *    code           I: (Q9) fixed codebook excitation
 *    gain_code      I: (Q0) gain of code
 *    L_subfr        I: subframe length
 *
 * Function:
 *    Find the voicing factor.
 *
 * Returns:
 *    (Q15) 1=voice to -1=unvoiced
 */
Word16 D_GAIN_find_voice_factor(Word16 exc[], Word16 Q_exc,
                                Word16 gain_pit, Word16 code[],
                                Word16 gain_code, Word16 L_subfr)
{
   Word32 tmp, ener1, ener2, i;
   Word16 exp, exp1, exp2;
   ener1 = (D_UTIL_dot_product12(exc, exc, L_subfr, &exp1)) >> 16;
   exp1 = (Word16)(exp1 - (Q_exc + Q_exc));
   tmp = (gain_pit * gain_pit) << 1;
   exp = D_UTIL_norm_l(tmp);
   tmp = (tmp << exp) >> 16;
   ener1 = (ener1 * tmp) >> 15;
   exp1 = (Word16)((exp1 - exp) - 10);   /* 10 -> gain_pit Q14 to Q9 */
   ener2 = D_UTIL_dot_product12(code, code, L_subfr, &exp2) >> 16;
   exp = D_UTIL_norm_s(gain_code);
   tmp = gain_code << exp;
   tmp = (tmp * tmp) >> 15;
   ener2 = (ener2 * tmp) >> 15;
   exp2 = (Word16)(exp2 - (exp << 1));
   i = exp1 - exp2;
   if(i >= 0)
   {
      ener1 = ener1 >> 1;
      ener2 = ener2 >> (i + 1);
   }
   else if(i > (-16))
   {
      ener1 = ener1 >> (1 - i);
      ener2 = ener2 >> 1;
   }
   else
   {
      ener1 = 0;
      ener2 = ener2 >> 1;
   }
   tmp = ener1 - ener2;
   ener1 = (ener1 + ener2) + 1;
   tmp = (tmp << 15) / ener1;
   return((Word16)tmp);
}

⌨️ 快捷键说明

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