前面我们介绍了 WebRTC 音频 3A 中的声学回声消除(AEC:Acoustic Echo Cancellation)的基本原理与优化方向,这一章我们接着聊另外一个 "A" -- 自动增益控制(AGC:Auto Gain Control)。本文将结合实例全面解析 WebRTC AGC 的基本框架,一起探索其基本原理、模式的差异、存在的问题以及优化方向。
作者|珞神
审校|泰一
前言
自动增益控制(AGC:Auto Gain Control)是我认为链路最长,最影响音质和主观听感的音频算法模块,一方面是 AGC 必须作用于发送端来应对移动端与 PC 端多样的采集设备,另一方面 AGC 也常被作为压限器作用于接收端,均衡混音信号防止爆音。设备的多样性最直接的体现就是音频采集的差异,一般表现为音量过大导致爆音,采集音量过小对端听起来很吃力。
// Scale from VoE to ADM level range.uint32_t new_voe_mic_level = shared_->transmit_mixer()->CaptureLevel();if (new_voe_mic_level != voe_mic_level) { // Return the new volume if AGC has changed the volume. new_mic_volume = static_cast<int>((new_voe_mic_level * max_volume +static_cast<int>(kMaxVolumeLevel / 2)) / kMaxVolumeLevel); return new_mic_volume;}
/* Increment through the table towards the target gain. * If micVol drops below maxAnalog, we allow the gain * to be dropped immediately. */if (stt->gainTableIdx < targetGainIdx) { stt->gainTableIdx++;} else if (stt->gainTableIdx > targetGainIdx) { stt->gainTableIdx--;}gain = kGainTableAnalog[stt->gainTableIdx];// apply gainsample = (in_mic[j] * gain) >> 12;
存在的问题:
无语音状态下的模拟值上调行为;
调整幅度过大,造成明显的声音起伏;
频繁调整操作系统 API,带来不必要的性能消耗,严重的会导致线程阻塞;
数字部分增益能力有限,无法与模拟增益形成互补;
爆音检测不是很敏感,不能及时下调模拟增益;
AddMic 模块精度不够,补偿过程中存在爆音的风险爆音。
自适应数字增益 - AdaptiveDigital
基于音频视频通信的娱乐、社交、在线教育等领域离不开多种多样的智能手机和平板设备,然而这些移动端并没有类似 PC 端调节模拟增益的接口。声源与设备的距离,声源音量以及硬件采集能力等因素都会影响采集音量,单纯依赖固定数字增益效果十分有限,尤其是多人会议的时候会明显感受到不同说话人的音量并不一致,听感上音量起伏较大。
为了解决这个问题,WebRTC 科学家仿照了 PC 端模拟增益调节的能力,基于模拟增益框架新增了虚拟麦克风调节模块:WebRtcAgc_VirtualMic,利用两个长度为 128 的数组:增益曲线 - kGainTableVirtualMic 和抑制曲线 - kSuppressionTableVirtualMic 来模拟 PC 端模拟增益(增益部分为单调递增的直线,抑制部分为单调递减的凹曲线),前者提供 1.0~3.0 倍的增益能力,后者提供 1.0~0.1 的下压能力。