📄 melp_syn.c
字号:
ifact = divide_s(syn_begin, FRAME); /* ifact in Q15 */
if (syn_begin >= GAINFR){
gaincnt = 2;
temp1 = sub(syn_begin, GAINFR);
ifact_gain = divide_s(temp1, GAINFR);
} else {
gaincnt = 1;
ifact_gain = divide_s(syn_begin, GAINFR);
}
/* interpolate gain. It is assumed that par->gain[] are obtained */
/* from gain_vq_cb[] in "qnt12_cb.c", and gain_vq_cb[] lies between */
/* 2564 and 18965 (Q8). Therefore, the interpolated "gain" is also */
/* assumed to be between these two values. */
if (gaincnt > 1){
/* gain = ifact_gain * par->gain[gaincnt - 1] +
(1.0 - ifact_gain) * par->gain[gaincnt - 2]; */
L_temp1 = L_mult(par->gain[gaincnt - 1], ifact_gain);
temp1 = sub(ONE_Q15, ifact_gain);
L_temp2 = L_mult(par->gain[gaincnt - 2], temp1);
gain = extract_h(L_add(L_temp1, L_temp2)); /* gain in Q8 */
} else {
/* gain = ifact_gain * par->gain[gaincnt - 1] +
(1.0 - ifact_gain) * prev_par.gain[NUM_GAINFR - 1]; */
L_temp1 = L_mult(par->gain[gaincnt - 1], ifact_gain);
temp1 = sub(ONE_Q15, ifact_gain);
L_temp2 = L_mult(prev_par.gain[NUM_GAINFR - 1], temp1);
gain = extract_h(L_add(L_temp1, L_temp2)); /* gain in Q8 */
}
/* Set overall interpolation path based on gain change */
temp1 = sub(par->gain[NUM_GAINFR - 1], prev_par.gain[NUM_GAINFR - 1]);
if (abs_s(temp1) > SIX_Q8){
/* Power surge: use gain adjusted interpolation */
/* intfact = (gain - prev_par.gain[NUM_GAINFR - 1])/temp; */
temp2 = sub(gain, prev_par.gain[NUM_GAINFR - 1]);
if (((temp2 > 0) && (temp1 < 0)) ||
((temp2 < 0) && (temp1 > 0)))
intfact = 0;
else {
temp1 = abs_s(temp1);
temp2 = abs_s(temp2);
if (temp2 >= temp1)
intfact = ONE_Q15;
else
intfact = divide_s(temp2, temp1); /* intfact in Q15 */
}
} else /* Otherwise, linear interpolation */
intfact = ifact;
/* interpolate LSF's and convert to LPC filter */
interp_array(prev_par.lsf, par->lsf, lsf, intfact, LPC_ORD);
lpc_lsp2pred(lsf, &(lpc[1]), LPC_ORD);
/* Check signal probability for adaptive spectral enhancement filter */
temp1 = add(noise_gain, X12_Q8);
temp2 = add(noise_gain, X30_Q8);
/* sig_prob in Q15 */
sig_prob = lin_int_bnd(gain, temp1, temp2, 0, ONE_Q15);
/* Calculate adaptive spectral enhancement filter coefficients */
ase_num[0] = ONE_Q12; /* ase_num and ase_den in Q12 */
temp1 = mult(sig_prob, ASE_NUM_BW_Q15);
lpc_bw_expand(&(lpc[1]), &(ase_num[1]), temp1, LPC_ORD);
temp1 = mult(sig_prob, ASE_DEN_BW_Q15);
lpc_bw_expand(&(lpc[1]), ase_den, temp1, LPC_ORD);
/* tilt_cof[1] = sig_prob * (intfact * curr_tilt +
(1.0 - intfact) * prev_tilt); */
temp1 = mult(curr_tilt, intfact);
intfact1 = sub(ONE_Q15, intfact);
temp2 = mult(prev_tilt, intfact1);
temp1 = add(temp1, temp2);
tilt_cof[1] = mult(sig_prob, temp1); /* tilt_cof in Q15 */
/* interpolate pitch and pulse gain */
/* syn_gain = SYN_GAIN * (intfact * lpc_gain +
(1.0 - intfact) * prev_lpc_gain); */
temp1 = mult(lpc_gain, intfact); /* lpc_gain in Q15 */
temp2 = mult(prev_lpc_gain, intfact1);
temp1 = add(temp1, temp2); /* temp1 in Q15 */
syn_gain = mult(SYN_GAIN_Q4, temp1);
/* syn_gain in Q4 */
/* pitch = intfact * par->pitch + (1.0 - intfact) * prev_par.pitch; */
temp1 = mult(par->pitch, intfact);
temp2 = mult(prev_par.pitch, intfact1);
pitch = add(temp1, temp2); /* pitch in Q7 */
/* pulse_gain = syn_gain * sqrt(pitch); */
temp1 = sqrt_fxp(pitch, 7);
L_temp1 = L_mult(syn_gain, temp1);
L_temp1 = L_shl(L_temp1, 4);
pulse_gain = extract_h(L_temp1); /* pulse_gain in Q0 */
/* interpolate pulse and noise coefficients */
temp1 = sqrt_fxp(ifact, 15);
interp_array(prev_pcof, curr_pcof, pulse_cof, temp1, MIX_ORD + 1);
interp_array(prev_ncof, curr_ncof, noise_cof, temp1, MIX_ORD + 1);
set_fc(prev_par.bpvc, &fc_prev);
set_fc(par->bpvc, &fc_curr);
temp2 = sub(ONE_Q15, temp1);
temp1 = mult(temp1, fc_curr); /* temp1 is now Q3 */
temp2 = mult(temp2, fc_prev); /* Q3 */
fc = add(temp1, temp2); /* Q3 */
/* interpolate jitter */
/* jitter = ifact * par->jitter + (1.0 - ifact) * prev_par.jitter; */
temp1 = mult(par->jitter, ifact);
temp2 = sub(ONE_Q15, ifact); /* temp2 is Q15 */
temp2 = mult(prev_par.jitter, temp2);
jitter = add(temp1, temp2); /* jitter is Q15 */
/* scale gain by 0.05 but keep gain in log. */
/* gain = pow(10.0, 0.05 * gain); */
gain = mult(X005_Q19, gain); /* gain in Q12 */
/* Set period length based on pitch and jitter */
rand_num(&temp1, ONE_Q15, 1);
/* length = pitch * (1.0 - jitter * temp) + 0.5; */
temp1 = mult(jitter, temp1);
temp1 = shr(temp1, 1); /* temp1 in Q14 */
temp1 = sub(ONE_Q14, temp1);
temp1 = mult(pitch, temp1); /* length in Q6 */
length = shift_r(temp1, -6); /* length in Q0 with rounding */
if (length < PITCHMIN)
length = PITCHMIN;
if (length > PITCHMAX)
length = PITCHMAX;
fill(fs_real, ONE_Q13, length);
fs_real[0] = 0;
interp_array(prev_par.fs_mag, par->fs_mag, &fs_real[1], intfact,
NUM_HARM);
#if TIME_DOMAIN_SYN
/* Use inverse DFT for pulse excitation */
idft_real(fs_real, &sigbuf[BEGIN], length); /* sigbuf in Q15 */
/* Delay overall signal by PDEL samples (circular shift) */
/* use fs_real as a scratch buffer */
v_equ(fs_real, &sigbuf[BEGIN], length);
v_equ(&sigbuf[BEGIN + PDEL], fs_real, length - PDEL);
v_equ(&sigbuf[BEGIN], &fs_real[length - PDEL], PDEL);
/* Scale by pulse gain */
v_scale(&sigbuf[BEGIN], pulse_gain, length); /* sigbuf in Q0 */
/* Filter and scale pulse excitation */
v_equ(&sigbuf[BEGIN - MIX_ORD], pulse_del, MIX_ORD);
v_equ(pulse_del, &sigbuf[length + BEGIN - MIX_ORD], MIX_ORD);
zerflt_Q(&sigbuf[BEGIN], pulse_cof, &sigbuf[BEGIN], MIX_ORD, length,
14);
temp1 = shr(mult(X1_732_Q14, syn_gain), 3); /* Q0 */
/* Get scaled noise excitation */
rand_num(&sig2[BEGIN], temp1, length); /* sig2 in Q0 */
/* Filter noise excitation */
v_equ(&sig2[BEGIN - MIX_ORD], noise_del, MIX_ORD);
v_equ(noise_del, &sig2[length + BEGIN - MIX_ORD], MIX_ORD);
zerflt_Q(&sig2[BEGIN], noise_cof, &sig2[BEGIN], MIX_ORD, length, 14);
/* Add two excitation signals (mixed excitation) */
v_add(&sigbuf[BEGIN], &sig2[BEGIN], length); /* sigbuf in Q0 */
#else
harm_syn_pitch(fs_real, &sigbuf[BEGIN], fc, length);
v_scale(&sigbuf[BEGIN], pulse_gain, length); /* sigbuf[] is Q0 */
#endif
/* Adaptive spectral enhancement */
v_equ(&sigbuf[BEGIN - LPC_ORD], ase_del, LPC_ORD);
lpc_synthesis(&sigbuf[BEGIN], &sigbuf[BEGIN], ase_den, LPC_ORD,
length);
v_equ(ase_del, &sigbuf[BEGIN + length - LPC_ORD], LPC_ORD);
zerflt(&sigbuf[BEGIN], ase_num, &sigbuf[BEGIN], LPC_ORD, length);
v_equ(&sigbuf[BEGIN - TILT_ORD], tilt_del, TILT_ORD);
v_equ(tilt_del, &sigbuf[length + BEGIN - TILT_ORD], TILT_ORD);
zerflt_Q(&sigbuf[BEGIN], tilt_cof, &sigbuf[BEGIN], TILT_ORD, length,
15);
/* Possible Signal overflow at this point! */
/* Perform LPC synthesis filtering */
v_equ(&sigbuf[BEGIN - LPC_ORD], lpc_del, LPC_ORD);
lpc_synthesis(&sigbuf[BEGIN], &sigbuf[BEGIN], &(lpc[1]), LPC_ORD,
length);
v_equ(lpc_del, &sigbuf[length + BEGIN - LPC_ORD], LPC_ORD);
/* Adjust scaling of synthetic speech, sigbuf in Q0 */
scale_adj(&sigbuf[BEGIN], gain, length, SCALEOVER, INV_SCALEOVER_Q18);
/* Implement pulse dispersion filter on output speech */
v_equ(&sigbuf[BEGIN - DISP_ORD], disp_del, DISP_ORD);
v_equ(disp_del, &sigbuf[length + BEGIN - DISP_ORD], DISP_ORD);
zerflt_Q(&sigbuf[BEGIN], disp_cof, &sigbuf[BEGIN], DISP_ORD,
length, 15);
/* Copy processed speech to output array (not past frame end) */
if (add(syn_begin, length) >= FRAME){
v_equ(&sp_out[syn_begin], &sigbuf[BEGIN], (Shortword) (FRAME - syn_begin));
#if POSTFILTER
postfilt(sp_out, prev_par.lsf, par->lsf);
#endif
/* past end: save remainder in sigsave[0] */
v_equ(sigsave, &sigbuf[BEGIN + FRAME - syn_begin],
(Shortword) (length - (FRAME - syn_begin)));
} else
v_equ(&sp_out[syn_begin], &sigbuf[BEGIN], length);
/* Update syn_begin for next period */
syn_begin = add(syn_begin, length);
}
/* Save previous pulse and noise filters for next frame */
v_equ(prev_pcof, curr_pcof, MIX_ORD + 1);
v_equ(prev_ncof, curr_ncof, MIX_ORD + 1);
/* Copy current parameters to previous parameters for next time */
prev_par = *par;
prev_tilt = curr_tilt;
prev_lpc_gain = lpc_gain;
/* Update syn_begin for next frame */
syn_begin = sub(syn_begin, FRAME);
}
/* =========================================================== */
/* melp_syn_init() performs initialization for melp synthesis. */
/* =========================================================== */
void melp_syn_init()
{
register Shortword i;
Shortword temp;
v_zap(prev_par.gain, NUM_GAINFR);
prev_par.pitch = UV_PITCH_Q7;
temp = 0;
for (i = 0; i < LPC_ORD; i++){
temp = add(temp, INV_LPC_ORD);
prev_par.lsf[i] = temp;
}
prev_par.jitter = 0;
v_zap(&prev_par.bpvc[0], NUM_BANDS);
syn_begin = 0;
v_zap(sigsave, PITCHMAX);
fill(prev_par.fs_mag, ONE_Q13, NUM_HARM);
/* Initialize fixed MSE weighting and inverse of weighting */
if (!w_fs_init){
vq_fsw(w_fs, NUM_HARM, X60_Q9);
for (i = 0; i < NUM_HARM; i++)
w_fs_inv[i] = divide_s(ONE_Q13, w_fs[i]); /* w_fs_inv in Q14 */
w_fs_init = TRUE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -