介绍与应用
google webrtc:https://chromium.googlesource.com/external/webrtc/ 使用深度学习抑制音频:https://developer.nvidia.com/zh-cn/blog/nvidia-real-time-noise-suppression-deep-learning/
深度噪声抑制 (DNS) 挑战 4 - ICASSP 2022:https://github.com/microsoft/DNS-Challenge
深度噪声抑制挑战 – ICASSP 2021:https://www.microsoft.com/en-us/research/academic-program/deep-noise-suppression-challenge-icassp-2021/
用于语音增强的交互式语音和噪声建模:https://arxiv.org/abs/2012.09408
其他论文:https://arxiv.org/pdf/2012.09408.pdf
手动注释音频事件的大规模数据集:https://research.google.com/audioset/index.html
Noise suppression,就是大家说的降噪。这种降噪是把人声和非人声区分开来,把非人声当成噪声。
一段包含人声和噪声的音频经过该模块处理,从理论上讲,只剩下人声了。
webrtc的NS在业内还是赫赫有名的,通过实际对比测试,我们发现webrtc的降噪的确是性能和稳定性
都要高于同类开源算法。
webrtc的ns原理是这样的:把启动前50帧的数据拿来构建噪声模型,把启动前200帧的信号强度用来计
算归一化的频谱差值计算。根据这两个模型使用概率目的函数来计算出每帧的信噪比并区分出噪声和声音,
然后根据计算出的信噪比在频域使用维纳滤波器对噪声信号进行噪声消除,最后在根据降噪前后的能量比
和信号噪声似然比对降噪后的数据进行修复和调整后输出。
webrtc的NS使用分析:webrtc的降噪支持三种采样率,8k,16k和32k,其它的采样率的降噪可以通过
瞎采样来完成。降噪模式有四种:分别是,0,1,2,3 四种模式的降噪量依次增加,笔者亲自测过,一般是2比较
好,对声音损失小,降噪效果又不错。还有个比较重要的参数就是噪声估计模型宏定义,如下所示,推荐在
系统计算能力够的情况下使用第三种,效果最好。
#define PROCESS_FLOW_0 // Use the traditional method.
#define PROCESS_FLOW_1 // Use traditional with DD estimate of prior SNR.
#define PROCESS_FLOW_2 // Use the new method of speech/noise classification.
使用方法和代码调用:
初始化:申请内存,设置采样率和降噪模式。
WebRtcNs_Create(&pNS_inst);
WebRtcNs_Init(pNS_inst,nSample);
WebRtcNs_set_policy(pNS_inst,nMode);
处理主函数:针对降噪的帧进行处理,默认是10ms的帧长度。
int WebRtcNs_Process(NsHandle* NS_inst, short* spframe, short* spframe_H,
short* outframe, short* outframe_H)
linux下可以直接编译运行的代码路径: https://github.com/DyLanCao/webrtc
补充
本文将会介绍如何使用 google 的 webtrc 项目中的 noise suppression 模块。该模块可以对输入的音频信号进行降噪处理,并输出降噪后的信号,从时域图来看有点类似于 noise gate,从效果上来看降噪后的信号频谱图变化不大,但是实际听感会有点干,总体而言效果还是不错的。
需要注意的是,webrtc 中的 noise suppression 算法是针对于语音信号设计的,如果直接应用在音乐信号上效果会有所折扣(后续的测试也验证了这一点),并且对于输入信号的采样率有一定的要求,不能大于32k(大于32k需要 resample),因此本文仅就如何从 webrtc 项目中提取 noise suppression 模块以及如何使用该模块进行讲解,如何应用需要根据实际的需求进行取舍。
背景介绍
WebRtc,web real-time communication,是由谷歌创立并开源的为浏览器、手机应用提供简单而又高效的实时通信解决方案的项目,该项目同时包含视频处理、音频处理、网络交互等模块,主要在浏览器中应用。Noise suppression ,为音频处理模块下的一个子项,音频处理模块(APM,audio processing module)下还有 AGC、AEC 、VAD等子模块。
在开源领域,还有另一个项目 Speex 也提供了类似于 webrtc 的全套音频解决方案,该项目的商业化项目为 Opus。除了使用传统的音频处理的方式降噪之外,还有一些使用更为现代的方式进行降噪,RNNoise 项目就是基于 RNN 神经网络实现对噪声的滤除,并且由于该方法的特性,可适用于全频带降噪(音乐信号),因此应用场景会更广。
以上提及的项目可以从以下链接中找到更详细的介绍:
https://webrtc.org
https://www.speex.org
https://people.xiph.org/~jm/demo/rnnoise/
本文将会介绍如何提取 WebRtc 中的 noise suppression 模块。
程序框架及过程
首先,到官方程序库下载 noise suppression 需要用到的文件:
https://chromium.googlesource.com/external/webrtc/stable/webrtc/+/master/modules/audio_processing
参考:https://github.com/jagger2048/WebRtc_noise_suppression/blob/master/readme_cn.md
需要注意的是,提取出来的文件要修改对应的 #include 选项才可以正常使用
接下来进入正题,了解 noise suppression 模块的程序流程,并以此重新构建自己的处理模块。
处理流程
WebRtc noisesuppression 模块的处理流程主要是按照以下来进行:
开始->初始化->设置处理模式->帧处理->释放句柄->结束
具体的步骤如下:
初始化句柄
NsHandle *nsHandle = WebRtcNs_Create();
int status = WebRtcNs_Init(nsHandle, sample_rate);
其中初始化成功则 status 返回 0
设置处理模式
status = WebRtcNs_set_policy(nsHandle, kVeryHigh);
kVeryHigh 为降噪的等级,取值 0~3 ,对应降噪等级从低到高,根据实际应用选择,本文选择2。status 设置成功返回 0
帧处理
分帧输入
float inf_buffer[maxSamples];
float outf_buffer[maxSamples];
// input the signal to process
for (int n = 0; n != samples; ++n) {
inf_buffer[n] = input[0][samples * i + n]; // 后续考虑使用其他方式
}
…
从输入信号中,取 10ms 的信号,16k的采样率也就是160点,8khz 则是 80 点。webRtc的函数最多只能处理160点,对大于16k的输入信号,需要降采样输入处理
ps:此处存疑,按照查阅的资料,内置函数最高可以处理 32k 的信号,不过需要进行分频后按照不同的频带进行输入(由于内置的分频函数需要用到Q16定点数,因此不推荐使用分频法处理高采样率的信号),因此对大于16k的信号,可以直接降采样为16k进行处理,也可以降采样为32k,然后分频段输入处理。为简单起见直接降采样处理。
噪声分析
float *nsIn[1] = { inf_buffer }; //ns input[band][data]
float *nsOut[1] = { outf_buffer };//ns output[band][data]
WebRtcNs_Analyze(nsHandle, nsIn[0]);
调用用函数进行处理,注意输入待处理的数据
降噪处理
WebRtcNs_Process(nsHandle, (const float *const *)nsIn, num_bands, nsOut);
对输入信号进行降噪,函数中 num_bands 参数(取值1~2)对应着分频带之后的频段,对于16khz 的输入信号来讲可以可以不用管,鉴于我们直接使用降采样的方式处理高采样率的信号,因此该参数可以设置为 1
按帧输出
// output the processed signal
for (int n = 0; n != samples; ++n) {
output[0].push_back(nsOut[0][n]); // test
}
按帧输出信号
释放句柄
WebRtcNs_Free(nsHandle);
对应的例程可以在 webRtc_official 中找到,后续我们会补充处理 16khz 采样率以上的音频信号的例程【直接使用降采样将高采样率的信号降成16k的信号,然后降噪输出,输出的分辨率视情况而定,指定/不变】
ps:
由于分频法在最新的文件依赖中有所改动,并且还需要将原有浮点数转成定点格式才能处理,因此不再尝试用该方法处理高采样率下的情况
对于音乐信号,经过本算法处理后虽然也有降噪效果,但实际听感会有点不自然,因此不推荐对音乐信号降噪时使用本算法,推荐用于语音信号的降噪。
在经过降噪后,会使信号增益下降,实际应用中需考虑增加 AGC,Auto gain control, 模块。
参考文献
网易云信神经网络音频降噪算法:提升瞬态噪声抑制效果,适合移动端设备https://blog.csdn.net/shichaog/category_10836967.htmlhttps://blog.csdn.net/shichaog/article/details/52514816 音频汉宁窗:https://blog.csdn.net/xingzhedai/article/details/53170470https://github.com/coldbrother/WebRtc/blob/master/windows_private.h NLP-ASR语音识别项目整理(一) 音频预处理:https://www.it610.com/article/1179393032953319424.htm
文档资料:https://www.it610.com/article/1179393032953319424.htm 宁窗hanning汉明窗hamming矩形窗:https://max.book118.com/html/2018/0416/161740876.shtm 用 FFT(快速傅里叶/余弦/正弦变换)封装源码:https://www.kurims.kyoto-u.ac.jp/~ooura/fft.html 语音信号滤波去噪——使用汉宁窗设计的FIR滤波器要点:https://wenku.baidu.com/view/271a7e8ecf2f0066f5335a8102d276a20029603f.html Active Noise Cancelling-主动噪声消除: 经典滤波器篇: 音频噪声抑制(1):经典滤波器篇 http://www.noobyard.com/article/p-anajedkw-bv.htmlhtml
基于RNN的音频降噪算法 (附完整C代码) 算法
音频噪声抑制(4):普通最小均方偏差(LMS)算法
音频噪声抑制(2):维纳(Wiener)滤波器篇 http://www.noobyard.com/article/p-hsppwaap-hn.htmlhtm
回音消除、噪音抑制的原理
音频特征提取及差别
自适应滤波器 http://www.noobyard.com/article/p-cyhjymiy-gg.html音频
基于STFT的语音信号时频分析 https://wenku.baidu.com/view/a4263cc0c1c708a1284a4452.html原理
基于谱减法的声音去噪 和 自适应
单通道语音加强之维纳滤波 http://www.noobyard.com/article/p-tcocvsbn-th.html 和 http://www.noobyard.com/article/p-exmokeys-th.html 和 http://www.noobyard.com/article/p-anbrqhxt-th.html