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( ...@@ -581,24 +581,37 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
if (properties.goog_auto_gain_control || if (properties.goog_auto_gain_control ||
properties.goog_experimental_auto_gain_control) { properties.goog_experimental_auto_gain_control) {
bool use_hybrid_agc = false; base::Optional<blink::AdaptiveGainController2Properties> agc2_properties;
base::Optional<bool> use_peaks_not_rms; if (properties.goog_experimental_auto_gain_control &&
base::Optional<int> saturation_margin; base::FeatureList::IsEnabled(features::kWebRtcHybridAgc)) {
if (properties.goog_experimental_auto_gain_control) { DCHECK(properties.goog_auto_gain_control)
use_hybrid_agc = base::FeatureList::IsEnabled(features::kWebRtcHybridAgc); << "Cannot enable hybrid AGC when AGC is disabled.";
if (use_hybrid_agc) { agc2_properties = blink::AdaptiveGainController2Properties{};
DCHECK(properties.goog_auto_gain_control) agc2_properties->vad_probability_attack =
<< "Cannot enable hybrid AGC when AGC is disabled."; base::GetFieldTrialParamByFeatureAsDouble(
} features::kWebRtcHybridAgc, "vad_probability_attack", 1.0);
use_peaks_not_rms = base::GetFieldTrialParamByFeatureAsBool( agc2_properties->use_peaks_not_rms =
features::kWebRtcHybridAgc, "use_peaks_not_rms", false); base::GetFieldTrialParamByFeatureAsBool(features::kWebRtcHybridAgc,
saturation_margin = base::GetFieldTrialParamByFeatureAsInt( "use_peaks_not_rms", false);
features::kWebRtcHybridAgc, "saturation_margin", -1); 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( blink::ConfigAutomaticGainControl(
&apm_config, properties.goog_auto_gain_control, properties.goog_auto_gain_control,
properties.goog_experimental_auto_gain_control, use_hybrid_agc, properties.goog_experimental_auto_gain_control, agc2_properties,
use_peaks_not_rms, saturation_margin, gain_control_compression_gain_db); gain_control_compression_gain_db, apm_config);
} }
if (goog_typing_detection) { if (goog_typing_detection) {
......
...@@ -185,23 +185,22 @@ void StopEchoCancellationDump(AudioProcessing* audio_processing) { ...@@ -185,23 +185,22 @@ void StopEchoCancellationDump(AudioProcessing* audio_processing) {
} }
void ConfigAutomaticGainControl( void ConfigAutomaticGainControl(
AudioProcessing::Config* apm_config,
bool agc_enabled, bool agc_enabled,
bool experimental_agc_enabled, bool experimental_agc_enabled,
bool use_hybrid_agc, base::Optional<AdaptiveGainController2Properties> agc2_properties,
base::Optional<bool> hybrid_agc_use_peaks_not_rms, base::Optional<double> compression_gain_db,
base::Optional<int> hybrid_agc_saturation_margin, AudioProcessing::Config& apm_config) {
base::Optional<double> compression_gain_db) {
const bool use_fixed_digital_agc2 = agc_enabled && const bool use_fixed_digital_agc2 = agc_enabled &&
!experimental_agc_enabled && !experimental_agc_enabled &&
compression_gain_db.has_value(); compression_gain_db.has_value();
const bool use_hybrid_agc = agc2_properties.has_value();
const bool agc1_enabled = const bool agc1_enabled =
agc_enabled && (use_hybrid_agc || !use_fixed_digital_agc2); agc_enabled && (use_hybrid_agc || !use_fixed_digital_agc2);
// Configure AGC1. // Configure AGC1.
if (agc1_enabled) { if (agc1_enabled) {
apm_config->gain_controller1.enabled = true; apm_config.gain_controller1.enabled = true;
apm_config->gain_controller1.mode = apm_config.gain_controller1.mode =
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
AudioProcessing::Config::GainController1::Mode::kFixedDigital; AudioProcessing::Config::GainController1::Mode::kFixedDigital;
#else #else
...@@ -211,32 +210,44 @@ void ConfigAutomaticGainControl( ...@@ -211,32 +210,44 @@ void ConfigAutomaticGainControl(
// Configure AGC2. // Configure AGC2.
if (experimental_agc_enabled) { 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 // Experimental AGC is enabled. Hybrid AGC may or may not be enabled. Config
// AGC2 with adaptive mode and the given options, while ignoring // AGC2 with adaptive mode and the given options, while ignoring
// |use_fixed_digital_agc2|. // |use_fixed_digital_agc2|.
apm_config->gain_controller2.enabled = use_hybrid_agc; apm_config.gain_controller2.enabled = use_hybrid_agc;
apm_config->gain_controller2.fixed_digital.gain_db = 0.f; apm_config.gain_controller2.fixed_digital.gain_db = 0.f;
apm_config->gain_controller2.adaptive_digital.enabled = true; apm_config.gain_controller2.adaptive_digital.enabled = true;
using LevelEstimator = if (use_hybrid_agc) {
AudioProcessing::Config::GainController2::LevelEstimator; auto& adaptive_digital = apm_config.gain_controller2.adaptive_digital;
apm_config->gain_controller2.adaptive_digital.level_estimator =
hybrid_agc_use_peaks_not_rms.value() ? LevelEstimator::kPeak 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; : LevelEstimator::kRms;
if (hybrid_agc_saturation_margin.value() != -1) { adaptive_digital.level_estimator_adjacent_speech_frames_threshold =
apm_config->gain_controller2.adaptive_digital.extra_saturation_margin_db = agc2_properties->level_estimator_speech_frames_threshold;
hybrid_agc_saturation_margin.value();
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) { } else if (use_fixed_digital_agc2) {
// Experimental AGC is disabled, thus hybrid AGC is disabled. Config AGC2 // Experimental AGC is disabled, thus hybrid AGC is disabled. Config AGC2
// with fixed gain mode. // with fixed gain mode.
apm_config->gain_controller2.enabled = true; apm_config.gain_controller2.enabled = true;
apm_config->gain_controller2.fixed_digital.gain_db = apm_config.gain_controller2.fixed_digital.gain_db =
compression_gain_db.value(); 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( ...@@ -115,15 +115,27 @@ PLATFORM_EXPORT void StartEchoCancellationDump(
PLATFORM_EXPORT void StopEchoCancellationDump( PLATFORM_EXPORT void StopEchoCancellationDump(
AudioProcessing* audio_processing); 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( PLATFORM_EXPORT void ConfigAutomaticGainControl(
AudioProcessing::Config* apm_config,
bool agc_enabled, bool agc_enabled,
bool experimental_agc_enabled, bool experimental_agc_enabled,
bool use_hybrid_agc, base::Optional<AdaptiveGainController2Properties> agc2_properties,
base::Optional<bool> hybrid_agc_use_peaks_not_rms, base::Optional<double> compression_gain_db,
base::Optional<int> hybrid_agc_saturation_margin, AudioProcessing::Config& apm_config);
base::Optional<double> compression_gain_db);
PLATFORM_EXPORT void PopulateApmConfig( PLATFORM_EXPORT void PopulateApmConfig(
AudioProcessing::Config* apm_config, AudioProcessing::Config* apm_config,
......
...@@ -11,11 +11,11 @@ namespace blink { ...@@ -11,11 +11,11 @@ namespace blink {
TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) { TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) {
webrtc::AudioProcessing::Config apm_config; webrtc::AudioProcessing::Config apm_config;
ConfigAutomaticGainControl(&apm_config, ConfigAutomaticGainControl(
true, // |agc_enabled|. /*agc_enabled=*/true,
false, // |experimental_agc_enabled|. /*experimental_agc_enabled=*/false,
false, // |use_hybrid_agc|. /*agc2_properties=*/base::nullopt,
base::nullopt, base::nullopt, base::nullopt); /*compression_gain_db=*/base::nullopt, apm_config);
EXPECT_TRUE(apm_config.gain_controller1.enabled); EXPECT_TRUE(apm_config.gain_controller1.enabled);
EXPECT_EQ( EXPECT_EQ(
apm_config.gain_controller1.mode, apm_config.gain_controller1.mode,
...@@ -29,11 +29,10 @@ TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) { ...@@ -29,11 +29,10 @@ TEST(ConfigAutomaticGainControlTest, EnableDefaultAGC1) {
TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) { TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) {
webrtc::AudioProcessing::Config apm_config; webrtc::AudioProcessing::Config apm_config;
const double compression_gain_db = 10.0; const double compression_gain_db = 10.0;
ConfigAutomaticGainControl(&apm_config, ConfigAutomaticGainControl(
true, // |agc_enabled|. /*agc_enabled=*/true,
false, // |experimental_agc_enabled|. /*experimental_agc_enabled=*/false,
false, // |use_hybrid_agc|. /*agc2_properties=*/base::nullopt, compression_gain_db, apm_config);
base::nullopt, base::nullopt, compression_gain_db);
EXPECT_FALSE(apm_config.gain_controller1.enabled); EXPECT_FALSE(apm_config.gain_controller1.enabled);
EXPECT_TRUE(apm_config.gain_controller2.enabled); EXPECT_TRUE(apm_config.gain_controller2.enabled);
EXPECT_FALSE(apm_config.gain_controller2.adaptive_digital.enabled); EXPECT_FALSE(apm_config.gain_controller2.adaptive_digital.enabled);
...@@ -43,15 +42,19 @@ TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) { ...@@ -43,15 +42,19 @@ TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) {
TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) { TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) {
webrtc::AudioProcessing::Config apm_config; webrtc::AudioProcessing::Config apm_config;
const bool use_peaks_not_rms = true; blink::AdaptiveGainController2Properties agc2_properties;
const int saturation_margin = 10; agc2_properties.vad_probability_attack = 0.2f;
const double compression_gain_db = 10.0; // Will test that it has no effect. agc2_properties.use_peaks_not_rms = true;
ConfigAutomaticGainControl(&apm_config, agc2_properties.level_estimator_speech_frames_threshold = 3;
true, // |agc_enabled|. agc2_properties.initial_saturation_margin_db = 10;
true, // |experimental_agc_enabled|. agc2_properties.extra_saturation_margin_db = 10;
true, // |use_hybrid_agc|. agc2_properties.gain_applier_speech_frames_threshold = 5;
use_peaks_not_rms, saturation_margin, const double compression_gain_db = 10.0;
compression_gain_db);
ConfigAutomaticGainControl(
/*agc_enabled=*/true,
/*experimental_agc_enabled=*/true, agc2_properties, compression_gain_db,
apm_config);
EXPECT_TRUE(apm_config.gain_controller1.enabled); EXPECT_TRUE(apm_config.gain_controller1.enabled);
EXPECT_EQ( EXPECT_EQ(
apm_config.gain_controller1.mode, apm_config.gain_controller1.mode,
...@@ -61,14 +64,24 @@ TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) { ...@@ -61,14 +64,24 @@ TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) {
webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog); webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog);
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
EXPECT_TRUE(apm_config.gain_controller2.enabled); 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_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( EXPECT_EQ(
apm_config.gain_controller2.adaptive_digital.level_estimator, adaptive_digital.level_estimator,
webrtc::AudioProcessing::Config::GainController2::LevelEstimator::kPeak); webrtc::AudioProcessing::Config::GainController2::LevelEstimator::kPeak);
EXPECT_EQ( EXPECT_EQ(adaptive_digital.level_estimator_adjacent_speech_frames_threshold,
apm_config.gain_controller2.adaptive_digital.extra_saturation_margin_db, agc2_properties.level_estimator_speech_frames_threshold);
saturation_margin); 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) { 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