背景
unimrcp 本身没有提供降噪功能,降噪的功能一般由对接的asr 服务提供。但是如果asr 服务没有提供降噪功能,
那么就需要在unimrcp 中实现降噪功能。结合已有的技术积累,目前主要有以下两种方案:
- 集成
webrtc源码中的降噪模块。 - 使用
ffmpeg来实现降噪功能。
接下来,我将详细介绍这两种方案的实现效果,下面是原始8k的音频文件,没有降噪处理。
webrtc 降噪
webrtc 源码介绍
webrtc的源码地址为: https://webrtc.googlesource.com/src, 最新版本是c++的。
因为unimrcp是c的,所以要集成webrtc的c++代码,有一定的难度,想挑战的可以尝试一下。
webrtc的降噪模块在src/modules/audio_processing/ns/noise_suppressor.cc文件中。
我集成的是webrtc早期的版本,之前的版本是c写的,时间为2013。这是git log信息:
|
|
webrtc 降噪效果
webrtc的降噪等级有0-3共4个等级, 0最低,3最高, 以下是实际测试的波形图:
- 降噪等级
1:

- 降噪等级
2:

- 降噪等级
3:

可以看到,对于背景噪音较大时,webrtc的降噪效果不好。
ffmpeg 降噪模块
集成方式
实现方式比较多,可以使用c调用ffmpeg, 我用的是golang调用ffmpeg, 提供.so给unimrcp调用。
ffmpeg 降噪类型
ffmpeg 降噪算法有多种,包括:
| 推荐滤镜 | 场景 | 降噪强度 | CPU开销 | 实时性建议 |
|---|---|---|---|---|
afftdn |
通用背景噪音 | 中等 | 低 | 效果均衡,无需外部文件,计算快。 |
arnndn |
专业人声提取 (会议) | 极高 | 中/高 | 针对语音优化,效果最接近专业软件,需要模型文件。 |
anlmdn |
高保真除噪(音乐) | 高 | 高 | 不推荐高并发流式 |
agate |
消除空白期杂音 | 取决于阈值 | 极低 | 配合其他降噪滤镜使用,效果好。 |
highpass/lowpass |
电流嗡嗡声 | 低 | 低 | 直接切断高低频段,简单粗暴有效。 |
官方文档:ffmpeg filter 文档
afftdn(自适应采样)
常用参数:
nr: 降噪强度,默认:12dB, 范围:0.01-97dBnf: 噪声底电平,默认:-50dB, 范围:-80dB到-20dB
使用命令:
|
|
可以看到这个降噪幅度很小,最高也就97dB, 所以针对我们打电话示例中的音频,背景声有几千dB,降噪效果并不好。
arnndn(神经网络降噪)
其参数只有两个:
m: 模型文件路径,必须。mix: 混合系数,默认:1, 范围:-1到1。
模型文件有:bd.rnnn,cb.rnnn,lq.rnnn,mp.rnnn,sh.rnnn,std.rnnn,常用的是cb.rnnn。
通过对比,std.cnnn降噪最差,sh.rnnn效果更好,其他的都差不多,自己可以按照实际情况选择。
可以从: https://github.com/richardpl/arnndn-models.git 下载模型文件。
如果你的cb.cnnn在其他的目录下,就可以这样:
|
|
原始的音频波形为:

cb.rnnn 降噪效果

可以看到效果很好, 背景噪音被显著减少,语音也没有明显的失真。相比于原始音频,人声的分贝也降低了很多, 当用户声音较小时,可能会失真。
bd.rnnn 降噪效果

lq.rnnn 降噪效果

mp.rnnn 降噪效果

sh.rnnn 降噪效果

std.rnnn 降噪效果

anlmdn(非局部均值去噪)
常用参数:
s: 降噪强度,默认:0.00001, 范围:0.00001-10000dB。p: 补丁长度(毫秒),用于匹配相似音频块的长度,默认:2ms, 范围:1-100ms。r: 搜索窗口长度(毫秒),在多大的范围内寻找相似的声音块,默认:6ms, 范围:2-300ms。m: 平滑因子,默认:11, 范围:1-1000。
使用命令:
|
|
我把s=1000dB, 这样可以达到和arnndn一样的效果,但是如果声音较小时,会失真,所以s设置多大很重要。
和highpass/lowpass降噪滤镜配合使用,效果会更好。
anlmdn 降噪效果

agate(自动门限)
它的工作原理像一个“自动开关”:
当声音低于某个设定的阈值(Threshold)时,它会降低音量甚至静音;
当声音高于阈值时,它会让声音通过。
常用参数:
threshold: 门限阈值,低于此电平的声音将被压缩/静音。值越小越灵敏,默认:0.125, 范围:0-1。ratio: 压缩比,门关闭时音量降低的倍数, 默认:2, 范围:1-9000。attack: 攻击时间(毫秒),声音超过阈值后,门开启的速度,默认:20ms, 范围:0.01-9000ms。release: 释放时间(毫秒),声音低于阈值后,门关闭的速度,默认:250ms, 范围:0.01-9000ms。makeup: 增益补偿,由于门可能会降低整体能量,可以用它补回音量, 默认:1, 范围:1-64。knee: 拐点柔顺度。让开关切换更自然,不至于听起来很突兀, 默认: 2.828427125,, 范围:1-8。
使用命令:
|
|
agate 降噪效果

看着效果也不错,但是和highpass/lowpass降噪滤镜配合使用,效果会更好。
highpass/lowpass(高通/低通滤波)
highpass: 让高于设定频率的声音通过,切断低于该频率的声音。
lowpass: 让低于设定频率的声音通过,切断高于该频率的声音。
常用参数:
f: 截止频率,highpass默认:3000Hz,lowpass默认:500Hz。p: 滤波器阶数, 增加阶数会让边缘切得更“陡”,默认:2。w: 带宽,控制过渡带的形状。
使用命令:
|
|
highpass/lowpass 降噪效果

有一定的降噪能力,但是还达不到想要的结果。
组合以上降噪滤镜
highpass/lowpass+anlmdn+agate
使用命令:
|
|
效果 :

可以看到把背景音都去掉了,而且语音也没有明显的失真。
highpass/lowpass+arnndn+agate(补充增益)
使用命令:
|
|
效果 :

可以看到加了增益,人声分贝也提高了。
总结
- 实际的降噪能力,还是
ffmpeg更好。 ffmpeg降噪算法首选arnndn, 可能CPU占用较高。ffmpeg次一级的算法可以使用highpass/lowpass+anlmdn+agate组合方式,效果也不错。需要根据实际情况调整参数。