加速
加速处理的动机是为了解决抖动延迟过大,抖动缓冲区中的缓存数据过大,在不丢包的情况下,尽快减少延迟抖动,使用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;
}
上图步骤如下:
- decoder_buffer数据不够,从sync_buffer中借数据,凑齐30ms。
- 对decoder_buffer数据进行算法处理,处理数据放入algorithm_buffer中。
- 从algorithm_buffer数据头部取出等量数据还给sync_buffer,覆盖到sync_buffer尾部。
- 并且去掉algorithm头部的那部分数据。
存在特殊情况,比如algorthm_buffer中的数据不够还了怎么办?
下图是algorithm_buffer中的数据不够还的处理方式.
处理步骤如下:
- sync_buffer把数据借给decoder_buffer,使decoder_buffer凑齐30ms数据。
- 对decoder_buffer数据进行算法处理,处理后的数据放入到algorithm_buffer中。
- 还数据时数据不够还,有多少还多少,这时algorithm_buffer有部分数据没有被覆盖。
- 把algorithm_buffer中尾部没有被覆盖的数据移除,并且在algorithm_buffer前端补0,长度和后面移除的长度一致。
- 移除algorithm_buffer中的数据,这时algorithm_buffer中的数据为空。
加速和减速的具体实现见TimeStretch::Process,具体实现为:
- 找基音周期
先做下采样到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−iA[i]+203−Pi+1B[i]′+0.5
●填充sync_buffer
从上图C部分取SampleLeft + 5个样本,从E处取235 + P - sampleLeft个样本,掐头去尾拼接起来即可,最后algorithm_buffer数据为240 + P个。
若有收获,就点个赞吧