在去年疫情期間,在線教育行業得到了井噴式的發展,這背後的技術功臣非 RTC 莫屬。本文將分享 RTC 技術在音樂教育場景下的實踐經驗。android
做者| 逸城
審校| 泰一ios
2020 年的新冠疫情改變了在線教育中素質教育行業的生態,音樂陪練是其中的典型場景。衆多線下琴行因沒法承擔高昂的租金關門,在線音樂教育平臺用戶激增,這其中的表明有 The One、VIP 陪練、快陪練、美悅陪練、音樂筆記等。根據公開信息,目前 VIP 陪練的日上課量達到 3 萬節,快陪練在 2020 年 10 月用戶突破 120 萬。有投資機構指出,到 2022 年,音樂教育市場預計達 4000 多億元規模,而在線陪練市場的需求近千億元。
可是打造一款傳遞高音質的陪練 App 並不是易事,在實際開發過程當中音樂陪練類 App 相比普通在線教育 App 的音質的要求更高,下面我將以鋼琴教育爲例,從技術角度來分析 WebRTC 在樂器教育場景下遇到的問題以及解決方案。算法
以鋼琴類爲例,頻譜主要集中在 5KHz 如下,下圖是一段 44.1khz 採樣率的鋼琴曲的音樂通過 FFmpeg 解碼後的頻譜圖,從下圖能夠看到,考慮到實際錄音場景可能存在高頻諧波或者其餘環境音的影響,頻率範圍集中在 7kHz 如下頻段:框架
WebRTC 在音頻採集後的前處理流程是:record->ans->aec->agc。咱們先分析第一個環節,錄音的影響。下面測試基於 Andorid 手機播放鋼琴曲,手機距離 Mac 電腦 15cm 左右,在單講模式下,原始鋼琴曲頻譜以下:
通過錄音後的頻譜以下:
圖中 400Hz 如下的頻譜基本損失殆盡,考慮到聲音從手機播放,通過手機揚聲器,空氣傳輸,再通過對端 mic 接收,與真實鋼琴教育場景不太同樣,因此咱們錄製了一段真實鋼琴教育的語料以下:ide
能夠看出真實的鋼琴教育錄音下頻譜保真度仍是與手機播放再錄製有差別的,所以錄音的因素在真實鋼琴場景能夠暫不考慮。測試
單講狀況下(aec 未生效):錄音音頻:
通過 ans 後頻譜:
結論:通過 ans 後頻率有較大損失,中高頻部分損失較爲嚴重。優化
雙講狀況下(通過 ans 和 aec):
ans 後頻譜(遠端有人說話):
aec 後頻譜:
雙講狀況對音樂損失也很大,重點是 aec 模塊損失大。阿里雲
Opus 是由 SILK+CELT 混合的編碼器,學術上的叫法叫作 USAC,Unify Speech and Audio Coding, 不區分音樂語音的編解碼器。這個編解碼器內有個 Music detector 去判斷當前幀是語音仍是音樂,語音選擇 silk 框架編碼,音樂選擇 celt 框架編碼,一般建議不限制編碼器固定採用哪一種模式編碼。編碼
目前 WebRTC 採用 Application 是 kvoip,默認開啓混合編碼模式,並未限制固定是 celt only 或者 silk only 模式。
編碼器內混合編碼模式下的音樂與語音編碼算法判決:
測試語料:
選擇音樂模式編碼 + 混合編碼後:
選擇語音編碼 + 混合編碼模式後:
測試反饋顯示音樂編碼的狀況下切換 silk 模式很靈敏,可是若是採用 VoIP 模式下對音樂切換不夠靈敏,會出現語音後對音樂下延遲爲 silk 編碼的狀況;所以,語音編碼後的幾秒種內 silk 編碼對高頻部分略有損失,相比 celt 編碼略差。視頻
綜上所述,影響鋼琴教育音質的因素主要是降噪模塊和回聲消除模塊。
完整的解決方案須要考慮鋼琴教育場景下語音和音樂共存的狀況,須要對當前的語音幀作模式判別,識別是語音仍是音樂,若是是語音幀則走正常的 3A 處理流程,若是是音樂幀則須要調整 3A 的算法,最大限度保證音樂的完整性。
大體流程圖以下:
分析了影響鋼琴教育場景下的因素及技術方案,下面主要從實現的角度分析遇到的相關技術問題。根據上面的分析結論,一般在 VoIP 場景下,ios 和 android 採用了硬件 3A 的方案,可是在樂器教育場景下,則必須採用軟件 3A 的方案,不然 3A 算法沒法根據音樂和人聲動態調整。
WebRTC 在 iOS 平臺用的是 AudioUnit 採集,相關代碼以下:
根據蘋果的 API 說明,iOS 提供了三個 I/O units,其中 Remote I/O unit 是最經常使用的。鏈接輸入輸出音頻硬件,對傳入和傳出的樣本值低延遲訪問,提供硬件音頻格式和應用音頻格式之間的格式轉化。Voice-Processing I/O unit 是對 Remote I/O unit 的拓展,添加了語音聊天中的回聲消除,還提供了自動增益矯正,語音質量調整,靜音等特性。Generic Output unit 不鏈接音頻硬件,而是提供了一種將處理鏈的輸出發送到應用程序的機制。一般會使用作離線音頻處理。
所以,在樂器教育場景下,須要初始化 AudioUnit 的類型設置爲 Remote I/O 模式,這樣錄音數據不會通過硬件 3A 處理。可是在啓用 Remote I/O 模式下後,錄音數據以下:
發現啓用 Remote I/O 後,系統硬件也不作音量增益,所以致使錄進去的音量很低(-14db 左右), 所以,對應的軟件 agc 算法增益也須要針對性調整。
一般,在 Android 平臺,VoIP 模式下,經過適配,大部分機型可使用硬件 3A,這樣既能夠保證效果,又能夠帶來更低的功耗和延時。而 Andoird 平臺又爲 Java 的採集播放和 Opensles 的採集播放兩種方式能夠選擇,一般經驗下 opensles 的延遲更小,而且適配性更好。咱們接下來也以 opensles 爲例來介紹 VoIP 場景和樂器教育場景下的設置不一樣之處。opensles 提供了 audiosource 和 audiotype 的幾種模式供選擇:
以 VoIP 場景爲例,opensles 的一般選擇是 audiosource:VOICE_COMMUNICATION, stream_type:STREAM_VOICE;可是若是是樂器教育場景,則須要採用 audiosource: MIC, stream_type:STREAM_MEDIA 的組合方式,不然容易出現觸發啓動硬件 3A 的狀況。
下圖就是小米手機裏設置 audiosouce: MIC, stream_type: STREAM_VOICE 下對音樂的採集效果,圖中能夠看到因爲 stream_type 設置的模式不對,在播放的時候就會影響系統採集觸發硬件 3A, 對音樂信號形成嚴重的損傷。
上篇文章提到,opus 提供了語音和音樂檢測模塊,根據測試,在編碼器設置默認爲音樂時對語音和音樂的檢測很靈敏,可是若是設置爲語音編碼模式時當由語音切換爲音樂時存在數秒左右的算法檢測滯後,仔細分析 opus 代碼以下:
編碼器在作模式判決時會根據設置的默認編碼模式來設置門限值,語音編碼下的門限值會調高,這種作法是當由語音切換爲音樂時編碼器不立刻切換音樂模式,以便於最大限度保留語音信息,由於語音信息的幀間相關性會比較強。
所以在鋼琴教育場景建議默認採用音樂編碼方式,以便於最大程度保留音樂信息,減小 3A 處理對音質形成的損傷。
基於 WebRTC 的音樂教育場景的工程化實踐有很多細節須要考慮,從音頻信號的採集,到 3A 的適配,再到音頻編碼器的參數調整,都須要作針對性調優,才能最大限度的作到既能保證語音信號的清晰可辨,又能保證音樂信號的細節豐富而不失真。另外,隨着在線教育細分市場的不斷成熟,針對部分特殊樂器好比打擊類樂器的場景,又會帶來新的技術難點,須要 RTC 進一步探索優化。
「視頻雲技術」你最值得關注的音視頻技術公衆號,每週推送來自阿里雲一線的實踐技術文章,在這裏與音視頻領域一流工程師交流切磋。