`AgcManagerDirect` ctor API and doc string improved
Bug: chromium:1275566
Change-Id: Iedc8f5cbbf65fbf018da9df1aaa1f8ade1bbc063
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/268840
Reviewed-by: Hanna Silen <silen@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37569}
diff --git a/modules/audio_processing/agc/BUILD.gn b/modules/audio_processing/agc/BUILD.gn
index ade35af..1142f36 100644
--- a/modules/audio_processing/agc/BUILD.gn
+++ b/modules/audio_processing/agc/BUILD.gn
@@ -24,6 +24,7 @@
":gain_control_interface",
":gain_map",
":level_estimation",
+ "..:api",
"..:apm_logging",
"..:audio_buffer",
"..:audio_frame_view",
diff --git a/modules/audio_processing/agc/agc_manager_direct.cc b/modules/audio_processing/agc/agc_manager_direct.cc
index 93f38bc..be9a394 100644
--- a/modules/audio_processing/agc/agc_manager_direct.cc
+++ b/modules/audio_processing/agc/agc_manager_direct.cc
@@ -53,8 +53,8 @@
// frames).
constexpr int kClippingPredictorEvaluatorHistorySize = 500;
-using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
- AnalogGainController::ClippingPredictor;
+using AnalogAgcConfig =
+ AudioProcessing::Config::GainController1::AnalogGainController;
// Returns whether a fall-back solution to choose the maximum level should be
// chosen.
@@ -441,51 +441,35 @@
std::atomic<int> AgcManagerDirect::instance_counter_(0);
AgcManagerDirect::AgcManagerDirect(
- Agc* agc,
- int startup_min_level,
- int clipped_level_min,
- int clipped_level_step,
- float clipped_ratio_threshold,
- int clipped_wait_frames,
- const ClippingPredictorConfig& clipping_config)
- : AgcManagerDirect(/*num_capture_channels=*/1,
- startup_min_level,
- clipped_level_min,
- /*disable_digital_adaptive=*/false,
- clipped_level_step,
- clipped_ratio_threshold,
- clipped_wait_frames,
- clipping_config) {
+ const AudioProcessing::Config::GainController1::AnalogGainController&
+ analog_config,
+ Agc* agc)
+ : AgcManagerDirect(/*num_capture_channels=*/1, analog_config) {
RTC_DCHECK(channel_agcs_[0]);
RTC_DCHECK(agc);
channel_agcs_[0]->set_agc(agc);
}
-AgcManagerDirect::AgcManagerDirect(
- int num_capture_channels,
- int startup_min_level,
- int clipped_level_min,
- bool disable_digital_adaptive,
- int clipped_level_step,
- float clipped_ratio_threshold,
- int clipped_wait_frames,
- const ClippingPredictorConfig& clipping_config)
+AgcManagerDirect::AgcManagerDirect(int num_capture_channels,
+ const AnalogAgcConfig& analog_config)
: min_mic_level_override_(GetMinMicLevelOverride()),
data_dumper_(new ApmDataDumper(instance_counter_.fetch_add(1) + 1)),
use_min_channel_level_(!UseMaxAnalogChannelLevel()),
num_capture_channels_(num_capture_channels),
- disable_digital_adaptive_(disable_digital_adaptive),
- frames_since_clipped_(clipped_wait_frames),
+ disable_digital_adaptive_(!analog_config.enable_digital_adaptive),
+ frames_since_clipped_(analog_config.clipped_wait_frames),
capture_output_used_(true),
- clipped_level_step_(clipped_level_step),
- clipped_ratio_threshold_(clipped_ratio_threshold),
- clipped_wait_frames_(clipped_wait_frames),
+ clipped_level_step_(analog_config.clipped_level_step),
+ clipped_ratio_threshold_(analog_config.clipped_ratio_threshold),
+ clipped_wait_frames_(analog_config.clipped_wait_frames),
channel_agcs_(num_capture_channels),
new_compressions_to_set_(num_capture_channels),
clipping_predictor_(
- CreateClippingPredictor(num_capture_channels, clipping_config)),
- use_clipping_predictor_step_(!!clipping_predictor_ &&
- clipping_config.use_predicted_step),
+ CreateClippingPredictor(num_capture_channels,
+ analog_config.clipping_predictor)),
+ use_clipping_predictor_step_(
+ !!clipping_predictor_ &&
+ analog_config.clipping_predictor.use_predicted_step),
clipping_predictor_evaluator_(kClippingPredictorEvaluatorHistorySize),
clipping_predictor_log_counter_(0),
clipping_rate_log_(0.0f),
@@ -499,15 +483,16 @@
ApmDataDumper* data_dumper_ch = ch == 0 ? data_dumper_.get() : nullptr;
channel_agcs_[ch] = std::make_unique<MonoAgc>(
- data_dumper_ch, startup_min_level, clipped_level_min,
- disable_digital_adaptive_, min_mic_level);
+ data_dumper_ch, analog_config.startup_min_volume,
+ analog_config.clipped_level_min, disable_digital_adaptive_,
+ min_mic_level);
}
RTC_DCHECK(!channel_agcs_.empty());
- RTC_DCHECK_GT(clipped_level_step, 0);
- RTC_DCHECK_LE(clipped_level_step, 255);
- RTC_DCHECK_GT(clipped_ratio_threshold, 0.f);
- RTC_DCHECK_LT(clipped_ratio_threshold, 1.f);
- RTC_DCHECK_GT(clipped_wait_frames, 0);
+ RTC_DCHECK_GT(clipped_level_step_, 0);
+ RTC_DCHECK_LE(clipped_level_step_, 255);
+ RTC_DCHECK_GT(clipped_ratio_threshold_, 0.0f);
+ RTC_DCHECK_LT(clipped_ratio_threshold_, 1.0f);
+ RTC_DCHECK_GT(clipped_wait_frames_, 0);
channel_agcs_[0]->ActivateLogging();
}
@@ -529,22 +514,21 @@
}
void AgcManagerDirect::SetupDigitalGainControl(
- GainControl* gain_control) const {
- RTC_DCHECK(gain_control);
- if (gain_control->set_mode(GainControl::kFixedDigital) != 0) {
+ GainControl& gain_control) const {
+ if (gain_control.set_mode(GainControl::kFixedDigital) != 0) {
RTC_LOG(LS_ERROR) << "set_mode(GainControl::kFixedDigital) failed.";
}
const int target_level_dbfs = disable_digital_adaptive_ ? 0 : 2;
- if (gain_control->set_target_level_dbfs(target_level_dbfs) != 0) {
+ if (gain_control.set_target_level_dbfs(target_level_dbfs) != 0) {
RTC_LOG(LS_ERROR) << "set_target_level_dbfs() failed.";
}
const int compression_gain_db =
disable_digital_adaptive_ ? 0 : kDefaultCompressionGain;
- if (gain_control->set_compression_gain_db(compression_gain_db) != 0) {
+ if (gain_control.set_compression_gain_db(compression_gain_db) != 0) {
RTC_LOG(LS_ERROR) << "set_compression_gain_db() failed.";
}
const bool enable_limiter = !disable_digital_adaptive_;
- if (gain_control->enable_limiter(enable_limiter) != 0) {
+ if (gain_control.enable_limiter(enable_limiter) != 0) {
RTC_LOG(LS_ERROR) << "enable_limiter() failed.";
}
}
diff --git a/modules/audio_processing/agc/agc_manager_direct.h b/modules/audio_processing/agc/agc_manager_direct.h
index dbf8616..3c281b9 100644
--- a/modules/audio_processing/agc/agc_manager_direct.h
+++ b/modules/audio_processing/agc/agc_manager_direct.h
@@ -20,6 +20,7 @@
#include "modules/audio_processing/agc/clipping_predictor.h"
#include "modules/audio_processing/agc/clipping_predictor_evaluator.h"
#include "modules/audio_processing/audio_buffer.h"
+#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/gtest_prod_util.h"
@@ -28,53 +29,60 @@
class MonoAgc;
class GainControl;
-// Direct interface to use AGC to set volume and compression values.
-// AudioProcessing uses this interface directly to integrate the callback-less
-// AGC.
-//
-// This class is not thread-safe.
+// Adaptive Gain Controller (AGC) that combines an analog and digital gain
+// controller. The digital controller determines and applies the digital
+// compression gain. The analog controller recommends what input volume (a.k.a.,
+// analog level) to use, handles input volume changes and input clipping. In
+// particular, it handles input volume changes triggered by the user (e.g.,
+// input volume set to zero by a HW mute button). This class is not thread-safe.
class AgcManagerDirect final {
public:
- // AgcManagerDirect will configure GainControl internally. The user is
- // responsible for processing the audio using it after the call to Process.
- // The operating range of startup_min_level is [12, 255] and any input value
- // outside that range will be clamped. `clipped_level_step` is the amount
- // the microphone level is lowered with every clipping event, limited to
- // (0, 255]. `clipped_ratio_threshold` is the proportion of clipped
- // samples required to declare a clipping event, limited to (0.f, 1.f).
- // `clipped_wait_frames` is the time in frames to wait after a clipping event
- // before checking again, limited to values higher than 0.
+ // Ctor. `num_capture_channels` specifies the number of channels for the audio
+ // passed to `AnalyzePreProcess()` and `Process()`. Clamps
+ // `analog_config.startup_min_level` in the [12, 255] range.
AgcManagerDirect(
int num_capture_channels,
- int startup_min_level,
- int clipped_level_min,
- bool disable_digital_adaptive,
- int clipped_level_step,
- float clipped_ratio_threshold,
- int clipped_wait_frames,
- const AudioProcessing::Config::GainController1::AnalogGainController::
- ClippingPredictor& clipping_config);
+ const AudioProcessing::Config::GainController1::AnalogGainController&
+ analog_config);
~AgcManagerDirect();
AgcManagerDirect(const AgcManagerDirect&) = delete;
AgcManagerDirect& operator=(const AgcManagerDirect&) = delete;
void Initialize();
- void SetupDigitalGainControl(GainControl* gain_control) const;
+ // Configures `gain_control` to work as a fixed digital controller so that the
+ // adaptive part is only handled by this gain controller. Must be called if
+ // `gain_control` is also used to avoid the side-effects of running two AGCs.
+ void SetupDigitalGainControl(GainControl& gain_control) const;
+
+ // Analyzes `audio` before `Process()` is called so that the analysis can be
+ // performed before external digital processing operations take place (e.g.,
+ // echo cancellation). The analysis consists of input clipping detection and
+ // prediction (if enabled).
void AnalyzePreProcess(const AudioBuffer* audio);
+
+ // Processes `audio`. Chooses and applies a digital compression gain on each
+ // channel and chooses the new input volume to recommend. Undefined behavior
+ // if `AnalyzePreProcess()` is not called beforehand.
void Process(const AudioBuffer* audio);
// Call when the capture stream output has been flagged to be used/not-used.
// If unused, the manager disregards all incoming audio.
void HandleCaptureOutputUsedChange(bool capture_output_used);
+
float voice_probability() const;
+ // Returns the recommended input volume.
int stream_analog_level() const { return stream_analog_level_; }
+
+ // Sets the current input volume.
void set_stream_analog_level(int level);
+
int num_channels() const { return num_capture_channels_; }
- // If available, returns a new compression gain for the digital gain control.
+ // If available, returns the latest digital compression gain that has been
+ // applied.
absl::optional<int> GetDigitalComressionGain();
// Returns true if clipping prediction is enabled.
@@ -109,17 +117,12 @@
FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectTest,
UnusedClippingPredictionsProduceEqualAnalogLevels);
- // Dependency injection for testing. Don't delete `agc` as the memory is owned
- // by the manager.
+ // Ctor that creates a single channel AGC and by injecting `agc`.
+ // `agc` will be owned by this class; hence, do not delete it.
AgcManagerDirect(
- Agc* agc,
- int startup_min_level,
- int clipped_level_min,
- int clipped_level_step,
- float clipped_ratio_threshold,
- int clipped_wait_frames,
- const AudioProcessing::Config::GainController1::AnalogGainController::
- ClippingPredictor& clipping_config);
+ const AudioProcessing::Config::GainController1::AnalogGainController&
+ analog_config,
+ Agc* agc);
void AnalyzePreProcess(const float* const* audio, size_t samples_per_channel);
diff --git a/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
index 3b11fe0..52e6392 100644
--- a/modules/audio_processing/agc/agc_manager_direct_unittest.cc
+++ b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
@@ -40,11 +40,11 @@
constexpr float kClippedRatioThreshold = 0.1f;
constexpr int kClippedWaitFrames = 300;
-constexpr AudioProcessing::Config::GainController1::AnalogGainController
- kDefaultAnalogConfig{};
-
+using AnalogAgcConfig =
+ AudioProcessing::Config::GainController1::AnalogGainController;
using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
AnalogGainController::ClippingPredictor;
+constexpr AnalogAgcConfig kDefaultAnalogConfig{};
class MockGainControl : public GainControl {
public:
@@ -68,28 +68,24 @@
MOCK_METHOD(bool, stream_is_saturated, (), (const, override));
};
+// TODO(bugs.webrtc.org/12874): Remove and use designated initializers once
+// fixed.
std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect(
- int startup_min_level,
- int clipped_level_step,
- float clipped_ratio_threshold,
- int clipped_wait_frames) {
- return std::make_unique<AgcManagerDirect>(
- /*num_capture_channels=*/1, startup_min_level, kClippedMin,
- /*disable_digital_adaptive=*/true, clipped_level_step,
- clipped_ratio_threshold, clipped_wait_frames,
- kDefaultAnalogConfig.clipping_predictor);
-}
-
-std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect(
- int startup_min_level,
+ int startup_min_volume,
int clipped_level_step,
float clipped_ratio_threshold,
int clipped_wait_frames,
- const ClippingPredictorConfig& clipping_cfg) {
- return std::make_unique<AgcManagerDirect>(
- /*num_capture_channels=*/1, startup_min_level, kClippedMin,
- /*disable_digital_adaptive=*/true, clipped_level_step,
- clipped_ratio_threshold, clipped_wait_frames, clipping_cfg);
+ const ClippingPredictorConfig& clipping_predictor_config =
+ kDefaultAnalogConfig.clipping_predictor) {
+ AnalogAgcConfig config;
+ config.startup_min_volume = startup_min_volume;
+ config.clipped_level_min = kClippedMin;
+ config.enable_digital_adaptive = false;
+ config.clipped_level_step = clipped_level_step;
+ config.clipped_ratio_threshold = clipped_ratio_threshold;
+ config.clipped_wait_frames = clipped_wait_frames;
+ config.clipping_predictor = clipping_predictor_config;
+ return std::make_unique<AgcManagerDirect>(/*num_capture_channels=*/1, config);
}
// Calls `AnalyzePreProcess()` on `manager` `num_calls` times. `peak_ratio` is a
@@ -185,6 +181,20 @@
} // namespace
+// TODO(bugs.webrtc.org/12874): Use constexpr struct with designated
+// initializers once fixed.
+constexpr AnalogAgcConfig GetAnalogAgcTestConfig() {
+ AnalogAgcConfig config;
+ config.startup_min_volume = kInitialVolume;
+ config.clipped_level_min = kClippedMin;
+ config.enable_digital_adaptive = true;
+ config.clipped_level_step = kClippedLevelStep;
+ config.clipped_ratio_threshold = kClippedRatioThreshold;
+ config.clipped_wait_frames = kClippedWaitFrames;
+ config.clipping_predictor = kDefaultAnalogConfig.clipping_predictor;
+ return config;
+};
+
class AgcManagerDirectTestHelper {
public:
AgcManagerDirectTestHelper()
@@ -197,16 +207,10 @@
audio(kNumChannels),
audio_data(kNumChannels * kSamplesPerChannel, 0.0f),
mock_agc(new MockAgc()),
- manager(mock_agc,
- kInitialVolume,
- kClippedMin,
- kClippedLevelStep,
- kClippedRatioThreshold,
- kClippedWaitFrames,
- kDefaultAnalogConfig.clipping_predictor) {
+ manager(GetAnalogAgcTestConfig(), mock_agc) {
ExpectInitialize();
manager.Initialize();
- manager.SetupDigitalGainControl(&mock_gain_control);
+ manager.SetupDigitalGainControl(mock_gain_control);
for (size_t ch = 0; ch < kNumChannels; ++ch) {
audio[ch] = &audio_data[ch * kSamplesPerChannel];
}
@@ -947,11 +951,11 @@
EXPECT_CALL(mock_gain_control, set_compression_gain_db(0));
EXPECT_CALL(mock_gain_control, enable_limiter(false));
- std::unique_ptr<AgcManagerDirect> manager =
- CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
- kClippedRatioThreshold, kClippedWaitFrames);
+ AnalogAgcConfig config;
+ config.enable_digital_adaptive = false;
+ auto manager = std::make_unique<AgcManagerDirect>(kNumChannels, config);
manager->Initialize();
- manager->SetupDigitalGainControl(&mock_gain_control);
+ manager->SetupDigitalGainControl(mock_gain_control);
}
TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDefault) {
@@ -1075,12 +1079,14 @@
const auto factory = []() {
// Use a large clipped level step to more quickly decrease the analog gain
// with clipping.
- auto controller = std::make_unique<AgcManagerDirect>(
- /*num_capture_channels=*/1, kInitialVolume,
- kDefaultAnalogConfig.clipped_level_min,
- /*disable_digital_adaptive=*/true, /*clipped_level_step=*/64,
- kClippedRatioThreshold, kClippedWaitFrames,
- kDefaultAnalogConfig.clipping_predictor);
+ AnalogAgcConfig config = kDefaultAnalogConfig;
+ config.startup_min_volume = kInitialVolume;
+ config.enable_digital_adaptive = false;
+ config.clipped_level_step = 64;
+ config.clipped_ratio_threshold = kClippedRatioThreshold;
+ config.clipped_wait_frames = kClippedWaitFrames;
+ auto controller =
+ std::make_unique<AgcManagerDirect>(/*num_capture_channels=*/1, config);
controller->Initialize();
controller->set_stream_analog_level(kInitialVolume);
return controller;
@@ -1181,11 +1187,9 @@
AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
kNumChannels, kSampleRateHz, kNumChannels);
- // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
- constexpr ClippingPredictorConfig kConfig{/*enabled=*/false};
- AgcManagerDirect manager(new ::testing::NiceMock<MockAgc>(), kInitialVolume,
- kClippedMin, kClippedLevelStep,
- kClippedRatioThreshold, kClippedWaitFrames, kConfig);
+ AnalogAgcConfig config = GetAnalogAgcTestConfig();
+ config.clipping_predictor.enabled = false;
+ AgcManagerDirect manager(config, new ::testing::NiceMock<MockAgc>());
manager.Initialize();
manager.set_stream_analog_level(/*level=*/255);
EXPECT_FALSE(manager.clipping_predictor_enabled());
@@ -1204,20 +1208,15 @@
AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
kNumChannels, kSampleRateHz, kNumChannels);
- // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
- ClippingPredictorConfig config_with_prediction;
- config_with_prediction.enabled = true;
- config_with_prediction.use_predicted_step = true;
- ClippingPredictorConfig config_without_prediction;
- config_without_prediction.enabled = false;
- AgcManagerDirect manager_with_prediction(
- new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
- kClippedLevelStep, kClippedRatioThreshold, kClippedWaitFrames,
- config_with_prediction);
+ AnalogAgcConfig config_with_prediction = GetAnalogAgcTestConfig();
+ config_with_prediction.clipping_predictor.enabled = true;
+ config_with_prediction.clipping_predictor.use_predicted_step = true;
+ AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
+ config_without_prediction.clipping_predictor.enabled = false;
+ AgcManagerDirect manager_with_prediction(config_with_prediction,
+ new ::testing::NiceMock<MockAgc>());
AgcManagerDirect manager_without_prediction(
- new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
- kClippedLevelStep, kClippedRatioThreshold, kClippedWaitFrames,
- config_without_prediction);
+ config_without_prediction, new ::testing::NiceMock<MockAgc>());
manager_with_prediction.Initialize();
manager_without_prediction.Initialize();
@@ -1307,20 +1306,15 @@
AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
kNumChannels, kSampleRateHz, kNumChannels);
- // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
- ClippingPredictorConfig config_with_prediction;
- config_with_prediction.enabled = true;
- config_with_prediction.use_predicted_step = false;
- ClippingPredictorConfig config_without_prediction;
- config_without_prediction.enabled = false;
- AgcManagerDirect manager_with_prediction(
- new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
- kClippedLevelStep, kClippedRatioThreshold, kClippedWaitFrames,
- config_with_prediction);
+ AnalogAgcConfig config_with_prediction = GetAnalogAgcTestConfig();
+ config_with_prediction.clipping_predictor.enabled = true;
+ config_with_prediction.clipping_predictor.use_predicted_step = false;
+ AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
+ config_without_prediction.clipping_predictor.enabled = false;
+ AgcManagerDirect manager_with_prediction(config_with_prediction,
+ new ::testing::NiceMock<MockAgc>());
AgcManagerDirect manager_without_prediction(
- new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
- kClippedLevelStep, kClippedRatioThreshold, kClippedWaitFrames,
- config_without_prediction);
+ config_without_prediction, new ::testing::NiceMock<MockAgc>());
constexpr int kInitialLevel = 255;
constexpr float kClippingPeakRatio = 1.0f;
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index b7d2340..cb0c4d6 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -1889,22 +1889,13 @@
stream_analog_level = submodules_.agc_manager->stream_analog_level();
}
submodules_.agc_manager.reset(new AgcManagerDirect(
- num_proc_channels(),
- config_.gain_controller1.analog_gain_controller.startup_min_volume,
- config_.gain_controller1.analog_gain_controller.clipped_level_min,
- !config_.gain_controller1.analog_gain_controller
- .enable_digital_adaptive,
- config_.gain_controller1.analog_gain_controller.clipped_level_step,
- config_.gain_controller1.analog_gain_controller.clipped_ratio_threshold,
- config_.gain_controller1.analog_gain_controller.clipped_wait_frames,
- config_.gain_controller1.analog_gain_controller.clipping_predictor));
+ num_proc_channels(), config_.gain_controller1.analog_gain_controller));
if (re_creation) {
submodules_.agc_manager->set_stream_analog_level(stream_analog_level);
}
}
submodules_.agc_manager->Initialize();
- submodules_.agc_manager->SetupDigitalGainControl(
- submodules_.gain_control.get());
+ submodules_.agc_manager->SetupDigitalGainControl(*submodules_.gain_control);
submodules_.agc_manager->HandleCaptureOutputUsedChange(
capture_.capture_output_used);
}
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 1088f9b..6e50f21 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -286,10 +286,12 @@
// Enables the analog gain controller functionality.
struct AnalogGainController {
bool enabled = true;
+ // TODO(bugs.webrtc.org/1275566): Describe `startup_min_volume`.
int startup_min_volume = kAgcStartupMinVolume;
// Lowest analog microphone level that will be applied in response to
// clipping.
int clipped_level_min = kClippedLevelMin;
+ // If true, an adaptive digital gain is applied.
bool enable_digital_adaptive = true;
// Amount the microphone level is lowered with every clipping event.
// Limited to (0, 255].