1. 程式人生 > >【轉載】基於WebRTC的Android數字樓宇對講系統回聲消除

【轉載】基於WebRTC的Android數字樓宇對講系統回聲消除

本文轉載自部落格:http://www.qttaudio.com/webrtc-android-lydj.html

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在一般的數字樓宇對講系統應用中,對講雙方需要進行實時的語音交流,而在室內或是樓道門E1都採用外接音箱放音的形式,這勢必會產生回聲H。21,即通話的一方說話後通過網路傳到通話另一方的音箱進行播放,然後播放出來的聲音又被另一方的傳聲器採集到並且通過網路傳回自己。這時,回聲的產生將會影響對講的通話質量和使用者對於樓宇對講產品體驗,而對於現在新興的Android數字樓宇對講系統。更是如此。目前Android數字樓宇對講系統中的回聲消除技術實現有以下3方面的難點和問題:
1)Android本地實時回聲消除技術問題Android系統是行動式嵌入式系統,軟硬體的計算資源相對有限,很多在Windows系統等PC機平臺上應用很成熟的回聲消除演算法和技術到Android平臺上可能都會出現一些適應性問題。
2)回聲消除中音訊採集、播放的延時問題因為Android不是實時作業系統,造成傳聲器的錄音、音響的放音之間都有一定時延,而且這個時延每個Android裝置可能都不一樣,這樣即便有很好的回聲消除方法,由於不能將錄音、放音對齊將會使得回聲消除沒有效果或是消去正常通話聲音,這會進一步增加Android回聲消除難度。
3)Android回聲消除的平臺移植性
目前,Android版本很多,如何使Android回聲消除技術能應用於多樣的終端上是一個現實問題。
為了解決以上問題,採用WebRTC的回聲消除模組實現Android本地實時回聲消除,並設計了多執行緒程式設計技術實現音訊採集、播放的同步,解決了Android樓宇對講系統的回聲問題,最後利用JNI(Java Native Interface——JAVA本地呼叫)技術將Android樓宇對講系統回聲消除程式進行封裝,便於不同Android平臺的移植。

1 技術基礎

目前,主流的實時通訊軟體中應對回聲消除問題基本都採用了這兩種回聲消除模組:Speex[41和Global IPSound(GIPS)”1。Speex是很多開源即時通訊軟體都會使用的方案,其最大亮點也是完全開源的,而GlobalIP Sound(GIPS)則是瑞典Global IP Solutions公司所研製的回聲消除技術,廣泛應用與商業軟體中。針對Speex和GIPS這兩個回聲消除模組,筆者採用了兩種通訊軟體進行了實際網路語音測試:Skype(採用GIPS)、Speex(採用Speex),以證明哪種回聲消除的效果更好。結果Skype的通話很好,基本沒有迴音,雙方交流很順暢,而相對Skype,使用Speex通話一直有殘餘迴音,雙方交流困難。由此可見,GIPS回聲消除模組有更好的回聲消除效果,但是一般GIPS回聲消除模組都是商用,且費用不菲。

2010年Google高價收購了Global IP Solutions公司,並將其擁有的WebRTC(Web Real Time Communiea—tion)技術專案開源。WebRTC是於Web瀏覽器應用的實時音視訊的通訊技術,其功能非常強大,內容主要包含語音引擎模組(voice engine)、視訊引擎模組(videoengine)、傳輸層模組(Transport)、會話管理模組(sessionmanagement),而在其語音引擎模組(voice engine)中就公開了GIPS回聲處理技術(AEC),這為Android數字樓宇對講系統的回聲消除實現提供了很好的基礎,並對研究Android數字樓宇對講系統的回聲消除處理問題具有重要意義。

2 Android數字樓宇系統回聲消除技術設計

在引言中提到,Android數字樓宇對講系統中回聲消除技術的實現具有3個問題或者說是難點:一是An·droid本地實時回聲消除技術問題,二是回聲消除中音訊採集、播放的延時問題,三是Android回聲消除的平臺移植性。
針對這三個問題,解決方案如下:
1)使用WebRTC中的GIPS回聲處理技術實現Android數字樓宇對講系統的本地實時回聲消除;
2)採用多執行緒快取技術,將音訊採集、播放進行同步處理,以使GIPS回聲處理技術能夠應用並取得很好的回聲消除效果。
3)利用JNI技術,將WebRTC中的GIPS核心C程式碼都編譯成動態連結庫以應用,可保證Android回聲消除應用於不同版本的Android平臺上。

3 Android數字樓宇系統回聲消除技術實現

本部分內容主要針對上文的設計思路進行具體的實現。首先利用WebRTC中的GIPS回聲處理技術實現本地回聲消除,然後採用多執行緒態連結庫便於使用。
3.1 WebRTC中的GILES本地回聲消除
前文中介紹過WebRTC中語音引擎模組(voice en—gine)公開了GIPS回聲處理技術(AEC),而另一方面WebRTC功能很強大,包括很多的模組,這意味著程式碼量也很大,這裡能否將GIPS回聲處理技術(AEC)提取出來單獨使用呢?答案是肯定的。
WebRTC的程式碼結構佈局清晰,在“webrtc\modules\audio_processing\aee”目錄下可以找到幾個用於回聲處理GIPS的AEC原始檔。然後主要查詢每個AEC原始檔所關聯的WebRTC程式碼,就可找出回聲處理模組所需要WebRTC相關的原始碼檔案和標頭檔案,這樣就可以將AEC從WebRTC中提取出來單獨使用。為方便使用,將需要這些程式碼分成2個模組,通用音訊處理模組webRTC_AUDIO和GIPS-AEC模組。WebRTC—AUDIO模組中包含AEC原始檔執行所依賴的WebRTC音訊處理相關原始檔及標頭檔案,而GIPS—AEC模組則是WebRTC中專門用於回聲處理GIPS的AEC原始檔。GIPS-AEC模組以WebRTC_AUDIO模組為基礎,對回聲進行處理。
在GIPS-AEC模組主要使用了5個函式完成回聲消除:
1)建立回聲消除函式
WebRtc—Word32 WebRtcAec—Create(void * aecInst);
函式會建立一個AEC資料結構,用於存放AEC過程中的變數和狀態,並將這個結構的地址存在形參aecInst指向的void指標中。
2)初始化回聲消除函式
WebRte_Word32 WebRtcAec_Init(void * aecInst,WebRtc_Word32 sampFreq,WebRtc_Word32 scSampFreq);
該函式可指定取樣率來初始化aecInst所指向的AEC資料結構(如取樣率sampFreq、scSampFreq可設定為8000)。
3)設定需要消去的參考音訊資料函式
WebRtc_Word32 WebRtcAec_BufferFarend(void * aeclnst,
const WebRtc_Wordl6 * farend,
WebRtc—Wordl6 nrOfSamples);
其中,形參farend指向需要消去的參考音訊資料塊,形參nrOfSamples是需要消去煩人音訊資料的取樣點數量(一般取值為160或80)。
4)回聲消除函式
WebRte_Word32 WebRtcAec—Process(void * aecInst,
const WebRtc_Wordl6 * nearend,
eonst WebRtc_Word 16 * nearendH,
WebRtc_Wordl6 * out,
WebRte Wordl6 * outH,
WebRtc_Wordl6 nrOiSamples,
WebRtc_Wordl6 mslnSndCardBuf,
WebRtc—Word32 skew):
該函式完成具體的回聲消除操作。AEC程式回聲消除的基本原理就是以音訊播放的資料為參照,消除傳聲器風采集到音訊中的已經播放內容。形參nearend就是指向本地所取樣的音訊資料指標,out是回聲消除後輸出資料指標;nrOfSamples是輸入的nearend音訊資料的取樣點數量(一般取值為160或80);形參mslnSnd.CardBuf就是音效卡實際輸入和輸出之間的時間差,即本地音訊和消去參考音訊之間的錯位時間。
5)釋放AEC回聲消除函式
WebRtc_Word32 WebRtcAec_Free(void * aecInst);
該函式釋放AEC資料結構。
完成這兩個模組後,筆者於單機進行了本地回聲消除的驗證,具體過程如圖1所示,首先準備2個音訊檔案,一個為帶有原聲和回聲的音訊檔案,另一個為只有回聲參考源的音訊檔案,然後將2個檔案的音訊資料分別匯入筆者實現的回聲消除模組,帶有原聲和回聲的音訊資料帶入到nearend,只有回聲參考源的音訊資料帶人到farend,通過回聲消除處理後,生成的out資料並儲存為檔案,即為只有原聲資料的音訊檔案。通過該實驗驗證,得到了非常滿意的回聲消除效果,原聲清晰且無回聲。
QttAudio-回聲消除
3.2音訊採集、播放的同步
因為Android不是實時作業系統,造成傳聲器的錄音、音響的放音之間都有一定時延,而且這個時延每個Android裝置可能都不一樣,這樣即便有很好的回聲消除方法,但有很多人卻得不到理想的回聲消除效果。
回聲消除AEC的基本原理就是以音訊播放的資料為參照,消除傳聲器風采集到音訊中的已經播放內容。如果音訊播放和音訊採集之間的時間差過大,即做回聲消除時參照的音訊播放資料和音訊採集資料之間有過大的錯位,那麼必然無法正確地消除回聲。
如果想要在網路音訊通訊中成功消除回聲,必須實現音訊採集、播放的同步。為此採用4個程式執行緒和3個佇列進行具體的實現(如圖2所示)。4個執行緒分別是ReadThread、WriteThread、InThread和AecOutThread。執行緒之間的資料交換則是使用了3個佇列來完成,這3個佇列分別是接收佇列、採集佇列和播放佇列。
QttAudio-回聲消除
在Android應用程式中,使用AudioRecord類進行音訊採集,使用AudiorTraek進行遠端音訊播放。為了保證時間上的連續性和時間差,使用了兩個單獨執行緒ReadThread和WriteThread來分別進行音訊採集和音訊播放,且這2個執行緒同時進行的。
InThread完成網路音訊資料的接收。而AecOut-Thread則完成回聲消除操作,並將處理後的資料傳送給通話另一方。
執行緒之間的資料交換使用佇列來完成,接收佇列儲存InThread通過網路接收到對方發來的音訊資料,WriteThread從接收佇列中讀出對方發來音訊資料並播放。WriteThread播放過的音訊資料會放入播放佇列儲存,等待AecOutThread執行緒使用。採集佇列用於儲存ReadThread通過傳聲器風采集到的音訊資料,供AecOutThread使用。AecOutThread同時提取採集佇列和播放佇列中音訊資料進行回聲消除處理,並把處理後結果通過傳送出去。這樣就可以保證音訊採集、播放的同步性,並達到滿意的回聲消除效果。
3.3 WebRTC中的GIPS回聲消除程式碼封裝
為了方便使用,通過JNI技術。將GIPS核心C程式碼封裝成動態連結庫。本部分的主要工作就是將使用的通用音訊處理模組WebRTC_AUDIO和GIPS—AEC模組進行封裝,得到Android下的動態連結庫檔案。具體就是需要編寫WebRTC_AUDIO和GIPS-AEC的Android.mk檔案以控制.SO檔案的編譯過程。
通用音訊處理模組WebRTC—AUDIO和GIPS—AEC模組在Android下編譯基本的步驟是:
1)編寫WebRTC_AUDIO的Android.mk檔案,將Osip中的所有原始碼和標頭檔案按照要求加進去,然後利用NDK(Native Development Kit——本地開發工具包)在Cygwin(linux平臺)下直接編譯WebRTC_AUDIO原始碼和Android.mk生成libWebRTC_AUDIO.SO動態連結庫檔案。
2)然後完成GIPS-AEC的Android.mk檔案,基本過程與上面類似,但是GIPS-AEC是基於WebRTC_AUDIO的,所以必須將生成的WebRTC_AUDIO.SO匯入到自己的Android.mk的檔案中,最後編譯生成libGIPS_AEC.SO檔案。
下面以webRTC_AUDIO的Android.mk簡單介紹一下.mk的編寫,其基本內容如下:
LOCAL_PATH:=$(call my-dir) 指定本地LOCAL_PATH變數位置
include $(CLEAR_VARS) 編譯模組開始
LOCAL_SRC_FILES:=...此處加入需要編譯的C原始檔名稱
LOCAL_CFLAGS+= -DWEBRTC_ANDROID\-DWEBRTC_ARCH_ARM\
..... 定義巨集
LOCAL—C—INCLUDES:= .... 加入所需要包含的標頭檔案路徑
LOCAL_LDLIBS+= -ldl 呼叫第三方庫
LOCAL_MODULE:=WebRTC_audio 指定生成.SO檔名稱
include $(BUILD_SHARED—LIBRARY) 指定生成.SO檔案,編譯模組結束
通過JNI技術將獨立出來的通用音訊處理模組WebRTC_AUDIO和GIPS—AEC模組核心C程式碼封裝成libWebRTC_AUDIO.SO和libGIPS-AEC.SO動態連結庫檔案,便於應用於不同的Android版本平臺上。

4 總結

Android回聲消除技術直接影響著Android數字樓宇對講系統對講的通話質量及使用者產品體驗。本文的目的是實現一種便於使用的Android樓宇對講的Android回聲消除技術。採用WebRTC的回聲消除模組實現Android本地實時回聲消除,並設計了多執行緒程式設計技術實現音訊採集、播放的同步,解決了Android樓宇對講系統的回聲問題,最後利用JNI技術將我們的Android樓宇對講系統回聲消除程式進行封裝,便於不同Android平臺的移植應用。本文中所研究的Android回聲消除技術不僅可應用於Android數字樓宇對講系統,對於其他Android數字通訊系統也同樣適用。