WebRTC的回聲抵消(aec、aecm)算法主要包括以下幾個(gè)重要模塊:回聲時(shí)延估計(jì);NLMS(歸一化最小均方自適應(yīng)算法);NLP(非線性濾波);CNG(舒適噪聲產(chǎn)生)。一般經(jīng)典aec算法還應(yīng)包括雙端檢測(DT)。
考慮到WebRTC使用的NLMS、NLP和CNG都屬于經(jīng)典算法范疇,故只做簡略介紹,本文重點(diǎn)介紹webrtc的回聲時(shí)延估計(jì)算法,這也是webrtc回聲抵消算法區(qū)別一般算法(如視頻會(huì)議中的算法)比較有特色的地方。
1) 回聲時(shí)延估計(jì)
回聲延時(shí)長短對回聲抵消器的性能有比較大的影響(此處不考慮pc上的線程同步的問題),過長的濾波器抽頭也無法實(shí)際應(yīng)用,因此時(shí)延估計(jì)算法就顯得比較重要了。常用且容易想到的估計(jì)算法是基于相關(guān)的時(shí)延估計(jì)算法(學(xué)過通信原理的應(yīng)該不會(huì)陌生),另外相關(guān)算法在語音編碼中也得到廣泛的應(yīng)用,如amr系列,G。729系列,G。718等編碼器。在語音信號(hào)自相關(guān)求基音周期時(shí),由于編碼器一般按幀處理,幀長度一般是10或20ms,在該時(shí)延范圍內(nèi)搜索基音周期運(yùn)算量較小,然而對于回聲抵消的應(yīng)用場合,延時(shí)搜索范圍比較大,帶來很高的運(yùn)算復(fù)雜度。在手持終端設(shè)備上,我們需要考慮移動(dòng)環(huán)境的變化對算法性能的影響,比如時(shí)延是否隨機(jī)變化,反射路徑線性還是非線性,以及運(yùn)算量(電池)是否符合要求,則更為復(fù)雜。
回到WebRTC的回聲時(shí)延估計(jì),它采用的是gips首席科學(xué)家Bastiaan的算法。下面介紹一下該算法的主要思想:
設(shè)1表示有說話音,0表示無說話音(靜音或者很弱的聲音)。
參考端(遠(yuǎn)端)信號(hào)x(t)和接收端(近端)信號(hào)y(t)可能的組合方式有以下幾種:(0,0),(0,1),(1,0),(1,1)。
(0,0)表示遠(yuǎn)端和近端都是比較弱的聲音;
(1,1)表示遠(yuǎn)端和近端都是比較強(qiáng)的聲音;
WebRTC的代碼默認(rèn)其它兩種情況是不可能發(fā)生的。
設(shè)在時(shí)間間隔p上,即p=1,2,…,P,頻帶q,q=1,2,…,Q上,輸入信號(hào)x加窗(如漢寧窗)后的功率譜用Xw(p,q)來表示,對每個(gè)頻帶中的功率譜設(shè)定一個(gè)門限Xw(p,q)_threshold,
如果Xw(p,q)>=Xw(p,q)_threshold,則Xw(p,q)=1;
如果Xw(p,q)<Xw(p,q)_threshold,則Xw(p,q)=0;
同理,對于信號(hào)y(t),加窗信號(hào)功率譜Yw(p,q)和門限Yw(p,q)_threshold,
如果Yw(p,q)>=Yw(p,q)_threshold,則Yw(p,q)=1;
如果Yw(p,q)<Yw(p,q)_threshold,則Yw(p,q)=0;
考慮到實(shí)際處理的方便,在WebRTC的C代碼中,將經(jīng)過fft變換后的頻域功率譜分為32個(gè)子帶,這樣每個(gè)特定子帶Xw(p,q)的值可以用1個(gè)比特來表示,總共需要32個(gè)比特,只用一個(gè)32位數(shù)據(jù)類型就可以表示了。
WebRTC對參考信號(hào)定義了75個(gè)32位binary_far_history的數(shù)組存放歷史遠(yuǎn)端參考信號(hào),定義了16個(gè)32位binary_near_history的數(shù)組存放歷史近端參考信號(hào),最近的值都放在下標(biāo)為0的數(shù)組中,使用binary_near_history[15]的32位bit與binary_far_history數(shù)組中75個(gè)32位bit分別按位異或,得到75個(gè)32位比特?cái)?shù)據(jù),32位bit的物理意義是近似地使用功率譜來統(tǒng)計(jì)兩幀信號(hào)的相關(guān)性。統(tǒng)計(jì)32位結(jié)果中的1的個(gè)數(shù)存于bit_counts中,接下來用對bit_counts進(jìn)行平滑防止延時(shí)突變,得到mean_bit_count,可以看出mean_bit_count越小,則表明近端數(shù)據(jù)與該幀的遠(yuǎn)端數(shù)據(jù)越吻合,兩者的時(shí)延越接近所需要的延時(shí)數(shù)值,用value_best_candidate表示。剩下的工作是對邊界數(shù)值進(jìn)行保護(hù),如果value_best_candidate接近最差延時(shí)(預(yù)設(shè)),則表明數(shù)值不可靠,這時(shí)不更新延時(shí)數(shù)據(jù);如果數(shù)據(jù)可靠,則進(jìn)一步使用一階markvo模型,比照上一次時(shí)延數(shù)據(jù)確定本次最終的更新時(shí)延last_delay。
Bastiaan的專利本身要比現(xiàn)有的c代碼實(shí)現(xiàn)更為復(fù)雜,比如在異或的時(shí)候(0,0),(0,1),(1,0),(1,1)四種組合可以附加代價(jià)函數(shù),而c代碼相當(dāng)于默認(rèn)給(0,0),(1,1)附加權(quán)值為1,給(0,1),(1,0)附加權(quán)值為0;另外c代碼算法是按幀順序依次對遠(yuǎn)端和近端數(shù)組異或,實(shí)際應(yīng)用時(shí)也可以每隔1幀或2幀做異或,這樣可以擴(kuò)大搜索范圍。
總的來說WebRTC異或的時(shí)延估計(jì)算法復(fù)雜度比求相關(guān)大大簡化,尤其適用于移動(dòng)終端等對運(yùn)算量比較敏感的場合進(jìn)行回聲消除。針對實(shí)際應(yīng)用場合,算法還有提升的空間。
2) NLMS(歸一化最小均方自適應(yīng)算法)
LMS/NLMS/AP/RLS等都是經(jīng)典的自適應(yīng)濾波算法,此處只對webrtc中使用的NLMS算法做簡略介紹。設(shè)遠(yuǎn)端信號(hào)為x(n),近段信號(hào)為d(n),W(n),則誤差信號(hào)e(n)=d(n)-w'(n)x(n)(此處‘表示轉(zhuǎn)秩),NLMS對濾波器的系數(shù)更新使用變步長方法,即步長u=u0/(gamma+x'(n)*x(n));其中u0為更新步長因子,gamma是穩(wěn)定因子,則濾波器系數(shù)更新方程為W(n+1)=W(n)+u*e(n)*x(n);NLMS比傳統(tǒng)LMS算法復(fù)雜度略高,但收斂速度明顯加快。LMS/NLMS性能差于AP和RLS算法。
另外值得一提的是webrtc使用了分段塊頻域自適應(yīng)濾波(PBFDAF)算法,這也是自適應(yīng)濾波器的常用算法。自適應(yīng)濾波的更多資料可以參考simonhaykin的《自適應(yīng)濾波器原理》。
3) NLP(非線性濾波)
WebRTC采用了維納濾波器。此處只給出傳遞函數(shù)的表達(dá)式,設(shè)估計(jì)的語音信號(hào)的功率譜為Ps(w),噪聲信號(hào)的功率譜為Pn(w),則濾波器的傳遞函數(shù)為H(w)=Ps(w)/(Ps(w)+Pn(w))。
4) CNG(舒適噪聲產(chǎn)生)
WebRTC采用的舒適噪聲生成器比較簡單,首先生成在[0,1]上均勻分布的隨機(jī)噪聲矩陣,再用噪聲的功率譜開方后去調(diào)制噪聲的幅度。
總的說來,WebRTC的aec算法簡單、實(shí)用、易于商業(yè)化,另一方面猜測c代碼還有所保留。
由于工作需要,最近一直在研究WebRTC里的AEC算法。根據(jù)源碼里面的fullaec。m文件,總體來說,我認(rèn)為該AEC算法是屬于分段快頻域自適應(yīng)濾波算法,Partioned block frequeney domain adaPtive filter(PBFDAF)。具體可以參考Paez Borrallo J M and Otero M G
使用該AEC算法要注意兩點(diǎn):
1)延時(shí)要小,因?yàn)樗惴J(rèn)濾波器長度是分為12塊,每塊64點(diǎn),按照8000采樣率,也就是12*8ms=96ms的數(shù)據(jù),而且超過這個(gè)長度是處理不了的。
2)延時(shí)抖動(dòng)要小,因?yàn)樗惴ㄊ悄J(rèn)10塊也計(jì)算一次參考數(shù)據(jù)的位置(即濾波器能量最大的那一塊),所以如果抖動(dòng)很大的話找參考數(shù)據(jù)時(shí)不準(zhǔn)確的,這樣回聲就消除不掉了。