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

📄 melp_syn.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -