WebRTC音频QoS方法五(音频变速算法之Expand算法实现)
一、概述介绍
在WebRTC中,存在两种扩展算法:PreemptiveExpand和Expand。尽管这两种算法的目标都是扩展音频信号,但它们的实现原理和应用场景却有所不同。
- PreemptiveExpand(预防性扩张)
主动扩展策略,旨在防止即将出现的音频数据短缺。当系统检测到可播放的音频数据即将耗尽,会根据当前的语音信号状况,适当地插入舒适噪声或复制基音周期,以减缓数据不足的趋势。这种方法的关键在于:
平滑过渡:通过在音频流中插入额外的噪声或信号,PreemptiveExpand能够确保播放的连贯性,不会引起听觉上的不适。
预防为主:目前还有数据可播,不会强制补充破坏音质的数据,只是根据音频数据的实际情况,适当的填充舒适噪音或周期基因。
- 2. Expand(扩展)
与PreemptiveExpand不同,Expand是在系统已经没有可播放音频的情况下进行的补偿措施。这种扩展算法主要用于处理丢包或音频数据丢失的情况,确保音频流的平滑过渡。其特点包括:
丢包补偿:当音频数据完全耗尽时,Expand通过生成合成音频来填补空白,使得音频播放不会突然中断。
合成信号:该算法利用已有的信号特征(如有声和无声部分)来合成新的音频信号,以保持音频流的连贯性。
二、扩张实现
当网络传输中出现音频包丢失时,直接播放会产生卡顿。Expand在刚刚没有数据可播的起始阶段,在Expand::AnalyzeSignal函数中会调取之前播放的最后一帧数据,提取的播放前的最后一帧数据的音频特征(周期性、频谱、能量等),生成与原始音频相似的临时片段,填补丢包造成的时间缺口,让听众感觉不到卡顿。
后续在持续没有数据送来的情况下,通过混合、衰减、加噪声等优化,尽量确保生成的填补音频自然流畅,让听众无法察觉丢包的存在。
step1:准备与初始化
首次扩张:调用 AnalyzeSignal 提取原始音频的关键特征(基音周期、LPC 参数、混合比例等),存储在 channel_parameters_ 中;
非首次扩张:直接复用已提取的特征,仅生成新的随机噪声向量(用于清音生成)。
step2:生成浊音部分(复制基因周期片段)
浊音的强周期性是生成的关键,若原始音频中基音周期内的波形高度相似,则可通过复制周期片段 + 交叉淡入淡出生成新的浊音:
1)选择扩张向量
从 AnalyzeSignal 提取的 expand_vector0 和 expand_vector1(原始音频中两个高相似性的周期片段)中,根据当前滞后(current_lag,即基音周期长度)选择片段:
current_lag_index_=0:直接使用 expand_vector0;
current_lag_index_=1:3/4 expand_vector0 + 1/4 expand_vector1;
current_lag_index_=2:1/2 expand_vector0 + 1/2 expand_vector1;
混合不同比例是为了避免单纯复制导致的 “机械感”,增加自然度。
2)重叠拼接(消除拼接杂音)
生成的新片段与历史音频的重叠部分(overlap_length_)采用 “交叉淡入淡出” 处理:
历史音频的重叠部分音量逐渐减小(muting_window);
新生成片段的重叠部分音量逐渐增大(unmuting_window);
两者叠加后,拼接处音量平滑过渡,无 “爆音” 或 “断裂感”。
step3:生成清音部分(滤波噪声模拟频谱)
清音无周期性,无法通过复制生成,需通过LPC 滤波随机噪声模拟原始音频的频谱特征:
1)生成随机噪声
通过 GenerateRandomVector 生成白噪声(random_vector),作为清音的 “原材料”。
2)LPC 滤波塑造频谱
用 AnalyzeSignal 提取的 LPC 参数(ar_filter)对随机噪声滤波:
LPC 参数模拟了原始音频的声道频谱响应;
滤波后,白噪声的频谱被重塑为与原始清音相似的频谱,保证音色一致;
同时通过 ar_gain 控制能量,避免音量突变。
step4:混合浊音与清音(比例动态调整)
根据 voice_mix_factor(浊音 / 清音混合比例,由 AnalyzeSignal 计算)动态混合两部分:
高周期性(浊音为主):voice_mix_factor 大,浊音占比高;
低周期性(清音为主):voice_mix_factor 小,清音占比高;
混合通过 “交叉淡入淡出” 实现(DspHelper::CrossFade),避免过渡突兀。
step5:音量控制与背景噪声(避免听觉疲劳)
静音衰减:连续扩张时(consecutive_expands_ 增加),通过 mute_slope 逐渐降低音量(如 3 次扩张后从 1.0→0.95),避免长时间重复片段导致的听觉疲劳;
背景噪声补充:当音量过低或扩张次数过多时,调用
background_noise_->GenerateBackgroundNoise 添加与环境匹配的背景噪声,避免完全静音的 空洞感。
step6:输出与更新状态
生成的临时音频片段存入 output,同时更新连续扩张计数(consecutive_expands_)和总扩张时长,防止无限制扩张导致音质恶化(超过阈值后强制限制)。
三、算法总结
该算法的核心逻辑是基于特征的相似性生成,本质是用已知推未知:
1、先通过AnalyzeSignal提取原始音频的特征值(周期、频谱、能量等参数);
2、对浊音:复制周期片段并混合,利用周期性保证相似性;
3、对清音:用LPC滤波噪声,利用频谱特征保证相似性;
最后通过混合、衰减、加噪声等优化,确保生成的填补音频自然流畅,让听众无法察觉丢包的存在。