視頻社交SDK中回聲消除技術是如何實現的
社交網路一路走來,先是文字 + 表情,接著是圖片 + 短視頻,現在是音視頻社交強勢崛起並成為潮流的時代。音視頻社交將是社交網路的發展趨勢,畢竟音視頻才是人類最自然的社交方式。在自然的社交環境中,回聲是十分影響溝通體驗的。而回聲消除一直是音視頻技術的難點。
遊戲語音就是音視頻社交在遊戲領域的一個典型的應用。如果你不希望討厭戴耳機的用戶放棄你的遊戲,那麼在遊戲實時語音中實現回聲消除是必須的。
無論是競技類還是休閑類的遊戲,遊戲實時語音都成了標配。競技類的遊戲,包括 MMORPG、MOBA、和 FPS,需要快節奏和高頻率的團隊協同,遊戲語音就像戰時通訊裝備一樣必不可少。休閑類的遊戲,包括棋牌和狼人殺,需要慢節奏但是零距離的在線社交,玩家在通過遊戲建立的社交紐帶中進行多人實時聊天,遊戲實時語音讓玩家們像坐在同一個房間玩牌一樣。
在業界,回聲消除技術是公認難啃的硬骨頭。它本質上是一個複雜的數學問題的工程化。音頻工程師往往是數學或者物理專業而不是計算機專業出身的,沒有過相關經驗的工程師根本就無從下手。回聲消除技術做得比較好的產品有 Tencent QQ 和 Microsoft Skype,開源的項目有 WebRTC 和 Speex。在這些開源項目之前,回聲消除技術是大廠的獨門武藝,其它團隊只能靠自己一點一滴地摸索積累。在這些開源項目之後,WebRTC 和 Speex 提供開源的 AEC 模塊,成為業界不錯的教材。
AEC 的原理
回聲消除的原理很多文章介紹過,這裡只簡單介紹筆者在工作中的實踐。簡單地來說,遠端的聲音信號首先通過揚聲器播放出來,然後在房間中經過多個傳播和反射路徑,最後和近端的聲音一起被麥克風采集進去。如果沒有做回聲消除處理,那麼遠端就會把重新採集進去的遠端聲音信號播放出來,而且和原始的遠端聲音有一定的延遲時間。這就是回聲產生的原理。
要消除回聲,其實真的很難。這有點像把紅墨水倒進藍墨水裡,混合在一起,然後要求把紅墨水從藍墨水中分離出來。對於採集端來說,無論是近端的聲音,還是揚聲器播放出來的聲音,都是從空氣中無差別地採集到的聲音。對機器來說,遠端信號播放出來的聲音和近端的聲音是沒有任何區別的,就像對水來說紅墨水和藍墨水沒有區別一樣。回聲消除的工作就是要把沒有任何區別的遠端回聲和近端聲音分離。這項工作其實比想像中要難得多。
幸運的是,我們並非沒有任何辦法可以找到遠端回聲和近端聲音的邊界。
遠端的聲音信號和回聲是相關的。也許有朋友會一拍腦袋煥然大悟地說:那就直接把遠端聲音從採集到的聲音中減掉就可以了。然而事情並沒有那麼簡單。
遠端的聲音信號並非等同於回聲。遠端的聲音從揚聲器播放出來,到被採集端採集,經歷過揚聲器 - 房間 - 麥克風(Loudspeaker-Room-Microphone,LRM)這樣的回聲饋路。在 LRM 回聲饋路中傳播的時候,遠端聲音一方面經過多次反射,另外一方面經過多次疊加,最後變得和遠端聲音信號有差別了。我們把這個差別用一個函數來表示:
fe=f(fs)
其中,
fs=far-end signal(遠端信號);
fe=far-end echo (遠端回聲);
如果能夠對這個函數求解,那麼就可以根據遠端聲音信號和遠端回聲之間的相關性進行建模。這個模型是對回聲饋路 LRM 的模擬,會高度逼近回聲饋路 LRM。
等到這個模型穩定時,輸入遠端聲音信號 fs,就可以輸出高度接近遠端回聲的信號 fe。通過濾波器生成反相的信號,和採集到的聲音信號進行疊加,就可以把回聲信號消除掉。這就是回聲消除 AEC 的基本原理。
這個函數求出來的解不大可能和遠端回聲完全一致,只能高度逼近。該函數求出來的解和遠端回聲越逼近,回聲消除的效果就越好。
靜音、單講和雙講
雖然實時語音的通話是雙工模式,但是可以分為不同的情形:靜音、單講和雙講。針對不同的情形要採取不同的回聲消除策略。
1. 靜音
即沒有人說話的情形。
在語音段才需要做回聲消除,在非語音段不會有回聲,不需要做回聲消除,甚至不需要發送語音信息,從而可以降低碼率,節約帶寬成本。
因此,準確探測語音活動十分重要。語音的探測演算法叫 VAD(Voice Activity Detection)。不同的廠商有不同的 VAD 實現方法。我們是利用基音周期實現 VAD,有效地提高 VAD 判斷的準確性,避免將非語音段誤判為語音段。
2. 單講
即只有遠端說話的情形。
由於只有遠端說話,從麥克風采集進來的語音信號只包含遠端的回聲,而不包含近端的語音。單講情形下的回聲消除相對比較容易處理,可以採取比較激進的處理策略。
如果確定單講是高概率事件的情況下,可以直接地把所有語音信號都幹掉,然後適當地填充舒適噪音。一般來說,在單講情形下,用線性自適應濾波器跟蹤回聲饋路,可以很好地消除回聲,大概能夠抑制掉 18dB 的回聲。
3. 雙講
有多方同時說話的情形。
由於有多方同時說話,從麥克風采集進來的語音信號就包含了遠端的回聲和近端的語音,兩者混合在一起。雙講情形下的回聲消除就十分困難:一方面要保護近端的語音信號不被損傷,另外一方面還要盡量地把回聲消除乾淨。
這裡不但有「紅墨水藍墨水分離」的難題,而且還有「投鼠忌器」的困境。一般來說,在遠端回聲比近端語音要高大概 6dB~8dB 的情況下,如果要把遠端回聲消除乾淨,那麼肯定會或多或少地損傷到近端語音。
另外,如果遠端回聲比近端語音要高出 18dB 以上,比如說揚聲器離麥克風太近,遠端回聲把近端語音完全掩蓋掉了,那麼回聲消除的效果肯定是不好的。這種情形下,可以採取比較激進的策略,把遠端回聲和近端語音一起幹掉,然後適當地填充舒適噪音。
因此,回聲消除模塊要有能力區分這三種情形,才能針對各種情形採取不同的演算法。通過 VAD 可以區分非語音段和語音段。如何區分單講和雙講的方法將在下面討論。
AEC 的實現
回聲消除主要包含兩個步驟:線性自適應濾波和非線性處理。
線性自適應濾波就是對 fe=f(fs) 求解,建立遠端回聲的語音模型,進行第一輪迴聲消除。
非線性處理又分為兩個步驟:殘留回聲處理和非線性剪切處理。殘留回聲處理進行第二輪迴聲消除,處理殘留回聲;非線性剪切處理就是對衰減量達到閾值的語音信號進行比較激進的剪切處理。
線性自適應濾波和非線性剪切處理在學術論文和開源項目中能找到東西學習。殘留回聲處理就很難,一般都是要靠團隊自行摸索、積累和創新。正是因為如此,語音技術的門檻才如此的高。
回聲消除的原理與實現
線性自適應濾波
以遠端聲音信號和遠端回聲的相關性為基礎,建立遠端回聲的語音模型,利用它對遠端回聲進行估計,目的是獲得對遠端回聲盡量逼近的估計。我們可以把回聲饋路 LRM 看作一個「環境濾波器」。
經過它的處理,遠端聲音信號被變成遠端回聲。回聲消除就是要構建一個「演算法濾波器」,基於對遠端回聲的語音模型,不斷地調整該濾波器的係數,使得估計值更加逼近真實的回聲。估計值越逼近真實回聲,回聲消除效果就越好。
自適應濾波器收斂後得到的就是需要求解的回聲饋路函數 fe=f(fs)。當濾波器收斂穩定之後,輸入遠端聲音信號 fs,就可以輸出相對準確的對遠端回聲信號的估計值 fe。把採集到的信號減去遠端回聲信號的估計值 fe,就得到實際要發送的語音信號。
實現線性自適應濾波器有兩個難點:
1. 快速收斂
在收斂階段,採集到聲音信號要求只有遠端的回聲信號,不能混有近端的語音信號。近端的語音信號和遠端的參考語音信號沒有相關性,會對自適應濾波器的收斂過程造成擾亂。
因此,我們的策略是讓自適應濾波器收斂的時間盡量地短,短到收斂過程的時間段里採集進來的信號只有遠端的回聲信號,這樣自適應濾波器收斂的效果就會很好。在收斂好之後,濾波器就穩定下來了,就可以用來過濾遠端的回聲信號了。
2. 動態自適應
在收斂好穩定下來以後,自適應濾波器還要隨時自動適應回聲饋路的變化。自適應濾波器要能夠判斷回聲饋路是否發生變化,並且能夠重新學習和對其進行建模,不斷地調整該濾波器的係數,進入一個新的收斂過程,最後快速地逼近新的回聲饋路。
這種情況在手游的場景中是十分常見的,用戶拿著手機邊走邊玩遊戲,遊戲語音周遭的回聲饋路時刻發生著變化,自適應濾波器就要時刻自動重新收斂來適應新的回聲饋路。
這兩個難點是一對矛盾的特徵,要求自適應濾波器一方面要能夠快速收斂後保持係數高度穩定,另外一方面要能夠隨時保持更新狀態跟蹤回聲饋路的變化。
非線性處理
1. 殘留回聲處理
通過自適應濾波器來消除回聲,並不能百分之一百把回聲消除乾淨,還需要進一步消除殘留的回聲。
一般來說,殘留回聲消除的策略是利用自適應濾波器處理後的殘留回聲與遠端參考語音信號的相關性,進一步消除殘留回聲。相關性越大,說明殘留回聲越多,需要對殘留回聲進一步消除的程度越大;反之,相關性越小,說明殘留回聲較少,需要對殘留回聲進一步消除的程度越小。
因此,首先要通過計算殘留回聲與參考信號的相關矩陣,得到一個反映消除程度的衰減因子;然後將殘留回聲乘以衰減因子,從而進一步消除殘留回聲。
在線性自適應濾波做完了以後,可以利用殘留回聲和麥克風采集到的遠端回聲信號的相關性來檢測是處於單講還是雙講狀態。根據單講還是雙講狀態,可以進一步調整衰減因子。
如果處於遠端單講狀態,因為近端沒有聲音信號(沒人說話),可以盡量多地抑制回聲,讓衰減因子盡量地小;如果處於雙講狀態,因為線性自適應濾波器是在盡量不損傷近端語音音質的前提下消除回聲,回聲抑制量不會太大,所以衰減因子相對較大。
消除殘留回聲的演算法難度甚高。在論文或者開源項目中甚少有可參考的東西,各家廠商都是通過私有的演算法來實現的,甚至很多廠商都選擇不實現。
2. 非線性剪切處理
在完成了上述處理以後,其實剩下的回聲一般都比較小了,但不排除仍有一些殘留的可以感知的小回聲。為了進一步消除這些小回聲,要根據前面處理得到的衰減量來做進一步的抑制處理。
在這裡要為衰減量設定一個閾值。一般來說,這個衰減量閾值要設定得比較保守(比較高)。
如果衰減量達到或者超過設定的閾值,就表明回聲消除量比較大,採集進來的語音信號很可能全部都是回聲信號,那麼就直接將語音信號全部消除掉,並填充舒適雜訊,防止聲音聽感起伏。能達到那麼大的衰減量,一般是處於遠端單講狀態,或者遠端回聲信號要遠遠大於近端語音信號的雙講狀態。
正常的雙講狀態下,為了保護近端語音的音質,自適應濾波器是不會做大幅的回聲消除的。因此,只要衰減量達到或者超過設定閾值,把採集到的語音信號全部消除掉是不會影響正常聽音效果的。
如果衰減量沒有超過設定的閾值,那麼就不要進一步做回聲消除了。這種情形可能是雙講狀態,要保護本地語音的音質,避免本地語音被當成回聲誤殺。
業界一般有兩種做法:一種是允許對近端聲音有些許損傷也要把遠端回聲消除乾淨,另外一種是允許保留些許遠端回聲也不要對近端聲音造成損傷。如果過分消除回聲,就會造成斷續的聽音感覺。回聲消除就是要在這兩種做法之間找平衡點。
筆者在即構科技的工作中的實踐表明,在音視頻社交行業,回聲消除是客戶高度關注的一個技術特徵。與此同時,回聲消除也是音視頻社交中最有難度的技術,沒有之一。即使是王者榮耀這種頂級的遊戲,也十分重視回聲消除的效果。在以用戶體驗為生命線的遊戲行業,特別在手游做得越來越重的今天,回聲消除技術做得好不好,往往決定了用戶是否繼續玩你的遊戲。
<The End>
轉載自infoQ:
音視頻社交中回聲消除技術是如何實現的
作者
冼牛,即構科技 Zego 技術專家,北京郵電大學計算機碩士,香港大學工商管理碩士,多年從事語音視頻雲服務技術研究,專註互動直播技術和實時遊戲語音。
推薦閱讀:
※短視頻行業下半場,如何滿足用戶訴求尋找突破口?
※短視頻應用的鼻祖Vine死了,中國快手、美拍們的寒冬也快到了嗎?
※我刷了三天三夜抖音,差點「猝死」在床上…