• 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

  • 相关阅读:
    JavaScript系列---【分析局部作用域下的预解析】
    javaScript系列---【分析全局作用域下的预解析】
    javaScript系列---【分析函数的arguments】
    JavaScript系列---【条件if--切换图片案例2 高亮及按钮同步显示】
    javaScript系列---【this详解及call和apply修改this指向】
    JavaScript系列---【选项卡案例】
    JavaScript系列---【QQ列表展开及闭合案例】
    系统安装01-CentOS6系统安装
    hdoj--3635--Dragon Balls(并查集记录深度)
    hdoj--1281--棋盘游戏(最小点覆盖+枚举)
  • 原文地址:https://www.cnblogs.com/cpuimage/p/8976346.html
Copyright © 2020-2023  润新知