WebRTC 音訊演算法 附完整C程式碼

cpuimage發表於2018-05-01

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

相關文章