單獨編譯和使用webrtc音頻回聲消除模塊(附完整源碼+測試音頻文件)

單獨編譯和使用webrtc音頻降噪模塊(附完整源碼+測試音頻文件)html

單獨編譯和使用webrtc音頻增益模塊(附完整源碼+測試音頻文件)web

說實話很不想寫這篇文章,由於這和我一向推崇的最好所有編譯並使用webrtc音頻處理模塊相悖。但是不知不覺已經把降噪和增益寫出來,回聲消除若是用戶能夠獲得完美利用也不失爲一個很好的方法。可是仍是那句話,最好仍是所有編譯和使用webrtc的整個音頻處理模塊。另外這篇文章已經不僅僅的回聲消除模塊了,其中包括了降噪,增益,靜音檢測,若是有須要能夠選擇其中的一部分單獨提取調試。函數

相對而言回聲消除比起其餘模塊要複雜不少,不光光是計算量大(以前在一部380MHz的攝像頭中測試過,其消耗的時間爲降噪的三倍以上,若是音頻延遲更大甚至根本跑不起來),並且其中也涉及到一個delay的計算,delay計算是否精確徹底影響回聲消除的效果。post

至於delay的計算,網上有不少說明,有複雜也有簡單的。在這裏我仍是簡單的提一下:測試


這張圖不少東西能夠無視,咱們重點看T0,T1,T2三項。
T0表明着聲音從揚聲器傳到麥克風的時間,這個時間能夠忽略,由於通常來講話筒和揚聲器之間距離不會太遠,考慮到聲音340米每秒的速度,這個時間都不會超過1毫秒。spa

T1表明遠處傳到你這來的聲音,這個聲音被傳遞到回聲消除遠端接口(WebRtcAec_BufferFarend)的到播放出來的時間。通常來講接收到的音頻數據傳入這個接口的時候也就是上層傳入揚聲器的時刻,因此能夠理解成該聲音防到播放隊列中開始計時,到播放出來的時間。調試

T2表明一段聲音被揚聲器採集到,而後到被送到近端處理函數(WebRtcAec_Process)的時刻,因爲聲音被採集到立刻會作回聲消除處理,因此這個時間能夠理解成麥克風採集到聲音開始計時,而後到你的代碼拿到音頻PCM數據所用的時間。code

好了,delay=T0+T1+T2,其實也就是T1+T2。htm

通常來講,一個設備若是能找到合適的delay,那麼這個設備再作回聲消除處理就和降噪增益同樣幾乎沒什麼難度了。從網上看iPhone的固定delay是60ms,不過不肯定,MacBook掛了,在等四季度新MacBook上市,因此暫時沒辦法作驗證。blog

由於回聲消除過程,能夠理解成已經把藍黑兩種顏色的墨水徹底混合,而後分離出來所須要的藍色或者黑色顏色。事實上徹底混在一塊兒的音頻數據是沒法完全分開的,可是咱們能夠把混在一塊兒的聲音理解成兩段聲音,其中有一段聲音能夠找到一段幾乎相近的對比原聲,而後在混音中找到和原聲近似的數據,這樣就能夠分離了。delay的意義顯而易見就是要把原聲和混在一塊兒的聲音數據做對比時,校訂時刻所用,這個時刻越是精確,那麼回聲消除的效果越好。不過從實際效果來看這個delay也並不須要特別精確,在這段測試音頻數據裏面範圍能夠接近100毫秒。

從兩段音頻波形起始位置看delay的時間應該超過100毫秒,那麼能夠用一段代碼作測試,測試代碼和音頻文件來自於網上:

 1 int WebRtcAecTest()
 2 {
 3 #define  NN 160
 4     short far_frame[NN];
 5     short near_frame[NN];
 6     short out_frame[NN];
 7 
 8     void *aecmInst = NULL;
 9     FILE *fp_far  = fopen("speaker.pcm", "rb");
10     FILE *fp_near = fopen("micin.pcm", "rb");
11     FILE *fp_out  = fopen("out.pcm", "wb");
12 
13     do 
14     {
15         if(!fp_far || !fp_near || !fp_out)
16         {
17             printf("WebRtcAecTest open file err \n");
18             break;
19         }
20 
21         WebRtcAec_Create(&aecmInst);
22         WebRtcAec_Init(aecmInst, 8000, 8000);
23 
24         AecConfig config;
25         config.nlpMode = kAecNlpConservative;
26         WebRtcAec_set_config(aecmInst, config);
27 
28         while(1)
29         {
30             if (NN == fread(far_frame, sizeof(short), NN, fp_far))
31             {
32                 fread(near_frame, sizeof(short), NN, fp_near);
33                 WebRtcAec_BufferFarend(aecmInst, far_frame, NN);//對參考聲音(回聲)的處理
34 
35                 WebRtcAec_Process(aecmInst, near_frame, NULL, out_frame, NULL, NN,109,0);//回聲消除
36                 fwrite(out_frame, sizeof(short), NN, fp_out);
37             }
38             else
39             {
40                 break;
41             }
42         }
43     } while (0);
44 
45     fclose(fp_far);
46     fclose(fp_near);
47     fclose(fp_out);
48     WebRtcAec_Free(aecmInst);
49     return 0;
50 }

 

源碼下載(VS2010編譯版本,也能夠移植到其餘平臺無縫編譯):WebRtcAudioAllTest.rar

相關文章
相關標籤/搜索