WebRTC 音频算法 附完整C代码

WebRTC提供一套音频处理引擎,

包含以下算法:

AGC自动增益控制(Automatic Gain Control)

ANS噪音抑制(Automatic Noise Suppression)

AEC是声学回声消除(Acoustic Echo Canceller for Mobile)

VAD是静音检测(Voice Activity Detection)

这是一套非常经典,以及值得细细品阅学习的音频算法资源。

在前面分享的博文,也有提及音频相关知识点。

一些算法优化的知识点,由于历史的原因,

WebRTC的实现已经不是当下最优的思路。

但也是非常经典的。

例如:

AGE算法中的WebRtcSpl_Sqrt  快速开平方的实现。

可以采用如下汇编函数替换之:

static float fast_sqrt(float x) {
    float s;
#if defined(__x86_64__)
    __asm__ __volatile__ ("sqrtss %1, %0" : "=x"(s) : "x"(x));
#elif defined(__i386__)
    s = x;
    __asm__ __volatile__ ("fsqrt" : "+t"(s));
#elif defined(__arm__) && defined(__VFP_FP__)
    __asm__ __volatile__ ("vsqrt.f32 %0, %1" : "=w"(s) : "w"(x));
#else
    s = sqrtf(x);
#endif
    return s;
}

现代很多cpu 汇编指令已经支持开平方的快速实现,

经过测试比对确实会比WebRtcSpl_Sqrt 快不少的。

关于开平方的快速实现,详情可以看下:

https://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi

做算法优化的同学,就放过开平方吧。

每个算法有两个基本指标,

性能,效果。

WebRTC 着力于音频通信,所以它对性能的要求是极高的。

而算法的性能的优化,绝大多数情况的思路,都是特例化。

以前在公司开技术分享会的时候,也分享过。

也就一句话,越靠近CPU,性能越快。

也就是除非要不得以,请不要写到硬盘上,然后再读上来。

因为硬盘离CPU太远了。

所以优化的思路也就非常明显了。

从快到慢的介质分别是

CPU的寄存器 -> CPU的缓存 -> 内存空间 -> 硬盘空间(磁盘)

所以 尽可能地要使用上层的资源,能用寄存器就用寄存器,

能往CPU的资源上靠,就要把算法数据结构和资源做得更加紧凑。

关于CPU的相关资源:

https://www.cpuid.com/softwares/cpu-z.html

可以下一个CPU-Z 查看一下。

抽丝剥茧,一定要了解CPU的结构性能信息。

然后对症下药,尽可能符合CPU的口味。

科普下算法优化的思路:

1.尽可能多用局部变量,编写最短,最有效的闭合函数。

为了编译处理的时候,能最终用上寄存器,去缓存。

2.尽可能少调用函数,参数最好是指针或引用传递,这样能减少拷贝,

当然,可以的话参数要尽可能地少。

3.处理的数据尽可能紧凑且少,数据对齐很大程度上,

就是为了符合CPU的喜好,用上它的缓存。

4.尽可能顺序读写,也是为了用上缓存资源

5.计算降级,一般情况下乘法比加法耗时,除法比乘法耗时。

浮点比整形耗时。

所以将乘法降为加法,将除法降为乘法,浮点降为整形(定点化)。

这一条大多数朋友若是不清楚为什么,可以移步资源:

https://github.com/ARM-software/CMSIS_5

阅读其中的一些实现,你会找到具体原因的。

这里就不展开了。

6.能用内存的,就不要用磁盘,我想这个没必要多解释了。

7.当然如果能用特定算法思路数据接口进行优化也是可以的,例如查表之类的。

好像有点跑题了,回到主题上。

抽空把以上提及的几个算法整理成 

单文件实现的方式,并附加示例代码。

便于学习或者工程化之用。

相关项目地址:

https://github.com/cpuimage/WebRTC_AECM

https://github.com/cpuimage/WebRTC_NS

https://github.com/cpuimage/WebRTC_VAD

https://github.com/cpuimage/WebRTC_AGC

路漫漫其修远兮,一条道走到黑。

用cmake即可进行编译示例代码,详情见CMakeLists.txt。

若有其他相关问题或者需求也可以邮件联系俺探讨。

联系邮箱:gaozhihan@vip.qq.com

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏咸鱼不闲

树莓派上安装pyaudio 及 对声音实时监控

在树莓派上最常用的录音是arecord命令,但是功能有限,不能实现检测到声音做出反应。但是pyaudio能。

1.4K10
来自专栏FreeBuf

Python工具分析风险数据

小安前言 随着网络安全信息数据大规模的增长,应用数据分析技术进行网络安全分析成为业界研究热点,小安在这次小讲堂中带大家用Python工具对风险数据作简单分析,主...

28590
来自专栏CDA数据分析师

Python进阶学习之阅读代码

起因 最近在公司的任务是写一些简单的运营工具,因为是很小的工具,所以就用了github上面的一个开源项目flask-admin,可以省去很多的事情。 但是,这个...

28770
来自专栏有趣的Python和你

Python数据分析之dataframe的groupbygroupby函数highcharts绘图

14530
来自专栏恰童鞋骚年

Unity3D游戏开发初探—4.开发一个“疯狂击箱子”游戏

  (1)如何在游戏脚本程序中创建对象而不是一开始就创建好对象?->使用GameObject的静态方法:CreatePrimitive()

15340
来自专栏IT大咖说

关于 Unicode 每个程序员应该知道的 5 件事

摘要 Unicode是一个令人难以置信的有用标准,它能使全世界的计算机、智能手机和智能手表以同样的方式显示相同的信息。不幸的是,它的复杂性使它成为了欺诈分子和恶...

29170
来自专栏灯塔大数据

每周学点大数据 | No.48 计算子图同构

No.48期 计算子图同构 Mr. 王:我们再来看一个例子——计算子图同构。这个问题给定(节点有标签)数据图G和查询图P,找到G 中和P 同构的子图。这是一个...

32280
来自专栏数据分析

[数据清洗]- Pandas 清洗“脏”数据(二)

概要 了解数据 分析数据问题 清洗数据 整合代码 了解数据 在处理任何数据之前,我们的第一任务是理解数据以及数据是干什么用的。我们尝试去理解数据的列/行、记录、...

37840
来自专栏极客生活

python爬虫隔一段时间一乐之海子的诗

每隔一段时间(一周到一个月)拿出1到2天来做一个好玩的东西,不求回报,只为快感。 前两天刚买了一本电子书《海子的诗》,晚上读了快一半,好多诗里面都提及了麦子和...

10510
来自专栏编舟记

生成式测试(Generative Testing)

满足需求是所有软件存在的必要条件,单元测试一定是为它服务的。从这一点出发,我们可以总结出写单元测试的两个动机:驱动(如:TDD)和验证功能实现。另外,软件需求易...

18630

扫码关注云+社区

领取腾讯云代金券