webrtc的 audio processing 模块是 webrtc音频处理的核心模块,webrtc命名为The Audio Processing Module (APM) ,该模块不仅融合音频的3A(AEC(Acoustic Echo Cancelling,回声消除)、AGC(Automatic Gain Control,自动增益控制)和 ANS(Active Noise Control,降噪)), 还融于了高通滤波,语音活动检测和瞬态抑制等功能。
一 核心函数模块介绍
AudioProcessingImpl::ProcessCaptureStreamLocked 函数为音频数据处理的核心函数,
按顺序调用的主要模块算法有:(部分算法根据配置文件确认是否执行)
-
高通滤波 (HPF)
-
前置放大器 (Pre-amplifier)
-
回声控制 (AEC/AEC3) - 分析捕获信号
-
自动增益控制 (AGC/AGC2) - 分析
-
分频带处理 (Split into frequency bands)
-
噪声抑制 (NS)
-
回声消除处理 (Process Capture)
-
瞬态抑制 (Transient Suppression)
-
增益应用 (Gain Application)
-
合并频带 (Merge frequency bands)
-
后置处理 (Post-processing)
音频处理的主要模块类:
cpp
std::unique_ptr<AgcManagerDirect> agc_manager;
std::unique_ptr<GainControlImpl> gain_control;
std::unique_ptr<GainController2> gain_controller2;
std::unique_ptr<HighPassFilter> high_pass_filter;
rtc::scoped_refptr<EchoDetector> echo_detector;
std::unique_ptr<EchoControl> echo_controller;
std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
std::unique_ptr<NoiseSuppressor> noise_suppressor;
std::unique_ptr<TransientSuppressor> transient_suppressor;
std::unique_ptr<CustomProcessing> capture_post_processor;
std::unique_ptr<CustomProcessing> render_pre_processor;
std::unique_ptr<GainApplier> pre_amplifier;
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer;
std::unique_ptr<LevelEstimator> output_level_estimator;
std::unique_ptr<VoiceDetection> voice_detector;
函数主要分为五大阶段(每个阶段流程,部分模块根据配置是否执行)
第一阶段:全频带预处理 (Full-band Pre-processing)
1.1 全频带高通滤波 (HPF)
如果配置要求在全频带进行且未被强制使用分频带,则先切除低频噪音
1.2 应用前置放大器增益 (Pre-amplifier)
用于补偿麦克风灵敏度或统一输入电平,在其它处理之前调整信号幅度
1.3 分析输入信号 RMS (均方根) 电平
用于统计和监控输入音量大小
第二阶段:分析与分频带 (Analysis & Splitting)
2.1 回声控制器 (AEC3) 前置分析
检测模拟增益、前置增益或播放音量的变化,这些变化会影响回声路径,需通知 AEC
2.2 AGC1 (旧版自动增益) 前置分析
2.3 分频带处理准备 (Split into Frequency Bands)
如果启用了需要分频带处理的模块(如 NS, AECM, VAD),则将信号从时域转换为频域子带
2.4 多通道降级处理
如果启用了 AEC 但不支持多通道捕获,强制将信号下混为单声道以简化处理
2.5 分频带高通滤波 (Split-band HPF)
如果未在全频带处理,或者被强制要求在分频带处理,则在此处执行 HPF
第三阶段:核心增强算法 (Core Enhancement)
3.1 AGC1 分析捕获音频
3.2 噪声抑制 (NS) 分析
如果未启用"分析线性AEC输出"功能,或者没有线性输出缓冲区,则分析原始捕获信号
3.3 执行回声消除 (AEC)
3.4 语音活动检测 (VAD)
3.5 AGC1 处理与应用增益
3.6 AGC1 最终处理(限幅器等)
第四阶段:后处理与合并 (Post-processing & Merging)
4.1 合并频带 (Merge Frequency Bands)
将处理后的子带信号重新合成为全频带时域信号
4.2 全频带缓冲区同步
如果存在独立的全频带缓冲区(用于某些全频带算法),且多频带处理改变了信号,
则将结果拷贝过去,并切换当前工作指针到全频带缓冲区
4.3 残留回声检测器 (Residual Echo Detector) 分析
4.4 瞬态抑制 (Transient Suppression)
抑制键盘敲击声等非平稳噪声
4.5 自定义捕获分析器 (Experimental)
4.6 AGC2 (新版自动增益控制) 处理
4.7 自定义后置处理器 (Custom Post-processor)
第五阶段:统计与指标上报 (Statistics & Metrics)
5.1 输出电平估计
5.2 分析输出信号 RMS 电平并记录直方图
5.3 记录 AGC 模拟电平用于调试
5.4 收集回声相关指标 (AEC Metrics)
5.5 收集残留回声指标
5.6 更新并上报统计数据
附函数
cpp
int AudioProcessingImpl::ProcessCaptureStreamLocked() {
// 1. 处理渲染端(Render/Playout)积压的音频数据
// AEC 需要参考扬声器播放的声音来消除回声,这里处理之前缓存的渲染帧
EmptyQueuedRenderAudioLocked();
// 2. 处理捕获端的运行时动态设置(如模拟增益变化、压缩增益等)
HandleCaptureRuntimeSettings();
// 确保 AEC3 (echo_controller) 和 AECM (echo_control_mobile) 不会同时激活
RTC_DCHECK_LE(
!!submodules_.echo_controller + !!submodules_.echo_control_mobile, 1);
AudioBuffer* capture_buffer = capture_.capture_audio.get(); // 主处理缓冲区
AudioBuffer* linear_aec_buffer = capture_.linear_aec_output.get(); // 线性AEC输出缓冲区(可选)
// --- 第一阶段:全频带预处理 (Full-band Pre-processing) ---
// 3. 全频带高通滤波 (HPF)
// 如果配置要求在全频带进行且未被强制使用分频带,则先切除低频噪音
if (submodules_.high_pass_filter &&
config_.high_pass_filter.apply_in_full_band &&
!constants_.enforce_split_band_hpf) {
submodules_.high_pass_filter->Process(capture_buffer,
/*use_split_band_data=*/false);
}
// 4. 应用前置放大器增益 (Pre-amplifier)
// 用于补偿麦克风灵敏度或统一输入电平,在其它处理之前调整信号幅度
if (submodules_.pre_amplifier) {
submodules_.pre_amplifier->ApplyGain(AudioFrameView<float>(
capture_buffer->channels(), capture_buffer->num_channels(),
capture_buffer->num_frames()));
}
// 5. 分析输入信号 RMS (均方根) 电平
// 用于统计和监控输入音量大小
capture_input_rms_.Analyze(rtc::ArrayView<const float>(
capture_buffer->channels_const()[0],
capture_nonlocked_.capture_processing_format.num_frames()));
const bool log_rms = ++capture_rms_interval_counter_ >= 1000;
if (log_rms) {
capture_rms_interval_counter_ = 0;
RmsLevel::Levels levels = capture_input_rms_.AverageAndPeak();
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureInputLevelAverageRms",
levels.average, 1, RmsLevel::kMinLevelDb, 64);
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureInputLevelPeakRms",
levels.peak, 1, RmsLevel::kMinLevelDb, 64);
}
// --- 第二阶段:分析与分频带 (Analysis & Splitting) ---
// 6. 回声控制器 (AEC3) 前置分析
// 检测模拟增益、前置增益或播放音量的变化,这些变化会影响回声路径,需通知 AEC
if (submodules_.echo_controller) {
int analog_mic_level = recommended_stream_analog_level_locked();
capture_.echo_path_gain_change =
capture_.prev_analog_mic_level != analog_mic_level &&
capture_.prev_analog_mic_level != -1;
capture_.prev_analog_mic_level = analog_mic_level;
if (submodules_.pre_amplifier) {
float pre_amp_gain = submodules_.pre_amplifier->GetGainFactor();
capture_.echo_path_gain_change =
capture_.echo_path_gain_change ||
(capture_.prev_pre_amp_gain != pre_amp_gain &&
capture_.prev_pre_amp_gain >= 0.f);
capture_.prev_pre_amp_gain = pre_amp_gain;
}
capture_.echo_path_gain_change =
capture_.echo_path_gain_change ||
(capture_.prev_playout_volume != capture_.playout_volume &&
capture_.prev_playout_volume >= 0);
capture_.prev_playout_volume = capture_.playout_volume;
// 分析捕获音频,提取特征用于后续回声消除
submodules_.echo_controller->AnalyzeCapture(capture_buffer);
}
// 7. AGC1 (旧版自动增益) 前置分析
if (submodules_.agc_manager) {
submodules_.agc_manager->AnalyzePreProcess(capture_buffer);
}
// 8. 分频带处理准备 (Split into Frequency Bands)
// 如果启用了需要分频带处理的模块(如 NS, AECM, VAD),则将信号从时域转换为频域子带
if (submodule_states_.CaptureMultiBandSubModulesActive() &&
SampleRateSupportsMultiBand(
capture_nonlocked_.capture_processing_format.sample_rate_hz())) {
capture_buffer->SplitIntoFrequencyBands();
}
// 9. 多通道降级处理
// 如果启用了 AEC 但不支持多通道捕获,强制将信号下混为单声道以简化处理
const bool multi_channel_capture = config_.pipeline.multi_channel_capture &&
constants_.multi_channel_capture_support;
if (submodules_.echo_controller && !multi_channel_capture) {
capture_buffer->set_num_channels(1);
}
// 10. 分频带高通滤波 (Split-band HPF)
// 如果未在全频带处理,或者被强制要求在分频带处理,则在此处执行 HPF
if (submodules_.high_pass_filter &&
(!config_.high_pass_filter.apply_in_full_band ||
constants_.enforce_split_band_hpf)) {
submodules_.high_pass_filter->Process(capture_buffer,
/*use_split_band_data=*/true);
}
// --- 第三阶段:核心增强算法 (Core Enhancement) ---
// 11. AGC1 分析捕获音频
if (submodules_.gain_control) {
RETURN_ON_ERR(
submodules_.gain_control->AnalyzeCaptureAudio(*capture_buffer));
}
// 12. 噪声抑制 (NS) 分析
// 如果未启用"分析线性AEC输出"功能,或者没有线性输出缓冲区,则分析原始捕获信号
if ((!config_.noise_suppression.analyze_linear_aec_output_when_available ||
!linear_aec_buffer || submodules_.echo_control_mobile) &&
submodules_.noise_suppressor) {
submodules_.noise_suppressor->Analyze(*capture_buffer);
}
// 13. 执行回声消除 (AEC)
if (submodules_.echo_control_mobile) {
// --- AECM (移动版回声消除) 路径 ---
if (!capture_.was_stream_delay_set) {
return AudioProcessing::kStreamParameterNotSetError;
}
// AECM 通常与 NS 紧密耦合,先处理 NS
if (submodules_.noise_suppressor) {
submodules_.noise_suppressor->Process(capture_buffer);
}
// 执行 AECM 处理
RETURN_ON_ERR(submodules_.echo_control_mobile->ProcessCaptureAudio(
capture_buffer, stream_delay_ms()));
} else {
// --- AEC3 (桌面版/高性能回声消除) 路径 ---
if (submodules_.echo_controller) {
data_dumper_->DumpRaw("stream_delay", stream_delay_ms());
// 设置音频缓冲延迟,帮助 AEC3 对齐回声参考信号
if (capture_.was_stream_delay_set) {
submodules_.echo_controller->SetAudioBufferDelay(stream_delay_ms());
}
// 执行 AEC3 处理,输出线性回声消除后的信号到 linear_aec_buffer
submodules_.echo_controller->ProcessCapture(
capture_buffer, linear_aec_buffer, capture_.echo_path_gain_change);
}
// 如果配置允许,噪声抑制可以分析经过线性回声消除后的信号(更干净)
if (config_.noise_suppression.analyze_linear_aec_output_when_available &&
linear_aec_buffer && submodules_.noise_suppressor) {
submodules_.noise_suppressor->Analyze(*linear_aec_buffer);
}
// 执行噪声抑制处理
if (submodules_.noise_suppressor) {
submodules_.noise_suppressor->Process(capture_buffer);
}
}
// 14. 语音活动检测 (VAD)
if (config_.voice_detection.enabled) {
capture_.stats.voice_detected =
submodules_.voice_detector->ProcessCaptureAudio(capture_buffer);
} else {
capture_.stats.voice_detected = absl::nullopt;
}
// 15. AGC1 处理与应用增益
if (submodules_.agc_manager) {
submodules_.agc_manager->Process(capture_buffer);
// 获取计算出的数字压缩增益,并应用到 GainControl 模块
absl::optional<int> new_digital_gain =
submodules_.agc_manager->GetDigitalComressionGain();
if (new_digital_gain && submodules_.gain_control) {
submodules_.gain_control->set_compression_gain_db(*new_digital_gain);
}
}
// 16. AGC1 最终处理(限幅器等)
if (submodules_.gain_control) {
RETURN_ON_ERR(submodules_.gain_control->ProcessCaptureAudio(
capture_buffer, /*stream_has_echo*/ false));
}
// --- 第四阶段:后处理与合并 (Post-processing & Merging) ---
// 17. 合并频带 (Merge Frequency Bands)
// 将处理后的子带信号重新合成为全频带时域信号
if (submodule_states_.CaptureMultiBandProcessingPresent() &&
SampleRateSupportsMultiBand(
capture_nonlocked_.capture_processing_format.sample_rate_hz())) {
capture_buffer->MergeFrequencyBands();
}
// 18. 全频带缓冲区同步
// 如果存在独立的全频带缓冲区(用于某些全频带算法),且多频带处理改变了信号,
// 则将结果拷贝过去,并切换当前工作指针到全频带缓冲区
if (capture_.capture_fullband_audio) {
const auto& ec = submodules_.echo_controller;
bool ec_active = ec ? ec->ActiveProcessing() : false;
if (submodule_states_.CaptureMultiBandProcessingActive(ec_active)) {
capture_buffer->CopyTo(capture_.capture_fullband_audio.get());
}
capture_buffer = capture_.capture_fullband_audio.get();
}
// 19. 残留回声检测器 (Residual Echo Detector) 分析
if (config_.residual_echo_detector.enabled) {
RTC_DCHECK(submodules_.echo_detector);
submodules_.echo_detector->AnalyzeCaptureAudio(rtc::ArrayView<const float>(
capture_buffer->channels()[0], capture_buffer->num_frames()));
}
// 20. 瞬态抑制 (Transient Suppression)
// 抑制键盘敲击声等非平稳噪声
if (submodules_.transient_suppressor) {
float voice_probability = submodules_.agc_manager.get()
? submodules_.agc_manager->voice_probability()
: 1.f;
submodules_.transient_suppressor->Suppress(
capture_buffer->channels()[0], capture_buffer->num_frames(),
capture_buffer->num_channels(),
capture_buffer->split_bands_const(0)[kBand0To8kHz],
capture_buffer->num_frames_per_band(),
capture_.keyboard_info.keyboard_data,
capture_.keyboard_info.num_keyboard_frames, voice_probability,
capture_.key_pressed);
}
// 21. 自定义捕获分析器 (Experimental)
if (submodules_.capture_analyzer) {
submodules_.capture_analyzer->Analyze(capture_buffer);
}
// 22. AGC2 (新版自动增益控制) 处理
if (submodules_.gain_controller2) {
submodules_.gain_controller2->NotifyAnalogLevel(
recommended_stream_analog_level_locked());
submodules_.gain_controller2->Process(capture_buffer);
}
// 23. 自定义后置处理器 (Custom Post-processor)
if (submodules_.capture_post_processor) {
submodules_.capture_post_processor->Process(capture_buffer);
}
// --- 第五阶段:统计与指标上报 (Statistics & Metrics) ---
// 24. 输出电平估计
if (config_.level_estimation.enabled) {
submodules_.output_level_estimator->ProcessStream(*capture_buffer);
capture_.stats.output_rms_dbfs = submodules_.output_level_estimator->RMS();
} else {
capture_.stats.output_rms_dbfs = absl::nullopt;
}
// 25. 分析输出信号 RMS 电平并记录直方图
capture_output_rms_.Analyze(rtc::ArrayView<const float>(
capture_buffer->channels_const()[0],
capture_nonlocked_.capture_processing_format.num_frames()));
if (log_rms) {
RmsLevel::Levels levels = capture_output_rms_.AverageAndPeak();
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureOutputLevelAverageRms",
levels.average, 1, RmsLevel::kMinLevelDb, 64);
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureOutputLevelPeakRms",
levels.peak, 1, RmsLevel::kMinLevelDb, 64);
}
// 26. 记录 AGC 模拟电平用于调试
if (submodules_.agc_manager) {
int level = recommended_stream_analog_level_locked();
data_dumper_->DumpRaw("experimental_gain_control_stream_analog_level", 1,
&level);
}
// 27. 收集回声相关指标 (AEC Metrics)
if (submodules_.echo_controller) {
auto ec_metrics = submodules_.echo_controller->GetMetrics();
capture_.stats.echo_return_loss = ec_metrics.echo_return_loss;
capture_.stats.echo_return_loss_enhancement =
ec_metrics.echo_return_loss_enhancement;
capture_.stats.delay_ms = ec_metrics.delay_ms;
}
// 28. 收集残留回声指标
if (config_.residual_echo_detector.enabled) {
RTC_DCHECK(submodules_.echo_detector);
auto ed_metrics = submodules_.echo_detector->GetMetrics();
capture_.stats.residual_echo_likelihood = ed_metrics.echo_likelihood;
capture_.stats.residual_echo_likelihood_recent_max =
ed_metrics.echo_likelihood_recent_max;
}
// 29. 更新并上报统计数据
stats_reporter_.UpdateStatistics(capture_.stats);
// 重置流延迟标记,等待下一帧的设置
capture_.was_stream_delay_set = false;
return kNoError;
}
二,audio_processing 模块调用
引用audio_processing.lib 和 audio_processing.h 文件
获取 webrtc::AudioProcessing 对象, 然后可以调用ProcessStream 进行音频增益处理
cpp
//使用默认配置
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing = AudioProcessingBuilder().Create();
或者
//自定义配置,定义是否使用3A等相关音频增益算法
webrtc::Config config;
config.PreAmplifier.enable = true/false;
config.HighPassFilter.enable = true/false;
其它配置......
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing = AudioProcessingBuilder().Create(config);
webrtc中的具体调用为:
cpp
void ProcessCaptureFrame(uint32_t delay_ms,
bool key_pressed,
bool swap_stereo_channels,
AudioProcessing* audio_processing,
AudioFrame* audio_frame) {
RTC_DCHECK(audio_frame);
if (audio_processing) {
audio_processing->set_stream_delay_ms(delay_ms);
audio_processing->set_stream_key_pressed(key_pressed);
int error = ProcessAudioFrame(audio_processing, audio_frame);
RTC_DCHECK_EQ(0, error) << "ProcessStream() error: " << error;
}
if (swap_stereo_channels) {
AudioFrameOperations::SwapStereoChannels(audio_frame);
}
}