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

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

轉載weixin_30748995 最後發佈於2018-05-28 08:07:00 閱讀數 55  收藏

展開

語音通信從最初的只有有線通信變成後來的有線通信與無線通信(移動通信)的競爭,當移動語音通信價格下來後有線語音通信明顯處於逆勢。如今移動語音通信的競爭對手是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以及用好要做的工作。

 

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編解碼器的框圖:

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

 

下面說說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。

下圖是在各種採樣率下支持的碼率:

從上圖看出只有在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帶來的高音質了。

轉載於:https://www.cnblogs.com/talkaudiodev/p/9074554.html

發佈了29 篇原創文章 · 獲贊 52 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章