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

📄 enc_acelp.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *===================================================================
 *  3GPP AMR Wideband Floating-point Speech Codec
 *===================================================================
 */
#include <math.h>
#include <memory.h>
#include <float.h>
#include "typedef.h"
#include "enc_util.h"
#define NEW_28bits     /* for amr_wbplus */
#define L_SUBFR         64
#define NB_PULSE_MAX    24
#define NPMAXPT ((NB_PULSE_MAX + 4 - 1) / 4)
#define NB_QUA_GAIN7B   128   /* Number of quantization level */
#define MODE_23k        7
extern const UWord8 E_ROM_tipos[];
extern const Float32 E_ROM_qua_gain6b[];
extern const Float32 E_ROM_qua_gain7b[];
/*
 * E_ACELP_Gain2_Q_init
 *
 * Parameters:
 *    mem           O: static memory
 *
 * Function:
 *    Initializes state memory
 *
 * Returns:
 *    void
 */
void E_ACELP_Gain2_Q_init(Word16 *mem)
{
   Word16 i;
   /* 2nd order quantizer energy predictor */
   for (i = 0; i < 4; i++)
   {
      mem[i] = -14336;   /* past_qua_en[i] */
   }
   return;
}
/*
 * E_ACELP_xy1_corr
 *
 * Parameters:
 *    xn          I: target signal
 *    y1          I: filtered adaptive codebook excitation
 *    g_coeff     O: correlations <y1,y1>  and -2<xn,y1>
 *
 * Function:
 *    Find the correlations between the target xn[] and the filtered adaptive
 *    codebook excitation y1[]. ( <y1,y1>  and -2<xn,y1> )
 *    Subframe size = L_SUBFR
 *
 * Returns:
 *    pitch gain  (0 ... 1.2F) (Q14)
 */
Float32 E_ACELP_xy1_corr(Float32 xn[], Float32 y1[], Float32 g_corr[])
{
   Float32 gain;
   Float32 t0, t1;
   Word16 i;
   t0 = xn[0] * y1[0];
   t1 = y1[0] * y1[0];
   for (i = 1; i < L_SUBFR; i += 7)
   {
      t0 += xn[i] * y1[i];
      t1 += y1[i] * y1[i];
      t0 += xn[i + 1] * y1[i + 1];
      t1 += y1[i + 1] * y1[i + 1];
      t0 += xn[i + 2] * y1[i + 2];
      t1 += y1[i + 2] * y1[i + 2];
      t0 += xn[i + 3] * y1[i + 3];
      t1 += y1[i + 3] * y1[i + 3];
      t0 += xn[i + 4] * y1[i + 4];
      t1 += y1[i + 4] * y1[i + 4];
      t0 += xn[i + 5] * y1[i + 5];
      t1 += y1[i + 5] * y1[i + 5];
      t0 += xn[i + 6] * y1[i + 6];
      t1 += y1[i + 6] * y1[i + 6];
   }
   g_corr[0] = t1;
   g_corr[1] = -2.0F * t0 + 0.01F;
   /* find pitch gain and bound it by [0,1.2F] */
   if (t1)
   {
      gain = t0 / t1;
   }
   else
   {
      gain = 1.0F;
   }
   if (gain < 0.0)
   {
      gain = 0.0;
   }
   else if (gain > 1.2F)
   {
      gain = 1.2F;
   }
   return gain;
}
/*
 * E_ACELP_xy2_corr
 *
 * Parameters:
 *    xn          I: target signal
 *    y1          I: filtered adaptive codebook excitation
 *    y2          I: filtered fixed codebook excitation
 *    g_corr      O: correlations <y2,y2>, -2<xn,y2>, 2<y1,y2>
 *    L_subfr     I: subframe size
 *
 * Function:
 *    Find the correlations between the target xn[], the filtered adaptive
 *    codebook exc. y1[], and the filtered fixed codebook innovation y2[].
 *    ( <y2,y2> , -2<xn,y2> and 2<y1,y2> )
 *    Subrame size = L_SUBFR
 *
 * Returns:
 *    pitch gain  (0 ... 1.2F)
 */
void E_ACELP_xy2_corr(Float32 xn[], Float32 y1[], Float32 y2[],
                      Float32 g_corr[])
{
   Float32 temp1, temp2, temp3;
   Word32 i;
   temp1 = 0.01F + y2[0] * y2[0];
   temp2 = 0.01F + xn[0] * y2[0];
   temp3 = 0.01F + y1[0] * y2[0];
   temp1 += y2[1] * y2[1];
   temp2 += xn[1] * y2[1];
   temp3 += y1[1] * y2[1];
   temp1 += y2[2] * y2[2];
   temp2 += xn[2] * y2[2];
   temp3 += y1[2] * y2[2];
   temp1 += y2[3] * y2[3];
   temp2 += xn[3] * y2[3];
   temp3 += y1[3] * y2[3];
   for (i = 4; i < L_SUBFR; i += 6)
   {
      temp1 += y2[i] * y2[i];
      temp2 += xn[i] * y2[i];
      temp3 += y1[i] * y2[i];
      temp1 += y2[i + 1] * y2[i + 1];
      temp2 += xn[i + 1] * y2[i + 1];
      temp3 += y1[i + 1] * y2[i + 1];
      temp1 += y2[i + 2] * y2[i + 2];
      temp2 += xn[i + 2] * y2[i + 2];
      temp3 += y1[i + 2] * y2[i + 2];
      temp1 += y2[i + 3] * y2[i + 3];
      temp2 += xn[i + 3] * y2[i + 3];
      temp3 += y1[i + 3] * y2[i + 3];
      temp1 += y2[i + 4] * y2[i + 4];
      temp2 += xn[i + 4] * y2[i + 4];
      temp3 += y1[i + 4] * y2[i + 4];
      temp1 += y2[i + 5] * y2[i + 5];
      temp2 += xn[i + 5] * y2[i + 5];
      temp3 += y1[i + 5] * y2[i + 5];
   }
   g_corr[2] = temp1;
   g_corr[3] = -2.0F * temp2;
   g_corr[4] = 2.0F * temp3;
   return;
}
/*
 * E_ACELP_xh_corr
 *
 * Parameters:
 *    h           I: impulse response (of weighted synthesis filter) (Q12)
 *    x           I: target signal (Q0)
 *    y           O: correlation between x[] and h[]
 *
 * Function:
 *    Compute the correlation between the target signal and the impulse
 *    response of the weighted synthesis filter.
 *
 *           y[i]=sum(j=i,l-1) x[j]*h[j-i], i=0,l-1
 *
 *    Vector size is L_SUBFR
 *
 * Returns:
 *    void
 */
void E_ACELP_xh_corr(Float32 *x, Float32 *y, Float32 *h)
{
   Word16 i, j;
   Float32 s;
   for (i = 0; i < L_SUBFR; i++)
   {
      s = 0.0F;
      for (j = i; j < L_SUBFR ; j++)
      {
         s += x[j] * h[j - i];
      }
      y[i] = s;
   }
   return;
}
/*
 * E_ACELP_codebook_target_update
 *
 * Parameters:
 *    x           I: old target (for pitch search) (Q0)
 *    x2          O: new target (for codebook search) (Q0)
 *    y           I: filtered adaptive codebook vector (Q0)
 *    gain        I: adaptive codebook gain (Q14)
 *
 * Function:
 *    Update the target vector for codebook search.
 *    Subframe size = L_SUBFR
 * Returns:
 *    void
 */
void E_ACELP_codebook_target_update(Float32 *x, Float32 *x2, Float32 *y,
                                    Float32 gain)
{
   Word16 i;
   for (i = 0; i < L_SUBFR; i ++)
   {
      x2[i] = x[i] - gain * y[i];
   }
}
/*
 * E_ACELP_h_vec_corr?
 *
 * Parameters:
 *    h              I: scaled impulse response
 *    vec            I: vector to correlate with h[]
 *    track          I: track to use
 *    sign           I: sign vector
 *    rrixix         I: correlation of h[x] with h[x]
 *    cor            O: result of correlation (16 elements)
 *
 * Function:
 *    Calculate the correlations of h[] with vec[] for the specified track
 *
 * Returns:
 *    void
 */
static void E_ACELP_h_vec_corr1(Float32 h[], Float32 vec[], UWord8 track,
                                Float32 sign[], Float32 (*rrixix)[16],
                                Float32 cor[], Word32 dn2_pos[],
                                Word32 nb_pulse)
{
   Word16 i, j;
   Word32 dn;
   Word32 *dn2;
   Float32 *p0;
   Float32 s;
   dn2 = &dn2_pos[track * 8];
   p0 = rrixix[track];
   for (i = 0; i < nb_pulse; i++)
   {
      dn = dn2[i];
      s = 0.0F;
      for (j = 0; j < (L_SUBFR - dn); j++)
      {
         s += h[j] * vec[dn + j];
      }
      cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];
   }
   return;
}
static void E_ACELP_h_vec_corr2(Float32 h[], Float32 vec[], UWord8 track,
                                Float32 sign[], Float32 (*rrixix)[16],
                                Float32 cor[])
{
   Word32 i, j;
   Float32 *p0;
   Float32 s;
   p0 = rrixix[track];
   for (i = 0; i < 16; i++)
   {
      s = 0.0F;
      for (j = 0; j < L_SUBFR - track; j++)
      {
         s += h[j] * vec[track + j];
      }
      cor[i] = s * sign[track] + p0[i];
      track += 4;
   }
   return;
}
/*
 * E_ACELP_2pulse_search
 *
 * Parameters:
 *    nb_pos_ix      I: nb of pos for pulse 1 (1..8)
 *    track_x        I: track of pulse 1
 *    track_y        I: track of pulse 2
 *    ps           I/O: correlation of all fixed pulses
 *    alp          I/O: energy of all fixed pulses
 *    ix             O: position of pulse 1
 *    iy             O: position of pulse 2
 *    dn             I: corr. between target and h[]
 *    dn2            I: vector of selected positions
 *    cor_x          I: corr. of pulse 1 with fixed pulses
 *    cor_y          I: corr. of pulse 2 with fixed pulses
 *    rrixiy         I: corr. of pulse 1 with pulse 2
 *
 * Function:
 *    Find the best positions of 2 pulses in a subframe
 *
 * Returns:
 *    void
 */
static void E_ACELP_2pulse_search(Word32 nb_pos_ix, UWord8 track_x,
                                  UWord8 track_y, Float32 *ps, Float32 *alp,
                                  Word32 *ix, Word32 *iy, Float32 dn[],
                                  Word32 *dn2, Float32 cor_x[],
                                  Float32 cor_y[], Float32 (*rrixiy)[256])
{
   Word32 x, x2, y, x_save = 0, y_save = 0, i, *pos_x;
   Float32 ps0, alp0;
   Float32 ps1, ps2, sq, sqk;
   Float32 alp1, alp2, alpk;
   Float32 *p1, *p2;
   Float32 s;
   /* eight dn2 max positions per track */
   pos_x = &dn2[track_x << 3];
   /* save these to limit memory searches */
   ps0 = *ps;
   alp0 = *alp;
   sqk = -1.0F;
   alpk = 1.0F;
   /* loop track 1 */
   for (i = 0; i < nb_pos_ix; i++)
   {
      x = pos_x[i];
      x2 = x >> 2;
      /* dn[x] has only nb_pos_ix positions saved */
      ps1 = ps0 + dn[x];
      alp1 = alp0 + cor_x[x2];
      p1 = cor_y;
      p2 = &rrixiy[track_x][x2 << 4];
      for (y = track_y; y < L_SUBFR; y += 4)
      {
         ps2 = ps1 + dn[y];
         alp2 = alp1 + (*p1++) + (*p2++);
         sq = ps2 * ps2;
         s = (alpk * sq) - (sqk * alp2);
         if (s > 0.0F)
         {
            sqk = sq;
            alpk = alp2;
            y_save = y;
            x_save = x;
         }
      }
   }
   *ps = ps0 + dn[x_save] + dn[y_save];
   *alp = alpk;
   *ix = x_save;
   *iy = y_save;
   return;
}
/*
 * E_ACELP_quant_1p_N1
 *
 * Parameters:
 *    pos      I: position of the pulse
 *    N        I: number of bits for position
 *
 * Function:
 *    Quantization of 1 pulse with N+1 bits
 *
 * Returns:
 *    return N+1 bits
 */
static Word32 E_ACELP_quant_1p_N1(Word32 pos, Word32 N)
{
   Word32 mask;
   Word32 index;
   mask = ((1<<N)-1);
   /*
    * Quantization of 1 pulse with N+1 bits:
    */
   index = (pos & mask);
   if ((pos & 16) != 0)
   {
      index += 1 << N;
   }
   return(index);
}
/*
 * E_ACELP_quant_2p_2N1
 *
 * Parameters:
 *    pos1     I: position of the pulse 1
 *    pos2     I: position of the pulse 2
 *    N        I: number of bits for position
 *
 * Function:
 *    Quantization of 2 pulses with 2*N+1 bits
 *
 * Returns:
 *    (2*N)+1 bits
 */
static Word32 E_ACELP_quant_2p_2N1(Word32 pos1, Word32 pos2, Word32 N)
{
   Word32 mask;
   Word32 index;
   mask = ((1 << N) - 1);
   /*
    * Quantization of 2 pulses with 2*N+1 bits:
    */
   if (((pos2 ^ pos1) & 16) == 0)
   {
      /* sign of 1st pulse == sign of 2th pulse */
      if ((pos1 - pos2) <= 0)
      {
         index = ((pos1 & mask) << N) + (pos2 & mask);
      }
      else
      {
         index = ((pos2 & mask) << N) + (pos1 & mask);
      }                                                  
      if ((pos1 & 16) != 0)
      {
         index += 1 << (2 * N);
      }
   }
   else
   {
      /* sign of 1st pulse != sign of 2th pulse */
      if (((pos1 & mask) - (pos2 & mask)) <= 0)
      {
         index = ((pos2 & mask) << N) + (pos1 & mask);
         if ((pos2 & 16) != 0)
         {
            index += 1 << (2 * N);
         }
      }
      else
      {
         index = ((pos1 & mask) << N) + (pos2 & mask);
         if ((pos1 & 16) != 0)
         {
            index += 1 << (2 * N);
         }
      }
   }
   return(index);
}
/*
 * E_ACELP_quant_3p_3N1
 *
 * Parameters:
 *    pos1     I: position of the pulse 1
 *    pos2     I: position of the pulse 2
 *    pos3     I: position of the pulse 3
 *    N        I: number of bits for position
 *
 * Function:
 *    Quantization of 3 pulses with 3*N+1 bits
 *
 * Returns:
 *    (3*N)+1 bits
 */
static Word32 E_ACELP_quant_3p_3N1(Word32 pos1, Word32 pos2, Word32 pos3,
                                   Word32 N)
{
   Word32 nb_pos;
   Word32 index;
   nb_pos = (1 << (N - 1));             
   /*
    * Quantization of 3 pulses with 3*N+1 bits:
    */

⌨️ 快捷键说明

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