音频降噪在58直播中的研究与实现
背景
在直播時主播經常會受到一些外部環境音、噪音等影響,直播時音頻采集會一并采集所有音頻推流到觀眾設備上,從而影響觀眾收聽體驗。因此需要在直播主播端主動進行降噪處理,提高觀眾收聽體驗。
58直播為了實現這個功能,通過綜合對比調研常見的開源降噪方案Speex、WebRTC、RNNoise,以及結合降噪之后的處理效果和58直播使用體驗,最終選擇WebRTC降噪方案。我們對其進行了優化兼容,將其移植應用到58視頻直播中,提升直播效果和體驗。
降噪方案
常見的開源降噪方案
- Speex
Speex是一套主要針對語音的開源免費,無專利保護的應用集合,它不僅包括編解碼器,還包括VAD(語音檢測)、DTX(不連續傳輸)、AEC(回聲消除)、NS(去噪)等實用模塊。
- WebRTC
WebRTC提供了視頻會議的核心技術,包括音視頻的采集、編解碼、網絡傳輸、顯示等功能,并且還支持跨平臺:Windows、Linux、Mac、Android。我們這里使用的就是WebRTC的音頻處理模塊audio_processing。
- RNNoise
RNNoise降噪算法是根據純語音以及噪聲通過GRU訓練來做。包含特征點提取、預料等核心部分。
RNNoise降噪算法與傳統算法對比分析
傳統降噪算法大部分是估計噪聲+維納濾波,噪聲估計的準確性是整個算法效果的核心。根據噪聲的不同大部分處理是針對平穩噪聲以及瞬時噪聲來做。
RNNoise的優點主要是一個算法通過訓練可以解決所有噪聲場景以及可以優化傳統噪聲估計的時延和收斂問題。
RNNoise的缺點是深度學習算法落地問題。因為相對大部分傳統算法,RNNoise訓練要得到一個很好的效果,由于特征點個數、隱藏單元的個數以及神經網絡層數的增加,導致模型增大,運行效率。
現在就WebRTC和RNNoise的降噪集成效果進行對比驗證分析。
降噪音頻數據對比
音頻原始PCM數據可通過Audacity軟件進行分析
下圖是58公司司慶直播時的截取一段音頻數據,音頻為雙聲道、44100采樣率。分別用RNNoise和WebRTC進行降噪處理得出效果對比圖如下:
下圖是網絡下載的一段帶有噪音的音頻數據,音頻為單聲道、32000采樣率。分別用RNNoise和WebRTC進行降噪處理得出效果對比圖如下:
綜合上面兩張效果圖可以結論出:
RNNoise處理之后的數據更干凈些,幾乎沒有電流音和雜音,但是受限于訓練集、特征點問題,在處理一些數據時候會把正常的原聲數據一并錯誤處理掉。
WebRTC處理之后的數據也相對干凈,能更好的保持原有聲音的數據,數據丟失較少。
降噪方案在直播實現
降噪方案調研過程
RNNoise過程
RNNoise的代碼是基于C開源的,集成到Android中需要使用NDK。
開源項目提供的一個測試方法,但是該方法是針對文件處理的,可以把一個帶噪音的PCM文件處理成無噪音文件。直播SDK中的音頻數據是分段的byte數組數據,所以中間需要添加一些接口來讓RNNoise來支持分段數據的降噪處理。
根據RNNoise的降噪過程和業務接口流程,把接口定義成init、process、free三個接口。
在process數據時發現RNNosie的處理窗口大小是480,所以傳入的數據也必須是480的正整數倍。如果不是的話處理之后會有明顯的新引入噪音。
*通過測試發現這個窗口大小是可以進行微調的,為了方便音頻數據的處理嘗試大小修改長512,雖然通過Audacity分析頻譜發現會有一些噪音波出現,但是在實際感觀中效果還是可以接受的。這個方案可以臨時解決非480正整數倍數的問題。
//強制修改FRAME_SIZE大小#define FRAME_SIZE (128\u0026lt;\u0026lt;FRAME_SIZE_SHIFT)- 開源代碼中的rnn_data.c和rnn_data.h是通過機器學習訓練出來的,不是通用的。在處理一個噪音數據時發現有些數據中的原聲也會一并處理掉,這個效果如果不通過新的數據集訓練那么降噪之后的數據是不可用的。
- 機器學習和訓練是RNNoise的靈魂,需要業務接入方根據自身的使用場景通過大量的數據集來找出最合適的處理集。
WebRTC過程
WebRTC的代碼是基于C++開源的,集成到Android中需要使用NDK。
WebRTC官方沒有提供降噪增益的測試代碼,需要查找相關資料找到其中的降噪、增益模塊,通過資料去熟悉其中的處理邏輯。
WebRTC只能處理特定的采樣率數據,這個是其代碼內部是寫死的,需要自己實現音頻重采樣來滿足WebRTC的降噪采樣率需求。音頻的重采樣算法有很多,在項目集成中都嘗試使用過,效果都是差不多的。
根據WebRTC的降噪過程和業務接口流程,把接口定義成init、process、free三個接口。區別RNNoise的是需要在process中做增益處理,WebRTC降噪會降低數據的聲音大小,通過增益用來補充聲音大小。
在process數據時發現WebRTC的處理窗口大小必須是160或是320個byte,根據采樣率不同窗口大小不同。測試發現這個和處理RNNoise是一致都只能傳正整數倍數據,要不還是會新引入噪音數據。
WebRTC在process時有兩種處理數據的方法:一種是需要把原始數據分成高頻數據和低頻數據給底層邏輯;一種是不用區分高低頻數據直接把數據給底層邏輯。資料上的解釋是32k以上需要分高低頻處理。但是在實際測試中發現分高低頻的處理效果不如不分高低頻的效果好。
WebRTC的降噪NS模塊和增益AGC模塊是獨立的,為了一次數據完成兩個過程需要組合數據,邊降噪邊增益,減少處理耗時。
WebRTC_NS在處理數據時不應該選擇高低頻分開采樣處理,應直接把數據給你WebRTC_NS處理就可以。經過測試發現通過高低頻處理之后的音頻降噪效果不如不區分高低頻的,高低頻處理之后會有明顯的人聲破音出現,且處理的降噪效果不純凈。這個地方走了一些彎路,在發現降噪效果不理想時沒有懷疑是api使用的問題,這個高低頻操作是很多資料都推薦的使用方法,但是在運用到實際場景時發現效果不如不使用的。
兩種降噪方案集成優缺點對比
目前WebRTC最新代碼只支持采樣率為8000、16000、32000、44100、48000的音頻進行降噪,針對其余的采樣率需要進行數據重采樣到上述采樣率之后進行降噪,處理完畢之后需要再次恢復原采樣率;RNNoise對采樣率沒有要求,可以適配常見的采樣率。
WebRTC在降噪之后還需要對數據進行增益處理,但是增益會增大電流音,效果會稍差些。
WebRTC處理數據的buffer目前代碼是320的整數倍;RNNoise處理數據的buffer目前代碼是480的整數倍。輸入的buffer需是固定大小的,如果不是正整數倍,需要外部在傳入時處理下。
從代碼復雜度看,WebRTC的代碼是多于RNNoise代碼的。RNNoise支持機器學習,通過機器學習生成rnn_data.h和rnn_data.c文件來匹配不同的降噪效果。
降噪耗時對比,RNNoise處理3840字節的buffer數據耗時大概在6ms左右,但在開始時耗時在30ms左右,遞減到6ms并穩定;WebRTC處理3840字節的buffer數據耗時大概在2ms左右,但在開始時耗時在10ms左右,遞減到2ms并穩定。對比發現WebRTC處理效率更好些。
從處理流程上看都是需要init、process、free操作的,對接入方接入成本是一致的。
安卓端58直播SDK接入降噪方案
通過上章節的優缺點對比以及58直播中已經在使用了WebRTC相關代碼邏輯,綜合調研和處理結果驗證工作之后,最終選擇了WebRTC降噪方案。
APM模塊集成WebRTC降噪功能
在58多媒體整體架構上選擇把降噪模塊單獨解耦提取一個APM module,方便58視頻編輯、58直播等需要降噪業務統一調用。對外暴露工具類AudioNoiseHelp方便業務接入。APM module的規劃以后會接入更多的音頻處理模塊,現在已經接入降噪、增益模塊。
由于58直播SDK支持音頻采樣率種類大于WebRTC支持的種類,因此需要對數據進行最優音頻重采樣處理。
- 由于WebRTC只能處理320byte長度正整數倍的數據,但是58直播的音頻采集數據在不同手機、不同采樣率上得到的音頻數據長度是不固定的,需要對數據進行切分處理。錄音采集數據如果是byte格式的,假如長度是4096,那么直接把4096數據傳入到WebRTC_NS里處理會出現雜音出現,所以在交給WebRTC_NS模塊之前需要用個緩沖區來處理下,一次最多可以傳入(4096/320)*320=3840長度數據,并且在數據處理完畢之后還需要用另外一個緩沖區來保證處理之后的長度仍然是4096個。
58直播接入降噪之后的效果對比
- 時域對比
下圖中藍色部分是58直播時截取的一段未開啟降噪邏輯的音頻波形dB圖,綠色部分是58直播時截取的一段開啟降噪邏輯的音頻波形dB圖。從時域波形圖對比上可以看到開啟降噪邏輯之后波形更加清晰了,降噪效果比較明顯。
- 頻譜圖對比
下圖中上半部分是58直播時截取的一段未開啟降噪邏輯音頻的頻譜圖,下半部分是58直播時截取的一段開啟降噪邏輯音頻的頻譜圖。從頻譜圖對比上可以看到開啟降噪邏輯之后噪音的頻譜被去除掉,音頻數據的原始數據更加清晰突出。
- 主觀感覺對比
在同樣的噪音環境下通過開啟和關閉降噪功能,在觀眾端體驗收聽效果。未開啟降噪功能時觀眾端可以明顯的聽到沙沙的雜音,開啟降噪功能之后沙沙聲音明顯減少或沒有,對應的主播的聲音凸顯出來。
總結
本文分享了58直播在降噪方面所做的一些調研實踐經驗,重點闡述了其中的一些痛點和難點問題以及我們的解決方案。由于RNNoise降噪方案的優勢是存在的,在后續研究中會對RNNoise的深度學習繼續進行深入了解,期望能更好的解決噪音問題,更好的提升直播體驗。也希望能有更多朋友一起來探討更優的解決方案。
本文作者:金開龍,來自58集團TEG多媒體部,安卓高級工程師,專注音視頻開發。
總結
以上是生活随笔為你收集整理的音频降噪在58直播中的研究与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我对RPC的理解
- 下一篇: MYSQL水平拆分与垂直拆分