01、回音降噪 echo_cancellation
02、自动增益控制 auto_gain_control
03、噪声抑制 noise_suppression
04、 高通滤波器 highpass_filter
05、立体声交换 stereo_swapping
06、NetEq容量 audio_jitter_buffer_max_packets
07、NetEq快速模式 audio_jitter_buffer_fast_accelerate
08、jitter buffer最小延迟 audio_jitter_buffer_min_delay_ms
09、itter buffer是否适应延迟重传 audio_jitter_buffer_enable_rtx_handling
10、键盘检测 typing_detection
11、残留回声检测 residual_echo_detector
12、音频网络适配器 audio_network_adaptor_config
// 设置音频参数
bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::ApplyOptions: "
<< options_in.ToString();
AudioOptions options = options_in; // 选项在下面进行了修改
// 设置和调整回声消除器选项。不使用硬件 AEC 时,默认使用桌面 AEC。
bool use_mobile_software_aec = false;
#if defined(WEBRTC_IOS)
if (options.ios_force_software_aec_HACK &&
*options.ios_force_software_aec_HACK) {
// 在ios上强制软件回声消除
options.echo_cancellation = true;
RTC_LOG(LS_WARNING)
<< "Force software AEC on iOS. May conflict with platform AEC.";
} else {
// 默认使用VPIO内置的回声消除
options.echo_cancellation = false;
RTC_LOG(LS_INFO) << "Always disable AEC on iOS. Use built-in instead.";
}
#elif defined(WEBRTC_ANDROID)
use_mobile_software_aec = true;
#endif
// Android 的噪声抑制选项
#if defined(WEBRTC_ANDROID)
options.typing_detection = false;
options.experimental_ns = false;
#endif
// 设置和调整增益控制选项.
#if defined(WEBRTC_IOS)
// iOS平台使用VIPIO内置的降噪。
options.auto_gain_control = false;
options.experimental_agc = false;
RTC_LOG(LS_INFO) << "Always disable AGC on iOS. Use built-in instead.";
#elif defined(WEBRTC_ANDROID)
// Android平台关闭试验性AGC.
options.experimental_agc = false;
#endif
#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
// 移动端(ios android)
// 如果设置了"WebRTC-Audio-MinimizeResamplingOnMobile"则关闭AGC。
// 然后如果开启降噪且未开启回声消除则关闭高通滤波器。。
// (https://bugs.chromium.org/p/webrtc/issues/detail?id=6181).
if (minimized_remsampling_on_mobile_trial_enabled_) {
options.auto_gain_control = false;
RTC_LOG(LS_INFO) << "Disable AGC according to field trial.";
if (!(options.noise_suppression.value_or(false) ||
options.echo_cancellation.value_or(false))) {
// If possible, turn off the high-pass filter.
RTC_LOG(LS_INFO)
<< "Disable high-pass filter in response to field trial.";
options.highpass_filter = false;
}
}
#endif
if (options.echo_cancellation) {
// 目前只有android支持内置aec
// 如果支持内置aec而且开启回声消除echo_cancellation和未开启use_delay_agnostic_aec
// 且内置EnableBuiltInAEC时关闭软件回声消除从而使用平台内置回声消除。
const bool built_in_aec = adm()->BuiltInAECIsAvailable();
// 除了Android平台为true,其他平台默认为false
if (built_in_aec) {
// 此设备上存在内置 EC。 根据 echo_cancellation 音频选项启用/禁用它
const bool enable_built_in_aec = *options.echo_cancellation;
if (adm()->EnableBuiltInAEC(enable_built_in_aec) == 0 &&
enable_built_in_aec) {
// 如果启用内置 EC,则禁用内部软件 EC,即将软件 EC 替换为内置 EC
options.echo_cancellation = false;
RTC_LOG(LS_INFO)
<< "Disabling EC since built-in EC will be used instead";
}
}
}
// 判断是否支持平台内置agc,如果支持则关闭软件agc
if (options.auto_gain_control) {
bool built_in_agc_avaliable = adm()->BuiltInAGCIsAvailable();
if (built_in_agc_avaliable) {
if (adm()->EnableBuiltInAGC(*options.auto_gain_control) == 0 &&
*options.auto_gain_control) {
// 如果启用了内置 AGC,则禁用内部软件 AGC,即将软件 AGC 替换为内置 AGC
options.auto_gain_control = false;
RTC_LOG(LS_INFO)
<< "Disabling AGC since built-in AGC will be used instead";
}
}
}
// 如果支持平台内置降噪则关闭软件降噪
if (options.noise_suppression) {
if (adm()->BuiltInNSIsAvailable()) {
bool builtin_ns = *options.noise_suppression;
if (adm()->EnableBuiltInNS(builtin_ns) == 0 && builtin_ns) {
// 如果启用了内置 NS,则禁用内部软件 NS
// 即用内置 NS 替换软件 NS
options.noise_suppression = false;
RTC_LOG(LS_INFO)
<< "Disabling NS since built-in NS will be used instead";
}
}
}
// 立体声通道交换
if (options.stereo_swapping) {
RTC_LOG(LS_INFO) << "Stereo swapping enabled? " << *options.stereo_swapping;
audio_state()->SetStereoChannelSwapping(*options.stereo_swapping);
}
// jitter buffer最大包数设置
if (options.audio_jitter_buffer_max_packets) {
RTC_LOG(LS_INFO) << "NetEq capacity is "
<< *options.audio_jitter_buffer_max_packets;
audio_jitter_buffer_max_packets_ =
std::max(20, *options.audio_jitter_buffer_max_packets);
}
// jitter buffer加速设置
if (options.audio_jitter_buffer_fast_accelerate) {
RTC_LOG(LS_INFO) << "NetEq fast mode? "
<< *options.audio_jitter_buffer_fast_accelerate;
audio_jitter_buffer_fast_accelerate_ =
*options.audio_jitter_buffer_fast_accelerate;
}
// jitter buffer最小延迟(毫秒)
if (options.audio_jitter_buffer_min_delay_ms) {
RTC_LOG(LS_INFO) << "NetEq minimum delay is "
<< *options.audio_jitter_buffer_min_delay_ms;
audio_jitter_buffer_min_delay_ms_ =
*options.audio_jitter_buffer_min_delay_ms;
}
if (options.audio_jitter_buffer_enable_rtx_handling) {
RTC_LOG(LS_INFO) << "NetEq handle reordered packets? "
<< *options.audio_jitter_buffer_enable_rtx_handling;
audio_jitter_buffer_enable_rtx_handling_ =
*options.audio_jitter_buffer_enable_rtx_handling;
}
webrtc::AudioProcessing* ap = apm();
if (!ap) {
RTC_LOG(LS_INFO)
<< "No audio processing module present. No software-provided effects "
"(AEC, NS, AGC, ...) are activated";
return true;
}
if (options.experimental_ns) {
experimental_ns_ = options.experimental_ns;
}
webrtc::AudioProcessing::Config apm_config = ap->GetConfig();
#if !(defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS))
if (experimental_ns_.has_value()) {
apm_config.transient_suppression.enabled = experimental_ns_.value();
}
#endif
if (options.echo_cancellation) {
apm_config.echo_canceller.enabled = *options.echo_cancellation;
apm_config.echo_canceller.mobile_mode = use_mobile_software_aec;
}
if (options.auto_gain_control) {
const bool enabled = *options.auto_gain_control;
apm_config.gain_controller1.enabled = enabled;
#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
apm_config.gain_controller1.mode =
apm_config.gain_controller1.kFixedDigital;
#else
apm_config.gain_controller1.mode =
apm_config.gain_controller1.kAdaptiveAnalog;
#endif
}
if (options.tx_agc_target_dbov) {
apm_config.gain_controller1.target_level_dbfs = *options.tx_agc_target_dbov;
}
if (options.tx_agc_digital_compression_gain) {
apm_config.gain_controller1.compression_gain_db =
*options.tx_agc_digital_compression_gain;
}
if (options.tx_agc_limiter) {
apm_config.gain_controller1.enable_limiter = *options.tx_agc_limiter;
}
if (options.highpass_filter) {
apm_config.high_pass_filter.enabled = *options.highpass_filter;
}
// 残留回声检测
if (options.residual_echo_detector) {
apm_config.residual_echo_detector.enabled = *options.residual_echo_detector;
}
if (options.noise_suppression) {
const bool enabled = *options.noise_suppression;
apm_config.noise_suppression.enabled = enabled;
apm_config.noise_suppression.level =
webrtc::AudioProcessing::Config::NoiseSuppression::Level::kHigh;
RTC_LOG(LS_INFO) << "NS set to " << enabled;
}
// 键盘声音检测
if (options.typing_detection) {
RTC_LOG(LS_INFO) << "Typing detection is enabled? "
<< *options.typing_detection;
apm_config.voice_detection.enabled = *options.typing_detection;
}
ap->ApplyConfig(apm_config);
return true;
}