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

📄 npp.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 4 页
字号:
	static BOOLEAN	first_time = TRUE;
	static Shortword	agal[ENH_VEC_LENF];                     /* GainD*Ymag */
	static Shortword	agal_shift[ENH_VEC_LENF];
	static Shortword	Ksi_min_var = GM_MIN;
	static Shortword	qk[ENH_VEC_LENF];   /* probability of noise only, Q15 */
	static Shortword	Gain[ENH_VEC_LENF];    /* MMSE LOG STA estimator gain */
	static Shortword	YY_LT, YY_LT_shift;
	static Shortword	SN_LT0, SN_LT0_shift;
	BOOLEAN		n_flag;
	Shortword	temp, temp_shift;
	Shortword	YY_av, gamma_av, gamma_max, gamma_av_shift, gamma_max_shift;
	Shortword	shift, YY_av_shift, max, temp1, temp2, temp3, temp4;
	Shortword	max_YY_shift, Y_shift, guard;
	Shortword	a_shift, ygal;
	Shortword	Ymag[ENH_VEC_LENF];             /* magnitude of current frame */
	Shortword	Ymag_shift[ENH_VEC_LENF];
	Shortword	GainD[ENH_VEC_LENF];                          /* Gain[].*GM[] */
	Shortword	analy[ENH_WINLEN];
	Shortword	gamaK[ENH_VEC_LENF];                      /* a posteriori SNR */
    Shortword	gamaK_shift[ENH_VEC_LENF];
	Shortword	biased_smoothedspect[ENH_VEC_LENF];      /* weighted smoothed */
                                                    /* spect. for long window */
    Shortword	biased_smoothedspect_sub[ENH_VEC_LENF];      /* for subwindow */
    Shortword	bias_shift[ENH_VEC_LENF], bias_sub_shift[ENH_VEC_LENF];
	Longword	L_sum, L_max;


	if (first_time){
		v_zap(agal, ENH_VEC_LENF);
		v_zap(agal_shift, ENH_VEC_LENF);
		fill(ksi, GM_MIN, ENH_VEC_LENF);
		v_zap(ksi_shift, ENH_VEC_LENF);
		fill(qk, ENH_QK_MAX, ENH_VEC_LENF);
		fill(Gain, GM_MIN, ENH_VEC_LENF);
		fill(GainD, GM_MIN, ENH_VEC_LENF);
		YY_LT = 0;
		YY_LT_shift = 0;
		SN_LT0 = SN_LT;
		SN_LT0_shift = SN_LT_shift;

		first_time = FALSE;
	}

	if (enh_i < 50)                  /* This ensures enh_i does not overflow. */
		enh_i ++;

	/* analysis window */
	window(inspeech, sqrt_tukey_256_180, analy, ENH_WINLEN);    /* analy[] Q0 */

	/* ---- Find normalization factor of the input signal ---- */
	max = 1;                           /* max starts with 1 to avoid problems */
                                                 /* with shift = norm_s(max). */
	for (i = 0; i < ENH_WINLEN; i++){
		temp1 = abs_s(analy[i]);
		if (temp1 > max)
			max = temp1;
	}
	shift = norm_s(max);
	/* ---- Now think input is Q15 ---- */
	a_shift = sub(15, shift);

	/* ------------- Fixed point fft -------------- */
	/* into frequency domain - D->Y, D->YD->Y, YY_av,
	   real and imaginary parts are interleaved */
	for (i = 0; i < ENH_WINLEN; i++)
		analy[i] = shl(analy[i], shift);

	v_zap(ybuf, 2*ENH_WINLEN + 2);
	for (i = 0; i < 2*ENH_WINLEN; i += 2)
		ybuf[i] = analy[i/2];
	guard = fft_npp(ybuf, 1);
	/* guard = fft(ybuf, ENH_WINLEN, MONE_Q15); */

	/* Previously here we copy ybuf[] to Y[] and process Y[].  In fact this   */
	/* is not necessary because Y[] is not changed before we use ybuf[] and   */
	/* update ybuf[] the next time.                                           */

	/* ---- D->YY shift is compared to original data ---- */
	Y_shift = add(a_shift, guard);
	YY_av_shift = shl(Y_shift, 1);

	temp_yy[0] = L_mult(ybuf[0], ybuf[0]);
	temp_yy[ENH_VEC_LENF - 1] = L_mult(ybuf[ENH_WINLEN], ybuf[ENH_WINLEN]);

	for (i = 1; i < ENH_VEC_LENF - 1; i++)
		temp_yy[i] = L_add(L_mult(ybuf[2*i], ybuf[2*i]),
						   L_mult(ybuf[2*i + 1], ybuf[2*i + 1]));

	max_YY_shift = SW_MIN;
	for (i = 0; i < ENH_VEC_LENF; i++){
		if (temp_yy[i] < 1)
			temp_yy[i] = 1;
		shift = norm_l(temp_yy[i]);
		YY[i] = extract_h(L_shl(temp_yy[i], shift));
		YY_shift[i] = sub(YY_av_shift, shift);
		if (max_YY_shift < YY_shift[i])
			max_YY_shift = YY_shift[i];
	}

	for (i = 0; i < ENH_VEC_LENF; i++){
		temp = YY[i];
		temp_shift = YY_shift[i];
		if (temp_shift & 0x0001){
			temp = shr(temp, 1);
			temp_shift = add(temp_shift, 1);
		}
		Ymag[i] = sqrt_Q15(temp);
		Ymag_shift[i] = shr(temp_shift, 1);
		YY_shift[i] = sub(YY_shift[i], 8);
	}

	/* ---- Compute YY_av ---- */
	L_sum = L_shl(L_deposit_l(YY[0]), sub(7, sub(max_YY_shift, YY_shift[0])));
	L_sum = L_add(L_sum, L_shl(L_deposit_l(YY[ENH_VEC_LENF - 1]),
				  sub(7, sub(max_YY_shift, YY_shift[ENH_VEC_LENF - 1]))));
	for (i = 1; i < ENH_VEC_LENF - 1; i++)
		L_sum = L_add(L_sum, L_shl(L_deposit_l(YY[i]),
					  sub(8, sub(max_YY_shift, YY_shift[i]))));
	if (L_sum == 0)
		L_sum = 1;
	temp1 = norm_l(L_sum);
	YY_av = extract_h(L_shl(L_sum, temp1));
	YY_av_shift = sub(add(max_YY_shift, 1), temp1);

	/* compute smoothed short time periodogram */
	smoothed_periodogram(YY_av, YY_av_shift);

	/* compute inverse bias and multiply short time periodogram with inverse  */
	/* bias */
	bias_compensation(biased_smoothedspect, bias_shift,
					  biased_smoothedspect_sub, bias_sub_shift);

	/* determine unbiased noise psd estimate by minimum search */
	min_search(biased_smoothedspect, bias_shift, biased_smoothedspect_sub,
			   bias_sub_shift);

	/* compute 'gammas' */
	for (i = 0; i < ENH_VEC_LENF; i++){
		gamaK[i] = divide_s(shr(YY[i], 1), lambdaD[i]);
		gamaK_shift[i] = sub(add(YY_shift[i], 1), lambdaD_shift[i]);
	}

	/* compute average of gammas */
	L_sum = L_shl(L_deposit_l(gamaK[0]), 7);
	shift = sub(gamaK_shift[0], 1);
	for (i = 1; i < ENH_VEC_LENF - 1; i++){
		temp1 = sub(shift, gamaK_shift[i]);
		if (temp1 > 0)
			L_sum = L_add(L_sum, L_shr(L_deposit_l(gamaK[i]), sub(temp1, 7)));
		else{
			L_sum = L_add(L_shl(L_sum, temp1),
						  L_shl(L_deposit_l(gamaK[i]), 7));
			shift = gamaK_shift[i];
		}
	}
	temp1 = sub(shift, sub(gamaK_shift[ENH_VEC_LENF - 1], 1));
	if (temp1 > 0)
		L_sum = L_add(L_sum, L_shr(L_deposit_l(gamaK[ENH_VEC_LENF - 1]),
								   sub(temp1, 7)));
	else{
		L_sum = L_add(L_shl(L_sum, temp1),
					  L_shl(L_deposit_l(gamaK[ENH_VEC_LENF - 1]), 7));
		shift = sub(gamaK_shift[ENH_VEC_LENF - 1], 1);
	}
	if (L_sum == 0)
		L_sum = 1;
	temp1 = norm_l(L_sum);
	gamma_av = extract_h(L_shl(L_sum, temp1));
	gamma_av_shift = add(sub(shift, temp1), 10 - 8);

	gamma_max = gamaK[0];
	gamma_max_shift = gamaK_shift[0];
	for (i = 1; i < ENH_VEC_LENF; i++){
		if (comp_data_shift(gamma_max, gamma_max_shift, gamaK[i],
							gamaK_shift[i]) < 0){
			gamma_max = gamaK[i];
			gamma_max_shift = gamaK_shift[i];
		}
	}

	/* determine signal presence */
	n_flag = FALSE;                          /* default flag - signal present */

	if ((comp_data_shift(gamma_max, gamma_max_shift, GAMMAX_THR, 6) < 0) &&
		(comp_data_shift(gamma_av, gamma_av_shift, GAMMAV_THR, 1) < 0)){
		n_flag = TRUE;                                          /* noise-only */

		temp1 = mult(n_pwr, GAMMAV_THR);
		temp2 = add(n_pwr_shift, 1 + 1);
		if (comp_data_shift(YY_av, YY_av_shift, temp1, temp2) > 0)
			n_flag = FALSE;            /* overiding if frame SNR > 3dB (9/98) */
	}

	if (enh_i == 1){            /* Initial estimation of apriori SNR and Gain */
		n_flag = TRUE;

		for (i = 0; i < ENH_VEC_LENF; i++){
			temp_yy[i] = L_mult(Ymag[i], GM_MIN);
			shift = norm_l(temp_yy[i]);
			agal[i] = extract_h(L_shl(temp_yy[i], shift));
			agal_shift[i] = sub(Ymag_shift[i], shift);
		}
	} else {                                                     /* enh_i > 1 */

		/* estimation of apriori SNR */
		for (i = 0; i < ENH_VEC_LENF; i++){
			L_sum = L_mult(agal[i], agal[i]);
			L_sum = L_mpy_ls(L_sum, ENH_ALPHAK);
			if (L_sum < 1)
				L_sum = 1;
			shift = norm_l(L_sum);
			temp1 = extract_h(L_shl(L_sum, shift));
			temp2 = sub(shl(agal_shift[i], 1), add(shift, 8));
			temp3 = lambdaD[i];
			temp4 = lambdaD_shift[i];
			if (sub(temp3, temp1) < 0){
				temp1 = shr(temp1, 1);
				temp2 = (Shortword) (temp2 + 1);
			}
			ksi[i] = divide_s(temp1, temp3);
			ksi_shift[i] = sub(temp2, temp4);
			if (comp_data_shift(gamaK[i], gamaK_shift[i], ENH_INV_NOISE_BIAS,
								0) > 0){
				L_sum = L_shr(L_deposit_h(ENH_INV_NOISE_BIAS),
							  gamaK_shift[i]);
				L_sum = L_sub(L_deposit_h(gamaK[i]), L_sum);
				shift = norm_l(L_sum);
				temp1 = extract_h(L_shl(L_sum, shift));
				temp1 = mult(temp1, ENH_BETAK);      /* note ENH_BETAK is Q18 */
				temp2 = sub(gamaK_shift[i], add(shift, 3));
				shift = sub(ksi_shift[i], temp2);
				if (shift > 0){
					ksi[i] = add(shr(ksi[i], 1), shr(temp1, (Shortword) (shift + 1)));
					ksi_shift[i] = add(ksi_shift[i], 1);
				} else {
					ksi[i] = add(shl(ksi[i], (Shortword) (shift - 1)), shr(temp1, 1));
					ksi_shift[i] = add(temp2, 1);
				}
			}
		}

		/*	Ksi_min_var = 0.9*Ksi_min_var +
						  0.1*ksi_min_adapt(n_flag, ksi_min, SN_LT);          */
		temp1 = mult(X09_Q15, Ksi_min_var);
		temp2 = mult(X01_Q15, ksi_min_adapt(n_flag, GM_MIN, SN_LT,
					 SN_LT_shift));
		Ksi_min_var = add(temp1, temp2);

		shift = norm_s(Ksi_min_var);
		temp1 = shl(Ksi_min_var, shift);
		/* ---- limit the bottom of the ksi ---- */
		for (i = 0; i < ENH_VEC_LENF; i++){
			if (comp_data_shift(ksi[i], ksi_shift[i],
								temp1, negate(shift)) < 0){
				ksi[i] = temp1;
				ksi_shift[i] = negate(shift);
			}
		}

		/* estimation of k-th component 'signal absence' prob and gain */
		/* default value for qk's % (9/98)	*/
		fill(qk, ENH_QK_MAX, ENH_VEC_LENF);

		if (!n_flag){                                       /* SIGNAL PRESENT */
			/* computation of the long term SNR */
			if (comp_data_shift(gamma_av, gamma_av_shift, GAMMAV_THR, 1) > 0){

				/*	YY_LT = YY_LT * alpha_LT + beta_LT * YY_av; */
				L_sum = L_mult(YY_LT, ENH_ALPHA_LT);
				shift = norm_l(L_sum);
				temp1 = extract_h(L_shl(L_sum, shift));
				temp2 = sub(YY_LT_shift, shift);
				L_sum = L_mult(YY_av, ENH_BETA_LT);
				shift = norm_l(L_sum);
				temp3 = extract_h(L_shl(L_sum, shift));
				temp4 = sub(YY_av_shift, shift);
				temp1 = shr(temp1, 1);
				temp3 = shr(temp3, 1);
				shift = sub(temp2, temp4);
				if (shift > 0){
					YY_LT = add(temp1, shr(temp3, shift));
					YY_LT_shift = temp2;
				} else {
					YY_LT = add(shl(temp1, shift), temp3);
					YY_LT_shift = temp4;
				}
				YY_LT_shift = add(YY_LT_shift, 1);

				/*	SN_LT = (YY_LT/n_pwr) - 1;  Long-term S/N */
				temp1 = sub(YY_LT, n_pwr);
				if (temp1 > 0){
					YY_LT = shr(YY_LT, 1);
					YY_LT_shift = add(YY_LT_shift, 1);
				}
				SN_LT = divide_s(YY_LT, n_pwr);
				SN_LT_shift = sub(YY_LT_shift, n_pwr_shift);

				/*	if (SN_LT < 0); we didn't subtract 1 from SN_LT yet.      */
				if (comp_data_shift(SN_LT, SN_LT_shift, ONE_Q15, 0) < 0){
					SN_LT = SN_LT0;
					SN_LT_shift = SN_LT0_shift;
				} else {
					temp1 = ONE_Q15;
					L_sum = L_sub(L_deposit_h(SN_LT),
									L_shr(L_deposit_h(temp1), SN_LT_shift));
					shift = norm_l(L_sum);
					SN_LT = extract_h(L_shl(L_sum, shift));
					SN_LT_shift = sub(SN_LT_shift, shift);
				}

				/*	SN_LT0 = SN_LT; */
				SN_LT0 = SN_LT;
				SN_LT0_shift = SN_LT_shift;
			}

			/* Estimating qk's using hard-decision approach (7/98) */
			compute_qk(qk, gamaK, gamaK_shift, ENH_GAMMAQ_THR);

			/*	vec_limit_top(qk, qk, qk_max, vec_lenf); */
			/*	vec_limit_bottom(qk, qk, qk_min, vec_lenf); */
			for (i = 0; i < ENH_VEC_LENF; i++){
				if (qk[i] > ENH_QK_MAX)
					qk[i] = ENH_QK_MAX;
				else if (qk[i] < ENH_QK_MIN)
					qk[i] = ENH_QK_MIN;
			}

		}

		gain_log_mmse(qk, Gain, gamaK, gamaK_shift, ENH_VEC_LENF);

		/* Previously the gain modification is done outside of gain_mod() and */
		/* now it is moved inside. */

		v_equ(GainD, Gain, ENH_VEC_LENF);
		gain_mod(qk, GainD, ENH_VEC_LENF);

		/*	vec_mult(Agal, GainD, Ymag, vec_lenf); */
		for (i = 0; i < ENH_VEC_LENF; i++){
			L_sum = L_mult(GainD[i], Ymag[i]);
			shift = norm_l(L_sum);
			agal[i] = extract_h(L_shl(L_sum, shift));
			agal_shift[i] = sub(Ymag_shift[i], shift);

		}

	}

	/* enhanced signal in frequency domain */
	/*	 (implement ygal = GainD .* Y)	 */
	for (i = 0; i < ENH_WINLEN + 2; i++)
		temp_yy[i] = L_mult(ybuf[i], GainD[i/2]);
	L_max = 0;
	for (i = 0; i < ENH_WINLEN + 2; i++)
		if (L_max < L_abs(temp_yy[i]))
			L_max = L_abs(temp_yy[i]);

	shift = norm_l(L_max);
	for (i = 0; i < ENH_WINLEN + 2; i++)
		ybuf[i] = extract_h(L_shl(temp_yy[i], shift));
	shift = sub(Y_shift, shift);

	/* transformation to time domain */
	for (i = 0; i < ENH_WINLEN/2 - 1; i++){
		ybuf[ENH_WINLEN + 2*i + 2] = ybuf[ENH_WINLEN - 2*i - 2];
		ybuf[ENH_WINLEN + 2*i + 3] = negate(ybuf[ENH_WINLEN - 2*i - 2 + 1]);
	}

	guard = fft_npp(ybuf, -1);
	/* guard = fft(ybuf, ENH_WINLEN, ONE_Q15); */
	shift = add(shift, guard);
	shift = sub(shift, 8);

#if USE_SYN_WINDOW
	for (i = 0; i < ENH_WINLEN; i++){
		ygal = shl(ybuf[2*i], sub(shift, 15));
		outspeech[i] = mult(ygal, sqrt_tukey_256_180[i]);
	}
#endif

	/* Misc. updates */
	max_YY_shift = SW_MIN;
	for (i = 0; i < ENH_VEC_LENF; i++){
		if (max_YY_shift < lambdaD_shift[i])
			max_YY_shift = lambdaD_shift[i];
	}

	L_sum = L_shl(L_deposit_l(lambdaD[0]),
				  sub(7, sub(max_YY_shift, lambdaD_shift[0])));
	L_sum = L_add(L_sum, L_shl(L_deposit_l(lambdaD[ENH_VEC_LENF - 1]),
				  sub(7, sub(max_YY_shift,
							 lambdaD_shift[ENH_VEC_LENF - 1]))));

	for (i = 1; i < ENH_VEC_LENF - 1; i++)
		L_sum = L_add(L_sum, L_shl(L_deposit_l(lambdaD[i]),
					  sub(8, sub(max_YY_shift, lambdaD_shift[i]))));
	if (L_sum == 0)
		L_sum = 1;
	shift = norm_l(L_sum);
	n_pwr = extract_h(L_shl(L_sum, shift));
	n_pwr_shift = add(sub(max_YY_shift, shift), 1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -