speex 回聲消除的用法


 

speex 回聲消除的用法

 

分類: speex AEC 回聲消除 1336人閱讀 評論(0) 收藏 舉報

 

speex的回聲消息

就是speex_echo_cancellation函數的正確用法

 

回聲消息的原理:

對參考聲音(解碼的對端原始語音包)做延遲(會有多個延遲,如麥克風直接采集到音箱的聲音,經牆壁反射后再次采集),衰減,

從聲卡里采集到的語音,做一個語音合成。

 

回聲產生的條件:

通話中,有一方使用音箱(或者雙方都用音箱)。

 

在實際中如何使用speex_echo_cancellation這個函數呢?錯誤的使用,將導致speex無法快速地收斂回聲濾波器的參數。

 

使用音箱的那一方,這里我們稱之為"發送方",調用speex_echo_cancellation,

這樣做就繞開了網絡延遲,引起對算法收斂的干撓。

這是第一點要注意的

(也可以在"接收方"調用speex_echo_cancellation,但網絡出現抖動時,就會使算法無法快速收斂,就無法消除回聲了)

 

這樣,我們的代碼中,大概會是這樣的邏輯:

解碼網絡語音包(記為 play)

寫入聲卡

采集麥克風的聲音(記為rec)

調用speex_echo_cancellation 參play與rec傳給這個函數

 

回想一下,應用層的程序可能會是這樣(當然您的程序也可能不是這樣,但情形類似):

一個接收線程,收包,放音

一個發送線程,錄音,發包

我們自然會在錄音線程里調用speex_echo_cancellation

但這有一個問題,錄音線程與放音線程因為系統的調度問題,也會造成抖動,導致speex的回聲消除算法無法收斂。

 

以下的一個程序模形,讀者們可以參考

1 接收線程A,解碼網絡語音包,接語音包推入一個消息隊列A

2 放音錄音線程B,從隊列A中取出語音包,放音,錄音,錄音得到的語音包,通過speex_echo_cancellation處理后,存入隊列B

3 發送線程C,從隊列B中取語音包,編碼,發送

簡單地說,就是用一個線程放音,錄音,然后echo cancel,這樣就不存在線程調度引起的延遲抖動

 

采用這種方式,就避免了因為線程調度引起的抖動,避免了不確定的延遲對speex算法收斂過程的干撓。

 

最后一個干撓因素:os提供的錄音放音接口也是異步的。。。

這個干撓因素基本在應用層是無法排除的了。。。可能就是幾毫秒的誤差,但足以干撓回聲消除算法了。

 

多路語音(會議)

選一個超級節點做合成語音,或者終端對語音進行合成,之后,處理就變成與單對單語音通話類似的情形了

直接上speex_echo_cancellation

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM