Commit bdf52e4e authored by Alessio Bazzica's avatar Alessio Bazzica Committed by Commit Bot

WebRTC AGC Hybrid experiment: wire-up AGC2 params (+ refactoring)

ConfigAutomaticGainControl now supports more AGC2 params that are
needed for experimentation.

The CL includes a refactoring to avoid base::Optional boilerplate and
it improves the docstring for `ConfigAutomaticGainControl()`.

Tested: checked feature activation via AECdump using appr.tc
$ out/Default/Chromium.app/Contents/MacOS/Chromium \
  --enable-features=WebrtcHybridAgc

Bug: webrtc:7494
Change-Id: I0d226b9e7e6f17acb8408af8ded80d80db7cabe0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2446149
Commit-Queue: Ale Bzk <alessiob@chromium.org>
Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813736}
parent 398971c0
......@@ -581,24 +581,37 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
if (properties.goog_auto_gain_control ||
properties.goog_experimental_auto_gain_control) {
bool use_hybrid_agc = false;
base::Optional<bool> use_peaks_not_rms;
base::Optional<int> saturation_margin;
if (properties.goog_experimental_auto_gain_control) {
use_hybrid_agc = base::FeatureList::IsEnabled(features::kWebRtcHybridAgc);
if (use_hybrid_agc) {
DCHECK(properties.goog_auto_gain_control)
<< "Cannot enable hybrid AGC when AGC is disabled.";
}
use_peaks_not_rms = base::GetFieldTrialParamByFeatureAsBool(
features::kWebRtcHybridAgc, "use_peaks_not_rms", false);
saturation_margin = base::GetFieldTrialParamByFeatureAsInt(
features::kWebRtcHybridAgc, "saturation_margin", -1);
base::Optional<blink::AdaptiveGainController2Properties> agc2_properties;
if (properties.goog_experimental_auto_gain_control &&
base::FeatureList::IsEnabled(features::kWebRtcHybridAgc)) {
DCHECK(properties.goog_auto_gain_control)
<< "Cannot enable hybrid AGC when AGC is disabled.";
agc2_properties = blink::AdaptiveGainController2Properties{};
agc2_properties->vad_probability_attack =
base::GetFieldTrialParamByFeatureAsDouble(
features::kWebRtcHybridAgc, "vad_probability_attack", 1.0);
agc2_properties->use_peaks_not_rms =
base::GetFieldTrialParamByFeatureAsBool(features::kWebRtcHybridAgc,
"use_peaks_not_rms", false);
agc2_properties->level_estimator_speech_frames_threshold =
base::GetFieldTrialParamByFeatureAsInt(
features::kWebRtcHybridAgc,
"level_estimator_speech_frames_threshold", 1);
agc2_properties->initial_saturation_margin_db =
base::GetFieldTrialParamByFeatureAsInt(
features::kWebRtcHybridAgc, "initial_saturation_margin", 20);
agc2_properties->extra_saturation_margin_db =
base::GetFieldTrialParamByFeatureAsInt(features::kWebRtcHybridAgc,
"extra_saturation_margin", 5);
agc2_properties->gain_applier_speech_frames_threshold =
base::GetFieldTrialParamByFeatureAsInt(
features::kWebRtcHybridAgc,
"gain_applier_speech_frames_threshold", 1);
}
blink::ConfigAutomaticGainControl(
&apm_config, properties.goog_auto_gain_control,
properties.goog_experimental_auto_gain_control, use_hybrid_agc,
use_peaks_not_rms, saturation_margin, gain_control_compression_gain_db);
properties.goog_auto_gain_control,
properties.goog_experimental_auto_gain_control, agc2_properties,
gain_control_compression_gain_db, apm_config);
}
if (goog_typing_detection) {
......
......@@ -185,23 +185,22 @@ void StopEchoCancellationDump(AudioProcessing* audio_processing) {
}
void ConfigAutomaticGainControl(
AudioProcessing::Config* apm_config,
bool agc_enabled,
bool experimental_agc_enabled,
bool use_hybrid_agc,
base::Optional<bool> hybrid_agc_use_peaks_not_rms,
base::Optional<int> hybrid_agc_saturation_margin,
base::Optional<double> compression_gain_db) {
base::Optional<AdaptiveGainController2Properties> agc2_properties,
base::Optional<double> compression_gain_db,
AudioProcessing::Config& apm_config) {
const bool use_fixed_digital_agc2 = agc_enabled &&
!experimental_agc_enabled &&
compression_gain_db.has_value();
const bool use_hybrid_agc = agc2_properties.has_value();
const bool agc1_enabled =
agc_enabled && (use_hybrid_agc || !use_fixed_digital_agc2);
// Configure AGC1.
if (agc1_enabled) {
apm_config->gain_controller1.enabled = true;
apm_config->gain_controller1.mode =
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.mode =
#if defined(OS_ANDROID)
AudioProcessing::Config::GainController1::Mode::kFixedDigital;
#else
......@@ -211,32 +210,44 @@ void ConfigAutomaticGainControl(
// Configure AGC2.
if (experimental_agc_enabled) {
DCHECK(hybrid_agc_use_peaks_not_rms.has_value() &&
hybrid_agc_saturation_margin.has_value());
// Experimental AGC is enabled. Hybrid AGC may or may not be enabled. Config
// AGC2 with adaptive mode and the given options, while ignoring
// |use_fixed_digital_agc2|.
apm_config->gain_controller2.enabled = use_hybrid_agc;
apm_config->gain_controller2.fixed_digital.gain_db = 0.f;
apm_config->gain_controller2.adaptive_digital.enabled = true;
using LevelEstimator =
AudioProcessing::Config::GainController2::LevelEstimator;
apm_config->gain_controller2.adaptive_digital.level_estimator =
hybrid_agc_use_peaks_not_rms.value() ? LevelEstimator::kPeak
apm_config.gain_controller2.enabled = use_hybrid_agc;
apm_config.gain_controller2.fixed_digital.gain_db = 0.f;
apm_config.gain_controller2.adaptive_digital.enabled = true;
if (use_hybrid_agc) {
auto& adaptive_digital = apm_config.gain_controller2.adaptive_digital;
adaptive_digital.vad_probability_attack =
agc2_properties->vad_probability_attack;
using LevelEstimator =
AudioProcessing::Config::GainController2::LevelEstimator;
adaptive_digital.level_estimator = agc2_properties->use_peaks_not_rms
? LevelEstimator::kPeak
: LevelEstimator::kRms;
if (hybrid_agc_saturation_margin.value() != -1) {
apm_config->gain_controller2.adaptive_digital.extra_saturation_margin_db =
hybrid_agc_saturation_margin.value();
adaptive_digital.level_estimator_adjacent_speech_frames_threshold =
agc2_properties->level_estimator_speech_frames_threshold;
adaptive_digital.initial_saturation_margin_db =
agc2_properties->initial_saturation_margin_db;
adaptive_digital.extra_saturation_margin_db =
agc2_properties->extra_saturation_margin_db;
adaptive_digital.gain_applier_adjacent_speech_frames_threshold =
agc2_properties->gain_applier_speech_frames_threshold;
}
} else if (use_fixed_digital_agc2) {
// Experimental AGC is disabled, thus hybrid AGC is disabled. Config AGC2
// with fixed gain mode.
apm_config->gain_controller2.enabled = true;
apm_config->gain_controller2.fixed_digital.gain_db =
apm_config.gain_controller2.enabled = true;
apm_config.gain_controller2.fixed_digital.gain_db =
compression_gain_db.value();
apm_config->gain_controller2.adaptive_digital.enabled = false;
apm_config.gain_controller2.adaptive_digital.enabled = false;
}
}
......
......@@ -115,15 +115,27 @@ PLATFORM_EXPORT void StartEchoCancellationDump(
PLATFORM_EXPORT void StopEchoCancellationDump(
AudioProcessing* audio_processing);
// Enables automatic gain control with flags and optional configures.
// Adaptive Gain Controller 2 (aka AGC2) properties.
struct PLATFORM_EXPORT AdaptiveGainController2Properties {
float vad_probability_attack;
bool use_peaks_not_rms;
int level_estimator_speech_frames_threshold;
int initial_saturation_margin_db;
int extra_saturation_margin_db;
int gain_applier_speech_frames_threshold;
};
// Configures automatic gain control in `apm_config`. If `agc_enabled` is true
// and `agc2_properties` is specified, the AGC2 adaptive digital replaces the
// adaptive digital controller of AGC1 - i.e., hybrid configuration (AGC1 analog
// plus AGC2 adaptive digital).
// TODO(crbug.com/webrtc/7494): Clean up once hybrid AGC experiment finalized.
PLATFORM_EXPORT void ConfigAutomaticGainControl(
AudioProcessing::Config* apm_config,
bool agc_enabled,
bool experimental_agc_enabled,
bool use_hybrid_agc,
base::Optional<bool> hybrid_agc_use_peaks_not_rms,
base::Optional<int> hybrid_agc_saturation_margin,
base::Optional<double> compression_gain_db);
base::Optional<AdaptiveGainController2Properties> agc2_properties,
base::Optional<double> compression_gain_db,
AudioProcessing::Config& apm_config);
PLATFORM_EXPORT void PopulateApmConfig(
AudioProcessing::Config* apm_config,
......
......@@ -11,11 +11,11 @@ namespace blink {
TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) {
webrtc::AudioProcessing::Config apm_config;
ConfigAutomaticGainControl(&apm_config,
true, // |agc_enabled|.
false, // |experimental_agc_enabled|.
false, // |use_hybrid_agc|.
base::nullopt, base::nullopt, base::nullopt);
ConfigAutomaticGainControl(
/*agc_enabled=*/true,
/*experimental_agc_enabled=*/false,
/*agc2_properties=*/base::nullopt,
/*compression_gain_db=*/base::nullopt, apm_config);
EXPECT_TRUE(apm_config.gain_controller1.enabled);
EXPECT_EQ(
apm_config.gain_controller1.mode,
......@@ -29,11 +29,10 @@ TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) {
TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) {
webrtc::AudioProcessing::Config apm_config;
const double compression_gain_db = 10.0;
ConfigAutomaticGainControl(&apm_config,
true, // |agc_enabled|.
false, // |experimental_agc_enabled|.
false, // |use_hybrid_agc|.
base::nullopt, base::nullopt, compression_gain_db);
ConfigAutomaticGainControl(
/*agc_enabled=*/true,
/*experimental_agc_enabled=*/false,
/*agc2_properties=*/base::nullopt, compression_gain_db, apm_config);
EXPECT_FALSE(apm_config.gain_controller1.enabled);
EXPECT_TRUE(apm_config.gain_controller2.enabled);
EXPECT_FALSE(apm_config.gain_controller2.adaptive_digital.enabled);
......@@ -43,15 +42,19 @@ TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) {
TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) {
webrtc::AudioProcessing::Config apm_config;
const bool use_peaks_not_rms = true;
const int saturation_margin = 10;
const double compression_gain_db = 10.0; // Will test that it has no effect.
ConfigAutomaticGainControl(&apm_config,
true, // |agc_enabled|.
true, // |experimental_agc_enabled|.
true, // |use_hybrid_agc|.
use_peaks_not_rms, saturation_margin,
compression_gain_db);
blink::AdaptiveGainController2Properties agc2_properties;
agc2_properties.vad_probability_attack = 0.2f;
agc2_properties.use_peaks_not_rms = true;
agc2_properties.level_estimator_speech_frames_threshold = 3;
agc2_properties.initial_saturation_margin_db = 10;
agc2_properties.extra_saturation_margin_db = 10;
agc2_properties.gain_applier_speech_frames_threshold = 5;
const double compression_gain_db = 10.0;
ConfigAutomaticGainControl(
/*agc_enabled=*/true,
/*experimental_agc_enabled=*/true, agc2_properties, compression_gain_db,
apm_config);
EXPECT_TRUE(apm_config.gain_controller1.enabled);
EXPECT_EQ(
apm_config.gain_controller1.mode,
......@@ -61,14 +64,24 @@ TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) {
webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog);
#endif // defined(OS_ANDROID)
EXPECT_TRUE(apm_config.gain_controller2.enabled);
// `compression_gain_db` has no effect when hybrid AGC is active.
EXPECT_EQ(apm_config.gain_controller2.fixed_digital.gain_db, 0);
EXPECT_TRUE(apm_config.gain_controller2.adaptive_digital.enabled);
const auto& adaptive_digital = apm_config.gain_controller2.adaptive_digital;
EXPECT_TRUE(adaptive_digital.enabled);
EXPECT_FLOAT_EQ(adaptive_digital.vad_probability_attack,
agc2_properties.vad_probability_attack);
EXPECT_EQ(
apm_config.gain_controller2.adaptive_digital.level_estimator,
adaptive_digital.level_estimator,
webrtc::AudioProcessing::Config::GainController2::LevelEstimator::kPeak);
EXPECT_EQ(
apm_config.gain_controller2.adaptive_digital.extra_saturation_margin_db,
saturation_margin);
EXPECT_EQ(adaptive_digital.level_estimator_adjacent_speech_frames_threshold,
agc2_properties.level_estimator_speech_frames_threshold);
EXPECT_FLOAT_EQ(adaptive_digital.initial_saturation_margin_db,
agc2_properties.initial_saturation_margin_db);
EXPECT_FLOAT_EQ(adaptive_digital.extra_saturation_margin_db,
agc2_properties.extra_saturation_margin_db);
EXPECT_EQ(adaptive_digital.gain_applier_adjacent_speech_frames_threshold,
agc2_properties.gain_applier_speech_frames_threshold);
}
TEST(PopulateApmConfigTest, DefaultWithoutConfigJson) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment