NetEq(四)-算法处理(加速、减速、Merge)

加速

加速处理的动机是为了解决抖动延迟过大,抖动缓冲区中的缓存数据过大,在不丢包的情况下,尽快减少延迟抖动,使用WSOLA算法在时域上进行信号压缩,主流程在NetEqImpl::DoAccelerate函数中。

decoder_buffer中最少需要有30ms数据才可以处理,这是因为可能会有基音检测处理,最少需要由2个基音周期数据.

如果数据不够需要从语音缓冲区"借数据"。

  • 当decoder_buffer中的数据不够30ms时,先从sync_buffer尾部获取一些数据放到decoder_buffer头部,让其凑够30ms。
  • decoder buffer处理完之后,把数据放入algorithm_buffer中,这时需要“还”从sync_buffer中借的数据。
  • 从algorithm_buffer头部取相同长度借的数据overwrite 到sync_buffer尾部。
  • algorithm_buffer再从头部remove掉等量数据。
if (decoded_length_per_channel < required_samples) { // 一个通道的数据少于30ms,从语音缓冲区借数据,填充满足30ms数据条件
    // Must move data from the |sync_buffer_| in order to get 30 ms.
    borrowed_samples_per_channel =
        static_cast<int>(required_samples - decoded_length_per_channel);
    memmove(&decoded_buffer[borrowed_samples_per_channel * num_channels],
            decoded_buffer, sizeof(int16_t) * decoded_length);
    sync_buffer_->ReadInterleavedFromEnd(borrowed_samples_per_channel,
                                         decoded_buffer);
    decoded_length = required_samples * num_channels;
  }

上图步骤如下:

  1. decoder_buffer数据不够,从sync_buffer中借数据,凑齐30ms。
  2. 对decoder_buffer数据进行算法处理,处理数据放入algorithm_buffer中。
  3. 从algorithm_buffer数据头部取出等量数据还给sync_buffer,覆盖到sync_buffer尾部。
  4. 并且去掉algorithm头部的那部分数据。

存在特殊情况,比如algorthm_buffer中的数据不够还了怎么办?

下图是algorithm_buffer中的数据不够还的处理方式.

处理步骤如下:

  1. sync_buffer把数据借给decoder_buffer,使decoder_buffer凑齐30ms数据。
  2. 对decoder_buffer数据进行算法处理,处理后的数据放入到algorithm_buffer中。
  3. 还数据时数据不够还,有多少还多少,这时algorithm_buffer有部分数据没有被覆盖。
  4. 把algorithm_buffer中尾部没有被覆盖的数据移除,并且在algorithm_buffer前端补0,长度和后面移除的长度一致。
  5. 移除algorithm_buffer中的数据,这时algorithm_buffer中的数据为空。

加速和减速的具体实现见TimeStretch::Process,具体实现为:

  1. 找基音周期

先做下采样到4kHz,然后相关,峰值检测

相关长度取50,minLag和maxLag分别为10和60对应基音周期分别为2.5ms和15ms,和PLC流程一致。

2.求相关系数

当相关系数大于门限值(fast mode为0.5,一般加速模式为0.9),合并基音周期

这样就缩小了一个基音周期,时间压缩了,播放加速了,p为基音周期。

减速 

加速处理和加速处理流程几乎一样,不同之处在于加速是要减少一个基音周期,而减速是要增加一个语音周期,减速不存在algorithm_buffer不够还的情况.

Merge

Merge处理解决问题上一个播放的帧号和当前帧号不连续,需要平滑过渡。步骤如下:

●准备expanded_数据
expanded_数据为sync_buffer中未播数据,如果不够202,做Expand操作,用Expand数据补齐202.

expanded_.PushBackFromIndex(*sync_buffer_, sync_buffer_->next_index());

●找相关性最大的位置P
如下图所示,找到位置Expanded后面202 - P个sample和Decode_buffer的前202 - P个sample的相关性最大。


●做平滑处理

BLi]-(a+0.004*))Bi+0.5

E[i-(a+0.004*iD[i+0.5

C[i]=203−P202−P−i​A[i]+203−Pi+1​B[i]′+0.5


●填充sync_buffer
从上图C部分取SampleLeft + 5个样本,从E处取235 + P - sampleLeft个样本,掐头去尾拼接起来即可,最后algorithm_buffer数据为240 + P个。

若有收获,就点个赞吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neil_baby

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值