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

📄 enc_acelp.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            ipos[5] = 1;
         }
#endif
      }
      else if ((nbbits == 36) | (nbbits == 44))
      {
         /* first stage: fix 2 pulses */
         pos = 2;
         ind[0] = pos_max[ipos[0]];
         ind[1] = pos_max[ipos[1]];
         ps = dn[ind[0]] + dn[ind[1]];
         alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
            rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];  
         if (sign[ind[0]] < 0.0)
         {
            p0 = h_inv - ind[0];
         }
         else
         {
            p0 = h - ind[0];
         }
         if (sign[ind[1]] < 0.0)
         {
            p1 = h_inv - ind[1];
         }
         else
         {
            p1 = h - ind[1];
         }
         vec[0] = p0[0] + p1[0];
         vec[1] = p0[1] + p1[1];
         vec[2] = p0[2] + p1[2];
         vec[3] = p0[3] + p1[3];
         for (i = 4; i < L_SUBFR; i += 6)
         {
            vec[i] = p0[i] + p1[i];
            vec[i + 1] = p0[i + 1] + p1[i + 1];
            vec[i + 2] = p0[i + 2] + p1[i + 2];
            vec[i + 3] = p0[i + 3] + p1[i + 3];
            vec[i + 4] = p0[i + 4] + p1[i + 4];
            vec[i + 5] = p0[i + 5] + p1[i + 5];
         }
         if (nbbits == 44)
         {
            ipos[8] = 0;
            ipos[9] = 1;
         }
      }
      else
      {
         /* first stage: fix 4 pulses */    
         pos = 4;
         ind[0] = pos_max[ipos[0]];
         ind[1] = pos_max[ipos[1]];
         ind[2] = pos_max[ipos[2]];
         ind[3] = pos_max[ipos[3]];
         ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];
         p0 = h - ind[0];
         if (sign[ind[0]] < 0.0)
         {
            p0 = h_inv - ind[0];
         }
         p1 = h - ind[1];
         if (sign[ind[1]] < 0.0)
         {
            p1 = h_inv - ind[1];
         }
         p2 = h - ind[2];
         if (sign[ind[2]] < 0.0)
         {
            p2 = h_inv - ind[2];
         }
         p3 = h - ind[3];
         if (sign[ind[3]] < 0.0)
         {
            p3 = h_inv - ind[3];
         }
         vec[0] = p0[0] + p1[0] + p2[0] + p3[0];
         for (i = 1; i < L_SUBFR; i += 3)
         {
            vec[i] = p0[i] + p1[i] + p2[i] + p3[i];
            vec[i + 1] = p0[i + 1] + p1[i + 1] + p2[i + 1] + p3[i + 1];
            vec[i + 2] = p0[i + 2] + p1[i + 2] + p2[i + 2] + p3[i + 2];
         }
         alp = 0.0F;
         alp += vec[0] * vec[0] + vec[1] * vec[1];
         alp += vec[2] * vec[2] + vec[3] * vec[3];
         for (i = 4; i < L_SUBFR; i += 6)
         {
            alp += vec[i] * vec[i];
            alp += vec[i + 1] * vec[i + 1];
            alp += vec[i + 2] * vec[i + 2];
            alp += vec[i + 3] * vec[i + 3];
            alp += vec[i + 4] * vec[i + 4];
            alp += vec[i + 5] * vec[i + 5];
         }
         alp *= 0.5F;
         if (nbbits == 72)
         {
            ipos[16] = 0;
            ipos[17] = 1;
         }
      }
      /* other stages of 2 pulses */
      for (j = pos, st = 0; j < nb_pulse; j += 2, st++)
      {
         /*
          * Calculate correlation of all possible positions
          * of the next 2 pulses with previous fixed pulses.
          * Each pulse can have 16 possible positions.
          */
         E_ACELP_h_vec_corr1(h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos,
            nbpos[st]);                                     
         E_ACELP_h_vec_corr2(h, vec, ipos[j + 1], sign, rrixix, cor_y);
         /*
          * Find best positions of 2 pulses.
          */
         E_ACELP_2pulse_search(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
            &ind[j], &ind[j+1], dn, dn2_pos, cor_x, cor_y, rrixiy);
         if (j < (nb_pulse - 2))
         {
            p0 = h - ind[j];
            if (sign[ind[j]] < 0.0)
            {
               p0 = h_inv - ind[j];
            }
            p1 = h - ind[j + 1];
            if (sign[ind[j + 1]] < 0.0)
            {
               p1 = h_inv - ind[j + 1];
            }
            vec[0] += p0[0] + p1[0];
            vec[1] += p0[1] + p1[1];                            
            vec[2] += p0[2] + p1[2];
            vec[3] += p0[3] + p1[3];
            for (i = 4; i < L_SUBFR; i += 6)
            {
               vec[i] += p0[i] + p1[i];
               vec[i + 1] += p0[i + 1] + p1[i + 1];
               vec[i + 2] += p0[i + 2] + p1[i + 2];
               vec[i + 3] += p0[i + 3] + p1[i + 3];
               vec[i + 4] += p0[i + 4] + p1[i + 4];
               vec[i + 5] += p0[i + 5] + p1[i + 5];
            }
         }
      }
      /* memorise the best codevector */
      ps = ps * ps;
      s = (alpk * ps) - (psk * alp);
      if (s > 0.0F)
      {
         psk = ps;
         alpk = alp;
         memcpy(codvec, ind, nb_pulse * sizeof(Word32));
      }
  }
  /*
   * Build the codeword, the filtered codeword and index of codevector.
   */
  memset(code, 0,  L_SUBFR * sizeof(Word16));
  memset(y, 0,  L_SUBFR * sizeof(Float32));
  memset(ind, 0xffffffff, NPMAXPT * 4 * sizeof(Word32));
  for (k = 0; k < nb_pulse; k++)
  {
     i = codvec[k];  /* read pulse position  */
     val = sign[i];  /* read sign            */
     index = i / 4;  /* pos of pulse (0..15) */
     track = i % 4;
     if (val > 0)
     {
        code[i] += 512;
        codvec[k] += (2 * L_SUBFR);
     }
     else
     {
        code[i] -= 512;
        index += 16;
     }
     i = track * NPMAXPT;
     while (ind[i] >= 0)
     {
        i++;
     }
     ind[i] = index;
     p0 = h_inv - codvec[k];
     y[0] += p0[0];
     for(i = 1; i < L_SUBFR; i += 3)
     {
        y[i] += p0[i];
        y[i + 1] += p0[i + 1];                                  
        y[i + 2] += p0[i + 2];
     }
  }
  if (nbbits == 20)
  {
     for (track = 0; track < 4; track++)
     {
        k = track * NPMAXPT;
        _index[track] = E_ACELP_quant_1p_N1(ind[k], 4);
     }
  }
#ifdef NEW_28bits
  else if (nbbits == 28)
  {
     for (track = 0; track < (4 - 2); track++)
     {
        k = track * NPMAXPT;
        _index[track] = E_ACELP_quant_2p_2N1(ind[k], ind[k + 1], 4);
     }
     for (track = 2; track < 4; track++)
     {
        k = track * NPMAXPT;
        _index[track] = E_ACELP_quant_1p_N1(ind[k], 4);
     }
  }
#endif
  else if (nbbits == 36)
  {
     for (track = 0; track < 4; track++)
     {
        k = track * NPMAXPT;
        _index[track] = E_ACELP_quant_2p_2N1(ind[k], ind[k + 1], 4);
     }
  }
  else if (nbbits == 44)
  {
     for (track = 0; track < (4 - 2); track++)
     {
        k = track * NPMAXPT;
        _index[track] =
           E_ACELP_quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4);
     }
     for (track = 2; track < 4; track++)
     {
        k = track * NPMAXPT;
        _index[track] = E_ACELP_quant_2p_2N1(ind[k], ind[k + 1], 4);
     }
  }
  else if (nbbits == 52)
  {
     for (track = 0; track < 4; track++)
     {
        k = track*NPMAXPT;
        _index[track] =
           E_ACELP_quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4);
     }
  }
  else if (nbbits == 64)
  {
     for (track = 0; track < 4; track++)
     {
        k = track * NPMAXPT;
        L_index = E_ACELP_quant_4p_4N(&ind[k], 4);
        _index[track] = ((L_index >> 14) & 3);
        _index[track + 4] = (L_index & 0x3FFF);
     }
  }
  else if (nbbits == 72)
  {
     for (track=0; track< (4 - 2); track++)
     {
        k = track * NPMAXPT;
        L_index = E_ACELP_quant_5p_5N(&ind[k], 4);
        _index[track] = ((L_index >> 10) & 0x03FF);
        _index[track + 4] = (L_index & 0x03FF);
     }
     for (track = 2; track < 4; track++)
     {
        k = track * NPMAXPT;
        L_index = E_ACELP_quant_4p_4N(&ind[k], 4);
        _index[track] = ((L_index >> 14) & 3);
        _index[track + 4] = (L_index & 0x3FFF);
     }
  }
  else if (nbbits == 88)
  {
     for (track = 0; track < 4; track++)
     {
        k = track * NPMAXPT;
        L_index = E_ACELP_quant_6p_6N_2(&ind[k], 4);
        _index[track] = ((L_index >> 11) & 0x07FF);
        _index[track + 4] = (L_index & 0x07FF);
     }
  }
  return;
}
/*
 * E_ACELP_gains_quantise
 *
 * Parameters:
 *    code        I: Innovative code vector
 *    nbits       I: number of bits (6 or 7)
 *    gain_pit  I/O: Pitch gain / Quantized pitch gain
 *    gain_code   O: Quantized codebook gain
 *    coeff       O: correlations
 *                   <y1,y1>, -2<xn,y1>, <y2,y2>, -2<xn,y2>, 2<y1,y2>
 *    gp_clip     I: gain pitch clipping flag (1 = clipping)
 *    mem       I/O: static memory
 *
 * Function:
 *    Quantization of pitch and codebook gains.
 *    MA prediction is performed on the innovation energy
 *    (in dB with mean removed).
 *    An initial predicted gain, g_0, is first determined and the correction
 *    factor alpha = gain / g_0 is quantized.
 *    The pitch gain and the correction factor are vector quantized and the
 *    mean-squared weighted error criterion is used in the quantizer search.
 *    Subrame size is L_SUBFR
 *
 * Returns:
 *    index of quantizer
 */
Word32 E_ACELP_gains_quantise(Word16 code[], Word32 nbits, Float32 f_gain_pit,
                              Word16 *gain_pit, Word32 *gain_code,
                              Float32 *coeff, Word32 gp_clip,
                              Word16 *past_qua_en)
{
   Word32 i, j, indice = 0, min_ind, size, L_tmp, gcode_inov, L_gcode0;
   Word32 exp;
   Float32 gcode0;
   Float32 dist, dist_min, g_pitch, g_code, ener_code, pred_code;
   Float32 coef0, coef1, coef2, coef3, coef4;
   const Float32 *t_qua_gain, *p;
   Word16 s_exp, s_gcode0, exp_gcode0, frac;
   /*
    * Find the initial quantization pitch index
    * Set gains search range
    */
   if (nbits == 6)
   {
      t_qua_gain = E_ROM_qua_gain6b;
      min_ind = 0;
      size = 64;
      if (gp_clip == 1)
      {
         size -= 16; /* limit gain pitch to 1.0 */
      }
   }
   else
   {
      t_qua_gain = E_ROM_qua_gain7b;
      p = E_ROM_qua_gain7b + 64; /* pt at 1/4th of table */
      j = NB_QUA_GAIN7B - 64;
      if (gp_clip == 1)
      {
         j -= 27; /* limit gain pitch to 1.0 */
      }
      min_ind = 0;
      g_pitch = f_gain_pit;
      for (i = 0; i < j; i++, p += 2)
      {
         if (g_pitch > *p)
         {
            min_ind++;
         }
      }
      size = 64;
   }
   /* innovation energy */
   L_tmp = E_UTIL_dot_product12(code, code, L_SUBFR, &exp);
   ener_code = (Float32)(L_tmp * pow(2, (exp - 31) - 18));
   ener_code = (Float32)(10.0F * log10(ener_code * 0.015625F));
   /* exp: -18 (code in Q9), -6 (/L_subfr) */
   s_exp = (Word16)(exp - (18 + 6));
   E_UTIL_normalised_inverse_sqrt(&L_tmp, &s_exp);
   if (s_exp > 3)
   {
      L_tmp <<= (s_exp - 3);
   }
   else
   {
      L_tmp >>= (3 - s_exp);
   }
   gcode_inov = (Word16)(L_tmp >> 16);  /* g_code_inov in Q12 */
   /*
    * Compute gcode0.
    *  = Sum(i=0,1) pred[i] * past_qua_en[i] + mean_ener - ener_code
    */
   /* MEAN_ENER in Q24 = 0x1e000000 */
   /* MA prediction coeff = {0.5, 0.4, 0.3, 0.2} in Q13 */
   L_tmp = 0xF000000 + 4096 * past_qua_en[0]; /* Q13 * Q10 -> Q24 */
   L_tmp = L_tmp + 3277 * past_qua_en[1];     /* Q13 * Q10 -> Q24 */
   L_tmp = L_tmp + 2458 * past_qua_en[2];     /* Q13 * Q10 -> Q24 */
   L_tmp = L_tmp + 1638 * past_qua_en[3];     /* Q13 * Q10 -> Q24 */
   L_gcode0 = L_tmp >> 15;             /* From Q24 to Q8  */
   pred_code = (Float32)(L_gcode0 * pow(2, -8));
   /*
    * gcode0 = pow(10.0, gcode0/20)
    *        = pow(2, 3.321928*gcode0/20)
    *        = pow(2, 0.166096*gcode0)
    */
   L_tmp = (L_gcode0 * 5443) >> 7; /* *0.166096 in Q15 -> Q24, From Q24 to Q16 */
   E_UTIL_l_extract(L_tmp, &exp_gcode0, &frac); /* Extract exponant of gcode0  */
   s_gcode0 = (Word16)(E_UTIL_pow2(14, frac));  /* Put 14 as exponant so that  */
   /*
    * output of Pow2() will be:
    * 16384 < Pow2() <= 32767
    */
   exp_gcode0 = (Word16)(exp_gcode0 - 14);
   /* Search for best quantizer */
   gcode0 = pred_code - ener_code;
   gcode0 = (Float32)pow(10.0, gcode0 * 0.05F);   /* predicted gain */
   dist_min = FLT_MAX;
   p = t_qua_gain + min_ind * 2;
   coef0 = coeff[0];
   coef1 = coeff[1];
   coef2 = coeff[2];
   coef3 = coeff[3];
   coef4 = coeff[4];
   for (i = 0; i < size; i++)
   {
      g_pitch = *p++;                  /* pitch gain */
      g_code = gcode0 * *p++;         /* codebook gain */
      dist = g_pitch * g_pitch * coef0
         + g_pitch * coef1
         + g_code * g_code * coef2
         + g_code * coef3
         + g_pitch * g_code * coef4;
      if (dist < dist_min)
      {
         dist_min = dist;
         indice = i;
      }
   }
   indice += min_ind;
   *gain_pit  = (Word16)floor(t_qua_gain[indice * 2] * (1 << 14) + 0.5F);
   L_tmp = (Word32)floor(t_qua_gain[indice * 2 + 1] * (1 << 11) + 0.5F);
   L_tmp = E_UTIL_saturate(L_tmp);
   L_tmp *= s_gcode0;
   exp_gcode0 += 5;
   if (exp_gcode0 >= 0)
   {
      *gain_code = L_tmp << exp_gcode0; /* gain of code in Q16 */
   }
   else
   {
      *gain_code = L_tmp >> -exp_gcode0; /* gain of code in Q16 */
   }
   /* adjust gain according to energy of code */
   E_UTIL_l_extract((Word32)*gain_code, &s_exp, &frac);
   L_tmp = E_UTIL_mpy_32_16(s_exp, frac, (Word16)gcode_inov);
   if (L_tmp < 0xFFFFFFF)
   {
      *gain_code = L_tmp << 3;             /* gcode_inov in Q12 */
   }
   else
   {
      *gain_code = 0x7FFFFFFF;
   }
   /*
    * qua_ener = 20*log10(g_code)
    *          = 6.0206*log2(g_code)
    *          = 6.0206*(log2(g_codeQ11) - 11)
    */
   L_tmp = (Word32)floor(t_qua_gain[indice * 2 + 1] * (1 << 11) + 0.5F);
   L_tmp = E_UTIL_saturate(L_tmp);
   E_UTIL_log2_32(L_tmp, &s_exp, &frac);
   s_exp = (Word16)(s_exp - 11);
   L_tmp = E_UTIL_mpy_32_16(s_exp, frac, 24660);   /* x 6.0206 in Q12 */
   /* update table of past quantized energies */
   past_qua_en[3] = past_qua_en[2];
   past_qua_en[2] = past_qua_en[1];
   past_qua_en[1] = past_qua_en[0];
   past_qua_en[0] = (Word16)(L_tmp >> 3); /* result in Q10 */
   return indice;
}

⌨️ 快捷键说明

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