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
// controller.
const AudioProcessing::Config AdjustConfig(
// If `disallow_transient_supporessor_usage` is true, disables transient
// suppression. When `input_volume_controller_config_override` is specified,
// switches all gain control to AGC2.
AudioProcessing::Config AdjustConfig(
const AudioProcessing::Config& config,
bool disallow_transient_supporessor_usage,
const absl::optional<InputVolumeController::Config>&
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.mode ==
AudioProcessing::Config::GainController1::kAdaptiveAnalog ||
config.gain_controller1.analog_gain_controller.enabled);
// Do not update the config if none of the analog AGCs is active
// regardless of the input volume controller override.
if (!analog_agc_enabled ||
!input_volume_controller_config_override.has_value()) {
return config;
}
if (agc1_analog_enabled &&
input_volume_controller_config_override.has_value()) {
// Check that the unadjusted AGC config meets the preconditions.
const bool hybrid_agc_config_detected =
config.gain_controller1.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.adaptive_digital.enabled;
const bool full_agc1_config_detected =
config.gain_controller1.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;
if (hybrid_agc_config_detected == full_agc1_config_detected ||
const bool one_and_only_one_input_volume_controller =
hybrid_agc_config_detected != full_agc1_config_detected;
if (!one_and_only_one_input_volume_controller ||
config.gain_controller2.input_volume_controller.enabled) {
RTC_LOG(LS_ERROR) << "Unexpected AGC config: Config not adjusted.";
return config;
}
AudioProcessing::Config adjusted_config = config;
RTC_LOG(LS_ERROR) << "Cannot adjust AGC config (precondition failed)";
if (!one_and_only_one_input_volume_controller)
RTC_LOG(LS_ERROR)
<< "One and only one input volume controller must be enabled.";
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.analog_gain_controller.enabled = false;
adjusted_config.gain_controller2.enabled = true;
adjusted_config.gain_controller2.adaptive_digital.enabled = true;
adjusted_config.gain_controller2.input_volume_controller.enabled = true;
}
}
return adjusted_config;
}
@ -583,13 +597,17 @@ AudioProcessingImpl::AudioProcessingImpl(
GetInputVolumeControllerConfigOverride()),
use_denormal_disabler_(
!field_trial::IsEnabled("WebRTC-ApmDenormalDisablerKillSwitch")),
disallow_transient_supporessor_usage_(
field_trial::IsEnabled("WebRTC-ApmTransientSuppressorKillSwitch")),
transient_suppressor_vad_mode_(GetTransientSuppressorVadMode()),
capture_runtime_settings_(RuntimeSettingQueueSize()),
render_runtime_settings_(RuntimeSettingQueueSize()),
capture_runtime_settings_enqueuer_(&capture_runtime_settings_),
render_runtime_settings_enqueuer_(&render_runtime_settings_),
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,
!!render_pre_processor,
!!capture_analyzer),
@ -824,11 +842,9 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
MutexLock lock_render(&mutex_render_);
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 =
AdjustConfig(config, input_volume_controller_config_override_);
AdjustConfig(config, disallow_transient_supporessor_usage_,
input_volume_controller_config_override_);
RTC_LOG(LS_INFO) << "AudioProcessing::ApplyConfig: "
<< adjusted_config.ToString();

View File

@ -191,14 +191,19 @@ class AudioProcessingImpl : public AudioProcessing {
static std::atomic<int> instance_count_;
const bool use_setup_specific_default_aec3_config_;
// TODO(bugs.webrtc.org/7494): Remove the the config when the field trial is
// removed. "WebRTC-Audio-InputVolumeControllerExperiment" field trial
// override for the input volume controller config.
// TODO(bugs.webrtc.org/7494): Remove when the linked field trial is removed.
// Override base on the "WebRTC-Audio-InputVolumeControllerExperiment" field
// trial for the AGC2 input volume controller configuration.
const absl::optional<InputVolumeController::Config>
input_volume_controller_config_override_;
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_;
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.
TEST_P(InputVolumeStartupParameterizedTest,
VerifyStartupMinVolumeAppliedAtStartup) {