在實做VoIP的同時,迴聲一般發生在手機聽筒播出的聲音同時又被手機麥克風收錄進去,這樣會造成發話方會聽見自己說出的話,這種是最常見的迴聲;(還有另一種迴聲是透過環境的反射而重複收錄進去的迴聲。) 雖說雖然看了一些文章... 但要實作出一個可靠的消迴聲機制... 似乎又是另外一回事了。
好在之前在研究OPUS(Free Audio Codec)的語音編碼相關使用方式的時候,就有看到底下這句:
Does Opus have an echo canceller like Speex does?
Echo cancellation is completely independent from codecs. You can use any echo canceller (including the one from libspeexdsp) along with Opus. That being said, among the free acoustic echo cancelers (AEC) we're aware of, the best is probably the Google AEC from the WebRTC codebase.
Google提供的 WebRTC 裡面的 AEC 確實時值得一試,感覺越來越依靠google了 Orz
附帶一提 WebRTC 裡的 AEC 還提供了特別給 Mobile 使用的版本: AECM (AEC for Mobile)
要使用 AECM來幫忙消除回聲 主要透過 echo_control_mobile.c 裡的兩個函式: WebRtcAecm_BufferFarend 及 WebRtcAecm_Process
- WebRtcAecm_BufferFarend(void *aecmInst, const int16_t *farend, int16_t nrOfSamples)
- 這裡的 farend 需要傳入的是遠端傳來的語音資料,也就是將要從聽筒被播放出來的聲音。
- WebRtcAecm_Process(void *aecmInst, const int16_t *nearendNoisy, const int16_t *nearendClean, int16_t *out, int16_t nrOfSamples, int16_t msInSndCardBuf)
- 這裡的 nearendNoisy 要放入的便是從麥克風所收錄到的聲音
- nearendClean 則是可以放入經過 Noise Reduction (除躁過後的資料)
- msInSndCarBuf 這個值則是需要特別計算才能夠取得良好的回音消除效果,回音的消除是需要將聽筒播出的聲音及麥克風錄到的聲音做一個相對精準的計算來給定這個值,才能讓AECM達到良好的效果。
來看看實驗結果:
底下這個波形所錄到的聲音是將VoIP時的,受話端聽筒音量調到最大,讓聲音盡可能地被受話端又重複收錄所造成的迴聲:
下面這個波形是重複上面的動作,但同時我們將AECM的功能打開來看看迴聲消除的效果:
實際上的效果確實還不錯!
不過實際在使用的情況,不同的人聲、各式各樣的背景聲,有時候得到的迴聲消除效果似乎也還沒到特別滿意的地步,尤其當播出的音量特大時,依然能聽到清楚的迴聲...。看來這就是人蔘阿 還有很多事要改 Orz...
沒有留言:
張貼留言