摘要:在分析了分组交换网络中影响语音质量的几种因素之后,探讨如何对网络延迟进行分析与统计。并以支持静音消除功能的编码解码器G729AB为例,在分析网络抖动的统计方法的基础上,设计1种传输G729AB语音分组的构造系统和接收端的复现系统,及相应的抖动缓冲自适应算法,以求提高IP电话的语音质量。
关键词:网络电话;语音质量;抖动缓冲;G729AB;实时协议
A STudy of Improving Voice Quality of IP Telephone
ZHU Xiao dong, ZHANG Zai hong
Abstract: This thesis exploits certain properties of transmitting G729AB audio packets over the packet- switch network.Based on the analysis of network delay and jitter, the G729AB voice packets construction and reconstruction scheme,as well as corresponding adaptive jitter control algorithm,are designed to improve the voice quality of IP telephone.
Key words: IP telephon;Voice quality;Jitter buffer;G729AB;Real- time protocol
1 引言
VoIP的基本原理是由专门设备或软件将呼叫方的话音信号采样并数字化、压缩、转换为一定长度的数字化语音包,以数据包的形式经过分组交换网络传输到对方,对方接收到语音包后解压缩,还原成模拟信号。相对于传统电话清晰、稳定的话音,IP电话在话音质量方面还有待改进,主要表现为回声、抖动、分组丢失与延迟4个问题。本文讨论的G729AB是支持静音消除功能的编码解码器,其特点是可以有效降低网络负荷。而设计抖动缓冲自适应控制算法的主要目的是为了消除或者降低网络抖动的影响,从而平滑语音流,同时尽可能的降低延迟,而较低的延迟对于降低声学回声也有积极的意义。
目前关于抖动缓冲自适应控制算法的讨论已经非常深入,主要集中在如何平衡降低语音分组丢失率以及减少延迟。但是并未涉及如何具体在接收端支持静音消除功能。此外,该自适应抖动缓冲算法也需要在抖动缓冲大小和平滑语音流之间寻找折衷方案。
本文讨论如何将G729AB应用于VoIP终端,以及如何在此系统中寻求实现的语音质量。该解决方案同样适用于语音网关。
2 语音质量
影响语音质量的因素主要有语音压缩编码技术、延迟、分组丢失和抖动。语音压缩编码的主要目的在于降低对带宽的需求。语音延迟是指语音发送端1个声音样本在通过话筒采样后,到达接收端被播放出来之前这一时间间隔。
在考虑IP电话的延迟时,本文在算法延迟、处理延迟、网络延迟之外引入抖动缓冲延迟以简化抖动缓冲算法的设计。
(1)算法延迟
语音处理以语音分组为单位,当音频数据采样量达到一定数量后才进行编码。基于目前的编码解码方式,这种延迟无法避免。
(2)处理延迟
语音分组进行编码解码,回声消除,抖动算法,处理器间通信,Socket读写而引入的延迟。这种延迟可以通过改进算法以及优化软件而减少。
(3)网络延迟
由于网络物理、路由等原因引起的延迟。数据分组传送延迟主要由带宽情况决定。系统的整个延迟主要是语音数据分组在IP网上传输的延迟。
(4)抖动缓冲延迟
语音分组进入接收端后,直到被抖动缓冲算法决定交给解码器播放之前的延迟。这也是抖动缓冲算法所要尽量减少的延迟。
IP网络的1个特征就是网络延迟与抖动,这将导致IP电话音质下降。网络延迟是指1个IP包在网络上传输所需的时间,网络抖动是指IP包传输时间的长短变化。如果网络抖动较严重,那么有的话音包因迟到而被丢弃,会产生话音的断续及部份失真,严重影响音质。为了降低或者消除抖动的影响,人们采用抖动缓冲技术,即在接收方设定1个缓冲区,话音包到达时首先进入缓冲池暂存,系统以稳定平滑的速率将话音包从缓冲池中取出、解压、播放给受话者。这种缓冲技术可以在一定限度内有效处理话音抖动,并提高音质。
3 G729AB构造系统
本节中我们设计并实现了基于G729AB的语音分组发送端RTP构造系统,以实现发送端的实时语音流以及SID数据包。基于目前还没有出现G729AB的RTP封装标准,本文参照互联网草稿“RTP Profile for Audio and Video Conferences with Minimal Control”[1]作为设计基础思想。
G729AB在附录A的基础上增加了静噪抑制技术(VAD),断续传送(DTX),以及舒适噪音发生器(CNG)[2]。G729AB构造单元用于将G729AB编码器产生的数据帧打包成为RTP数据分组。G729AB编码器每10ms产生1个数据帧,其结果可能为语音数据帧(G729A),静音数据帧(SID帧,G729B帧),或者返回空值。为了将G729B数据帧同G729A数据帧一起打包为RTP数据分组,需要确定RTP数据分组的格式。
1个G729RTP数据包可以由零个或更多的G.729或者G729A数据帧所组成,其后有零个或1个G.729B数据帧[1]。由此推论:
(1)当其所有的3个数据帧均为G.729A数据帧的时候,输出30字节数据分组。
(2)当2个G.729A数据帧后为1G.729B数据帧时,输出22字节数据分组。
(3)当1个G.729A数据帧后为1G.729B数据帧时,输出12字节数据分组。
(4)当只有1个G.729B数据帧时,输出2字节数据分组。
(5)当没有G.729AB数据帧产生时,停止打包,直到有G.729A数据帧或者G.729B数据帧出现。
(6)1个语音段的个数据分组,其RTP数据包头部中设定标志位。此外,在RTP数据分组头部中时间戳的定义为产生数据分组的个数据帧中个语音样本产生的时间。
综上所述,G729AB数据包大小不是静态的30ms,而是随着发送端语音而变化。而且其时间戳不会以固定的30ms作为边界。数据帧索引在RTP数据分组中指出数据帧的位置。每当G729AB编码器返回1个语音数据帧或1个SID数据帧,数据帧索引将会被加1。当数据分组大小到达30ms时,或编码的数据帧是1个SID数据帧,则认为数据分组已经完整。如果数据帧是语音数据帧,而且上1个数据帧是1个SID数据帧或者空帧,RTP数据分组头部的标志位将会被设定,否则它将会被清零。而对于序列号,当1个新的有效RTP数据包准备好了时,自动加1。
4 G729AB复现系统
接收端为了忠实复现语音信号,语音数据分组中将尽量以其在发送端产生的相同方式被播放。对于G729AB的语音传输过程,复现系统扮演着重要的角色。G729AB接收端中,语音解码器负责处理G729A语音数据帧,DTX/CNG模块负责处理静音帧并且产生舒适噪音。为了产生平滑的语音输出,以下情况需要考虑:
(1)语音数据帧同SID帧的边界问题。
(2)考虑如何扩展为自适应抖动缓冲。
(3)假定有1语音段在1个SID帧之后被播放,
如果只有序列号,我们无法决定此前的SID帧的播放时间以及新的语音段何时应该开始。因此如何有效利用时间戳是G729AB复现系统的关键。
(4)由于IP电话在发送端和接收端之间没有时钟同步的手段,从而无法计算数据分组传输的真正延迟。
本文采用如下3种时间戳:
——RTP头部中的时间戳。
——本地的到达时间戳。
——本地的播放时间戳。
(5)一般而言,电话中交谈双方总有1方处于倾听方式,而另外1方发送的语音流也总是在语音和静默两种状态之间切换。这意味着接收端也应该能够适应这种切换。
(6)对于G729AB解码器,数据分组大小用来决定被解码的数据分组的类型。
抖动缓冲写入方法的目的是将有效的RTP数据分组分配到抖动缓冲的正确位置,并且丢弃过时或无效的数据分组。本文中的数据分组在抖动缓冲的位置由其序列号决定。此外,保存本地的到达时间戳以用于自适应抖动缓冲的设计。通过数据分组的大小以及RTP头部的时间戳,我们可以知道每个数据分组应该被播放多久。
抖动缓冲读出方法为1个包括3种状态的状态机,如图1所示。
图1 抖动缓冲读出方法
每当VoIP终端开始1个新的会话时,它将进入INITSTATE。如果我们采用静态抖动缓冲技术,并且其抖动缓冲大小为60ms时,首先到达的数据分组将有60ms延迟,此后INITSTATE停止。然后决定下1个状态,该决定基于抖动缓冲中时间戳的数据分组的大小。此后状态机将会在SPEECHS TATE和SILENCESTATE之间切换,该转换将体现语音段与静默段之间的转换。此外,在抖动缓冲中,每个数据分组有4种状态:
(1)READY
这是新到达的数据分组的状态。当数据分组到达时由抖动缓冲写入方法设置。
(2)INIT
当新的会话开始的时候数据分组的状态。该状态用来检查是否有任何新的数据分组到达。如果有任何新的数据分组到达,状态机将会进入INITSTATE。
(3)BUSY
这是正在被播放数据分组的状态。当下1个数据分组开始播放后,该数据分组将转为EMPTY状态。
(4)EMPTY
这是已被播放或者从未出现的数据分组的状态。处于该状态的数据分组的位置在抖动缓冲中可以用来存放准备其他状态的数据分组。
在进入状态机之前,复现系统需要知道抖动缓冲的当前情况:
——抖动缓冲的大小;
——的延迟;
——的延迟;
——播放的数据分组的位置;
——每个状态类型的数据分组的数量,READY、INIT、BUSY、EMPTY;
——当的数据分组被播放的时候,抖动缓冲的状态。
INITSTATE是当抖动缓冲开始初始化它本身的时候的状态。抖动缓冲被初始化之前,它总是检查是否有数据分组进入抖动缓冲。如果我们采用60ms静态抖动缓冲,首先到达的数据包将被作60ms延迟,此后INITSTATE将被中止。当INITSTAE或SPEECH STAT结束后,而且在抖动缓冲中时间戳的数据分组有1个SID帧时,抖动缓冲将会进入SILENCES TATE。该数据分组将被设置为状态READY。SILENCESTATE将会继续,直到1个没有SID的数据分组开始播放。当抖动缓冲决定播放1个语音数据帧的时候,SILENCESTATE将会转变到SPEECHSTATE。相同,在SILENCESTATE中,也会检查是否有任何新的数据分组到达抖动缓冲,SILENCESTATE将决定其是否播出和何时播放。
当在SILENCESTATE中,如果有任何的有SID帧的数据分组丢失时,1个SID帧将会被播放,直到有1个新的SID帧或者1个新的语音数据分组出现。当决定转变到SPEECHSTATE时,一个语音数据分组在SILENCESTATE中,将会被播放。
在SPEECHSTATE中,在抖动缓冲中的数据分组将被作为连续的数据流读出,间隔是固定的30ms。由于在同1个语音段中抖动缓冲的大小是1个固定值,不必为每1个数据分组重新设定延迟。如果有任何遗失的数据分组,舒适噪音将会被播放以取代,直到下个有效的语音数据分组可以被播放。
在极端情况下,带有SID帧的1个数据分组失去了。由于无法判定其后连续的无包情况的原因,不会进行状态转换,仍然播放舒适噪音直到下1个数据分组出现。而当新的数据分组为语音包时,由于没有进行状态转换,仍将其作为同1语音段的语音包处理,所以不会进行抖动缓冲大小的重新设定。
5 抖动缓冲算法设计
在自适应抖动缓冲算法中,缓冲大小伴随网络抖动的实际情况而变化。接收端根据接当前收到的数据分组的延迟与算法保存的延迟信息进行比较,得出当前可能得到的抖动,从而选择相应的抖动缓冲大小。其优点是网络抖动较大时丢包率低,而延迟及抖动较小时,语音延迟相对较小。
RTP头部的时间戳提供了1种传递语音流平滑信息的手段。如果不存在抖动现象,则只用RTP头部的时间戳就可以复现语音流。当需要进行抖动缓冲设计时,则应采用如下3种时间戳:RTP头部中的时间戳、本地的到达时间戳和本地的播放时间戳。
假设有2个数据分组,其序列号是i和j(j>i),则时间戳定义如下:
Si:数据分组i的RTP时间戳;
Ri:数据分组i到达的本地时间戳;
Pi:数据分组i播放的本地时间戳。
其他的定义是:
Dr(j,i)=Rj- Ri;
Ds(j,i) = Sj- Si;
Dp(j,i) = Pj- Pi
Jn(j,i)=Dr(j,i)- Ds(j,i)
=(Rj- Ri)- (Sj- Si)
Jp(j,i)=Ds(j,i)- Dp(j,i)
=(Sj- Si)- (Pj- Pi)
Jj(j,i)=Dp(j,i)- Dr(j,i)
=(Pj- Pi)- (Rj- Ri)
Ds(j,i)反映在发送端产生2个数据分组时的时间间隔。如果在语音段中只有固定速率的语音流,则语音流传输速率Ds(j,j-1)总是1个固定的数值。
Dr(j,i)反映在接收端收到2个数据分组时的时间间隔。Dr(j,j-1)根据网络抖动和语音流传输速率Ds(j,j-1)改变,所以如果我们将Ds(j,i)从Dr(j,i)减去,我们可以得到数据分组之间的网络抖动Jn(j,i)。
Dp(j,i)反映在2个播放数据分组时的时间间隔。如果我们能完整地复现语音流,则对于所有的数据分组,Dp(j,i)应该等同于Ds(j,i)。
Jn(j,i)反映在2个数据分组之间的网络延迟的不同,即网络抖动。Jn(j,i)被网络产生,而且用来决定抖动缓冲区的大小。
Jp(j,i)反映在数据分组之间播放间隔和数据分组产生间隔间的差异。Jp(j,i)应当被尽可能的缩小以保持语音流的连续性。
Jj(j,i)反映数据分组在抖动缓冲区中被延迟的时间的不同。
需要注意Jn(j,i)+Jp(j,i)+Jj(j,i)=0。其计算公式可以被简化成如下形式以便于应用:
Jn(j,i)=(Rj-Ri)-(Sj-Si)=(Rj-Sj)-(Ri-Si)
Jp(j,i)=(Sj-Si)-(Pj-Pi)=(Sj-Pj)-(Si-Pi)
Jj(j,i)=(Pj-Pi)-(Rj-Ri)=(Pj-Rj)-(Pi-Ri)
在静态的抖动缓冲区控制运算中,我们只需要考虑该如何将Jp(j,i)减到少。如果Jp(j,i)=0,则意味着播放数据分组j的时间:Pj=Pi-Ri+Rj=Pi+(Rj-Ri)。(Rj-Ri)只考虑在2个数据分组之间的抖动。在静态的抖动缓冲区控制算法中它将会被1个常量替换。而在1个自适应抖动缓冲区控制算法中它将会被1个变量替换。
此外,我们应该注意网络抖动有可能突变。1个抖动突变意味网络延迟的突然增加,增加的延迟可以是100ms或更长。抖动突变的结果是1系列的数据分组几乎同时到达。为了处理抖动突变,抖动缓冲区大小一定可以是非常快地增加以适应突然出现的大的抖动。在本文中,我们采用全部抖动缓冲区用于解决抖动突变。假定抖动缓冲区可以保存数目MAX_JB_SIZE的数据分组,我们将会在抖动缓冲区中使用所有的数据分组的抖动信息,包括那些已经被播放的数据分组。在公式Pj=Pi中-Ri+Rj=Pi+(Rj-Ri),(Rj-Ri)将会被JBSize替换。然后有:
JBSize=max[Ri-Si]-min[Ri-Si],
i=0,1,…MAX_JB_SIZE-1。
假设数据分组m有[Ri-Si],i=0,1,…MAX_JB_SIZE-1,则数据分组k的播放时间为:
Pk=Pm+JBSize
JBSize将会被作为新的语音段的抖动缓冲区的大小。类似于抖动缓冲的设计目的是为了在抖动和延迟之间寻找的折衷方案,G729AB复现系统自适应抖动缓冲区控制算法也必须在抖动缓冲大小和平滑语音流之间寻找折衷方案。我们可以从以下公式中得到结论:
Jn(j,i)+Jp(j,i)+Jj(j,i)=0
在我们的设计中,自适应总是当新的语音段启动的时候发生。基于这个理由,如果我们想要有一个完整复现的语音流,则应该有:
Jp(j,i)=Dp(j,i)-Ds(j,i)
=(Pj-Pi)-(Sj-Si)=0
对于i=j-1,Pj=P(j-1)+(Sj-S(j-1)),
令Sj-S(j-1)=PkgSize(j),则Pj=P(j-1)+PkgSize(j)。
对于自适应算法,
Pk=Pm+JBSize,JBSize是自适应抖动缓冲区的大小。
Pk=Pm+(w×JBSize+(1-w)PkgSize(k)),
式中0参数“w”的选择对于抖动缓冲算法的集成有直接影响。在理想情况下,参数“w”为一变量,反映语音上下文和网络抖动的变化。如果“w”设置得较小,可以更好地确保语音流的完整复现,但是如果JBSize较小而网络抖动变化较快时,丢包率也会相应提高,这是因为抖动缓冲的大小并没有真实反映网络抖动的变化。相反,如果“w”设置过大,丢包率虽然可以降低,但是当语音段较短,并且频繁出现时,如果此时网络抖动变化较快,虽然可以保持较低的丢包率,但是由于不同语音段的抖动缓冲大小亦不同,导致各语音段之间的起始延迟也不同,对于受话人来说,语音段之间延迟不断变化,将引起由于人为抖动导致的失真。
由此可见,选择参数“w”必须同时考虑语音上下文和网络抖动两种因素。然而目前由于无法确认语音上下文的变化规律,以及如何在复现系统中得到有价值的相关信息,需要进一步对不同网络抖动环境和各种可能的语音上下文同时进行大量测试,根据语音质量终确定如何选择参数“w”,例如将其设为以语音上下文特征为自变量的变量。这将有待于进一步研究。
6 总结
本文阐述了影响VoIP终端语音质量的几种因素,在延迟分析中引入了抖动缓冲延迟的概念,并且分析了抖动现象,建立了1种G729AB的构造系统模型与复现系统模型,设计了相应的抖动缓冲的自适应算法,并且将其与G729AB的复现系统集成。在G729AB的复现系统与抖动缓冲的自适应控制算法集成算法中,如何在抖动缓冲大小与语音流平滑之间求得平衡还有待深入讨论。
参考文献
[1] RTP Profile for Audio and Video Conferences with Minimal Control, RFC1890[Z], Network Working Group, Audio Video Transport Working Group,January 1996.
[2] ITU T Recommendation G.729 Annex B[Z]. International Telecommunication Union.1996,11.
[3] RTP: A Transport Protocol for Real Time Applications, RFC1889[Z], Network Working Group, Audio Video Transport Working Group,January 1996.
[4]. G.729 datasheet https://www.dzsc.com/datasheet/G.729_2060769.html.
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。