⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 melp_syn.c

📁 2400bps MELP语音编解码源程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
	  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 + -