音頻引擎,是實時通話程序(IM)裡的一個模塊。
例如webrtc、各種社交軟體,都含有這個模塊。
它大概有三個功能,錄音、放音、回音消除。
上篇文章裡Linux的alsa接口播放pcm音頻數據說過Linux ALSA框架的數據傳輸方向有播放和採集兩種,音頻引擎是把這兩個功能聯合起來,外加一個回音消除模塊。
在實時通話中,對端傳過來的聲音A,與你說話的聲音B,都會被麥克風錄音,實際錄下來的是A+B。
如果直接發送到對端,再播放出來,那麼就摻雜了對端上次說話的聲音A,即回音(echo),讓人聽起來比較彆扭。
使用特殊的算法,在錄音之後,發送之前,消除這個回音,只把你說話的聲音B發過去,就是回音消除(Audio Echo Cancellation)。
也就是說,相當於做了一個減法,從A+B裡減去A,把B發送給對端。
放音的代碼上一篇文章已經簡單說了下,錄音也差不多,就不單獨寫一篇了。
簡單說一下回音消除AEC的情況:
1,播放出來的聲音A,再錄進去時的強度是減弱了的,所以直接減是不行的。
2,播放的聲音被周圍障礙物反彈回來,再被錄進去時,與原聲是有時間偏差的。
3,麥克風直接錄進去的聲音A0,障礙物反彈回來的聲音A1,與原聲A是有差異的(強度、相位),但是只能以原聲A為參考來消除它們。
具體的消除算法,相當於一個濾波器。
詳細的數學原理和算法步驟,我也沒仔細研究過(捂臉
目前回音消除的第三方代碼,一個是webrtc自帶的AEC模塊,另一個是speex自帶的AEC模塊。
speex,就是發明opus音頻編碼協議的那個團隊,他們提供了一套聲音處理的庫。
音頻引擎的邏輯代碼就這麼幾行:
while(1)
{
play(A);
B = record();
C = aec(B, A);
//把C傳給編碼模塊
}
在使用耳機的時候,回音基本聽不出來,
甚至可以取消AEC功能。
但是在使用外放的時候,回音就比較明顯了。