Featured image of post unimrcp音频降噪方案

unimrcp音频降噪方案

背景

unimrcp 本身没有提供降噪功能,降噪的功能一般由对接的asr 服务提供。但是如果asr 服务没有提供降噪功能, 那么就需要在unimrcp 中实现降噪功能。结合已有的技术积累,目前主要有以下两种方案:

  1. 集成webrtc源码中的降噪模块。
  2. 使用ffmpeg来实现降噪功能。

接下来,我将详细介绍这两种方案的实现效果,下面是原始8k的音频文件,没有降噪处理。

webrtc 降噪

webrtc 源码介绍

webrtc的源码地址为: https://webrtc.googlesource.com/src, 最新版本是c++的。

因为unimrcpc的,所以要集成webrtcc++代码,有一定的难度,想挑战的可以尝试一下。

webrtc的降噪模块在src/modules/audio_processing/ns/noise_suppressor.cc文件中。

我集成的是webrtc早期的版本,之前的版本是c写的,时间为2013。这是git log信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
commit 3bca0df1d47f4ab54cf05ce9d8e11c90f84974ba (HEAD -> master, origin/master, origin/HEAD)
Author: wu@webrtc.org <wu@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>
Date:   Mon Dec 16 16:49:46 2013 +0000

    Update stable to r5300.

    git-svn-id: http://webrtc.googlecode.com/svn/stable/webrtc@5301 4adac7df-926f-26a2-2b94-8c16560cd09d

commit 658db909bd7d105d954f3021f825a55873a81499
Author: wu@webrtc.org <wu@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>
Date:   Fri Dec 13 19:20:56 2013 +0000

    Update stable to r5287.

    git-svn-id: http://webrtc.googlecode.com/svn/stable/webrtc@5288 4adac7df-926f-26a2-2b94-8c16560cd09d

commit 15a8a6e7edb2c8df7f5b21e759ace213a4ab7292
Author: wu@webrtc.org <wu@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>
Date:   Fri Dec 13 00:53:00 2013 +0000

    Update stable to r5277.

    git-svn-id: http://webrtc.googlecode.com/svn/stable/webrtc@5278 4adac7df-926f-26a2-2b94-8c16560cd09d

webrtc 降噪效果

webrtc的降噪等级有0-34个等级, 0最低,3最高, 以下是实际测试的波形图:

  1. 降噪等级1

mode=1

  1. 降噪等级2

mode=2

  1. 降噪等级3

mode=3

可以看到,对于背景噪音较大时,webrtc的降噪效果不好。

ffmpeg 降噪模块

集成方式

实现方式比较多,可以使用c调用ffmpeg, 我用的是golang调用ffmpeg, 提供.sounimrcp调用。

ffmpeg 降噪类型

ffmpeg 降噪算法有多种,包括:

推荐滤镜 场景 降噪强度 CPU开销 实时性建议
afftdn 通用背景噪音 中等 效果均衡,无需外部文件,计算快。
arnndn 专业人声提取 (会议) 极高 中/高 针对语音优化,效果最接近专业软件,需要模型文件。
anlmdn 高保真除噪(音乐) 不推荐高并发流式
agate 消除空白期杂音 取决于阈值 极低 配合其他降噪滤镜使用,效果好。
highpass/lowpass 电流嗡嗡声 直接切断高低频段,简单粗暴有效。

官方文档:ffmpeg filter 文档

afftdn(自适应采样)

常用参数:

  • nr: 降噪强度,默认: 12dB, 范围: 0.01-97dB
  • nf: 噪声底电平,默认:-50dB, 范围: -80dB到-20dB

使用命令:

1
ffmpeg -f s16le -ar 8000 -ac 1  -i input.pcm  -af "afftdn=nr=12dB:nf=-50dB"  -ar 8000 -f wav output.wav

可以看到这个降噪幅度很小,最高也就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在其他的目录下,就可以这样:

1
ffmpeg -f s16le -ar 8000 -ac 1  -i input.pcm  -af "arnndn=m=./models/cb.rnnn"  -ar 8000 -f wav output.wav

原始的音频波形为: original

cb.rnnn 降噪效果

cb.rnnn

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

bd.rnnn 降噪效果

bd.rnnn

lq.rnnn 降噪效果

lq.rnnn

mp.rnnn 降噪效果

mp.rnnn

sh.rnnn 降噪效果

sh.rnnn

std.rnnn 降噪效果

std.rnnn

anlmdn(非局部均值去噪)

常用参数:

  • s: 降噪强度,默认: 0.00001, 范围: 0.00001-10000dB
  • p: 补丁长度(毫秒),用于匹配相似音频块的长度,默认:2ms, 范围: 1-100ms
  • r: 搜索窗口长度(毫秒),在多大的范围内寻找相似的声音块,默认: 6ms, 范围: 2-300ms
  • m: 平滑因子,默认: 11, 范围: 1-1000

使用命令:

1
ffmpeg -f s16le -ar 8000 -ac 1  -i input.pcm  -af "anlmdn=s=1000"  -ar 8000 -f wav output.wav

我把s=1000dB, 这样可以达到和arnndn一样的效果,但是如果声音较小时,会失真,所以s设置多大很重要。 和highpass/lowpass降噪滤镜配合使用,效果会更好。

anlmdn 降噪效果

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

使用命令:

1
ffmpeg -f s16le -ar 8000 -ac 1  -i input.pcm  -af "agate"  -ar 8000 -f wav agate.wav

agate 降噪效果

agate

看着效果也不错,但是和highpass/lowpass降噪滤镜配合使用,效果会更好。

highpass/lowpass(高通/低通滤波)

highpass: 让高于设定频率的声音通过,切断低于该频率的声音。 lowpass: 让低于设定频率的声音通过,切断高于该频率的声音。

常用参数:

  • f: 截止频率,highpass默认: 3000Hz, lowpass默认: 500Hz
  • p: 滤波器阶数, 增加阶数会让边缘切得更“陡”,默认: 2
  • w: 带宽,控制过渡带的形状。

使用命令:

1
ffmpeg -f s16le -ar 8000 -ac 1  -i input.pcm  -af "highpass=f=1000,lowpass=f=3400"  -ar 8000 -f wav highpass.wav

highpass/lowpass 降噪效果

highpass/lowpass

有一定的降噪能力,但是还达不到想要的结果。

组合以上降噪滤镜

  1. highpass/lowpass+ anlmdn+ agate

使用命令:

1
ffmpeg -ar 8000 -ac 1 -f s16le -i input.pcm -af "highpass=f=300,lowpass=f=3700, anlmdn=s=0.001:p=0.002:r=0.006, agate=threshold=-30dB:ratio=10:attack=10:release=200"  -ar 8000 -f wav pass-1.wav

效果 : pass-1

可以看到把背景音都去掉了,而且语音也没有明显的失真。

  1. highpass/lowpass+ arnndn+ agate(补充增益)

使用命令:

1
ffmpeg -ar 8000 -ac 1 -f s16le -i input.pcm -af "highpass=f=300, lowpass=f=3400, anlmdn=s=0.002, agate=threshold=-32dB:ratio=15:makeup=1.5"  -ar 8000 -f wav pass-2.wav

效果 : pass-2

可以看到加了增益,人声分贝也提高了。

总结

  1. 实际的降噪能力,还是ffmpeg更好。
  2. ffmpeg降噪算法首选arnndn, 可能CPU占用较高。
  3. ffmpeg次一级的算法可以使用highpass/lowpass+ anlmdn+ agate组合方式,效果也不错。需要根据实际情况调整参数。
本博客已稳定运行
发表了76篇文章 · 总计131.31k字
本站总访问量 次 · 您是本站第 位访问者
粤ICP备2025368587号-1| 使用 Hugo 构建
主题 StackJimmy 设计