zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/cpuimage/p/8976346.html
Copyright © 2011-2022 走看看