enc_acelp.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:50k
- /*
- *===================================================================
- * 3GPP AMR Wideband Floating-point Speech Codec
- *===================================================================
- */
- #include <math.h>
- #include "hlxclib/memory.h"
- #include <float.h>
- #include "typedef.h"
- #include "enc_util.h"
- #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)
- {
- Word32 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;
- Word32 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)
- {
- Word32 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)
- {
- Word32 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)
- {
- Word32 i, j, 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:
- */
- if (((pos1 ^ pos2) & nb_pos) == 0)
- {
- index = E_ACELP_quant_2p_2N1(pos1, pos2, (N - 1));
- index += (pos1 & nb_pos) << N;
- index += E_ACELP_quant_1p_N1(pos3, N) << (2 * N);
- }
- else if (((pos1 ^ pos3) & nb_pos) == 0)
- {
- index = E_ACELP_quant_2p_2N1(pos1, pos3, (N - 1));
- index += (pos1 & nb_pos) << N;
- index += E_ACELP_quant_1p_N1(pos2, N) << (2 * N);
- }
- else
- {
- index = E_ACELP_quant_2p_2N1(pos2, pos3, (N - 1));
- index += (pos2 & nb_pos) << N;
- index += E_ACELP_quant_1p_N1(pos1, N) << (2 * N);
- }
- return(index);
- }
- /*
- * E_ACELP_quant_4p_4N1
- *
- * Parameters:
- * pos1 I: position of the pulse 1
- * pos2 I: position of the pulse 2
- * pos3 I: position of the pulse 3
- * pos4 I: position of the pulse 4
- * N I: number of bits for position
- *
- * Function:
- * Quantization of 4 pulses with 4*N+1 bits
- *
- * Returns:
- * (4*N)+1 bits
- */
- static Word32 E_ACELP_quant_4p_4N1(Word32 pos1, Word32 pos2, Word32 pos3,
- Word32 pos4, Word32 N)
- {
- Word32 nb_pos;
- Word32 index;
- nb_pos = (1 << (N - 1));
- /*
- * Quantization of 4 pulses with 4*N+1 bits:
- */
- if (((pos1 ^ pos2) & nb_pos) == 0)
- {
- index = E_ACELP_quant_2p_2N1(pos1, pos2, (N - 1));
- index += (pos1 & nb_pos) << N;
- index += E_ACELP_quant_2p_2N1(pos3, pos4, N) << (2 * N);
- }
- else if (((pos1 ^ pos3) & nb_pos) == 0)
- {
- index = E_ACELP_quant_2p_2N1(pos1, pos3, (N - 1));
- index += (pos1 & nb_pos) << N;
- index += E_ACELP_quant_2p_2N1(pos2, pos4, N) << (2 * N);
- }
- else
- {
- index = E_ACELP_quant_2p_2N1(pos2, pos3, (N - 1));
- index += (pos2 & nb_pos) << N;
- index += E_ACELP_quant_2p_2N1(pos1, pos4, N) << (2 * N);
- }
- return(index);
- }
- /*
- * E_ACELP_quant_4p_4N
- *
- * Parameters:
- * pos I: position of the pulse 1..4
- * N I: number of bits for position
- *
- * Function:
- * Quantization of 4 pulses with 4*N bits
- *
- * Returns:
- * 4*N bits
- */
- static Word32 E_ACELP_quant_4p_4N(Word32 pos[], Word32 N)
- {
- Word32 i, j, k, nb_pos, n_1;
- Word32 posA[4], posB[4];
- Word32 index=0;
- n_1 = N - 1;
- nb_pos = (1 << n_1);
- i = 0;
- j = 0;
- for (k = 0; k < 4; k++)
- {
- if ((pos[k] & nb_pos) == 0)
- {
- posA[i++] = pos[k];
- }
- else
- {
- posB[j++] = pos[k];
- }
- }
- switch (i)
- {
- case 0:
- index = 1 << ((4 * N) - 3);
- index += E_ACELP_quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1);
- break;
- case 1:
- index = E_ACELP_quant_1p_N1(posA[0], n_1) << (( 3 * n_1) + 1);
- index += E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1);
- break;
- case 2:
- index = E_ACELP_quant_2p_2N1(posA[0], posA[1], n_1) << (( 2 * n_1) + 1);
- index += E_ACELP_quant_2p_2N1(posB[0], posB[1], n_1);
- break;
- case 3:
- index = E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N;
- index += E_ACELP_quant_1p_N1(posB[0], n_1);
- break;
- case 4:
- index = E_ACELP_quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1);
- break;
- }
- index += (i & 3) << ((4 * N) - 2);
- return(index);
- }
- /*
- * E_ACELP_quant_5p_5N
- *
- * Parameters:
- * pos I: position of the pulse 1..5
- * N I: number of bits for position
- *
- * Function:
- * Quantization of 5 pulses with 5*N bits
- *
- * Returns:
- * 5*N bits
- */
- static Word32 E_ACELP_quant_5p_5N(Word32 pos[], Word32 N)
- {
- Word32 i,j,k,nb_pos,n_1;
- Word32 posA[5], posB[5];
- Word32 index=0;
- n_1 = N-1;
- nb_pos = (1 << n_1);
- i = 0;
- j = 0;
- for (k = 0; k < 5; k++)
- {
- if ((pos[k] & nb_pos) == 0)
- {
- posA[i++] = pos[k];
- }
- else
- {
- posB[j++] = pos[k];
- }
- }
- switch (i)
- {
- case 0:
- index = 1 << ((5 * N) - 1);
- index +=
- E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posB[3], posB[4], N);
- break;
- case 1:
- index = 1 << ((5 * N) - 1);
- index +=
- E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posB[3], posA[0], N);
- break;
- case 2:
- index = 1 << ((5 * N) - 1);
- index +=
- E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posA[0], posA[1], N);
- break;
- case 3:
- index =
- E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posB[0], posB[1], N);
- break;
- case 4:
- index =
- E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posA[3], posB[0], N);
- break;
- case 5:
- index =
- E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
- index += E_ACELP_quant_2p_2N1(posA[3], posA[4], N);
- break;
- }
- return(index);
- }
- /*
- * E_ACELP_quant_6p_6N_2
- *
- * Parameters:
- * pos I: position of the pulse 1..6
- * N I: number of bits for position
- *
- * Function:
- * Quantization of 6 pulses with 6*N-2 bits
- *
- * Returns:
- * (6*N)-2 bits
- */
- static Word32 E_ACELP_quant_6p_6N_2(Word32 pos[], Word32 N)
- {
- Word32 i, j, k, nb_pos, n_1;
- Word32 posA[6], posB[6];
- Word32 index=0;
- n_1 = N - 1;
- nb_pos = 1 << n_1;
- i = 0;
- j = 0;
- for (k = 0; k < 6; k++)
- {
- if ((pos[k] & nb_pos) == 0)
- {
- posA[i++] = pos[k];
- }
- else
- {
- posB[j++] = pos[k];
- }
- }
- switch (i)
- {
- case 0:
- index = 1 << ((6 * N) - 5);
- index += E_ACELP_quant_5p_5N(posB, n_1) << N;
- index += E_ACELP_quant_1p_N1(posB[5], n_1);
- break;
- case 1:
- index = 1 << ((6 * N) - 5);
- index += E_ACELP_quant_5p_5N(posB, n_1) << N;
- index += E_ACELP_quant_1p_N1(posA[0], n_1);
- break;
- case 2:
- index = 1 << ((6 * N) - 5);
- index += E_ACELP_quant_4p_4N(posB, n_1) << ((2 * n_1) + 1);
- index += E_ACELP_quant_2p_2N1(posA[0], posA[1], n_1);
- break;
- case 3:
- index = E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1)
- << ((3 * n_1) + 1);
- index += E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1);
- break;
- case 4:
- i = 2;
- index = E_ACELP_quant_4p_4N(posA, n_1) << ((2 * n_1) + 1);
- index += E_ACELP_quant_2p_2N1(posB[0], posB[1], n_1);
- break;
- case 5:
- i = 1;
- index = E_ACELP_quant_5p_5N(posA, n_1) << N;
- index += E_ACELP_quant_1p_N1(posB[0], n_1);
- break;
- case 6:
- i = 0;
- index = E_ACELP_quant_5p_5N(posA, n_1) << N;
- index += E_ACELP_quant_1p_N1(posA[5], n_1);
- break;
- }
- index += (i & 3) << ((6 * N) - 4);
- return(index);
- }
- /*
- * E_ACELP_2t
- *
- * Parameters:
- * dn I: corr. between target and h[].
- * cn I: residual after Word32 term prediction
- * H I: impulse response of weighted synthesis filter (Q12)
- * code O: algebraic (fixed) codebook excitation (Q9)
- * y O: filtered fixed codebook excitation (Q9)
- * index O: index (12): 5 + 1 + 5 + 1 = 11 bits.
- *
- * Function:
- * 12 bits algebraic codebook.
- * 2 tracks x 32 positions per track = 64 samples.
- *
- * 12 bits --> 2 pulses in a frame of 64 samples.
- *
- * All pulses can have two (2) possible amplitudes: +1 or -1.
- * Each pulse can have 32 possible positions.
- *
- * Returns:
- * void
- */
- void E_ACELP_2t(Float32 dn[], Float32 cn[], Float32 H[],
- Word16 code[], Float32 y[], Word32 *index)
- {
- Word32 i, j, k, i0, i1, ix, iy, pos = 0, pos2;
- Float32 ps, psk, ps1, ps2, alpk, alp1, alp2, sq;
- Float32 s, cor, alp, val;
- Float32 *p0, *p1, *p2, *psign;
- Float32 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
- static Float32 sign[L_SUBFR], vec[L_SUBFR], dn2[L_SUBFR];
- static Float32 h_buf[4 * L_SUBFR];
- static Float32 rrixix[2][32];
- static Float32 rrixiy[1024];
- /*
- * Find sign for each pulse position.
- */
- alp = 2.0;
- /* calculate energy for normalization of cn[] and dn[] */
- val = 1.0;
- cor = 1.0;
- for(i = 0; i < L_SUBFR; i++)
- {
- val += cn[i] * cn[i];
- }
- for(i = 0; i < L_SUBFR; i++)
- {
- cor += dn[i] * dn[i];
- }
- s = (Float32)sqrt(cor / val);
- for(i = 0; i < 2; i++)
- {
- for(j = i; j < L_SUBFR; j += 2)
- {
- val = dn[j];
- cor = (s * cn[j]) + (alp * val);
- if(cor >= 0.0)
- {
- sign[j] = 1.0;
- vec[j] = -1.0;
- }
- else
- {
- sign[j] = -1.0;
- vec[j] = 1.0;
- val = -val;
- cor = -cor;
- }
- dn[j] = val; /* modify dn[] according to the fixed sign */
- dn2[j] = cor;
- }
- }
- /*
- * Select 16 position per track according to dn2[].
- */
- for(i = 0; i < 2; i++)
- {
- for(k = 0; k < 16; k++)
- {
- ps = -1;
- for(j = i; j < L_SUBFR; j += 2)
- {
- if(dn2[j] > ps)
- {
- ps = dn2[j];
- pos = j;
- }
- }
- dn2[pos] = (Float32)k - 16; /* dn2 < 0 when position is selected */
- }
- }
- /*
- * Compute h_inv[i].
- */
- h = h_buf;
- h_inv = h_buf + (2 * L_SUBFR);
- for(i = 0; i < L_SUBFR; i++)
- {
- *h++ = 0.0F;
- *h_inv++ = 0.0F;
- }
- for(i = 0; i < L_SUBFR; i++)
- {
- h[i] = H[i];
- h_inv[i] = -h[i];
- }
- /*
- * Compute rrixix[][] needed for the codebook search.
- */
- /* Init pointers to last position of rrixix[] */
- p0 = &rrixix[0][32 - 1];
- p1 = &rrixix[1][32 - 1];
- ptr_h1 = h;
- cor = 0.0F;
- for(i = 0; i < 32; i++)
- {
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p1-- = cor * 0.5F;
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p0-- = cor * 0.5F;
- }
- /*
- * Compute rrixiy[][] needed for the codebook search.
- */
- pos = 1024 - 1;
- pos2 = 1024 - 2;
- ptr_hf = h + 1;
- for(k = 0; k < 32; k++)
- {
- p1 = &rrixiy[pos];
- p0 = &rrixiy[pos2];
- cor = 0.0;
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
- for(i = k + 1; i < 32; i++)
- {
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p1 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p0 = cor;
- p1 -= (32 + 1);
- p0 -= (32 + 1);
- }
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p1 = cor;
- pos -= 32;
- pos2--;
- ptr_hf += 2;
- }
- /*
- * Modification of rrixiy[][] to take signs into account.
- */
- p0 = rrixiy;
- for(i = 0; i < L_SUBFR; i += 2)
- {
- psign = sign;
- if(psign[i] < 0.0)
- {
- psign = vec;
- }
- for(j = 1; j < L_SUBFR; j += 2)
- {
- *p0++ = *p0 * psign[j];
- }
- }
- /*
- * search 2 pulses:
- * ---------------
- * 32 pos x 32 pos = 1024 tests (all combinations are tested)
- */
- p0 = rrixix[0];
- p1 = rrixix[1];
- p2 = rrixiy;
- psk = -1.0;
- alpk = 1.0;
- ix = 0;
- iy = 1;
- for(i0 = 0; i0 < L_SUBFR; i0 += 2)
- {
- ps1 = dn[i0];
- alp1 = (*p0++);
- pos = -1;
- for(i1 = 1; i1 < L_SUBFR; i1 += 2)
- {
- ps2 = ps1 + dn[i1];
- alp2 = alp1 + (*p1++) + (*p2++);
- sq = ps2 * ps2;
- s = (alpk * sq) - (psk * alp2);
- if(s > 0.0)
- {
- psk = sq;
- alpk = alp2;
- pos = i1;
- }
- }
- p1 -= 32;
- if(pos >= 0)
- {
- ix = i0;
- iy = pos;
- }
- }
- /*
- * Build the codeword, the filtered codeword and index of codevector.
- */
- memset(code, 0, L_SUBFR * sizeof(Word16));
- i0 = ix / 2; /* pos of pulse 1 (0..31) */
- i1 = iy / 2; /* pos of pulse 2 (0..31) */
- if(sign[ix] > 0.0)
- {
- code[ix] = 512;
- p0 = h - ix;
- }
- else
- {
- code[ix] = -512;
- i0 += 32;
- p0 = h_inv - ix;
- }
- if(sign[iy] > 0.0)
- {
- code[iy] = 512;
- p1 = h - iy;
- }
- else
- {
- code[iy] = -512;
- i1 += 32;
- p1 = h_inv - iy;
- }
- *index = (i0 << 6) + i1;
- for(i = 0; i < L_SUBFR; i++)
- {
- y[i] = (*p0++) + (*p1++);
- }
- return;
- }
- /*
- * E_ACELP_4t
- *
- * Parameters:
- * dn I: corr. between target and h[].
- * cn I: residual after Word32 term prediction
- * H I: impulse response of weighted synthesis filter (Q12)
- * code O: algebraic (fixed) codebook excitation (Q9)
- * y O: filtered fixed codebook excitation (Q9)
- * nbbits I: 20, 36, 44, 52, 64, 72 or 88 bits
- * mode I: speech mode
- * _index O: index
- *
- * Function:
- * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
- * 4 tracks x 16 positions per track = 64 samples.
- *
- * 20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
- * 36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
- * 44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
- * 52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
- * 64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
- * 16 pulses in a frame of 64 samples.
- * 72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
- * 18 pulses in a frame of 64 samples.
- * 88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
- * 24 pulses in a frame of 64 samples.
- *
- * All pulses can have two (2) possible amplitudes: +1 or -1.
- * Each pulse can sixteen (16) possible positions.
- *
- * Returns:
- * void
- */
- void E_ACELP_4t(Float32 dn[], Float32 cn[], Float32 H[], Word16 code[],
- Float32 y[], Word32 nbbits, Word16 mode, Word32 _index[])
- {
- Float32 sign[L_SUBFR], vec[L_SUBFR];
- Float32 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
- Float32 rrixix[4][16];
- Float32 rrixiy[4][256];
- Float32 dn2[L_SUBFR];
- Word32 ind[NPMAXPT*4];
- Word32 codvec[NB_PULSE_MAX];
- Word32 nbpos[10];
- Word32 pos_max[4];
- Word32 dn2_pos[8 * 4];
- UWord8 ipos[NB_PULSE_MAX];
- Word32 i, j, k, st, pos = 0, index, track, nb_pulse = 0, nbiter = 4;
- Word32 L_index;
- Float32 psk, ps, alpk, alp = 0.0F;
- Float32 val;
- Float32 s, cor;
- Float32 *p0, *p1, *p2, *p3, *psign;
- Float32 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
- switch (nbbits)
- {
- case 20: /* 20 bits, 4 pulses, 4 tracks */
- nbiter = 4; /* 4x16x16=1024 loop */
- alp = 2.0;
- nb_pulse = 4;
- nbpos[0] = 4;
- nbpos[1] = 8;
- break;
- case 36: /* 36 bits, 8 pulses, 4 tracks */
- nbiter = 4; /* 4x20x16=1280 loop */
- alp = 1.0; /* coeff for sign setting */
- nb_pulse = 8;
- nbpos[0] = 4;
- nbpos[1] = 8;
- nbpos[2] = 8;
- break;
- case 44: /* 44 bits, 10 pulses, 4 tracks */
- nbiter = 4; /* 4x26x16=1664 loop */
- alp = 1.0;
- nb_pulse = 10;
- nbpos[0] = 4;
- nbpos[1] = 6;
- nbpos[2] = 8;
- nbpos[3] = 8;
- break;
- case 52: /* 52 bits, 12 pulses, 4 tracks */
- nbiter = 4; /* 4x26x16=1664 loop */
- alp = 1.0;
- nb_pulse = 12;
- nbpos[0] = 4;
- nbpos[1] = 6;
- nbpos[2] = 8;
- nbpos[3] = 8;
- break;
- case 64: /* 64 bits, 16 pulses, 4 tracks */
- nbiter = 3; /* 3x36x16=1728 loop */
- alp = 0.8F;
- nb_pulse = 16;
- nbpos[0] = 4;
- nbpos[1] = 4;
- nbpos[2] = 6;
- nbpos[3] = 6;
- nbpos[4] = 8;
- nbpos[5] = 8;
- break;
- case 72: /* 72 bits, 18 pulses, 4 tracks */
- nbiter = 3; /* 3x35x16=1680 loop */
- alp = 0.75F;
- nb_pulse = 18;
- nbpos[0] = 2;
- nbpos[1] = 3;
- nbpos[2] = 4;
- nbpos[3] = 5;
- nbpos[4] = 6;
- nbpos[5] = 7;
- nbpos[6] = 8;
- break;
- case 88: /* 88 bits, 24 pulses, 4 tracks */
- if (mode > MODE_23k)
- {
- nbiter = 1;
- }
- else
- {
- nbiter = 2; /* 2x53x16=1696 loop */
- }
- alp = 0.5;
- nb_pulse = 24;
- nbpos[0] = 2;
- nbpos[1] = 2;
- nbpos[2] = 3;
- nbpos[3] = 4;
- nbpos[4] = 5;
- nbpos[5] = 6;
- nbpos[6] = 7;
- nbpos[7] = 8;
- nbpos[8] = 8;
- nbpos[9] = 8;
- break;
- }
- /*
- * Find sign for each pulse position.
- */
- /* calculate energy for normalization of cn[] and dn[] */
- val = (cn[0] * cn[0]) + 1.0F;
- cor = (dn[0] * dn[0]) + 1.0F;
- for (i = 1; i < L_SUBFR; i += 7)
- {
- val += (cn[i] * cn[i]);
- cor += (dn[i] * dn[i]);
- val += (cn[i + 1] * cn[i + 1]);
- cor += (dn[i + 1] * dn[i + 1]);
- val += (cn[i + 2] * cn[i + 2]);
- cor += (dn[i + 2] * dn[i + 2]);
- val += (cn[i + 3] * cn[i + 3]);
- cor += (dn[i + 3] * dn[i + 3]);
- val += (cn[i + 4] * cn[i + 4]);
- cor += (dn[i + 4] * dn[i + 4]);
- val += (cn[i + 5] * cn[i + 5]);
- cor += (dn[i + 5] * dn[i + 5]);
- val += (cn[i + 6] * cn[i + 6]);
- cor += (dn[i + 6] * dn[i + 6]);
- }
- s = (Float32)sqrt(cor / val);
- for (j = 0; j < L_SUBFR; j++)
- {
- cor = (s * cn[j]) + (alp * dn[j]);
- if (cor >= 0.0F)
- {
- sign[j] = 1.0F;
- vec[j] = -1.0F;
- dn2[j] = cor; /* dn2[] = mix of dn[] and cn[] */
- }
- else
- {
- sign[j] = -1.0F;
- vec[j] = 1.0F;
- dn[j] = -dn[j]; /* modify dn[] according to the fixed sign */
- dn2[j] = -cor; /* dn2[] = mix of dn[] and cn[] */
- }
- }
- /*
- * Select 8 position per track according to dn2[].
- */
- for (i = 0; i < 4; i++)
- {
- for (k = 0; k < 8; k++)
- {
- ps = -1;
- for (j = i; j < L_SUBFR; j += 4)
- {
- if (dn2[j] > ps)
- {
- ps = dn2[j];
- pos = j;
- }
- }
- dn2[pos] = (Float32)k - 8; /* dn2 < 0 when position is selected */
- dn2_pos[i * 8 + k] = pos;
- }
- pos_max[i] = dn2_pos[i * 8];
- }
- /*
- * Compute h_inv[i].
- */
- memset(h_buf, 0, L_SUBFR * sizeof(Float32));
- memset(h_buf + (2 * L_SUBFR), 0, L_SUBFR * sizeof(Float32));
- h = h_buf + L_SUBFR;
- h_inv = h_buf + (3 * L_SUBFR);
- memcpy(h, H, L_SUBFR * sizeof(Float32));
- h_inv[0] = -h[0];
- h_inv[1] = -h[1];
- h_inv[2] = -h[2];
- h_inv[3] = -h[3];
- for(i = 4; i < L_SUBFR; i += 6)
- {
- h_inv[i] = -h[i];
- h_inv[i + 1] = -h[i + 1];
- h_inv[i + 2] = -h[i + 2];
- h_inv[i + 3] = -h[i + 3];
- h_inv[i + 4] = -h[i + 4];
- h_inv[i + 5] = -h[i + 5];
- }
- /*
- * Compute rrixix[][] needed for the codebook search.
- */
- /* storage order --> i3i3, i2i2, i1i1, i0i0 */
- /* Init pointers to last position of rrixix[] */
- p0 = &rrixix[0][16 - 1];
- p1 = &rrixix[1][16 - 1];
- p2 = &rrixix[2][16 - 1];
- p3 = &rrixix[3][16 - 1];
- ptr_h1 = h;
- cor = 0.0F;
- for(i = 0; i < 16; i++)
- {
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p3-- = cor * 0.5F;
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p2-- = cor * 0.5F;
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p1-- = cor * 0.5F;
- cor += (*ptr_h1) * (*ptr_h1);
- ptr_h1++;
- *p0-- = cor * 0.5F;
- }
- /*
- * Compute rrixiy[][] needed for the codebook search.
- */
- /* storage order --> i2i3, i1i2, i0i1, i3i0 */
- pos = 256 - 1;
- ptr_hf = h + 1;
- for(k = 0; k < 16; k++)
- {
- p3 = &rrixiy[2][pos];
- p2 = &rrixiy[1][pos];
- p1 = &rrixiy[0][pos];
- p0 = &rrixiy[3][pos - 16];
- cor = 0.0F;
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
- for(i = k + 1; i < 16; i++)
- {
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p3 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p2 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p1 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p0 = cor;
- p3 -= (16 + 1);
- p2 -= (16 + 1);
- p1 -= (16 + 1);
- p0 -= (16 + 1);
- }
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p3 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p2 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p1 = cor;
- pos -= 16;
- ptr_hf += 4;
- }
- /* storage order --> i3i0, i2i3, i1i2, i0i1 */
- pos = 256 - 1;
- ptr_hf = h + 3;
- for(k = 0; k < 16; k++)
- {
- p3 = &rrixiy[3][pos];
- p2 = &rrixiy[2][pos - 1];
- p1 = &rrixiy[1][pos - 1];
- p0 = &rrixiy[0][pos - 1];
- cor = 0.0F;
- ptr_h1 = h;
- ptr_h2 = ptr_hf;
- for(i= k + 1; i < 16; i++ )
- {
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p3 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p2 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p1 = cor;
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p0 = cor;
- p3 -= (16 + 1);
- p2 -= (16 + 1);
- p1 -= (16 + 1);
- p0 -= (16 + 1);
- }
- cor += (*ptr_h1) * (*ptr_h2);
- ptr_h1++;
- ptr_h2++;
- *p3 = cor;
- pos--;
- ptr_hf += 4;
- }
- /*
- * Modification of rrixiy[][] to take signs into account.
- */
- p0 = &rrixiy[0][0];
- for (k = 0; k < 4; k++)
- {
- for(i = k; i < L_SUBFR; i += 4)
- {
- psign = sign;
- if (psign[i] < 0.0F)
- {
- psign = vec;
- }
- j = (k + 1) % 4;
- *p0++ = *p0 * psign[j];
- *p0++ = *p0 * psign[j + 4];
- *p0++ = *p0 * psign[j + 8];
- *p0++ = *p0 * psign[j + 12];
- *p0++ = *p0 * psign[j + 16];
- *p0++ = *p0 * psign[j + 20];
- *p0++ = *p0 * psign[j + 24];
- *p0++ = *p0 * psign[j + 28];
- *p0++ = *p0 * psign[j + 32];
- *p0++ = *p0 * psign[j + 36];
- *p0++ = *p0 * psign[j + 40];
- *p0++ = *p0 * psign[j + 44];
- *p0++ = *p0 * psign[j + 48];
- *p0++ = *p0 * psign[j + 52];
- *p0++ = *p0 * psign[j + 56];
- *p0++ = *p0 * psign[j + 60];
- }
- }
- /*
- * Deep first search:
- * ------------------
- * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests
- * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
- * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
- * +(8x16)+(8x16)) = 1248 tests
- * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
- * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
- */
- psk = -1.0;
- alpk = 1.0;
- for (k = 0; k < nbiter; k++)
- {
- for (i = 0; i < nb_pulse - (nb_pulse % 3); i += 3)
- {
- ipos[i] = E_ROM_tipos[(k * 4) + i];
- ipos[i + 1] = E_ROM_tipos[(k * 4) + i + 1];
- ipos[i + 2] = E_ROM_tipos[(k * 4) + i + 2];
- }
- for (; i < nb_pulse; i ++)
- {
- ipos[i] = E_ROM_tipos[(k * 4) + i];
- }
- if (nbbits == 20)
- {
- pos = 0;
- ps = 0.0F;
- alp = 0.0F;
- memset(vec, 0, L_SUBFR * sizeof(Float32));
- }
- 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);
- }
- }
- 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;
- }