📄 npp.c
字号:
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 + -