📄 enc_main.c
字号:
*/
i = T0 - T0_min;
index = (Word16)(i * 4 + T0_frac);
E_MAIN_parm_store(index, &prms);
}
}
/*
* Gain clipping test to avoid unstable synthesis on frame erasure
*/
clip_gain = E_GAIN_clip_test(st->mem_gp_clip);
/*
* - find unity gain pitch excitation (adaptive codebook entry)
* with fractional interpolation.
* - find filtered pitch exc. y1[]=exc[] convolved with h1[])
* - compute pitch gain1
*/
/* find pitch exitation */
E_GAIN_adaptive_codebook_excitation(&exc[i_subfr], (Word16)T0, T0_frac, L_SUBFR + 1);
if(*mode > MODE_9k)
{
E_UTIL_convolve(&exc[i_subfr], st->mem_q, h1, y1);
gain1 = E_ACELP_xy1_corr(xn, y1, g_coeff);
/* clip gain if necessary to avoid problem at decoder */
if (clip_gain && (gain1 > 0.95))
{
gain1 = 0.95f;
}
/* find energy of new target xn2[] */
E_ACELP_codebook_target_update(xn, dn, y1, gain1);
}
else
{
gain1 = 0.0F;
}
/*
* - find pitch excitation filtered by 1st order LP filter.
* - find filtered pitch exc. y2[]=exc[] convolved with h1[])
* - compute pitch gain2
*/
/* find pitch excitation with lp filter */
for (i = 0; i < L_SUBFR; i++)
{
l_tmp = 5898 * exc[i - 1 + i_subfr];
l_tmp += 20972 * exc[i + i_subfr];
l_tmp += 5898 * exc[i + 1 + i_subfr];
s_code[i] = (Word16)((l_tmp + 0x4000) >> 15);
}
E_UTIL_convolve(s_code, st->mem_q, h1, y2);
gain2 = E_ACELP_xy1_corr(xn, y2, g_coeff2);
/* clip gain if necessary to avoid problem at decoder */
if (clip_gain && (gain2 > 0.95))
{
gain2 = 0.95F;
}
/* find energy of new target xn2[] */
E_ACELP_codebook_target_update(xn, xn2, y2, gain2);
/*
* use the best prediction (minimise quadratic error).
*/
select = 0;
if (*mode > MODE_9k)
{
f_tmp = 0.0;
for (i = 0; i < L_SUBFR; i++)
{
f_tmp += dn[i] * dn[i];
f_tmp -= xn2[i] * xn2[i];
}
if (f_tmp < 0.1)
{
select = 1;
}
E_MAIN_parm_store(select, &prms);
}
if (select == 0)
{
/* use the lp filter for pitch excitation prediction */
memcpy(&exc[i_subfr], s_code, L_SUBFR * sizeof(Word16));
memcpy(y1, y2, L_SUBFR * sizeof(Float32));
gain_pit = gain2;
g_coeff[0] = g_coeff2[0];
g_coeff[1] = g_coeff2[1];
}
else
{
/* no filter used for pitch excitation prediction */
gain_pit = gain1;
memcpy(xn2, dn, L_SUBFR * sizeof(Float32)); /* target vector for codebook search */
}
/*
* - update target vector for codebook search
* - scaling of cn[] to limit dynamic at 12 bits
*/
for (i = 0; i < L_SUBFR; i ++)
{
cn[i] = (Float32)(cn[i] - gain_pit * exc[i_subfr + i] * pow(2, Q_new));
}
/*
* - include fixed-gain pitch contribution into impulse resp. h1[]
*/
f_tmp = 0.0F;
E_UTIL_f_preemph(h1, (Float32)(st->mem_tilt_code / 32768.0), L_SUBFR, &f_tmp);
if (T0_frac > 2)
{
T0++;
}
E_GAIN_f_pitch_sharpening(h1, T0);
/*
* - Correlation between target xn2[] and impulse response h1[]
* - Innovative codebook search
*/
E_ACELP_xh_corr(xn2, dn, h1);
switch(*mode)
{
case MODE_7k:
E_ACELP_2t(dn, cn, h1, s_code, y2, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
break;
case MODE_9k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 20, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
break;
case MODE_12k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 36, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
break;
case MODE_14k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 44, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
break;
case MODE_16k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 52, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
break;
case MODE_18k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 64, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
E_MAIN_parm_store((Word16)indice[4], &prms);
E_MAIN_parm_store((Word16)indice[5], &prms);
E_MAIN_parm_store((Word16)indice[6], &prms);
E_MAIN_parm_store((Word16)indice[7], &prms);
break;
case MODE_20k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 72, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
E_MAIN_parm_store((Word16)indice[4], &prms);
E_MAIN_parm_store((Word16)indice[5], &prms);
E_MAIN_parm_store((Word16)indice[6], &prms);
E_MAIN_parm_store((Word16)indice[7], &prms);
break;
case MODE_23k:
case MODE_24k:
E_ACELP_4t(dn, cn, h1, s_code, y2, 88, *mode, indice);
E_MAIN_parm_store((Word16)indice[0], &prms);
E_MAIN_parm_store((Word16)indice[1], &prms);
E_MAIN_parm_store((Word16)indice[2], &prms);
E_MAIN_parm_store((Word16)indice[3], &prms);
E_MAIN_parm_store((Word16)indice[4], &prms);
E_MAIN_parm_store((Word16)indice[5], &prms);
E_MAIN_parm_store((Word16)indice[6], &prms);
E_MAIN_parm_store((Word16)indice[7], &prms);
break;
default:
return -1;
}
/*
* - Add the fixed-gain pitch contribution to code[].
*/
s_tmp = 0;
E_UTIL_preemph(s_code, st->mem_tilt_code, L_SUBFR, &s_tmp);
E_GAIN_pitch_sharpening(s_code, (Word16)T0);
E_ACELP_xy2_corr(xn, y1, y2, g_coeff);
/*
* - Compute the fixed codebook gain
* - quantize fixed codebook gain
*/
if (*mode <= MODE_9k)
{
index = (Word16)E_ACELP_gains_quantise(s_code, 6, gain_pit,
&s_gain_pit, &L_gain_code, g_coeff, clip_gain, st->mem_gain_q);
E_MAIN_parm_store(index, &prms);
}
else
{
index = (Word16)E_ACELP_gains_quantise(s_code, 7, gain_pit,
&s_gain_pit, &L_gain_code, g_coeff, clip_gain, st->mem_gain_q);
E_MAIN_parm_store(index, &prms);
}
/* find best scaling to perform on excitation (Q_new) */
s_tmp = st->mem_subfr_q[0];
for (i = 1; i < 4; i++)
{
if (st->mem_subfr_q[i] < s_tmp)
{
s_tmp = st->mem_subfr_q[i];
}
}
/* limit scaling (Q_new) to Q_MAX */
if (s_tmp > Q_MAX)
{
s_tmp = Q_MAX;
}
Q_new = 0;
l_tmp = L_gain_code; /* L_gain_code in Q16 */
while ((l_tmp < 0x08000000L) && (Q_new < s_tmp))
{
l_tmp = (l_tmp << 1);
Q_new = Q_new + 1;
}
if (l_tmp < 0x7FFF7FFF)
{
/* scaled gain_code with Qnew */
gain_code = (Word16)((l_tmp + 0x8000) >> 16);
}
else
{
gain_code = 32767;
}
if (Q_new > st->mem_q)
{
E_UTIL_signal_up_scale(exc + i_subfr - (PIT_MAX + L_INTERPOL),
(Word16)(Q_new - st->mem_q));
}
else
{
E_UTIL_signal_down_scale(exc + i_subfr - (PIT_MAX + L_INTERPOL),
PIT_MAX + L_INTERPOL + L_SUBFR, (Word16)(st->mem_q - Q_new));
}
st->mem_q = (Word16)Q_new;
/* test quantized gain of pitch for pitch clipping algorithm */
E_GAIN_clip_pit_test((Float32)(s_gain_pit * pow(2, -14)),
st->mem_gp_clip);
/*
* Update parameters for the next subframe.
* - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
*/
/* find voice factor in Q15 (1=voiced, -1=unvoiced) */
memcpy(exc2, &exc[i_subfr], L_SUBFR * sizeof(Word16));
E_UTIL_signal_down_scale(exc2, L_SUBFR, 3);
voice_fac = E_GAIN_voice_factor(exc2, -3, s_gain_pit, s_code, gain_code);
/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
st->mem_tilt_code = (Word16)((voice_fac >> 2) + 8192);
/*
* - Update filter's memory "mem_w0" for finding the
* target vector in the next subframe.
* - Find the total excitation
* - Find synthesis speech to update mem_syn[].
*/
memcpy(exc2, &exc[i_subfr], L_SUBFR * sizeof(Word16));
st->mem_w0 = (Float32)((xn[L_SUBFR - 1] -
((s_gain_pit / 16384.0F) * y1[L_SUBFR - 1])) -
(gain_code * pow(2, -st->mem_q) * y2[L_SUBFR - 1]));
if (*mode == MODE_24k)
{
Q_new = -st->mem_q;
for (i = 0; i < L_SUBFR; i++)
{
f_exc2[i_subfr + i] = (Float32)(exc[i_subfr + i] * pow(2, Q_new) * (s_gain_pit / 16384.0F));
}
}
s_max = 1;
for (i = 0; i < L_SUBFR; i++)
{
/* code in Q9, gain_pit in Q14 */
l_tmp = gain_code * s_code[i];
l_tmp = l_tmp << 5;
l_tmp += exc[i + i_subfr] * s_gain_pit; /* gain_pit Q14 */
l_tmp = (l_tmp + 0x2000) >> 14;
if ((l_tmp > MIN_16) & (l_tmp < 32768))
{
exc[i + i_subfr] = (Word16)l_tmp;
s_tmp = (Word16)abs(l_tmp);
if (s_tmp > s_max)
{
s_max = s_tmp;
}
}
else if (l_tmp > MAX_16)
{
exc[i + i_subfr] = MAX_16;
s_max = MAX_16;
}
else
{
exc[i + i_subfr] = MIN_16;
s_max = MAX_16;
}
}
/* tmp = scaling possible according to max value of excitation */
s_tmp = (Word16)((E_UTIL_norm_s(s_max) + st->mem_q) - 1);
st->mem_subfr_q[3] = st->mem_subfr_q[2];
st->mem_subfr_q[2] = st->mem_subfr_q[1];
st->mem_subfr_q[1] = st->mem_subfr_q[0];
st->mem_subfr_q[0] = s_tmp;
Q_new = -st->mem_q;
for (i = 0; i < L_SUBFR; i++)
{
f_exc[i + i_subfr] = (Float32)(exc[i + i_subfr] * pow(2, Q_new));
}
E_UTIL_synthesis(p_Aq, &f_exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);
if(*mode >= MODE_24k)
{
/*
* noise enhancer
* --------------
* - Enhance excitation on noise. (modify gain of code)
* If signal is noisy and LPC filter is stable, move gain
* of code 1.5 dB toward gain of code threshold.
* This decrease by 3 dB noise energy variation.
*/
/* 1=unvoiced, 0=voiced */
f_tmp = (Float32)(0.5 * (1.0 - (voice_fac / 32768.0)));
fac = stab_fac * f_tmp;
f_tmp = (Float32)(gain_code * pow(2, -st->mem_q));
if(f_tmp < st->mem_gc_threshold)
{
f_tmp = (Float32)(f_tmp * 1.19);
if(f_tmp > st->mem_gc_threshold)
{
f_tmp = st->mem_gc_threshold;
}
}
else
{
f_tmp = (Float32)(f_tmp / 1.19);
if(f_tmp < st->mem_gc_threshold)
{
f_tmp = st->mem_gc_threshold;
}
}
st->mem_gc_threshold = f_tmp;
f_tmp = (Float32)(((fac * f_tmp) + ((1.0 - fac) *
(gain_code * pow(2, -st->mem_q)))) * 0.001953125F);
for(i = 0; i < L_SUBFR; i++)
{
f_code[i] = (Float32)(s_code[i] * f_tmp);
}
/*
* pitch enhancer
* --------------
* - Enhance excitation on voice. (HP filtering of code)
* On voiced signal, filtering of code by a smooth fir HP
* filter to decrease energy of code in low frequency.
*/
/* 0.25=voiced, 0=unvoiced */
f_tmp = (Float32)(0.125F * (1.0F + (voice_fac / 32768.0)));
f_exc2[i_subfr] += f_code[0] - (f_tmp * f_code[1]);
for(i = 1; i < L_SUBFR - 1; i++)
{
f_exc2[i + i_subfr] +=
f_code[i] - (f_tmp * f_code[i - 1]) - (f_tmp * f_code[i + 1]);
}
f_exc2[i_subfr + L_SUBFR - 1] +=
f_code[L_SUBFR - 1] - (f_tmp * f_code[L_SUBFR - 2]);
corr_gain = (Word16)E_UTIL_enc_synthesis(p_Aq, &f_exc2[i_subfr],
&f_speech16k[i_subfr * 5 /4], st);
E_MAIN_parm_store(corr_gain, &prms);
}
p_A += (M + 1);
p_Aq += (M + 1);
} /* end of subframe loop */
/*
* Update signal for next frame.
* -> save past of speech[], wsp[] and exc[].
*/
memmove(st->mem_speech, &st->mem_speech[L_FRAME], (L_TOTAL - L_FRAME) * sizeof(Float32));
memmove(st->mem_wsp, &st->mem_wsp[L_FRAME / OPL_DECIM], (PIT_MAX / OPL_DECIM) * sizeof(Float32));
memmove(st->mem_exc, &st->mem_exc[L_FRAME], (PIT_MAX + L_INTERPOL) * sizeof(Word16));
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -