📄 cod_ld8k.c
字号:
/* Case of active frame */
*ana++ = 1;
seed = INIT_SEED;
ppastVad = pastVad;
pastVad = Vad;
/* LSP quantization */
Qua_lsp(lsp_new, lsp_new_q, ana);
ana += 2; /* Advance analysis parameters pointer */
/*--------------------------------------------------------------------*
* Find interpolated LPC parameters in all subframes (quantized) *
* The interpolated parameters are in array Aq_t[] of size (M+1)*4 *
*--------------------------------------------------------------------*/
Int_qlpc(lsp_old_q, lsp_new_q, Aq_t);
for(i=0; i<M; i++) lsp_old_q[i] = lsp_new_q[i];
/*----------------------------------------------------------------------*
* - Find the open-loop pitch delay *
*----------------------------------------------------------------------*/
T_op = Pitch_ol(wsp, PIT_MIN, PIT_MAX, L_FRAME);
/* Range for closed loop pitch search in 1st subframe */
T0_min = sub(T_op, 3);
if (sub(T0_min,PIT_MIN)<0) {
T0_min = PIT_MIN;
}
T0_max = add(T0_min, 6);
if (sub(T0_max ,PIT_MAX)>0)
{
T0_max = PIT_MAX;
T0_min = sub(T0_max, 6);
}
/*------------------------------------------------------------------------*
* 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 2 times. *
* - find the weighted LPC coefficients *
* - find the LPC residual signal res[] *
* - compute the target signal for pitch search *
* - compute impulse response of weighted synthesis filter (h1[]) *
* - find the closed-loop pitch parameters *
* - encode the pitch delay *
* - update the impulse response h1[] by including fixed-gain pitch *
* - find target vector for codebook search *
* - codebook search *
* - encode codebook address *
* - VQ of pitch and codebook gains *
* - find synthesis speech *
* - update states of weighting filter *
*------------------------------------------------------------------------*/
A = A_t; /* pointer to interpolated LPC parameters */
Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */
i_gamma = 0;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
/*---------------------------------------------------------------*
* Find the weighted LPC coefficients for the weighting filter. *
*---------------------------------------------------------------*/
Weight_Az(A, gamma1[i_gamma], M, Ap1);
Weight_Az(A, gamma2[i_gamma], M, Ap2);
i_gamma = add(i_gamma,1);
/*---------------------------------------------------------------*
* Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
for (i = 0; i <= M; i++) {
ai_zero[i] = Ap1[i];
}
Syn_filt(Aq, ai_zero, h1, L_SUBFR, zero, 0);
Syn_filt(Ap2, h1, h1, L_SUBFR, zero, 0);
/*------------------------------------------------------------------------*
* *
* 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. This configuration gives better performance *
* with fixed-point implementation. The memory of 1/A(z) is updated by *
* filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting *
* the synthesis speech from the input speech: *
* error[n] = speech[n] - syn[n]. *
* The memory of W(z) is updated by filtering error[n] through W(z), *
* or more simply by subtracting the filtered adaptive and fixed *
* codebook excitations from the target: *
* target[n] - gain_pit*y1[n] - gain_code*y2[n] *
* as these signals are already available. *
* *
*------------------------------------------------------------------------*/
Residu(Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); /* LPC residual */
Syn_filt(Aq, &exc[i_subfr], error, L_SUBFR, mem_err, 0);
Residu(Ap1, error, xn, L_SUBFR);
Syn_filt(Ap2, xn, xn, L_SUBFR, mem_w0, 0); /* target signal xn[]*/
/*----------------------------------------------------------------------*
* Closed-loop fractional pitch search *
*----------------------------------------------------------------------*/
T0 = Pitch_fr3(&exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max,
i_subfr, &T0_frac);
index = Enc_lag3(T0, T0_frac, &T0_min, &T0_max,PIT_MIN,PIT_MAX,i_subfr);
*ana++ = index;
if (i_subfr == 0) {
*ana++ = Parity_Pitch(index);
}
/*-----------------------------------------------------------------*
* - find unity gain pitch excitation (adaptive codebook entry) *
* with fractional interpolation. *
* - find filtered pitch exc. y1[]=exc[] convolve with h1[]) *
* - compute pitch gain and limit between 0 and 1.2 *
* - update target vector for codebook search *
* - find LTP residual. *
*-----------------------------------------------------------------*/
Pred_lt_3(&exc[i_subfr], T0, T0_frac, L_SUBFR);
Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
gain_pit = G_pitch(xn, y1, g_coeff, L_SUBFR);
/* clip pitch gain if taming is necessary */
temp = test_err(T0, T0_frac);
if( temp == 1){
if (sub(gain_pit, GPCLIP) > 0) {
gain_pit = GPCLIP;
}
}
/* xn2[i] = xn[i] - y1[i] * gain_pit */
for (i = 0; i < L_SUBFR; i++)
{
L_temp = L_mult(y1[i], gain_pit);
L_temp = L_shl(L_temp, 1); /* gain_pit in Q14 */
xn2[i] = sub(xn[i], extract_h(L_temp));
}
/*-----------------------------------------------------*
* - Innovative codebook search. *
*-----------------------------------------------------*/
index = ACELP_Codebook(xn2, h1, T0, sharp, i_subfr, code, y2, &i);
*ana++ = index; /* Positions index */
*ana++ = i; /* Signs index */
/*-----------------------------------------------------*
* - Quantization of gains. *
*-----------------------------------------------------*/
g_coeff_cs[0] = g_coeff[0]; /* <y1,y1> */
exp_g_coeff_cs[0] = negate(g_coeff[1]); /* Q-Format:XXX -> JPN */
g_coeff_cs[1] = negate(g_coeff[2]); /* (xn,y1) -> -2<xn,y1> */
exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1)); /* Q-Format:XXX -> JPN */
Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs ); /* Q0 Q0 Q12 ^Qx ^Q0 */
/* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2> */
/* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */
/* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2> */
*ana++ = Qua_gain(code, g_coeff_cs, exp_g_coeff_cs,
L_SUBFR, &gain_pit, &gain_code, temp);
/*------------------------------------------------------------*
* - Update pitch sharpening "sharp" with quantized gain_pit *
*------------------------------------------------------------*/
sharp = gain_pit;
if (sub(sharp, SHARPMAX) > 0) { sharp = SHARPMAX; }
if (sub(sharp, SHARPMIN) < 0) { sharp = SHARPMIN; }
/*------------------------------------------------------*
* - Find the total excitation *
* - find synthesis speech corresponding to exc[] *
* - update filters memories for finding the target *
* vector in the next subframe *
* (update error[-m..-1] and mem_w_err[]) *
* update error function for taming process *
*------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++)
{
/* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */
/* exc[i] in Q0 gain_pit in Q14 */
/* code[i] in Q13 gain_cod in Q1 */
L_temp = L_mult(exc[i+i_subfr], gain_pit);
L_temp = L_mac(L_temp, code[i], gain_code);
L_temp = L_shl(L_temp, 1);
exc[i+i_subfr] = round(L_temp);
}
update_exc_err(gain_pit, T0);
Syn_filt(Aq, &exc[i_subfr], &synth[i_subfr], L_SUBFR, mem_syn, 1);
for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++)
{
mem_err[j] = sub(speech[i_subfr+i], synth[i_subfr+i]);
temp = extract_h(L_shl( L_mult(y1[i], gain_pit), 1) );
k = extract_h(L_shl( L_mult(y2[i], gain_code), 2) );
mem_w0[j] = sub(xn[i], add(temp, k));
}
A += MP1; /* interpolated LPC parameters for next subframe */
Aq += MP1;
}
/*--------------------------------------------------*
* Update signal for next frame. *
* -> shift to the left by L_FRAME: *
* speech[], wsp[] and exc[] *
*--------------------------------------------------*/
Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME);
Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX);
Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL);
return;
}
/*---------------------------------------------------------------------------*
* routine corr_xy2() *
* ~~~~~~~~~~~~~~~~~~~~ *
* Find the correlations between the target xn[], the filtered adaptive *
* codebook excitation y1[], and the filtered 1st codebook innovation y2[]. *
* g_coeff[2]:exp_g_coeff[2] = <y2,y2> *
* g_coeff[3]:exp_g_coeff[3] = -2<xn,y2> *
* g_coeff[4]:exp_g_coeff[4] = 2<y1,y2> *
*---------------------------------------------------------------------------*/
void Corr_xy2(
Word16 xn[], /* (i) Q0 :Target vector. */
Word16 y1[], /* (i) Q0 :Adaptive codebook. */
Word16 y2[], /* (i) Q12 :Filtered innovative vector. */
Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */
Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */
)
{
Word16 i,exp;
Word16 exp_y2y2,exp_xny2,exp_y1y2;
Word16 y2y2, xny2, y1y2;
Word32 L_acc;
Word16 scaled_y2[L_SUBFR]; /* Q9 */
/*------------------------------------------------------------------*
* Scale down y2[] from Q12 to Q9 to avoid overflow *
*------------------------------------------------------------------*/
for(i=0; i<L_SUBFR; i++)
scaled_y2[i] = shr(y2[i], 3);
/* Compute scalar product <y2[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for(i=0; i<L_SUBFR; i++)
L_acc = L_mac(L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */
exp = norm_l(L_acc);
y2y2 = round( L_shl(L_acc, exp) );
exp_y2y2 = add(exp, 19-16); /* Q[19+exp-16] */
g_coeff[2] = y2y2;
exp_g_coeff[2] = exp_y2y2;
/* Compute scalar product <xn[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for(i=0; i<L_SUBFR; i++)
L_acc = L_mac(L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l(L_acc);
xny2 = round( L_shl(L_acc, exp) );
exp_xny2 = add(exp, 10-16); /* Q[10+exp-16] */
g_coeff[3] = negate(xny2);
exp_g_coeff[3] = sub(exp_xny2,1); /* -2<xn,y2> */
/* Compute scalar product <y1[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for(i=0; i<L_SUBFR; i++)
L_acc = L_mac(L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l(L_acc);
y1y2 = round( L_shl(L_acc, exp) );
exp_y1y2 = add(exp, 10-16); /* Q[10+exp-16] */
g_coeff[4] = y1y2;
exp_g_coeff[4] = sub(exp_y1y2,1); ; /* 2<y1,y2> */
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -