语音通信从最初的只有有线通信变成后来的有线通信与无线通信(移动通信)的竞争,当移动语音通信价格下来后有线语音通信明显处于逆势。如今移动语音通信的竞争对手是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带来的高音质了。

移动通信最先进的音频编解码器EVS及用好要做的工作的更多相关文章

  1. AliIAC 智能音频编解码器:在有限带宽条件下带来更高质量的音频通话体验

    随着信息技术的发展,人们对实时通信的需求不断增加,并逐渐成为工作生活中不可或缺的一部分.每年海量的音视频通话分钟数对互联网基础设施提出了巨大的挑战.尽管目前全球的互联网用户绝大多数均处于良好的网络状况 ...

  2. WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置

    1.VoiceEngine Codec数据结构 WebRTC中,用一个结构体struct CodecInst表示特定的音频编解码器对象: struct CodecInst { int pltype;  ...

  3. 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化

    本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...

  4. WebRTC的音频编码(转)

    一.一个典型的IP通信模型 二.Server2Server技术分类 Server2Server这块也是一个专门的领域,这里只简单分个类. 1.同一国家相同运营商之间: 同一运营商之间也有丢包,在铁通, ...

  5. Android Multimedia框架总结(十七)音频开发基础知识

    请尊重分享成果,转载请注明出处,本文来自逆流的鱼yuiop,原文链接:http://blog.csdn.net/hejjunlin/article/details/53078828 近年来,唱吧,全民 ...

  6. 游戏开发者注意!这个音频SDK可以完美兼容所有主流游戏引擎

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云 发表于云+社区专栏 在网络游戏中,无论是大逃杀.棋牌类.电子竞技类还是娱乐休闲类小游戏,玩家和玩家之间的互动.语音聊天是一 ...

  7. H5音频和视频

    使用媒体标签最大的缺点在于缺少编解码器的支持一.浏览器支持性检测检测浏览器是否支持audio元素或video元素最简单的方式就是用脚本动态创建它,然后检测特定函数是否存在 var hasVideo=! ...

  8. Adobe Audition音频制作

    Adobe Audition 同义词 AU(软件(Adobe Audition))一般指Adobe Audition Adobe Audition是一个专业音频编辑和混合环境,原名为Cool Edit ...

  9. 音频DAC剖析---解开HI-FI音质的秘密

    选自:http://mp3.zol.com.cn/54/547689.html 无论我们是买MP3.MP4也好,实际上我们的数码播放器最经常使用的就是音乐播放功能,所以数码播放器的音质,一直是消费者的 ...

随机推荐

  1. 2017 Gartner数据科学魔力象限出炉,16位上榜公司花落谁家?

    https://www.leiphone.com/news/201703/iZGuGfnER4Sv2zRe.html 2017年Gartner数据科学平台(在2016年被称作“高级分析平台”)的魔力象 ...

  2. AttributeError: module 'enum' has no attribute 'IntFlag'

    Mac PyCharm新建以Python3.6.1为解释器的Django项目的时候出现以下错误提示: AttributeError: module 'enum' has no attribute 'I ...

  3. Android Studio使用手记

    1.官方的Tip and Tricks:http://developer.android.com/intl/zh-cn/sdk/installing/studio-tips.html 2.项目的目录树 ...

  4. myeclipse 的Customize Perspective 没有反应

    MyEclipse 2014 工具栏里的Quick Access老是跳上跳下的,弄得我很烦,所以就想自定义一下工具栏,结果 window--> customize perspective 没用 ...

  5. php $_SERVER['HTTP_USER_AGENT'] 用法介绍

    在PHP中HTTP_USER_AGENT是用来获取用户的相关信息的,包括用户使用的浏览器,操作系统等信息, 显示结果为: Mozilla/5.0 (Windows NT 6.1; WOW64) App ...

  6. JSON Patch

    1.前言 可以这么说的是,任何一种非强制性约束同时也没有"标杆"工具支持的开发风格或协议(仅靠文档是远远不够的),最终的实现上都会被程序员冠上"务实"的名头,而 ...

  7. Python_字符串连接

    #join() 与split()相反,join()方法用来将列表中多个字符串进行连接,并在相邻两个字符串之间插入指定字符 li=['apple','peach','banana','pear'] se ...

  8. Shiro入门之一 -------- Shiro权限认证与授权

    一  将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 -->  ...

  9. Mysql中外键的 Cascade ,NO ACTION ,Restrict ,SET NULL

    外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update 外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配 ...

  10. 【转】怎么解决java.lang.NoClassDefFoundError错误 ,以及类的加载机制

    转自http://blog.csdn.net/jamesjxin/article/details/46606307 前言 在日常Java开发中,我们经常碰到java.lang.NoClassDefFo ...