📄 enc_acelp.c
字号:
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 + -