📄 melp_syn.c
字号:
intfact = ifact;
/* interpolate LSF's and convert to LPC filter */
interp_array(prev_par.lsf,par->lsf,lsf,intfact,LPC_ORD+1);
lpc_lsp2pred(lsf,lpc,LPC_ORD);
/* Check signal probability for adaptive spectral enhancement filter */
temp1 = add(noise_gain,(Shortword)X12_Q8);
temp2 = add(noise_gain,(Shortword)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,(Shortword)ASE_NUM_BW_Q15);
lpc_bw_expand(lpc,ase_num,temp1,LPC_ORD);
temp1 = mult(sig_prob,(Shortword)ASE_DEN_BW_Q15);
lpc_bw_expand(lpc,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((Shortword)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);
/* interpolate jitter */
/* jitter = ifact*par->jitter + (1.0-ifact)*prev_par.jitter; */
temp1 = mult(par->jitter,ifact);
temp2 = sub(ONE_Q15,ifact);
temp2 = mult(prev_par.jitter,temp2);
jitter = add(temp1,temp2);
/* scale gain by 0.05 but keep gain in log */
/* gain = pow(10.0,0.05*gain); */
gain = mult((Shortword)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 */
compare_nonzero();
if (length < PITCHMIN)
length = PITCHMIN;
compare_nonzero();
if (length > PITCHMAX)
length = PITCHMAX;
/* Use inverse DFT for pulse excitation */
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);
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,(Shortword)(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);
/* Get scaled noise excitation */
temp1 = shr(mult((Shortword)X1_732_Q14,syn_gain),3); /* temp1 in Q0 */
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 */
/* 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);
/* Perform LPC synthesis filtering */
v_equ(&sigbuf[BEGIN-LPC_ORD],lpc_del,LPC_ORD);
lpc_synthesis(&sigbuf[BEGIN],&sigbuf[BEGIN],lpc,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,&prev_scale,length,
SCALEOVER,(Shortword)INV_SCALEOVER_Q18);
/* Copy processed speech to output array (not past frame end) */
compare_nonzero();
if (add(syn_begin,length) > FRAME) {
v_equ(&sp_out[BEGIN+syn_begin],&sigbuf[BEGIN],
(Shortword)(FRAME-syn_begin));
/* past end: save remainder in sigsave[0] */
v_equ(&sigsave[0],&sigbuf[BEGIN+FRAME-syn_begin],
(Shortword)(length-(FRAME-syn_begin)));
}
else
v_equ(&sp_out[BEGIN+syn_begin],&sigbuf[BEGIN],length);
/* Update syn_begin for next period */
syn_begin = add(syn_begin,length);
}
/* Implement pulse dispersion filter on output speech */
v_equ(&sp_out[BEGIN-DISP_ORD],disp_del,DISP_ORD);
v_equ(disp_del,&sp_out[FRAME+BEGIN-DISP_ORD],DISP_ORD);
zerflt_Q(&sp_out[BEGIN],disp_cof,speech_out,DISP_ORD,FRAME,15);
/* 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);
#if (COMPLEXITY_COUNT)
complexity_count();
#endif
}
/*
*
* Subroutine melp_syn_init(): perform initialization for melp
* synthesis
*
*/
#define INV_LPC_ORD 2979 /* ((1.0/(LPC_ORD+1))*(1<<15)+0.5) */
void melp_syn_init()
{
Shortword i;
Shortword w_fs[NUM_HARM];
v_zap(prev_par.gain,NUM_GAINFR);
prev_par.pitch = UV_PITCH_Q7;
prev_par.lsf[0] = 0;
for (i = 1; i < LPC_ORD+1; i++)
prev_par.lsf[i] = add(prev_par.lsf[i-1],(Shortword)INV_LPC_ORD);
prev_par.jitter = 0;
v_zap(&prev_par.bpvc[0],NUM_BANDS);
prev_tilt=0;
prev_gain = 0;
prev_scale = 0;
prev_lpc_gain = ONE_Q15;
syn_begin = 0;
noise_gain = (Shortword)MIN_NOISE_Q8;
firstcall = 1;
prev_gain_err = 0;
v_zap(pulse_del,MIX_ORD);
v_zap(noise_del,MIX_ORD);
v_zap(lpc_del,LPC_ORD);
v_zap(ase_del,LPC_ORD);
v_zap(tilt_del,TILT_ORD);
v_zap(disp_del,DISP_ORD);
v_zap(sig2,BEGIN+PITCHMAX);
v_zap(sigbuf,BEGIN+PITCHMAX);
v_zap(sigsave,PITCHMAX);
v_zap(prev_pcof,MIX_ORD+1);
v_zap(prev_ncof,MIX_ORD+1);
prev_ncof[MIX_ORD/2] = ONE_Q15;
fill(prev_par.fs_mag,ONE_Q13,NUM_HARM);
/*
* Initialize multi-stage vector quantization (read codebook)
*/
vq_par.num_best = MSVQ_M;
vq_par.num_stages = 4;
vq_par.dimension = 10;
/*
* Allocate memory for number of levels per stage and indices
* and for number of bits per stage
*/
MEM_ALLOC(MALLOC,vq_par.num_levels,vq_par.num_stages,Shortword);
MEM_ALLOC(MALLOC,vq_par.indices,vq_par.num_stages,Shortword);
MEM_ALLOC(MALLOC,vq_par.num_bits,vq_par.num_stages,Shortword);
vq_par.num_levels[0] = 128;
vq_par.num_levels[1] = 64;
vq_par.num_levels[2] = 64;
vq_par.num_levels[3] = 64;
vq_par.num_bits[0] = 7;
vq_par.num_bits[1] = 6;
vq_par.num_bits[2] = 6;
vq_par.num_bits[3] = 6;
vq_par.cb = msvq_cb;
vq_par.cb_mean = msvq_cb_mean;
/*
* Initialize Fourier magnitude vector quantization (read codebook)
*/
fs_vq_par.num_best = 1;
fs_vq_par.num_stages = 1;
fs_vq_par.dimension = NUM_HARM;
/*
* Allocate memory for number of levels per stage and indices
* and for number of bits per stage
*/
MEM_ALLOC(MALLOC,fs_vq_par.num_levels,fs_vq_par.num_stages,Shortword);
MEM_ALLOC(MALLOC,fs_vq_par.indices,fs_vq_par.num_stages,Shortword);
MEM_ALLOC(MALLOC,fs_vq_par.num_bits,fs_vq_par.num_stages,Shortword);
fs_vq_par.num_levels[0] = FS_LEVELS;
fs_vq_par.num_bits[0] = FS_BITS;
fs_vq_par.cb = fsvq_cb;
/*
* Initialize fixed MSE weighting and inverse of weighting
*/
vq_fsw(w_fs, NUM_HARM, (Shortword)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 */
/*
* Pre-weight codebook (assume single stage only)
*/
if (fsvq_weighted == 0)
{
fsvq_weighted = 1;
for (i = 0; i < fs_vq_par.num_levels[0]; i++)
window_Q(&fs_vq_par.cb[i*NUM_HARM],w_fs,
&fs_vq_par.cb[i*NUM_HARM],NUM_HARM,14);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -