1. 程式人生 > >深入剖析 iLBC 編碼器原理

深入剖析 iLBC 編碼器原理

      早在2005年就聽說iLBC編解碼演算法,主要是應用在VOIP 的speech codec,但是一直沒有深入研究演算法原理,碰巧近期有一些時間可以學習一下它相比基於CELP模型的speech codec的優勢。這套程式碼是浮點的,聽朋友說要是轉成定點程式碼會比較有用,只是可能需要的時間會多一點。如果想了解iLBC的一般介紹,如編碼速率、應用等,可以參考前面的文章《iLBC編解碼相關知識》,下面主要是我的一些學習筆記,僅供大家參考。

 一、演算法整體流程

      輸入的語音逐幀進行預處理,然後計算LPC係數和殘差訊號,在殘差訊號中選擇初始狀態,並對其進行標量量化,再對剩下的殘差訊號進行增益/形狀向量量化,最後封包成位元流。

      iLBC的每frame/block保持獨立編碼,這樣才能保證在丟包的情況下,保持良好的重建語音質量;而CELP模型的codec往往都需要look head buffer 才能對當前幀進行編碼,這樣雖然可以使重建語音連線比較平滑,但是在網路傳輸中一旦發生丟包,則連續性遭到破壞,解碼語音的質量就會下降。

      在iLBC的編碼流程中有三個模組Select Start state、Scalar quantization和CB Search是與CELP模型不同的,下面重點研究這三個模組。

1、起始狀態(Start State)

     這個概念是iLBC所特有的處理方式,下面以30ms frame mode為例,那麼每個frame有6個sub-frame。iLBC在計算完LPC殘差訊號後,會找出整個幀內具有最高功率的兩個連續子幀,來決定起始狀態的位置。下圖給出了start state 在兩個子幀的位置。

 

2、對起始狀態樣點的量化

      這裡並不對兩個子幀的全部sample進行精細量化,只是對從起始狀態位置以後的57/58 sample(20ms/30ms frame mode)進行精細量化,所以這57/58 sample的量化需要三個部分:

1)子幀位置;

     是指哪兩個子幀,如 sub-frame 0,1; 1,2; 2,3; 3,4; 4,5

     3bit 量化這五種情況。

2)兩個子幀內的前半部分還是後半部分;

     1bit 表示 state_first;

3)57/58 sample的標量量化。

     這裡首先要進行全通濾波,使得樣點大小比較平均分佈,然後進行能量的歸一化,這個scaler factor用6bit標量量化,歸一化後的樣點動態範圍就比較小了,然後對每一個樣點都採用3bit 的DPCM量化。

3、碼書搜尋

     這部分是指起始狀態量化後,整個frame剩餘的樣點量化方法。這裡主要採用了動態碼書的量化方法,碼書是由整個frame的樣點通過線性組合(加權濾波)和已經量化樣點的解碼訊號組成,具體的流程見圖3。

 

     上圖首先解碼已經量化的Start state,然後構建codebook memory,結合目標向量進行感知加權濾波,在Codebook內部搜尋與目標向量最接近的向量,這裡採用三階段的增益/形狀向量量化的方法進行搜尋量化,最後調整增益以補償能量損失。這裡主要的重點還是碼書的組成、大小以及量化順序、搜尋過程。

     例如,圖4給出了一個30ms 幀的量化順序,這裡有6個子幀,假設Start state是在1、2子幀之間,並且位置在兩個子幀後半部分,那麼進行量化的順序如下:

1)Q0:量化Start State;

2)Q1:兩個子幀內除了start state的22/23個樣點;

3)Q2,Q3,Q4:Start state的後面每個子幀;

4)Q5:Start state的前面每個子幀;

     到這裡可以知道,目標向量包括兩種長度不同的向量(除了start state):22/23個樣點的向量和40個樣點的子幀向量,下表給出了對於不同向量的碼書大小。 

 

    下圖具體給出了量化目標向量時動態碼書的構造,需要注意的有以下幾點:

1)不同的目標向量(22/23、子幀40)對應的碼書大小不同,具體資料見參考資料;

2)量化Start State前向的向量需要對碼書進行反轉,再進行搜尋,如對Q1、Q5進行量化;

3)動態碼書的構成是解碼的已量化樣點而不是原來的經過感知加權的殘差訊號;

4)碼書通過補零長度對齊;

 

     增益/形狀向量量化屬於乘積碼向量量化中的一種方法,它的基本思想就是將待量化的向量的形狀和增益分別量化,同時保持它們之間的有機聯絡,最後將碼字相乘就可以得到重構向量。這種量化方法可以實現高維數的向量量化,以提高系統的效能。

     下表給出了iLBC編碼器的位元流定義,值得注意的是在封包前每個引數的bit是分成三個級別的,1表示最重要,2比較重要,3一般重要,因此封包是按照級別處理的,如圖先處理級別1,然後級別2,最後級別3,這樣提高了抗干擾性: 

二、總結

      與傳統的CELP模型的speech codec有較大不同,精髓在於幀內的獨立編碼,同時也利用了長時預測編碼(LPC)去除冗餘資訊和語音訊號本身準週期性的特徵構造動態碼書。與CELP模型codec相比,在丟包率較高的網路情況下,語音質量不會下降很快。對於解碼端的丟包補償演算法(packet loss concealment)現在還沒有看到,這個技術應該也是iLBC的一個特點。

本文並沒有列出詳細的資料和語音質量評測,那些都可以在下面得參考資料找到。

參考資料:

 《rfc3951.txt》

一家之言,歡迎討論交流!