webRTC的舒适噪聲實際上就是,一個随機噪聲經過同一幀消回聲輸出NLP參數的權重處理産生的噪聲。如果是32K信号,則對産生的高頻段随機噪聲統一權重,權重值是同一幀消回聲輸出NLP參數的平均值。
static void ComfortNoise(AecCore* aec,
float efw[2][PART_LEN1],
complex_t* comfortNoiseHband,
const float* noisePow,
const float* lambda) {
int i, num;
float rand[PART_LEN];
float noise, noiseAvg, tmp, tmpAvg;
int16_t randW16[PART_LEN];
complex_t u[PART_LEN1];
const float pi2 = 6.28318530717959f;
// Generate a uniform random array on [0 1]
// 依據seed産生一個part = 64長度的僞随機數組,存放在randW16的位址處,後面用于計算角頻率
WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed);
// 将産生的僞随機數組轉存到臨時數組變量rand中
for (i = 0; i < PART_LEN; i++) {
rand[i] = ((float)randW16[i]) / 32768;
}
// Reject LF noise
u[0][0] = 0;
u[0][1] = 0;
// 依次根據随機數組中的元素産生噪聲的時域信号
for (i = 1; i < PART_LEN1; i++) {
// 2*π*f = w,根據随機數組計算角頻率
tmp = pi2 * rand[i - 1];
// 根據傳入的噪聲功率數組,産生相應的噪聲幅值
noise = sqrtf(noisePow[i]);
// 産生噪聲,存放于二維數組u中
u[i][0] = noise * cosf(tmp);
u[i][1] = -noise * sinf(tmp);
}
u[PART_LEN][1] = 0;
for (i = 0; i < PART_LEN1; i++) {
// 根據傳入參數lambda數組選取合适的權重,用于非線性的調整噪聲幅值u
tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0));
efw[0][i] += tmp * u[i][0];
efw[1][i] += tmp * u[i][1];
}
// 對于高頻段的噪聲
// TODO: don't compute noise and "tmp" twice. Use the previous results.
noiseAvg = 0.0;
tmpAvg = 0.0;
num = 0;
if (aec->sampFreq == 32000 && flagHbandCn == 1) {
// average noise scale
// average over second half of freq spectrum (i.e., 4->8khz)
// TODO: we shouldn't need num. We know how many elements we're summing.
// 計算傳入的噪聲功率noisePow中所有元素的平均功率
for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) {
num++;
noiseAvg += sqrtf(noisePow[i]);
}
noiseAvg /= (float)num;
// average nlp scale
// average over second half of freq spectrum (i.e., 4->8khz)
// TODO: we shouldn't need num. We know how many elements we're summing.
// 同理計算傳入參數lambda中所有元素的平均值
num = 0;
for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) {
num++;
tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0));
}
tmpAvg /= (float)num;
// 通過計算出來的平均噪聲産生高頻段的噪聲
// TODO: we should probably have a new random vector here.
// Reject LF noise
u[0][0] = 0;
u[0][1] = 0;
for (i = 1; i < PART_LEN1; i++) {
tmp = pi2 * rand[i - 1];
// Use average noise for H band
u[i][0] = noiseAvg * (float)cos(tmp);
u[i][1] = -noiseAvg * (float)sin(tmp);
}
u[PART_LEN][1] = 0;
for (i = 0; i < PART_LEN1; i++) {
// 使用非線性參數lambda的平均值對高頻噪聲進行權重處理
comfortNoiseHband[i][0] = tmpAvg * u[i][0];
comfortNoiseHband[i][1] = tmpAvg * u[i][1];
}
}
}