語音通信從最初的只有有線通信變成后來的有線通信與無線通信(移動通信)的競爭,當移動語音通信價格下來后有線語音通信明顯處于逆勢。如今移動語音通信的競爭對手是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值??梢奅VS的語音質量是相當不錯的。
用好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帶來的高音質了。
評論
查看更多