📄 cod_main.c
字号:
/* last L_FILT samples for autocorrelation window */
Copy(st->mem_sig_in, code, 6);
HP50_12k8(new_speech + L_FRAME, L_FILT, code);
/*---------------------------------------------------------------*
* Perform fixed preemphasis through 1 - g z^-1 *
* Scale signal to get maximum of precision in filtering *
*---------------------------------------------------------------*/
mu = shr(PREEMPH_FAC, 1); /* Q15 --> Q14 */
/* get max of new preemphased samples (L_FRAME+L_FILT) */
L_tmp = L_mult(new_speech[0], 16384);
L_tmp = L_msu(L_tmp, st->mem_preemph, mu);
L_max = L_abs(L_tmp);
for (i = 1; i < L_FRAME + L_FILT; i++)
{
L_tmp = L_mult(new_speech[i], 16384);
L_tmp = L_msu(L_tmp, new_speech[i - 1], mu);
L_tmp = L_abs(L_tmp);
test();
if (L_sub(L_tmp, L_max) > (Word32) 0)
{
L_max = L_tmp; move32();
}
}
/* get scaling factor for new and previous samples */
/* limit scaling to Q_MAX to keep dynamic for ringing in low signal */
/* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */
tmp = extract_h(L_max);
test();
if (tmp == 0)
{
shift = Q_MAX; move16();
} else
{
shift = sub(norm_s(tmp), 1);
test();
if (shift < 0)
{
shift = 0; move16();
}
test();
if (sub(shift, Q_MAX) > 0)
{
shift = Q_MAX; move16();
}
}
Q_new = shift; move16();
test();
if (sub(Q_new, st->Q_max[0]) > 0)
{
Q_new = st->Q_max[0]; move16();
}
test();
if (sub(Q_new, st->Q_max[1]) > 0)
{
Q_new = st->Q_max[1]; move16();
}
exp = sub(Q_new, st->Q_old);
st->Q_old = Q_new; move16();
st->Q_max[1] = st->Q_max[0]; move16();
st->Q_max[0] = shift; move16();
/* preemphasis with scaling (L_FRAME+L_FILT) */
tmp = new_speech[L_FRAME - 1]; move16();
for (i = L_FRAME + L_FILT - 1; i > 0; i--)
{
L_tmp = L_mult(new_speech[i], 16384);
L_tmp = L_msu(L_tmp, new_speech[i - 1], mu);
L_tmp = L_shl(L_tmp, Q_new);
new_speech[i] = round(L_tmp); move16();
}
L_tmp = L_mult(new_speech[0], 16384);
L_tmp = L_msu(L_tmp, st->mem_preemph, mu);
L_tmp = L_shl(L_tmp, Q_new);
new_speech[0] = round(L_tmp); move16();
st->mem_preemph = tmp; move16();
/* scale previous samples and memory */
Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp);
Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp);
Scale_sig(st->mem_syn, M, exp);
Scale_sig(st->mem_decim2, 3, exp);
Scale_sig(&(st->mem_wsp), 1, exp);
Scale_sig(&(st->mem_w0), 1, exp);
/*------------------------------------------------------------------------*
* Call VAD *
* Preemphesis scale down signal in low frequency and keep dynamic in HF.*
* Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT). *
*------------------------------------------------------------------------*/
Copy(new_speech, buf, L_FRAME);
Scale_sig(buf, L_FRAME, sub(1, Q_new));
vad_flag = wb_vad(st->vadSt, buf);
if (vad_flag == 0)
{
st->vad_hist = add(st->vad_hist, 1); move16();
} else
{
st->vad_hist = 0; move16();
}
/* DTX processing */
test();
if (allow_dtx != 0)
{
/* Note that mode may change here */
tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
*ser_size = nb_of_bits[*mode]; move16();
}
test();
if (sub(*mode, MRDTX) != 0)
{
Parm_serial(vad_flag, 1, &prms);
}
/*------------------------------------------------------------------------*
* Perform LPC analysis *
* ~~~~~~~~~~~~~~~~~~~~ *
* - autocorrelation + lag windowing *
* - Levinson-durbin algorithm to find a[] *
* - convert a[] to isp[] *
* - convert isp[] to isf[] for quantization *
* - quantize and code the isf[] *
* - convert isf[] to isp[] for interpolation *
* - find the interpolated ISPs and convert to a[] for the 4 subframes *
*------------------------------------------------------------------------*/
/* LP analysis centered at 4nd subframe */
Autocorr(p_window, M, r_h, r_l); /* Autocorrelations */
Lag_window(r_h, r_l); /* Lag windowing */
Levinson(r_h, r_l, A, rc, st->mem_levinson); /* Levinson Durbin */
Az_isp(A, ispnew, st->ispold); /* From A(z) to ISP */
/* Find the interpolated ISPs and convert to a[] for all subframes */
Int_isp(st->ispold, ispnew, interpol_frac, A);
/* update ispold[] for the next frame */
Copy(ispnew, st->ispold, M);
/* Convert ISPs to frequency domain 0..6400 */
Isp_isf(ispnew, isf, M);
/* check resonance for pitch clipping algorithm */
Gp_clip_test_isf(isf, st->gp_clip);
/*----------------------------------------------------------------------*
* Perform PITCH_OL analysis *
* ~~~~~~~~~~~~~~~~~~~~~~~~~ *
* - Find the residual res[] for the whole speech frame *
* - Find the weighted input speech wsp[] for the whole speech frame *
* - scale wsp[] to avoid overflow in pitch estimation *
* - Find open loop pitch lag for whole speech frame *
*----------------------------------------------------------------------*/
p_A = A; move16();
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
Weight_a(p_A, Ap, GAMMA1, M);
Residu(Ap, M, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
p_A += (M + 1); move16();
}
Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
/* find maximum value on wsp[] for 12 bits scaling */
max = 0; move16();
for (i = 0; i < L_FRAME; i++)
{
tmp = abs_s(wsp[i]);
test();
if (sub(tmp, max) > 0)
{
max = tmp; move16();
}
}
tmp = st->old_wsp_max; move16();
test();
if (sub(max, tmp) > 0)
{
tmp = max; /* tmp = max(wsp_max, old_wsp_max) */
move16();
}
st->old_wsp_max = max; move16();
shift = sub(norm_s(tmp), 3);
test();
if (shift > 0)
{
shift = 0; /* shift = 0..-3 */
move16();
}
/* decimation of wsp[] to search pitch in LF and to reduce complexity */
LP_Decim2(wsp, L_FRAME, st->mem_decim2);
/* scale wsp[] in 12 bits to avoid overflow */
Scale_sig(wsp, L_FRAME / OPL_DECIM, shift);
/* scale old_wsp (warning: exp must be Q_new-Q_old) */
exp = add(exp, sub(shift, st->old_wsp_shift));
st->old_wsp_shift = shift;
Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp);
Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp);
scale_mem_Hp_wsp(st->hp_wsp_mem, exp);
/* Find open loop pitch lag for whole speech frame */
test();
if (sub(*ser_size, NBBITS_7k) == 0)
{
/* Find open loop pitch lag for whole speech frame */
T_op = Pitch_med_ol(wsp, PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
L_FRAME / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
} else
{
/* Find open loop pitch lag for first 1/2 frame */
T_op = Pitch_med_ol(wsp, PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
(L_FRAME / 2) / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
}
test();
if (sub(st->ol_gain, 19661) > 0) /* 0.6 in Q15 */
{
st->old_T0_med = Med_olag(T_op, st->old_ol_lag); move16();
st->ada_w = 32767; move16();
} else
{
st->ada_w = mult(st->ada_w, 29491);move16();
}
test();move16();
if (sub(st->ada_w, 26214) < 0)
st->ol_wght_flg = 0;
else
st->ol_wght_flg = 1;
wb_vad_tone_detection(st->vadSt, st->ol_gain);
T_op *= OPL_DECIM; move16();
test();
if (sub(*ser_size, NBBITS_7k) != 0)
{
/* Find open loop pitch lag for second 1/2 frame */
T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
(L_FRAME / 2) / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
test();
if (sub(st->ol_gain, 19661) > 0) /* 0.6 in Q15 */
{
st->old_T0_med = Med_olag(T_op2, st->old_ol_lag); move16();
st->ada_w = 32767; move16();
} else
{
st->ada_w = mult(st->ada_w, 29491); move16();
}
test();move16();
if (sub(st->ada_w, 26214) < 0)
st->ol_wght_flg = 0;
else
st->ol_wght_flg = 1;
wb_vad_tone_detection(st->vadSt, st->ol_gain);
T_op2 *= OPL_DECIM; move16();
} else
{
T_op2 = T_op; move16();
}
/*----------------------------------------------------------------------*
* DTX-CNG *
*----------------------------------------------------------------------*/
test();
if (sub(*mode, MRDTX) == 0) /* CNG mode */
{
/* Buffer isf's and energy */
Residu(&A[3 * (M + 1)], M, speech, exc, L_FRAME);
for (i = 0; i < L_FRAME; i++)
{
exc2[i] = shr(exc[i], Q_new); move16();
}
L_tmp = 0; move32();
for (i = 0; i < L_FRAME; i++)
L_tmp = L_mac(L_tmp, exc2[i], exc2[i]);
L_tmp = L_shr(L_tmp, 1);
dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
/* Quantize and code the ISFs */
dtx_enc(st->dtx_encSt, isf, exc2, &prms);
/* Convert ISFs to the cosine domain */
Isf_isp(isf, ispnew_q, M);
Isp_Az(ispnew_q, Aq, M, 0);
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st);
}
Copy(isf, st->isfold, M);
/* reset speech coder memories */
Reset_encoder(st, 0);
/*--------------------------------------------------*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -