📄 ns127.c
字号:
/* Functions */
void r_fft(short *, short);
/* Init the window function, channel gains one time */
if (first == TRUE)
{
ch_gain[0] = ch_gain[1] = SW_MAX;
for (i = LO_CHAN; i <= HI_CHAN; i++)
ch_enrg[i] = 0;
for (i = 0; i < DELAY; i++)
window_overlap[i] = 0;
for (i = 0; i < FFT_LEN - FRM_LEN; i++)
overlap[i] = 0;
pre_emp_mem = 0;
de_emp_mem = 0;
update_cnt = 0;
frame_cnt = 0;
}
/* Increment frame counter */
frame_cnt++;
/* Block normalize the input */
normb_shift = block_norm(farray_ptr, FRM_LEN, FFT_HEADROOM);
/*
* Preemphasize the input data and store in the data buffer with
* appropriate delay
*/
for (i = 0; i < DELAY; i++)
data_buffer[i] = shift_r(window_overlap[i], normb_shift-last_normb_shift);
pre_emp_mem = shift_r(pre_emp_mem, normb_shift-last_normb_shift);
last_normb_shift = normb_shift;
data_buffer[DELAY] = add(*farray_ptr, mult(PRE_EMP_FAC, pre_emp_mem));
for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++)
data_buffer[i] = add(*(farray_ptr + j), mult(PRE_EMP_FAC, *(farray_ptr + j - 1)));
pre_emp_mem = *(farray_ptr + FRM_LEN - 1);
for (i = DELAY + FRM_LEN; i < FFT_LEN; i++)
data_buffer[i] = 0;
/* update window_overlap buffer */
for (i = 0, j = FRM_LEN; i < DELAY; i++, j++)
window_overlap[i] = data_buffer[j];
/* Apply window to frame prior to FFT */
for (i = 0; i < FRM_LEN + DELAY; i++)
data_buffer[i] = mult_r(data_buffer[i], window[i]);
/* Perform FFT on the data buffer */
r_fft(data_buffer, +1);
/* Estimate the energy in each channel */
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
enrg = 0;
j1 = ch_tbl[i][0];
j2 = ch_tbl[i][1];
for (j = j1; j <= j2; j++)
{
enrg = L_mac(enrg, data_buffer[2 * j], data_buffer[2 * j]);
enrg = L_mac(enrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]);
}
if (ch_tbl_sh[i][0] == TRUE)
enrg = L_shr(enrg, ch_tbl_sh[i][1]);
else
{
norm_shift = norm_l(enrg);
tmp = extract_h(L_shl(enrg, norm_shift));
enrg = L_mult(tmp, ch_tbl_sh[i][1]);
enrg = L_shr(enrg, norm_shift);
}
if (first == TRUE)
ch_enrg[i] = L_shl(enrg, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
else
{
norm_shift = norm_l(enrg);
Ltmp1 = L_shl(enrg, norm_shift);
Ltmp1 = L_mpy_ls(CEE_SM_FAC, extract_h(Ltmp1));
Ltmp1 = L_shr(Ltmp1, norm_shift);
Ltmp2 = L_shl(Ltmp1, 7 - (2 * normb_shift)); /* rescaled from 30,1 to 23,8 (w/block denorm) */
norm_shift = norm_l(ch_enrg[i]);
Ltmp1 = L_shl(ch_enrg[i], norm_shift);
Ltmp3 = L_mpy_ls(ONE_MINUS_CEE_SM_FAC, extract_h(Ltmp1));
Ltmp3 = L_shr(Ltmp3, norm_shift);
ch_enrg[i] = L_add(Ltmp3, Ltmp2);
}
if (ch_enrg[i] < MIN_CHAN_ENRG)
ch_enrg[i] = MIN_CHAN_ENRG;
}
/* Initialize channel noise estimate to channel energy of first four frames */
if (frame_cnt <= 4)
{
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
if (ch_enrg[i] < INE_CHAN)
ch_noise[i] = INE_NOISE;
else
ch_noise[i] = ch_enrg[i];
}
}
/* Compute the channel SNR indices */
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
norm_shift = norm_l(ch_noise[i]);
Ltmp = L_shl(ch_noise[i], norm_shift);
norm_shift1 = norm_l(ch_enrg[i]);
Ltmp3 = L_shl(ch_enrg[i], norm_shift1 - 1);
Ltmp2 = L_divide(Ltmp3, Ltmp);
Ltmp2 = L_shr(Ltmp2, 27 - 1 + norm_shift1 - norm_shift); /* scaled as 27,4 */
if (Ltmp2 == 0)
Ltmp2 = 1;
Ltmp1 = fnLog10(Ltmp2);
Ltmp3 = L_add(Ltmp1, LOG_OFFSET - 80807124); /* -round32(log10(2^4)*2^26 */
Ltmp2 = L_mult(TEN_S5_10, extract_h(Ltmp3));
if (Ltmp2 < 0)
Ltmp2 = 0;
/* 0.1875 scaled as 10,21 */
Ltmp1 = L_add(Ltmp2, CONST_0_1875_S10_21);
/* tmp / 0.375 2.667 scaled as 5,10, Ltmp is scaled 15,16 */
Ltmp = L_mult(extract_h(Ltmp1), CONST_2_667_S5_10);
ch_snr[i] = extract_h(Ltmp);
}
/* Compute the sum of voice metrics */
vm_sum = 0;
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
if (ch_snr[i] < 89)
j = ch_snr[i];
else
j = 89;
vm_sum = add(vm_sum, vm_tbl[j]);
}
/* Compute the total noise estimate (tne) and total channel energy estimate (tce) */
tne = tce = 0;
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
tne = L_add(tne, ch_noise[i]);
tce = L_add(tce, ch_enrg[i]);
}
/* Calculate log spectral deviation */
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
Ltmp = ch_enrg[i];
if (Ltmp == 0)
Ltmp = 1;
Ltmp1 = fnLog10(Ltmp);
Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
ch_enrg_db[i] = mult(TEN_S5_10, extract_h(Ltmp2));
}
if (first == TRUE)
for (i = LO_CHAN; i <= HI_CHAN; i++)
ch_enrg_long_db[i] = ch_enrg_db[i];
ch_enrg_dev = 0;
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
tmp = abs_s(sub(ch_enrg_long_db[i], ch_enrg_db[i]));
ch_enrg_dev = add(ch_enrg_dev, tmp);
}
/*
* Calculate long term integration constant as a function of total channel energy (tce)
* (i.e., high tce (-40 dB) -> slow integration (alpha = 0.99),
* low tce (-60 dB) -> fast integration (alpha = 0.50)
*/
Ltmp1 = fnLog10(tce);
Ltmp2 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
tmp = mult(TEN_S5_10, extract_h(Ltmp2));
tmp2 = sub(HIGH_TCE_DB, tmp); /* HIGH_TCE_DB and tmp scaled as 10,5 */
tmp2 = shl(tmp2, 5); /* move scale to 5,10 get more fraction */
tmp1 = mult(ALPHA_RAN_DIV_TCE_RAN, tmp2);
alpha = sub(HIGH_ALPHA_S5_10, tmp1);
if (alpha > HIGH_ALPHA_S5_10)
alpha = HIGH_ALPHA;
else if (alpha < LOW_ALPHA_S5_10)
alpha = LOW_ALPHA;
else
alpha = shl(alpha, 5); /* rescale from 5,10 to 0,15 alpha is a fraction */
/* Calc long term log spectral energy */
tmp = sub(SW_MAX, alpha);
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
Ltmp1 = L_mult(tmp, ch_enrg_db[i]);
Ltmp2 = L_mult(alpha, ch_enrg_long_db[i]);
ch_enrg_long_db[i] = extract_h(L_add(Ltmp1, Ltmp2));
}
/* Set or reset the update flag */
update_flag = FALSE;
if (vm_sum <= UPDATE_THLD)
{
update_flag = TRUE;
update_cnt = 0;
}
else if (tce > NOISE_FLOOR_CHAN && ch_enrg_dev < DEV_THLD)
{
update_cnt++;
if (update_cnt >= UPDATE_CNT_THLD)
update_flag = TRUE;
}
if (update_cnt == last_update_cnt)
hyster_cnt++;
else
hyster_cnt = 0;
last_update_cnt = update_cnt;
if (hyster_cnt > HYSTER_CNT_THLD)
update_cnt = 0;
/* Set or reset modify flag */
index_cnt = 0;
for (i = MID_CHAN; i <= HI_CHAN; i++)
if (ch_snr[i] >= INDEX_THLD)
index_cnt++;
modify_flag = (index_cnt < INDEX_CNT_THLD) ? TRUE : FALSE;
/* Modify the SNR indices */
if (modify_flag == TRUE)
{
for (i = LO_CHAN; i <= HI_CHAN; i++)
if ((vm_sum <= METRIC_THLD) || (ch_snr[i] <= SETBACK_THLD))
ch_snr[i] = 1;
}
/* Compute the channel gains */
Ltmp1 = fnLog10(tne);
Ltmp1 = L_add(Ltmp1, LOG_OFFSET - 161614248); /* -round32(log10(2^8)*2^26) */
Ltmp1 = L_negate(Ltmp1);
gain = L_mpy_ls(Ltmp1, TEN_S5_10);
if (gain < MIN_GAIN)
gain = MIN_GAIN;
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
if (ch_snr[i] <= SNR_THLD)
ch_snr[i] = SNR_THLD;
tmp = sub(ch_snr[i], SNR_THLD);
Ltmp1 = L_mult(tmp, GAIN_SLOPE);
Ltmp2 = L_shl(Ltmp1, 5); /* rescaled to 10,5 */
Ltmp = L_add(Ltmp2, gain); /* gain scaled as 10,5 */
if (Ltmp > 0)
Ltmp = 0;
Ltmp1 = L_mpy_ls(Ltmp, ONE_OVER_20);
Ltmp1 = L_shl(Ltmp1, 5); /* rescale Ltmp1 to 5,26 */
if (Ltmp1 == 0)
Ltmp1 = -1;
Ltmp2 = fnExp10(Ltmp1);
ftmp2 = extract_h(Ltmp2);
j1 = ch_tbl[i][0], j2 = ch_tbl[i][1];
for (j = j1; j <= j2; j++)
{
ch_gain[j] = ftmp2;
}
}
/* Update the channel noise estimates */
if (update_flag == TRUE)
{
for (i = LO_CHAN; i <= HI_CHAN; i++)
{
norm_shift = norm_l(ch_noise[i]);
Ltmp = L_shl(ch_noise[i], norm_shift);
Ltmp1 = L_mult(extract_h(Ltmp), ONE_MINUS_CNE_SM_FAC);
Ltmp1 = L_shr(Ltmp1, norm_shift);
norm_shift = norm_l(ch_enrg[i]);
Ltmp = L_shl(ch_enrg[i], norm_shift);
Ltmp2 = L_mult(extract_h(Ltmp), CNE_SM_FAC);
Ltmp2 = L_shr(Ltmp2, norm_shift);
ch_noise[i] = L_add(Ltmp1, Ltmp2);
if (ch_noise[i] < MIN_NOISE_ENRG)
ch_noise[i] = MIN_NOISE_ENRG;
}
}
/* Filter the input data in the frequency domain and perform IFFT */
for (i = 0; i < FFT_LEN / 2; i++)
{
data_buffer[2 * i] = mult(data_buffer[2 * i], ch_gain[i]);
data_buffer[2 * i + 1] = mult(data_buffer[2 * i + 1], ch_gain[i]);
}
/* Block normalize data_buffer */
norm_shift = block_norm(data_buffer, FFT_LEN, IFFT_HEADROOM);
/* Inverse FFT */
r_fft(data_buffer, -1);
/* Block denormalize data_buffer */
/* block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift); */
block_denorm(data_buffer, FFT_LEN, normb_shift + norm_shift + 1);
/* Overlap add the filtered data from previous block.
* Save data from this block for the next. */
for (i = 0; i < FFT_LEN - FRM_LEN; i++)
data_buffer[i] = add(data_buffer[i], overlap[i]);
for (i = FRM_LEN; i < FFT_LEN; i++)
overlap[i - FRM_LEN] = data_buffer[i];
/* Deemphasize the filtered speech and write it out to farray */
tmp = mult(DE_EMP_FAC, de_emp_mem);
*farray_ptr = add(data_buffer[0], tmp);
for (i = 1; i < FRM_LEN; i++)
{
tmp = mult_r(DE_EMP_FAC, *(farray_ptr + i - 1));
*(farray_ptr + i) = add(data_buffer[i], tmp);
}
de_emp_mem = *(farray_ptr + FRM_LEN - 1);
first = FALSE;
} /* end noise_suprs () */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -