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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM