移動通訊最早進的音頻編解碼器EVS及用好要作的工做

語音通訊從最初的只有有線通訊變成後來的有線通訊與無線通訊(移動通訊)的競爭,當移動語音通訊價格下來後有線語音通訊明顯處於逆勢。現在移動語音通訊的競爭對手是OTT(On The Top)語音,OTT語音是互聯網廠商提供的服務,通常免費,如微信語音。目前語音通訊技術上就分紅了兩大陣營:傳統通訊陣營和互聯網陣營,互相競爭,推進着語音通訊技術的發展。具體到編解碼器上互聯網陣營提出了涵蓋語音和音樂的音頻編解碼器OPUS(OPUS是由非盈利的Xiph.org 基金會、Skype 和Mozilla 等共同主導開發的,全頻段(8kHZ到48kHZ),支持語音和音樂(語音用SILK, 音樂用CELT),已被IETF接納成爲網絡上的聲音編解碼標準(RFC6716)),絕大多數OTT語音的APP都支持,有一統互聯網陣營的趨勢。移動通訊標準組織3GPP爲了應對互聯網陣營的競爭,也提出了涵蓋語音和音樂的音頻編解碼器EVS(Enhanced Voice Service)。我曾經給我作的手機平臺上成功的加上了EVS,而且經過了中國移動的實網環境下的測試。下面就講講這個codec以及用好要作的工做。html

 

3GPP在2014年9月將EVS編解碼器標準化,由3GPP R12版本定義,主要適用於VoLTE, 但也同時適用於VoWiFi和固定網絡電話VoIP。EVS編解碼器由運營商、終端設備、基礎設施和芯片提供商以及語音與音頻編碼方面的專家聯合開發,其中包括愛立信、Fraunhofer集成電路研究所、華爲技術有限公司、諾基亞公司、日本電信電話公司(NTT)、日本NTT DOCOMO公司、法國電信(ORANGE)、日本松下公司、高通公司、三星電子公司、VoiceAge公司及中興通信股份有限公司等。它是3GPP迄今爲止性能和質量最好的語音頻編碼器,它是全頻段(8kHZ到48kHZ),能夠在5.9kbps至128kbps的碼率範圍內工做,不只對於語音和音樂信號都可以提供很是高的音頻質量,並且還具備很強的抗丟幀和抗延時抖動的能力,能夠爲用戶帶來全新的體驗。算法

 

下圖是3GPP EVS相關的SPEC,從TS26.441到TS26.451。微信

我已將關鍵的幾個用紅框標出,其中TS26.441是總覽,TS26.442是用C語言寫的定點實現(reference code),這也是後面用好EVS工做中的重中之重。TS26.444是測試序列,優化reference code過程當中幾乎天天都要保存一個優化的版本,天天都要用測試序列跑一跑優化的版本,如發現不同了,說明優化的有問題,要退到上一個版本,並檢查出哪一步優化出問題了。TS26.445是EVS算法的具體描述,近700頁,說實話看的頭疼,若是不是作算法的,算法部分看個大概就能夠了,可是對特性描述相關的必定要細看。網絡

 

EVS對語音信號和音樂信號採用不一樣的編碼器。語音編碼器是改進型代數碼激勵線性預測(ACELP),還採用了適合不一樣語音類別的線性預測模式。對於音樂信號編碼,則採用頻域(MDCT)編碼方式, 並特別關注低延遲/低比特率狀況下的頻域編碼效率,從而在語音處理器和音頻處理器之間實現無縫可靠的切換。下圖是EVS編解碼器的框圖:dom

編碼時先對輸入的PCM信號作預處理,同時肯定是語音信號仍是音頻信號。如是語音信號就用語音編碼器編碼獲得比特流,如是音頻信號就用感知編碼器進行編碼獲得比特流。解碼時根據比特流中的信息肯定是語音信號仍是音頻信號,如是語音信號就用語音解碼器解碼獲得PCM數據,而後作語音帶寬擴展。如是音頻信號就用感知解碼器解碼獲得PCM數據,而後作頻率帶寬擴展。最後再作後處理做爲EVS解碼器的輸出。ide

 

下面說說EVS的各個關鍵特性。函數

1,EVS支持全頻段(8kHZ--48kHZ),碼率範圍是5.9kbps至128kbps。每幀是20Ms時長。下圖是音頻帶寬的分佈:工具

窄帶(Narrow Band, NB)範圍是300HZ-3400HZ,對應的採樣率是8kHZ,AMR-NB用的就是這種採樣率。寬帶(Wide Band, WB)範圍是50HZ-7000HZ,對應的採樣率是16kHZ,AMR-WB用的就是這種採樣率。超寬帶(Super Wide Band, SWB)範圍是20HZ-14000HZ,對應的採樣率是32kHZ。全帶(Full Band, FB)範圍是20HZ-2000HZ,對應的採樣率是48kHZ。EVS支持全頻段,因此它支持四種採樣率:8kHZ、16kHZ、32kHZ和48kHZ。oop

下圖是在各類採樣率下支持的碼率:性能

從上圖看出只有在WB下支持全碼率,其餘採樣率下只支持部分碼率。須要注意的是EVS向前兼容AMR-WB,因此它也支持AMR-WB的全部碼率。

 

2,EVS支持DTX/VAD/CNG/SID,這同AMR-WB同樣。在通話過程當中一般有一半左右時間講話,其他時間處於聆聽狀態。在聆聽狀態時不必發語音包給對方,因而就有了DTX(非連續傳輸)。要用VAD(靜音檢測)算法去判斷是語音仍是靜音,是語音包時就發語音包,是靜音時就發靜音包(SID包)。對方收到SID包後就去用CNG(溫馨噪聲生成)算法去生成溫馨噪聲。EVS中有兩種CNG算法:基於線性預測的CNG(linear prediction-domain based CNG)和基於頻域的CNG(frequency-domain based CNG)。在SID包的發送機制上EVS跟AMR-WB不一樣,在AMR-WB中VAD檢測到是靜音時就發送一個SID包,而後40Ms後發送第二個SID包,隨後每隔160Ms發送一個SID包,不過VAD一檢測到是語音就馬上發送語音包。EVS中SID包的發送機制可配,能夠固定每隔一段時間(幾幀,範圍是3--100)發送一個SID包,也能夠根據SNR自適應的發送SID包,發送週期範圍是8—50幀。EVS SID包的payload大小也與AMR-WB不一樣,AMR-WB的是40個字節(50*40=2000bps),EVS是48個字節(50*48=2400bps)。從上能夠看出DTX有兩個好處,一是能夠節省帶寬,增長容量,二是由於不編解碼減小了運算量,從而下降功耗增長續航時長。

 

3,EVS也支持PLC(丟包補償),這也同AMR-WB同樣。不過EVS把Jitter Buffer Module(JBM)也包含了進來,這在之前的codec中是歷來沒有過的。我在使用中沒有用到JBM,因爲時間比較緊,也就沒有時間去研究。後面有時間了定要好好研究一下,JB但是語音通訊的難點之一同時也是語音質量的瓶頸之一呀。

 

EVS的算法時延根據採樣率不一樣而不一樣。當採樣率爲WB/SWB/FB時總時延爲32ms,包括一幀20ms的時延,編碼側輸入重採樣的0.9375ms時延以及8.75ms的前向時延,解碼側時域帶寬擴展的2.3125ms時延。當採樣率爲NB時總時延減少爲30.9375ms,相對WB/SWB/FB減少了1.0625ms, 這1.0625ms主要是在解碼側減小的。

 

EVS的語音質量(MOS值)相對於AMR-NB/AMR-WB有了明顯的提高。下圖是這幾種codec的MOS值比較:

從上圖看出,當採樣率爲NB時在各類碼率下EVS-NB的MOS值比AMR-NB的MOS值顯著提高;當採樣率爲WB時在各類碼率下EVS-WB的MOS值一樣比AMR-WB的MOS值顯著提高;當採樣率爲SWB而且碼率大於15kbps時EVS-SWB的MOS值接近了不編碼的PCM的MOS值。可見EVS的語音質量是至關不錯的。

 

用好EVS要作的工做在不一樣的平臺上會有所不一樣,我是用在手機平臺audio DSP上,用於語音通訊。下面就說說爲了手機支持EVS我作了哪些工做。

1,學習EVS相關的SPEC。要把前面我列的SPEC都看一遍,由於不是作算法,算法相關的能夠看的粗,可是對特性描述相關的必定要看的細,這關係到後面的使用。

 

2,在PC上生成encoder/decoder的應用程序。我是在Ubuntu上作的,把PCM文件做爲encoder的輸入,根據不一樣的配置生成相應的碼流文件,再把碼流文件做爲decoder的輸入,解碼還原成PCM文件。若是解碼後的PCM文件聽下來跟原始PCM文件無異樣,說明算法實現是可信的(權威組織出來的算法實現都是可信的,若是有異樣說明應用程序沒作好)。作應用程序是爲了後面的優化,也方便理解外圍實現,如怎麼把編碼後的值變成碼流。編碼後的值放在indices(最多有1953個indices)中, 每一個indices有兩個成員變量,一個是nb_bits,表示這個indices有多少位,另外一個是value,表示這個indices的值。Indices有兩種存儲方式:G192(ITU-T G.192)和MIME(Multipurpose Internet Mail Extensions)。先看G192,每一幀的G192的存儲格式見下圖:

第一個Word是同步值,分good frame(值爲0x6B21)和bad frame(值爲0x6B20)兩種,第二個Word是長度,後面是每一個值(1用0x0081表示, 0用0x007F表示)。Indices裏的value用二進制表示,位上的值爲1就存爲0x0081,爲0 就存爲0x007F。下圖是一個例子,採樣率爲16000HZ, 碼率爲8000bps,所以一幀有160位(160 = 8000/50),保存成G192格式就是160個Word。下圖中頭是0x6B21, 表示good frame,length是0x00A0, 後面160個Word是內容。

再來看MIME格式。要把indices的value值pack成serial值,具體怎麼pack,見pack_bit()函數。MIME的格式是第一個Word是header(低4位表示碼率index, 在用WB_IO時第5和6位要置1,EVS 時不須要),後面是比特流。仍是上面採樣率爲16000HZ碼率爲8000bps的例子,但存成MIME格式,一幀有160位,須要20byte(20 = 160/8),以下圖:

上圖中頭16個字節是reference code自帶的,第17個字節是header,0x2表示以EVS 編碼,碼率是8kbps(8kbps index爲2),後面的20個字節表示pack後的payload。

在語音通訊中,要把indices的value值pack成serial值,而後做爲payload發送給對方。對方收到後先unpack再解碼獲得PCM值。

 

3,原始reference code一般是不能直接使用的,須要優化。至於怎麼優化,請看我前面寫過的一篇文章(音頻的編解碼及其優化方法和經驗),文章寫的是比較通用的方法。我如今要在DSP上用,DSP的頻率較低,只有三百多MHZ,不用匯編優化時搞不定的。我以前沒用過DSP彙編,要在短期內優化的很好有很大難度。老闆權衡後決定用DSP IP廠商提供的優化好的庫,彙編方面它們更專業一點。

 

4,對reference code的應用程序改造,方便後面調試驗證時當工具使用。原始reference code保存成文件時是以字節爲單位的,而DSP是以Word(兩個字節)爲單位,因此要對reference code裏的pack/unpack函數改造,以適應DSP。

 

5,要想打電話時codec是EVS,Audio DSP 和CP上都要加相應的代碼,先寫各自的代碼自調,而後聯調。我自調時用AMR-WB的殼(由於EVS和AMR-WB的一幀都是20ms時長),即流程上用AMR-WB的,但codec從AMR-WB換成EVS。主要驗證encoder、pack、unpack、decoder是否ok,其中encoder和pack是上行的,unpack和decoder是下行的。它們的前後關係以下圖:

先調上行,把encode後的保存成G192格式,用decoder工具解碼成PCM數據用CoolEdit聽,跟本身說的話是同樣的,說明encoder是OK的。再調pack,把pack後的碼流保存成MIME格式,一樣用decoder工具解碼成PCM數據用CoolEdit聽,跟本身說的話是同樣的,說明pack是OK的。再調下行。因爲CP尚未正確的EVS碼流發給Audio DSP,就用loopback的方式來調試,具體是把pack後的碼流做爲unpack的輸入,unpack後獲得的保存成G192格式,用decoder工具解碼成PCM數據用CoolEdit聽,跟本身說的話是同樣的,說明unapck是OK的。最後調decoder,把decoder後的PCM數據用CoolEdit聽,跟本身說的話是同樣的,說明decoder是OK的。這樣自調就結束了。

 

6,與CP聯調。因爲前面自調時各關鍵模塊都是調好的,聯調起來相對比較順利,沒幾天就調好了。這樣打電話時就能享受EVS帶來的高音質了。

相關文章
相關標籤/搜索