編解碼器雜談:淺析 Opus

做者:趙曉涵,聲網 Agora 音頻算法工程師。原文首發於 RTC 開發者社區。

談起 Opus,對於編解碼器有所瞭解的同窗也許會知道,Opus 是由兩個編解碼器——Silk 和 Celt 融合而成。爲何來自兩個組織的編解碼器會合二爲一,Opus 的性能又如何,本文將簡述一下 Opus 的前世此生和部分技術分析。算法

提到 Opus,就不得不提到它的主要做者,Jean Marc Valin,他從學生時代就開始致力於高音質編解碼算法的實現,著名的編解碼器 Speex 也是他的做品之一。時間回到2007年,Jean Marc Valin 在博士後期間,完成了 Speex 的開發。在當時,業內編解碼器主要分爲兩個流派:高延時的音樂編解碼器(如 MP三、AAC 和 Vorbis)和低延時的語音編解碼器(AMR、Speex、G.729)。而工業界對低延時音樂編解碼器的需求愈來愈高,因而 Celt 的開發也被提上了日程。Celt 的早期目標是實現 4-8ms 的編碼延時,相比當時 MP3 和 AAC 編碼的 100ms+ 延時,優點是很是巨大的。架構

在研發過程當中,Jean Marc Valin 和其餘開發者始終圍繞着 Vorbis 做者 Christopher 「Monty」 Montgomery 的意見「儘可能保持信號能量譜的低失真」進行開發,這也是 Celt(Constrained Energy Lapped Transform)名字的由來。初版 Celt 的研發持續了兩年,但由於須要保證低延時的緣由,Celt 的表現並無超過 MP3 和 AAC。但在通過了持續六個月的改進後(使用了部分 MP3 的技術),Celt 的表現第一次超過了 MP3。也就是在那個時候,Celt 逐漸走出實驗室,迎來了它在工業界的第一批使用者–部分用戶由於低延時的強需求不得不選擇了 Celt。也就是這一批最先期的用戶給了 Celt 的開發者們寶貴的反饋,使其不斷改進 Celt。app

在開發 Celt 的同時,另外一批來自 Skype,以 Koen Vos 爲首的開發者開發了業內領先的語音編解碼器 Silk,並將其提交至 IETF,做爲一款免版稅的開源編解碼器。Celt 也緊隨 Silk 的步伐進行了提交。但 Silk 和 Celt 都遭遇了很大的阻力,這個阻力的來源更多的不是技術因素,而是『政治』因素:此前有大量投資者投資了帶版稅的編解碼器,這些投資者在業內的權威也很大。正是這些阻力促使 Silk 和 Celt 結合到一塊兒,誕生了 Opus。在 Opus 裏,Silk 主要負責處理 16khz 及 8khz 的信號,而 Celt 則能處理 8khz 以上的信號。實際上,關於 Opus 裏 Silk 和 Celt 的工做模式並不只僅這麼簡單,Opus 裏共有 32 種模式用來處理不一樣種類的信號。Opus編解碼器架構以下。模塊化

編碼器:函數

clipboard.png

解碼器:性能

clipboard.png

爲了和 Silk 結合,Celt 作出了必定的改動。以前 Celt 爲了極低延時,把幀長設置的比較短,但 Silk 須要 20ms 的幀長,因而 Celt 犧牲了部分延時和 Silk 的幀長對齊,但仍能把總體延時控制在 10ms。Opus 誕生後又通過了不少改進,關鍵的改進來自於 Broadcom 提供的一種濾波器,這個濾波器在編碼端和解碼端各有一個。在編碼端,前置濾波器能夠保留音樂信號的低頻部分,減弱高頻部分,這樣就能夠更高效的去編碼;在解碼端,後置濾波器能夠近乎無損的把被減弱的高頻恢復出來。這種前置-後置濾波器結合上述拉長到 20ms 的幀長,Opus 第一次在音樂音質和壓縮率上超過了 HE-AAC。這對於 Opus 來講是一個很是重要的節點,由於這表明着 Opus 在語音、音樂、複雜度和延時上有了全面超越其餘編解碼器的能力。測試

而融合進 Opus 的 Silk 模塊改動則不是很大,主要的改動點都是很是小的細節,我簡單整理了一些,以下所示:編碼

1、線性預測部分:兩者的計算邏輯是相同的。不一樣之處有:

  1. OPUS 的總體計算精度更高一些,由 Silk 裏的 Q10 轉換成了 Q14 後進行判斷,包括短時預測、長時預測和激勵部分。
  2. 在作 Delaydecision(一種延時選擇算法,能夠令標量量化擁有近似矢量量化的效率)的時候,OPUS 中對判斷算法進行了重寫,增長了一個 quantoffset 參數並從新規劃了量化的範圍,這裏和 Silk 比較,帶來的 MOS 分增益,我本身測的是大約在 0.05 左右(少許樣本測試,不必定準確,僅供參考)。
  3. OPUS 的 Delaydecision 模塊默認是計算 40 個採樣點的總偏差,Silk 是 32 個,選擇的採樣點越多,偏差越小,但延時會越大,這兩個我試了一下對 MOS 分的影響基本沒有,。
  4. 在編碼時,OPUS 使用 SHIFT_ROUND 將 Q10 轉化成了 Q0 傳入到編碼模塊,Silk 使用的是 SHIFT 方法,二者的不一樣之處在於,SHIFT_ROUND 會將 [-512,512] 的值都轉化爲 0,而 SHIFT 的置零區間爲 [0,1024],這裏使用不一樣的 SHIFT 算法會影響到後續編碼激勵時分配的碼率。
  5. OPUS 經過調整計算步驟,增長新參數(如 delayedgain 和 diff 等)等方法,減小了少許計算量。

2、編碼部分:

  1. OPUS 中的編碼模塊由依賴Silk中的機率密度函數 CDF 轉成了逆機率密度函數 iCDF,尚不清楚作這種改動的緣由,從結果上來看,使用 CDF 和 iCDF 的編碼效率是差很少的。
  2. OPUS 將編碼 index 和 excition 的函數區分開了,但函數的實現及各個參數的編碼順序和 Silk 是相同的,總的來講,這是一個關於模塊化的改進。

3、其他部分:

  1. 增益計算部分,OPUS 在較多函數裏使用的是 Q7,Silk 使用的是 Q0,所以 OPUS 對增益的控制能稍微準一些。
  2. OPUS 對碼率控制算法進行了重寫,但整體邏輯和 Silk 是相同的,我的認爲 OPUS 的碼率控制更爲激進一點,壓得狠,放的快。
  3. OPUS 的抖動算法中 Seed 的判斷方法也改變了,OPUS 中經過判斷 Seed 是否小於 0 進行符號的轉換,Silk 經過把 Seed 右移 31 位後作異或後自減進行判斷,其實這兩種方法的結果是徹底同樣的,只是方式一的計算量更小。

Silk 和 Celt 整合到一塊兒後,通過各方努力,Opus 在 2012 年做爲免版稅的開源編解碼器成爲了 IETF 的標準。也就是在差很少那個時候,WebRTC 也成爲了 IETF 在 Web 通訊上的標準,而 Opus 憑藉其卓越的性能成爲了 WebRTC 的內置編解碼器。一直到今天,Opus 仍在不斷髮布版本,就在前不久,Opus 發佈了 Opus 1.3.1。從發版趨勢能夠看出,Opus 也在擁抱 AI 化。spa

目前 Opus 裏和 AI 相關的技術有兩個:基於 RNN 的語音音樂分類器和一個附加的基於 RNN 的降噪模塊(這個降噪模塊目前並不在 Opus 自己的代碼裏,但不排除之後會和 Speex 同樣,把信號處理模塊耦合進編解碼器)。orm

從 Opus 的誕生和發展歷程能夠看出,任何產品作到極致都須要付出不懈的努力和漫長的打磨時間,尤爲是在創新領域,其路漫漫,道阻且長,各位同窗一塊兒加油吧。

相關文章
相關標籤/搜索