APM: add field trial to disable TransientSuppressor

Regardless of the APM config, the transient suppressor (TS) submodule
won't be created if the `WebRTC-ApmTransientSuppressorKillSwitch`
field trial, disabled by default, is enabled.

Bug: webrtc:13663
Change-Id: Ic1ef9aa57c728296d671d4ef253630c581a86610
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/286382
Reviewed-by: Hanna Silen <silen@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38839}
This commit is contained in:
Alessio Bazzica 2022-12-07 16:13:35 +01:00 committed by WebRTC LUCI CQ
parent a8c300e36f
commit 352f38c7a8
3 changed files with 114 additions and 44 deletions

View File

@ -394,50 +394,64 @@ GetInputVolumeControllerConfigOverride() {
}; };
} }
// Switches all gain control to AGC2 if experimenting with input volume // If `disallow_transient_supporessor_usage` is true, disables transient
// controller. // suppression. When `input_volume_controller_config_override` is specified,
const AudioProcessing::Config AdjustConfig( // switches all gain control to AGC2.
AudioProcessing::Config AdjustConfig(
const AudioProcessing::Config& config, const AudioProcessing::Config& config,
bool disallow_transient_supporessor_usage,
const absl::optional<InputVolumeController::Config>& const absl::optional<InputVolumeController::Config>&
input_volume_controller_config_override) { input_volume_controller_config_override) {
const bool analog_agc_enabled = AudioProcessing::Config adjusted_config = config;
// Override the transient suppressor configuration.
if (disallow_transient_supporessor_usage) {
adjusted_config.transient_suppression.enabled = false;
}
// Override the auto gain control configuration if the AGC1 analog gain
// controller is active and `input_volume_controller_config_override` is
// specified.
const bool agc1_analog_enabled =
config.gain_controller1.enabled && config.gain_controller1.enabled &&
(config.gain_controller1.mode == (config.gain_controller1.mode ==
AudioProcessing::Config::GainController1::kAdaptiveAnalog || AudioProcessing::Config::GainController1::kAdaptiveAnalog ||
config.gain_controller1.analog_gain_controller.enabled); config.gain_controller1.analog_gain_controller.enabled);
if (agc1_analog_enabled &&
// Do not update the config if none of the analog AGCs is active input_volume_controller_config_override.has_value()) {
// regardless of the input volume controller override. // Check that the unadjusted AGC config meets the preconditions.
if (!analog_agc_enabled ||
!input_volume_controller_config_override.has_value()) {
return config;
}
const bool hybrid_agc_config_detected = const bool hybrid_agc_config_detected =
config.gain_controller1.enabled && config.gain_controller1.enabled &&
config.gain_controller1.analog_gain_controller.enabled && config.gain_controller1.analog_gain_controller.enabled &&
!config.gain_controller1.analog_gain_controller.enable_digital_adaptive && !config.gain_controller1.analog_gain_controller
.enable_digital_adaptive &&
config.gain_controller2.enabled && config.gain_controller2.enabled &&
config.gain_controller2.adaptive_digital.enabled; config.gain_controller2.adaptive_digital.enabled;
const bool full_agc1_config_detected = const bool full_agc1_config_detected =
config.gain_controller1.enabled && config.gain_controller1.enabled &&
config.gain_controller1.analog_gain_controller.enabled && config.gain_controller1.analog_gain_controller.enabled &&
config.gain_controller1.analog_gain_controller.enable_digital_adaptive && config.gain_controller1.analog_gain_controller
.enable_digital_adaptive &&
!config.gain_controller2.enabled; !config.gain_controller2.enabled;
const bool one_and_only_one_input_volume_controller =
if (hybrid_agc_config_detected == full_agc1_config_detected || hybrid_agc_config_detected != full_agc1_config_detected;
if (!one_and_only_one_input_volume_controller ||
config.gain_controller2.input_volume_controller.enabled) { config.gain_controller2.input_volume_controller.enabled) {
RTC_LOG(LS_ERROR) << "Unexpected AGC config: Config not adjusted."; RTC_LOG(LS_ERROR) << "Cannot adjust AGC config (precondition failed)";
return config; if (!one_and_only_one_input_volume_controller)
} RTC_LOG(LS_ERROR)
<< "One and only one input volume controller must be enabled.";
AudioProcessing::Config adjusted_config = config; if (config.gain_controller2.input_volume_controller.enabled)
RTC_LOG(LS_ERROR)
<< "The AGC2 input volume controller must be disabled.";
} else {
adjusted_config.gain_controller1.enabled = false; adjusted_config.gain_controller1.enabled = false;
adjusted_config.gain_controller1.analog_gain_controller.enabled = false; adjusted_config.gain_controller1.analog_gain_controller.enabled = false;
adjusted_config.gain_controller2.enabled = true; adjusted_config.gain_controller2.enabled = true;
adjusted_config.gain_controller2.adaptive_digital.enabled = true; adjusted_config.gain_controller2.adaptive_digital.enabled = true;
adjusted_config.gain_controller2.input_volume_controller.enabled = true; adjusted_config.gain_controller2.input_volume_controller.enabled = true;
}
}
return adjusted_config; return adjusted_config;
} }
@ -583,13 +597,17 @@ AudioProcessingImpl::AudioProcessingImpl(
GetInputVolumeControllerConfigOverride()), GetInputVolumeControllerConfigOverride()),
use_denormal_disabler_( use_denormal_disabler_(
!field_trial::IsEnabled("WebRTC-ApmDenormalDisablerKillSwitch")), !field_trial::IsEnabled("WebRTC-ApmDenormalDisablerKillSwitch")),
disallow_transient_supporessor_usage_(
field_trial::IsEnabled("WebRTC-ApmTransientSuppressorKillSwitch")),
transient_suppressor_vad_mode_(GetTransientSuppressorVadMode()), transient_suppressor_vad_mode_(GetTransientSuppressorVadMode()),
capture_runtime_settings_(RuntimeSettingQueueSize()), capture_runtime_settings_(RuntimeSettingQueueSize()),
render_runtime_settings_(RuntimeSettingQueueSize()), render_runtime_settings_(RuntimeSettingQueueSize()),
capture_runtime_settings_enqueuer_(&capture_runtime_settings_), capture_runtime_settings_enqueuer_(&capture_runtime_settings_),
render_runtime_settings_enqueuer_(&render_runtime_settings_), render_runtime_settings_enqueuer_(&render_runtime_settings_),
echo_control_factory_(std::move(echo_control_factory)), echo_control_factory_(std::move(echo_control_factory)),
config_(AdjustConfig(config, input_volume_controller_config_override_)), config_(AdjustConfig(config,
disallow_transient_supporessor_usage_,
input_volume_controller_config_override_)),
submodule_states_(!!capture_post_processor, submodule_states_(!!capture_post_processor,
!!render_pre_processor, !!render_pre_processor,
!!capture_analyzer), !!capture_analyzer),
@ -824,11 +842,9 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
MutexLock lock_render(&mutex_render_); MutexLock lock_render(&mutex_render_);
MutexLock lock_capture(&mutex_capture_); MutexLock lock_capture(&mutex_capture_);
// TODO(bugs.webrtc.org/7494): Replace `adjusted_config` with `config` after
// "WebRTC-Audio-InputVolumeControllerExperiment" field trial is removed.
const auto adjusted_config = const auto adjusted_config =
AdjustConfig(config, input_volume_controller_config_override_); AdjustConfig(config, disallow_transient_supporessor_usage_,
input_volume_controller_config_override_);
RTC_LOG(LS_INFO) << "AudioProcessing::ApplyConfig: " RTC_LOG(LS_INFO) << "AudioProcessing::ApplyConfig: "
<< adjusted_config.ToString(); << adjusted_config.ToString();

View File

@ -191,14 +191,19 @@ class AudioProcessingImpl : public AudioProcessing {
static std::atomic<int> instance_count_; static std::atomic<int> instance_count_;
const bool use_setup_specific_default_aec3_config_; const bool use_setup_specific_default_aec3_config_;
// TODO(bugs.webrtc.org/7494): Remove the the config when the field trial is // TODO(bugs.webrtc.org/7494): Remove when the linked field trial is removed.
// removed. "WebRTC-Audio-InputVolumeControllerExperiment" field trial // Override base on the "WebRTC-Audio-InputVolumeControllerExperiment" field
// override for the input volume controller config. // trial for the AGC2 input volume controller configuration.
const absl::optional<InputVolumeController::Config> const absl::optional<InputVolumeController::Config>
input_volume_controller_config_override_; input_volume_controller_config_override_;
const bool use_denormal_disabler_; const bool use_denormal_disabler_;
// When true, the transient suppressor submodule is never created regardless
// of the APM configuration.
// TODO(bugs.webrtc.org/13663): Remove when the linked field trial is removed.
const bool disallow_transient_supporessor_usage_;
const TransientSuppressor::VadMode transient_suppressor_vad_mode_; const TransientSuppressor::VadMode transient_suppressor_vad_mode_;
SwapQueue<RuntimeSetting> capture_runtime_settings_; SwapQueue<RuntimeSetting> capture_runtime_settings_;

View File

@ -960,6 +960,55 @@ TEST(ApmWithSubmodulesExcludedTest, ToggleTransientSuppressor) {
} }
} }
TEST(AudioProcessingImplTest, CanDisableTransientSuppressor) {
// Do not explicitly disable "WebRTC-ApmTransientSuppressorKillSwitch" since
// to check that, by default, it is disabled.
auto apm = AudioProcessingBuilder()
.SetConfig({.transient_suppression = {.enabled = false}})
.Create();
EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
}
TEST(AudioProcessingImplTest, CanEnableTransientSuppressor) {
// Do not explicitly disable "WebRTC-ApmTransientSuppressorKillSwitch" since
// to check that, by default, it is disabled.
auto apm = AudioProcessingBuilder()
.SetConfig({.transient_suppression = {.enabled = true}})
.Create();
EXPECT_TRUE(apm->GetConfig().transient_suppression.enabled);
}
TEST(AudioProcessingImplTest, CanDisableTransientSuppressorIfUsageAllowed) {
// Disable the field trial that disallows to enable transient suppression.
test::ScopedFieldTrials field_trials(
"WebRTC-ApmTransientSuppressorKillSwitch/Disabled/");
auto apm = AudioProcessingBuilder()
.SetConfig({.transient_suppression = {.enabled = false}})
.Create();
EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
}
TEST(AudioProcessingImplTest, CanEnableTransientSuppressorIfUsageAllowed) {
// Disable the field trial that disallows to enable transient suppression.
test::ScopedFieldTrials field_trials(
"WebRTC-ApmTransientSuppressorKillSwitch/Disabled/");
auto apm = AudioProcessingBuilder()
.SetConfig({.transient_suppression = {.enabled = true}})
.Create();
EXPECT_TRUE(apm->GetConfig().transient_suppression.enabled);
}
TEST(AudioProcessingImplTest,
CannotEnableTransientSuppressorIfUsageDisallowed) {
// Enable the field trial that disallows to enable transient suppression.
test::ScopedFieldTrials field_trials(
"WebRTC-ApmTransientSuppressorKillSwitch/Enabled/");
auto apm = AudioProcessingBuilder()
.SetConfig({.transient_suppression = {.enabled = true}})
.Create();
EXPECT_FALSE(apm->GetConfig().transient_suppression.enabled);
}
// Tests that the minimum startup volume is applied at the startup. // Tests that the minimum startup volume is applied at the startup.
TEST_P(InputVolumeStartupParameterizedTest, TEST_P(InputVolumeStartupParameterizedTest,
VerifyStartupMinVolumeAppliedAtStartup) { VerifyStartupMinVolumeAppliedAtStartup) {