webrtc 的audio process介绍(新版本webrtc)

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 函数为音频数据处理的核心函数,

按顺序调用的主要模块算法有:(部分算法根据配置文件确认是否执行)

  1. 高通滤波 (HPF)

  2. 前置放大器 (Pre-amplifier)

  3. 回声控制 (AEC/AEC3) - 分析捕获信号

  4. 自动增益控制 (AGC/AGC2) - 分析

  5. 分频带处理 (Split into frequency bands)

  6. 噪声抑制 (NS)

  7. 回声消除处理 (Process Capture)

  8. 瞬态抑制 (Transient Suppression)

  9. 增益应用 (Gain Application)

  10. 合并频带 (Merge frequency bands)

  11. 后置处理 (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);
  }
}
相关推荐
EasyDSS1 小时前
讲座视频资源散存易丢失?视频直播点播EasyDSS校园/视频融媒体平台高效管理视频
音视频·媒体·easydss
2601_965619694 小时前
AI视频制作:做历史战争视频,兵力部署的老地图难找,AI怎么自动配战争地图?
人工智能·音视频
2601_965449086 小时前
AI视频制作:做系列考古视频音色不统一,AI 音色克隆的完整流程
人工智能·机器学习·音视频
2601_965449087 小时前
AI视频制作:做系列历史地图视频想固定音色,AI 音色克隆的流程实测
人工智能·音视频
智塑未来9 小时前
AI视频翻译配音工具怎么选?5款工具的链路覆盖对比
人工智能·音视频
做萤石二次开发的哈哈11 小时前
商场分区广播怎么开发?商用音频主机四大技能与音频文件管理实践
音视频·蓝海aiot一站式工作台·公共广播·智慧广播·萤石云开放平台·商用音频主机·矩阵路由
音视频牛哥12 小时前
大牛直播SDK(SmartMediaKit)iOS平台Unity3D RTSP/RTMP播放器集成实践
音视频·unity3d·ios rtmp播放器·ios rtsp播放器·ios unity3d播放器·ios unity rtsp·ios unity rtmp
美狐美颜SDK开放平台12 小时前
视频美颜SDK如何应对快速转头与大幅度面部动作?
android·人工智能·ios·音视频·直播美颜sdk·视频美颜sdk
甜到心里的蛋糕14 小时前
AI 生成 MV 音频异响排查:频谱定位、片段替换与 Nginx 缓存
人工智能·python·nginx·ffmpeg·音视频·音频处理
镭封1 天前
从视频文案提取到 AI 配音,短视频制作需要哪些工具?
人工智能·智能手机·音视频·语音识别·媒体