上周,咱们针对音频弱网对立技能中的前向纠错技能、后向纠错技能及 OPUS 编解码抗弱网特性进行了共享。文本共享 WebRTC 运用的抗颤动模块 NetEQ。关注【融云全球互联网通信云】了解更多

颤动的定义和消除原理

颤动是指因为网络原因,抵达接纳端的数据在不一起刻段,表现出的不均衡;或者说接纳端接纳数据包的时刻距离有大有小。

WebRTC 通过包抵达时刻距离的改变来评价颤动,公式如下:

WebRTC 音频抗弱网技术(下)
Ji定义为时刻 i 时丈量的颤动,E(T) 表明包抵达时刻的距离均值,Ti表明时刻 i 收到的包距上一次收包的时刻距离。

Ji> 0 阐明数据包提早到了,这样颤动缓存区数据将会呈现堆积,容易形成缓冲区数据溢出,导致端到端时刻推迟增大;Ji< 0 阐明数据包晚到或丢掉,会增大延时;不论早到还是晚到,都可能形成丢包,添加时延。

NetEQ 通过丈量包到达时刻距离,来猜测包在网络中的传输时刻延时; 依据收到的包但还未播映的缓冲语音数据的巨细来评价颤动的巨细。

原则上通过对网络延时的丈量,以其最大延时来设置颤动缓冲区的巨细,然后使每个包在网络中的延时加上该包在颤动缓冲区的延时之和坚持持平,这样能够消除颤动,就能够操控语音包从颤动缓冲区以一个相对平稳的速度播映音频数据。

下图[1]阐明晰颤动消除的中心思想:

WebRTC 音频抗弱网技术(下)
(颤动消除的中心思路)

A、B、C、D 包在发送端分别以 30ms 距离发送,即分别在 30ms、60ms、90ms、120ms 处发送;接纳端接纳到这些包对应的时刻为 40ms、90ms、100ms、130ms;这样它们在网络中的延时分别是 10ms、30ms、10ms、10ms;包抵达的距离分别为 50ms、10ms、30ms,即颤动。

因而能够使包 A、C、D 在颤动缓存中的延时 20ms 再播映,即 A、B、C、D 的播映时刻为 60ms、90ms、120ms、150ms,这样能够坚持一个平稳的距离进行播映。

NetEQ 通过预算网络传输延时,依据网络传输延时 95% 分位来调整颤动缓冲区;这使得 NetEQ 在消除颤动缓冲影响时,统筹最小延时。

下图[2]是官方对 NetEQ 和其它技能在消除颤动带来的延时比照,能够看出 NetEQ 在消除颤动时,能够坚持很低的时刻延时。

WebRTC 音频抗弱网技术(下)
(NetEQ 与其它技能消除颤动延时比照)

NetEQ 及其相关模块

下图[1]概要描绘了 WebRTC 的语音引擎架构。红色区域为 NetEQ 部分,能够看出 NetEQ 位于接纳端,包含了 jitter buffer 和解码器、PLC 等相关模块。接纳端从网络收到语音包后,语音包将先进入NetEQ 模块进行颤动消除、丢包隐藏、解码等操作,最终将音频数据输出到声卡播映。

WebRTC 音频抗弱网技术(下)
(WebRTC 的语音引擎架构图)

NetEQ 包含的模块见下图[1]:

WebRTC 音频抗弱网技术(下)
(NetEQ 模块)

NetEQ 中心模块有MCU 模块DSP 模块,MCU 模块担任往 jitter buffer 缓存中刺进数据和取数据,以及给 DSP 的操作;DSP 模块担任语音信息号的处理,包含解码、加快、减速、交融、PLC 等。一起 MCU 模块从 jitter buffer 中取包遭到 DSP 模块相关反馈影响。

MCU 模块包含音频包进入到 buffer,音频包从 buffer 中取出,通过语音包抵达距离评价网络传输时刻延时,以及对 DSP 模块履行何种操作(加快、减速、PLC、merge)等。

DSP 模块包含解码,对解码后的语音 PCM 数据进行相关操作,评价网络颤动 level,向 play buffer 传递可播映的数据等等。下面详细剖析MCU 和 DSP 各相关模块。

MCU

将收到的包刺进 packet_buffer_

从网络收到音频包后,将其刺进到颤动缓存 packet_buffer_中,最多缓存 200 个包;当缓存满了,会改写缓存中所有的包,一起该缓存最多缓存近 5 秒的音频数据,太早的会被守时清除。

若收到的包是 red 包,会将 red 包中的每个独⽴包解析出来存入到缓存行列中,包在缓存行列中依照 timestamp 的升序进行存储,即最近的音频包存储在行列后边,老的包存储在行列前面。收到音频包后,还会更新 NackTracker 模块,该模块首要是通过包的序列号来判别是否存在丢包,若存在丢包且重传恳求敞开,需求向发送端发起 nack 恳求,恳求发送端重发丢掉音频包。

预算网络传输延时

在将包刺进到颤动缓存中时,依据包抵达时刻距离对网络延时进行预算。这儿将 WebRTC中依据包抵达时刻距离来核算网络延时,WebRTC 核算音频网络延时,首要考虑如下几点:

核算音频包抵达时刻距离,取其 95% 分为作为网络时延估量。

WebRTC 音频抗弱网技术(下)
以上公式通过核算当时包和上一个包的时刻差,以及 seqnum 的差值,来核算每个 seq 包占有的时刻戳规模,即 packet_per_time,然后通过当时包和上一个包收包距离 iat_ms,来核算收包时刻距离延时,用包的个数来度量。

当正常包抵达时 iat = 1,iat = 0 表明提早到了,iat = 2,表明延时一个包, 最终用包个数来衡量推迟时刻。每算出一个 iat 后,会将其刺进到对应的直方图,直方图记载 0-64 个包,即记载 0-64 个包的推迟概率散布情况。所有推迟概率和为 1。

WebRTC 音频抗弱网技术(下)
核算出当时包的抵达距离 iat,将其刺进到直方图,并更新直方图每个推迟的概率,每个推迟散布乘以一个忘记因子 f,f 小于 1, 更新过程如下:

WebRTC 音频抗弱网技术(下)
上面公式的意义是确保每次核算出一个包抵达距离推迟后,对应添加其概率,一起对其它延时散布的概率进行忘记,使整个和坚持为 1。最终取其 95% 分为的推迟作为方针延时,即有 95% 的推迟都小于这个方针延时。

核算包抵达时刻距离最大峰值

核算多个包抵达距离峰值,最多 8 个,在必定情况下,以峰值作为网络延时估量。每次核算到包抵达时刻距离 iat 和按 95% 分位核算到的方针延时(记为target_level)后,来判别峰值。

以为该 iat 是⼀个延时峰值的条件是:

iat > target_level + threshold, 或 iat > 2 * target_level, 这儿的 threshold 为 3

且距前次峰值时刻距离小于阈值 5s

当判别该 iat 为延时峰值时,将其添加到峰值容器中,峰值容器中每个元素记载两个值,一个是峰值 iat 值,另一个是当时峰值距离上一次峰值的时刻距离(即为 period_ms);

当峰值容器超越了两个,且当时时刻距离上一次发现峰值时已流逝的时刻(记为 eplase_time)小于峰值容器元素中记载的最大period_ms 的两倍时,以为该峰值是有效的,需求从峰值容器取最大的 iat(记为 max_iat),则方针时延取值:

WebRTC 音频抗弱网技术(下)
当 target_level 取值是 max_iat 时,该峰值的理论有效时刻可抵达 40s 以上,此处存在优化空间。

最小延时限制

依据设置最低时延,调整方针延时估量,确保方针延时估量不低于最小时延;最小时延是音视频同步核算的出来的成果。方针延时小于该最小延时,会导致音视频不同步。

方针延时不能超越 0.75 * 最大颤动缓冲区巨细

WebRTC 中默认最大颤动缓冲区为 200,所以方针延时为:

WebRTC 音频抗弱网技术(下)
即 target_level 不大于 150 个包,也便是方针延时不大于 3s 延时。

从 packet_buffer_中取包

播映线程测验每次获取 10ms 数据来播映,要是颤动缓冲中没有数据,则播映静音数据。从packet_buffer_ 中获取的数据首先需求通过解码器解码,然后再依据反馈的操作进行对应的 DSP 操作(加快、减速、丢包隐藏、PLC、交融等)。最终将 DSP 处理完的数据填入到 sync_buffer_ 中待扬声器播映,并从 sync_buffer_ 中取 10ms 音频数据进行播映。

核算颤动延时

依据颤动缓冲区 packet_buffer_ 和 sync_buffer_ 中未播映完的音频数据总延时 total_dealy,来更新核算颤动缓存延时 filtered_level

WebRTC 音频抗弱网技术(下)
若通过加减速操作,需求从 filtered_level 中消除加减速操作后引入的延时改变,如下所示:

WebRTC 音频抗弱网技术(下)

获取对应的操作

下图中的 packet_buffer_ 和 sync_buffer_ 中未播映的数据巨细能够理解为颤动缓冲区巨细,从图中可看出数据从 packet_buffer_ 取出后,经解码器解码、DSP 处理,最终进入sync_buffer_中待播映。

low_limit = 3/4 *target_level
high_limit = max(target_level, low_limit + window_20ms

WebRTC 音频抗弱网技术(下)
(颤动缓冲区)

但进行何种 DSP 操作处理呢?

NetEQ 将依据 packet_buffer_和 sync_buffer_中未播映的音频数据总延时(记为 total_delay),以及 sync_buffer_ 中最终待播映的音频数据的时刻(记为 endtimestamp),和 packet_buffer_首包的时刻(记为 avaibleTimestamp),以及 target_level 和filtered_level 的关系,来综合判别接下来履行何种 DSP 操作。

下面将对几种中心的 DSP 处理操作条件进行扼要阐明:

norml 操作

满足以下条件之一,将履行 normal 操作

1. 若本来要做 expand 操作,可是 sync_buffer_ 待播映的数据量大于 10ms。
2. 接连 expand 操作次数超越阈值。
3.当时帧和前一帧都正常抵达,且 fitlered_level 在 low_limit 和 higth_limit 之间。
4. 上一次操作是 PLC,当时帧正常,但当时帧来得太早,履行 normal 操作。
5. 当时帧和前一帧都正常抵达, 本来通过 filtered_level > high_limit 判别,要加快操作,可是 sync_buffer_ 待播映的音频数据大于小于 30ms。

expand 操作条件

当时数据包丢掉或者还未抵达时,一起在 sync_buffer_ 待播映的音频数据小于 10ms 时,则满足下面4 个条件中任何一个,都将履行 expand 操作。

1. packet_buffer_ 没有可获取的音频数据。
2.上一次是 expand 操作,且当时 total_delay < 0.5* target_level。
3. 上一次是 expand 操作,且当时包(即availbeTimestamp - endtimestamp 大于必定阈值)来的太早,一起当时 filtered_level 小于 target_level。
4. 上一次包非 expand(加快、减速或 normal),且 availbeTimestamp - endtimestamp >0,即中心存在丢包。

加快操作

上一个包和当时包都正常抵达,filtered_level 大于 hight_limit,且 sync_buffer_ 中待播映的数据量大于 30ms。

减速操作

上一个包和当时包都正常抵达,filtered_level 小于 low_limit。

merge 操作

上一次为 expand 操作,当时包正常抵达。

DSP

基音[3]

基音是指发浊音时声带振荡所引起的周期性对应的信号基本谐波,基音周期等于声带振荡频率的倒数。一般的声响都是由发音体宣布的一系列频率、振幅各不相同的振荡复合而成的。这些振荡中有一个频率最低的振荡,由它宣布的音便是基音,其他为泛音。基音携带了大部分能量,决定了音高。

基音的周期提取,一般运用短时自相关函数,因为自相关函数一般在依据周期上表现出有极大值的特色。在 NetEQ 的 DSP 信号处理中,基音的提取是一个至关重要的过程。

语音的拉伸[4]

对语音的拉伸变速,有时域办法和频域办法。时域办法核算量相对频域办法少,适合 VoIP 这种场景;频域办法 适合频率剧烈改变的场景,如音乐。

NetEQ 中对语音的拉伸(加快或减速)运用的是WSOLA 算法,即通过波形类似叠加的办法来变速;该算法在拉伸语音时能够确保变速不变调。一起该算法是时域算法,对语音有比较好的效果,下图是其大致原理和流程:

WebRTC 音频抗弱网技术(下)
(WSOLA 算法原理)

WSOLA 算法大致流程:

WebRTC 音频抗弱网技术(下)

解码

从 packet_buffer_ 中获取数据,正常解码,解码数据存储到 decoded_buffer_ 中。

加快

NetEQ 中,当 sync_buffer_ 和 packet_buffer_ 中的待播映数据总延时堆积过多,且前一帧和当时帧都正常时,需求通过加快播映操作,来下降颤动缓冲区待播映的数据量,以到达下降时延的意图,否则容易导致颤动缓冲区溢出,呈现丢包。而加快是要求变速不变调的,WSOLA 算法通过寻觅类似波形并对类似波形进行叠加来完成变速意图。

这儿对 NetEQ 中的加快过程做扼要描绘:

WebRTC 音频抗弱网技术(下)

⾸先做加快要求最少需求 30ms 数据,数据一般来源于从 decoder_buffer_, 当 decoded_buffer_中得的数据缺乏 30ms,需求从 sync_buffer_中借一部分数据,凑满 30ms。
30ms 数据对应 240 个样本,将这 240 个样本下采样到 110 个样本;将下采样 110 个样本分红两部分 seq1 和seq2,seq2 为固定末尾 50 个样本,即[60,110]; seq1 也为 50 个样本,滑动规模[0,100],核算 seq1 和 seq2 的自相关性。
依据核算出来的自相关性成果,以抛物线拟合来找到自相关性峰值和方位,极大值呈现的方位,即为上图中的 offset,即 seq1 窗口向左滑动的距离,所以基音周期 T = offset + 10。
在要加快的 30ms 样本中,取 15ms 和 15ms - T 这两个基音周期信号,分别记为 XY 核算这两个基音周期信号的匹配度。

WebRTC 音频抗弱网技术(下)

当 best_correlation 大于 0.9 时,则履行将两个基音周期信号合并为⼀个基音周期信号,起到加快效果
加快完的数据,如下图的 output 将存储到 algorithm_buffer_中,
要是之前因为 decoded_buffer_中的数据量不行,从 sync_buffer_中借了部分数据,
则需求从 algorithm_buffer_中将借的数据 copu 回 sync_buffer_对应的方位(意图是确保音频的滑润过渡),
一起将 algorithm_buffer_中剩下的数据 copy 到 sync_buffer_末尾,如下图所示:

WebRTC 音频抗弱网技术(下)

WebRTC 音频抗弱网技术(下)

减速

当 NetEQ 颤动缓冲中待播映的数据延时水平小于方针延时下限时,阐明待播映的数据量小,为了到达播映端的最佳音质体会,需求将现有数据拉伸,恰当添加播映数据量;这和加快是相反的操作,底层技能相同。相同下面对其做扼要剖析:

4 步和加快基本上是相同的,这儿不再赘述
最终一步,是将 15ms - T15ms 两个基音周期交叉渐变合并的混合基音刺进到 15ms 后一个周期前。到达添加一个基音周期数据的意图,以此来添加播映数据量,一起需求从算法缓冲区中将借的数据返还给 sync_buffer_。
详细如下图所示:

WebRTC 音频抗弱网技术(下)

WebRTC 音频抗弱网技术(下)

丢包补偿

当时包丢掉时,在 NetEQ 中会触发丢包补偿来猜测丢掉的包;丢包补偿有两种方法,一种是通过编解码器来猜测重构丢掉的包,另一种是通过 NetEQ 模块来猜测重构丢掉的包;对应分别是kModeCodecPlc 和 kModeExpand。

不论是何种模式,前提要求是 sync_buffer_ 中待播映的音频数据量小于当时恳求要播映的数据量,才干履行该操作;丢包补偿通过最近的历史数据,来重构 PLC 相关参数,然后通过历史数据和 PLC 相关参数进行线性猜测,康复丢掉的包,最终再叠加必定的噪声。当接连屡次 PLC 操作时,失真将会加大,所以屡次操作后,将会下降 PLC 语音能量值。

下图是 NetEQ expand 操作的中心过程。

WebRTC 音频抗弱网技术(下)
(构建 PLC 参数过程,点击查看大图)

WebRTC 音频抗弱网技术(下)
(构建 PLC 包,点击查看大图)

PLC 操作中,首要任务是核算基音周期,这儿运用了自相关核算信号失真核算两种方法来核算基音周期,可通过下图扼要阐明。

WebRTC 音频抗弱网技术(下)

A 为结尾 60 个样本信号

B 为滑动窗口,窗口包含 60 个样本信号,窗口起始方位滑动规模[0, 54]

通过核算 A 和 B 的自相关系数,得到 54 个自相关成果,对这 54 个自相关成果运用抛物线拟合找到三个最大值的方位 peak1_idx1、peak_idx2、peak_idx3 为三个自相关系数最大的值的方位

以为基音是周期信号,极值呈现的方位为周期上

故基音周期 T

T1 = peak_idx3 + 10

T2 = peak_idx2 + 10

T3 = peak_idx1 + 10

WebRTC 音频抗弱网技术(下)

依据上面通过自相关及抛物线拟合找到的三个极值,得到了三个基音周期

取结尾 20 个信号作为 A,滑动窗口 B 也是 20 个样本(2.5ms),B 在距 A 一个基音周期前后 4 个样本规模内(0.5ms)滑动

故有三个窗口滑动规模,核算三个规模内的窗口 A 和窗口 B 的失真度

取最小失真度三个极值,这三个极值作为通过失真最小核算的基音周期 T’

1, T’2, T’3

最小失真的衡量是以 A 和 B 对应元素差值绝对值之和最小为依据的在得到依据自相关核算出来的三个基⾳周期 T1,T2,T3 和依据失真度最小得到的三个基⾳周期 T’1,T’2,T’3

通过比较这三对的 ratio = 自相值/失真度,当 ratio 最大时,则以为这对基音周期最佳

PLC操作中,expand_vector0 和 expand_vector1 的核算细节如下图:

WebRTC 音频抗弱网技术(下)

WebRTC 音频抗弱网技术(下)

WebRTC 音频抗弱网技术(下)
(从历史数据中结构 expand_vector0、expand_vector1)

结构 AR 滤波器参数,通过获取一组(7 个)自相关值,对这组自相关值通过 LevinsonDurbin 算法核算,猜测出 AR 滤波器参数。AR 滤波器是线性猜测器,通过历史数据来猜测当时数据;在构建 PLC 包时,通过对历史数据进行 AR 滤波,来猜测丢掉的包信息。

下图是对这个过程的扼要阐明:

WebRTC 音频抗弱网技术(下)

AR 滤波器公式如下所示:

WebRTC 音频抗弱网技术(下)

这儿 k = 7;e(n)为猜测值和实践值的差错;AR 滤波便是通过运用最近的历史数据来猜测当时时刻数据;LevinsonDurbin 算法通过自相性值的核算来猜测 ck,使得 e(n) 最小。

自相关性越大,阐明 e(n) 越小;
LevinsonbDurbin 算法通过运用自相关性值来猜测 AR 滤波器参数,能够理解为使⽤ e(n)来猜测。

交融

交融操作一般是上一帧丢掉了,但当时帧正常;

上一帧是通过猜测生成的 PLC 包,和当时帧需求做滑润处理,避免两种联接呈现显着改变;交融便是完成该功能,交融的组要过程有:

需求 202 个扩展样本信号,首要是向 sync_buffer_ 未播映的信号借用 sync_buffer_ 未播映的信号缺乏 202,通过生成满足 PLC 数据来凑满
通过扩展样本信号和输入信号,核算期它们的自相关性值,及通过抛物线拟合来获取基音周期
对 input 数据进行 Ramp 信号改换
对扩展信号和 input 信号部分段进行混合
从缓存算法取归还借用的信号数据到 sync_buffer_
将算法缓冲区剩下的滑润处理的信号追加到 sync_buffer_

下图对 NetEQ 中交融过程的扼要阐明:

WebRTC 音频抗弱网技术(下)
(基音周期和 mute_factor,点击查看大图)

WebRTC 音频抗弱网技术(下)
(混合 expand 和 input 信号,点击查看大图)

normal

当时帧能够正常播映,也便是能够直接将这段信号送⼊到 sync_buffer_ 中, 可是因为上一帧可能是expand 等,需求进行相关的滑润操作。

首要过程如下:

将输入信号复制到算法缓冲区生成一段 PLC 数据包
依据背景噪声和输入语音信号的能量比值,核算 mute_factor
依据 mute_factor 对算法缓冲区数据依照能量从弱到强的趋势批改
将 expand 和算法缓冲区的头 1ms 音频数据进行滑润混合,成果存在算法缓冲区;
相关混合滑润公式如下:

WebRTC 音频抗弱网技术(下)
将最终的算法缓冲区数据最加到 sync_buffer_ 后

下图对 normal 的操作流程做补充阐明:

WebRTC 音频抗弱网技术(下)
(normal 操作流程,点击查看大图)

NetEQ 相关 buffer

NetEQ 为了消除颤动、解码音频数据、对解码数据进行 DSP 处理(加减速、PLC、交融、滑润数据),以及滑润播映等,运用了多个缓存 buffer,下面是对这些 buffer 的扼要阐明:

**packet_buffer_:** 用来接纳网络中收到的音频包数据,也可称为颤动缓存,会守时删除当时时刻 5 秒前的包,一起最多缓存 200 个包,即 4 秒(这⾥以每个包 20ms 核算)。
**decoded_buffer_** : 当播映线程每次获取音频数据来播映时,会依据方针延时和颤动缓存延时来判别是否需求从 packet_buffer_中获取音频数据进行解码,解码后的数据存放到 decoded_buffer_中。最多可缓存 120ms 数据。
**algorithm_buffer_** : decoded_buffer_中的数据通过 DSP 处理后,将存放到该缓存,一般每处理一次会清空一次。
**sync_buffer_** : 一般是从算法缓存复制过来的数据,是待播映的数据;sync_buffer_中有两个变量,一个是 next_index,表明当时播映的方位,next_index 前的数据表明已经播映,后边的数据表明待播映;另一个是 endtimestamp, 表明 sync_buffer_中最终一个待播映的数据,也便是最近的音频数据量。
该 buffer 可最多缓存 180ms 数据,是一个循环缓存;播映线程每次会从 sync_buffer_中取 10ms 数据进行播映。

关于何时从 packet_buffer_中取数据解码阐明:

一般情况下每次从 packet_buffer_中取 10ms 数据进行解码。
当要履行 expand 操作时,但 sync_buffer_中有 10ms 以上数据,不从 packet_buffer_中取数据解码。
作为加快操作时,若 sync_buffer_中有 30ms 以上数据,不从 packet_buffer_中取数据;或若 sync_buffer_中有 10ms 以上待播映数据,一起前次解码了 30ms 数据,则不从 packet_buffer_中获取。
当加快操作,若 sync_buffer_待播映数据小于 20ms,一起前次解码的数据小于 30ms,从 packet_buffer_中获取 20ms 数据待解码。
当要做减速操作时,若 sync_buffer_中待播映的数据大于 30ms;或待播映的数据小于 10ms,但上一次解码的数据多余 30ms, 则不从 packet_buffer_中获取数据。
当要做减速操作,sycn_buffer_中待播映的数据量小于 20ms, 且前次解码的数据量少于 30ms,获取 20ms 数据进行解码。

NetEQ 能很好地跟踪网络颤动,一起在消除颤动时确保延时尽量小,对音频体会提升显着;结合上一篇关于弱网对立的一些技能,可显着提升音频在弱网环境下的体会。

参考资料:
[1]: WebRTC 语音引擎中 NetEQ 技能的研究
[2]:<http://www.gipscorp.alcatrazconsulting.com/files/english/datasheets/NetEQ.pdf>
[3]:<https://baike.sogou.com/v7850130.htm>
[4]:A Review of Time-Scale Modification of Music Signals