📄 cod_main.c
字号:
* Update signal for next frame. *
* -> save past of speech[] and wsp[]. *
*--------------------------------------------------*/
Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
return;
}
/*----------------------------------------------------------------------*
* ACELP *
*----------------------------------------------------------------------*/
/* Quantize and code the ISFs */
test();
if (sub(*ser_size, NBBITS_7k) <= 0)
{
Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);
Parm_serial(indice[0], 8, &prms);
Parm_serial(indice[1], 8, &prms);
Parm_serial(indice[2], 7, &prms);
Parm_serial(indice[3], 7, &prms);
Parm_serial(indice[4], 6, &prms);
} else
{
Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);
Parm_serial(indice[0], 8, &prms);
Parm_serial(indice[1], 8, &prms);
Parm_serial(indice[2], 6, &prms);
Parm_serial(indice[3], 7, &prms);
Parm_serial(indice[4], 7, &prms);
Parm_serial(indice[5], 5, &prms);
Parm_serial(indice[6], 5, &prms);
}
/* Check stability on isf : distance between old isf and current isf */
L_tmp = 0; move32();
for (i = 0; i < M - 1; i++)
{
tmp = sub(isf[i], st->isfold[i]);
L_tmp = L_mac(L_tmp, tmp, tmp);
}
tmp = extract_h(L_shl(L_tmp, 8)); /* saturation can occur here */
tmp = mult(tmp, 26214); /* tmp = L_tmp*0.8/256 */
tmp = sub(20480, tmp); /* 1.25 - tmp (in Q14) */
stab_fac = shl(tmp, 1); /* saturation can occur here */
test();
if (stab_fac < 0)
{
stab_fac = 0; move16();
}
Copy(isf, st->isfold, M);
/* Convert ISFs to the cosine domain */
Isf_isp(isf, ispnew_q, M);
test();
if (st->first_frame != 0)
{
st->first_frame = 0; move16();
Copy(ispnew_q, st->ispold_q, M);
}
/* Find the interpolated ISPs and convert to a[] for all subframes */
Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);
/* update ispold[] for the next frame */
Copy(ispnew_q, st->ispold_q, M);
p_Aq = Aq;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
p_Aq += (M + 1); move16();
}
/* Buffer isf's and energy for dtx on non-speech frame */
test();
if (vad_flag == 0)
{
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);
}
/* range for closed loop pitch search in 1st subframe */
T0_min = sub(T_op, 8);
test();
if (sub(T0_min, PIT_MIN) < 0)
{
T0_min = PIT_MIN; move16();
}
T0_max = add(T0_min, 15);
test();
if (sub(T0_max, PIT_MAX) > 0)
{
T0_max = PIT_MAX; move16();
T0_min = sub(T0_max, 15); move16();
}
/*------------------------------------------------------------------------*
* Loop for every subframe in the analysis frame *
*------------------------------------------------------------------------*
* To find the pitch and innovation parameters. The subframe size is *
* L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. *
* - compute the target signal for pitch search *
* - compute impulse response of weighted synthesis filter (h1[]) *
* - find the closed-loop pitch parameters *
* - encode the pitch dealy *
* - find 2 lt prediction (with / without LP filter for lt pred) *
* - find 2 pitch gains and choose the best lt prediction. *
* - find target vector for codebook search *
* - update the impulse response h1[] for codebook search *
* - correlation between target vector and impulse response *
* - codebook search and encoding *
* - VQ of pitch and codebook gains *
* - find voicing factor and tilt of code for next subframe. *
* - update states of weighting filter *
* - find excitation and synthesis speech *
*------------------------------------------------------------------------*/
p_A = A; move16();
p_Aq = Aq; move16();
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
pit_flag = i_subfr; move16();
test();test();
if ((sub(i_subfr, 2 * L_SUBFR) == 0) && (sub(*ser_size, NBBITS_7k) > 0))
{
pit_flag = 0; move16();
/* range for closed loop pitch search in 3rd subframe */
T0_min = sub(T_op2, 8);
test();
if (sub(T0_min, PIT_MIN) < 0)
{
T0_min = PIT_MIN; move16();
}
T0_max = add(T0_min, 15);
test();
if (sub(T0_max, PIT_MAX) > 0)
{
T0_max = PIT_MAX; move16();
T0_min = sub(T0_max, 15);
}
}
/*-----------------------------------------------------------------------*
* *
* Find the target vector for pitch search: *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* *
* |------| res[n] *
* speech[n]---| A(z) |-------- *
* |------| | |--------| error[n] |------| *
* zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
* exc |--------| |------| *
* *
* Instead of subtracting the zero-input response of filters from *
* the weighted input speech, the above configuration is used to *
* compute the target vector. *
* *
*-----------------------------------------------------------------------*/
for (i = 0; i < M; i++)
{
error[i] = sub(speech[i + i_subfr - M], st->mem_syn[i]); move16();
}
Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
Syn_filt(p_Aq, M, &exc[i_subfr], error + M, L_SUBFR, error, 0);
Weight_a(p_A, Ap, GAMMA1, M);
Residu(Ap, M, error + M, xn, L_SUBFR);
Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));
/*----------------------------------------------------------------------*
* Find approx. target in residual domain "cn[]" for inovation search. *
*----------------------------------------------------------------------*/
/* first half: xn[] --> cn[] */
Set_zero(code, M);
Copy(xn, code + M, L_SUBFR / 2);
tmp = 0; move16();
Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
Weight_a(p_A, Ap, GAMMA1, M);
Syn_filt(Ap, M, code + M, code + M, L_SUBFR / 2, code, 0);
Residu(p_Aq, M, code + M, cn, L_SUBFR / 2);
/* second half: res[] --> cn[] (approximated and faster) */
Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
/*---------------------------------------------------------------*
* Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
Set_zero(error, M + L_SUBFR);
Weight_a(p_A, error + M, GAMMA1, M);
for (i = 0; i < L_SUBFR; i++)
{
L_tmp = L_mult(error[i + M], 16384); /* x4 (Q12 to Q14) */
for (j = 1; j <= M; j++)
L_tmp = L_msu(L_tmp, p_Aq[j], error[i + M - j]);
h1[i] = error[i + M] = round(L_shl(L_tmp, 3)); move16();move16();
}
/* deemph without division by 2 -> Q14 to Q15 */
tmp = 0; move16();
Deemph2(h1, TILT_FAC, L_SUBFR, &tmp); /* h1 in Q14 */
/* h2 in Q12 for codebook search */
Copy(h1, h2, L_SUBFR);
Scale_sig(h2, L_SUBFR, -2);
/*---------------------------------------------------------------*
* scale xn[] and h1[] to avoid overflow in dot_product12() *
*---------------------------------------------------------------*/
Scale_sig(xn, L_SUBFR, shift); /* scaling of xn[] to limit dynamic at 12 bits */
Scale_sig(h1, L_SUBFR, add(1, shift)); /* set h1[] in Q15 with scaling for convolution */
/*----------------------------------------------------------------------*
* Closed-loop fractional pitch search *
*----------------------------------------------------------------------*/
/* find closed loop fractional pitch lag */
test();
if (sub(*ser_size, NBBITS_9k) <= 0)
{
T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);
/* encode pitch lag */
test();
if (pit_flag == 0) /* if 1st/3rd subframe */
{
/*--------------------------------------------------------------*
* The pitch range for the 1st/3rd subframe is encoded with *
* 8 bits and is divided as follows: *
* PIT_MIN to PIT_FR1-1 resolution 1/2 (frac = 0 or 2) *
* PIT_FR1 to PIT_MAX resolution 1 (frac = 0) *
*--------------------------------------------------------------*/
test();
if (sub(T0, PIT_FR1_8b) < 0)
{
index = sub(add(shl(T0, 1), shr(T0_frac, 1)), (PIT_MIN * 2));
} else
{
index = add(sub(T0, PIT_FR1_8b), ((PIT_FR1_8b - PIT_MIN) * 2));
}
Parm_serial(index, 8, &prms);
/* find T0_min and T0_max for subframe 2 and 4 */
T0_min = sub(T0, 8);
test();
if (sub(T0_min, PIT_MIN) < 0)
{
T0_min = PIT_MIN; move16();
}
T0_max = add(T0_min, 15);
test();
if (sub(T0_max, PIT_MAX) > 0)
{
T0_max = PIT_MAX; move16();
T0_min = sub(T0_max, 15);
}
} else
{ /* if subframe 2 or 4 */
/*--------------------------------------------------------------*
* The pitch range for subframe 2 or 4 is encoded with 5 bits: *
* T0_min to T0_max resolution 1/2 (frac = 0 or 2) *
*--------------------------------------------------------------*/
i = sub(T0, T0_min);
index = add(shl(i, 1), shr(T0_frac, 1));
Parm_serial(index, 5, &prms);
}
} else
{
T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);
/* encode pitch lag */
test();
if (pit_flag == 0) /* if 1st/3rd subframe */
{
/*--------------------------------------------------------------*
* The pitch range for the 1st/3rd subframe is encoded with *
* 9 bits and is divided as follows: *
* PIT_MIN to PIT_FR2-1 resolution 1/4 (frac = 0,1,2 or 3) *
* PIT_FR2 to PIT_FR1-1 resolution 1/2 (frac = 0 or 1) *
* PIT_FR1 to PIT_MAX resolution 1 (frac = 0) *
*--------------------------------------------------------------*/
test();test();
if (sub(T0, PIT_FR2) < 0)
{
index = sub(add(shl(T0, 2), T0_frac), (PIT_MIN * 4));
} else if (sub(T0, PIT_FR1_9b) < 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -