WebRtcNs_ProcessCore 降噪处理核心函数
1、分为高频、低频子带进行处理,采样率为8-16K时,一般只用到低频处理。
2、计算输入带噪语音数据帧的能量值。
3、FFT傅里叶变换
4、计算维纳滤波增益,通过直接判决法计算先验信噪比。
theFilter=snrPrior / (self->overdrive+ snrPrior);
5、对维纳增益值根据用户设置的降噪等级,进行下溢与上溢处理。
6、进行维纳滤波,并将增益后的频域数据(频率降噪)通过IFFT转为时域数据。
7、对降噪等级进行判断,如果等级为0 ,则维纳滤波输出则为最后的降噪结果。否则,继续处理。
8、计算维纳滤波后的帧数据能量,并计算与步骤2中的能量比值, gain = (float)sqrt(energy2/ (energy1 + 1.f));
9、当gain值大于0.5,计算因子1,factor1= 1.f + 1.3f * (gain - B_LIM);并判断gain *factor1是否大于1。如果大于1,因子1则为 factor1 = 1.f / gain;
10、当gain值小于0.5,判断gain是否小于增益下限值(用户设定),如果小于,则 gain = self->denoiseBound;计算因子2,factor2= 1.f - 0.3f * (B_LIM - gain);
11、结合先验语音概率计算最终的增益因子。
factor = self->priorSpeechProb* factor1 + (1.f - self->priorSpeechProb) * factor2;
12、在时域,将维纳滤波处理后的数据与facror相乘,得到最后的降噪结果。
13、如果对信号进行了分子带处理,则接下来需要对高频部分的自带进行处理。
13.1 计算高频部分的先验语音概率,这是是用低频子带求平均得到
avgProbSpeechHB = avgProbSpeechHB / ((float)deltaBweHB);。
13.2 将上一步计算的结果进行缩放,乘以上一帧处理后的输出信噪比。
avgProbSpeechHB*= sumMagnProcess / sumMagnAnalyze;
13.3 对先验语音概率进行映射,得到初步的增益值。
gainModHB = 0.5f * (1.f + (float)tanh(gainMapParHB* avgProbSpeechHBTmp));
13.4 计算第四步中得到的各频点的维纳滤波增益的平均值。
avgFilterGainHB= avgFilterGainHB / ((float)(deltaGainHB));
13.5 将上两步中得到的结果进行平滑,得到高频部分最终的增益因子。
gainTimeDomainHB= 0.5f * gainModHB + 0.5f * avgFilterGainHB;
WebRtcNs_AnalyzeCore 噪声及语音概率估计核心函数。
噪声估计和过滤包括:初始噪声估计、后验和先验SNR的判决引导(DD)更新、语音/噪声可能性测定,可能性测定是基于似然比(LR)因子进行的,而似然比是使用后验和先验SNR,以及语音概率密度函数(HF)模型 (如高斯、拉普拉斯算子、伽马、超高斯等),还有根据特征建模、噪声估计更新。
初始噪声估计是以分位数噪声估计为基础。噪声估计受分位数参数控制,该参数以q表示。根据初始噪声估计步骤确定的噪声估计,仅能用作促进噪声更新/估计的后续流程的初始条件。
1、对输入的时域帧数据进行FFT
2、计算能量和幅度
3、初始噪声估计
4、利用前50帧,计算得到高斯白噪声、粉红噪声模型,联合白噪声、粉红噪声模型,得到建模的混合噪声模型。
5、对初始估计的噪声利用上一步建好的模型进行加权。
6、直接判决法计算先验信噪比和后验信噪比。
7、提取 LRT特征、频谱平坦度、频谱差异度三个特征。
8、利用三个特征以及先验信噪比和后验信噪比分别计算语音/噪声概率检测。
indicator0 = 0.5f *((float)tanh(widthPrior* (logLrtTimeAvgKsum - threshPrior0)) + 1.f);
indicator1 = 0.5f * ((float)tanh((float)sgnMap* widthPrior * (threshPrior1 - tmpFloat1)) + 1.f);
indicator2 = 0.5f * ((float)tanh(widthPrior* (tmpFloat1 - threshPrior2)) + 1.f);
9、对上述三个概率值进行加权求和,得到综合概率。
indPrior = weightIndPrior0 * indicator0 +weightIndPrior1 * indicator1 + weightIndPrior2 * indicator2;
10、通过前面得到的噪声估计值、语音/噪声概率值,对噪声估计进行更新,得到最后的噪声估计值。
noiseUpdateTmp = 0.9 * self->noisePrev[i]+ 0.1* (probNonSpeech * magn[i] + probSpeech *
self->noisePrev[i]);
参考资料:https://blog.csdn.net/shichaog/article/details/52514816