Make AgcManagerDirect clipping parameters configurable
Bug: webrtc:12774 Change-Id: I99824b5aabe6f921a5db425dd1c1c1d4c606186c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219681 Commit-Queue: Hanna Silen <silen@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34069}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
e2b9fc6909
commit
b8dc7fa5a6
@ -27,33 +27,26 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Amount the microphone level is lowered with every clipping event.
|
||||
const int kClippedLevelStep = 15;
|
||||
// Proportion of clipped samples required to declare a clipping event.
|
||||
const float kClippedRatioThreshold = 0.1f;
|
||||
// Time in frames to wait after a clipping event before checking again.
|
||||
const int kClippedWaitFrames = 300;
|
||||
|
||||
// Amount of error we tolerate in the microphone level (presumably due to OS
|
||||
// quantization) before we assume the user has manually adjusted the microphone.
|
||||
const int kLevelQuantizationSlack = 25;
|
||||
constexpr int kLevelQuantizationSlack = 25;
|
||||
|
||||
const int kDefaultCompressionGain = 7;
|
||||
const int kMaxCompressionGain = 12;
|
||||
const int kMinCompressionGain = 2;
|
||||
constexpr int kDefaultCompressionGain = 7;
|
||||
constexpr int kMaxCompressionGain = 12;
|
||||
constexpr int kMinCompressionGain = 2;
|
||||
// Controls the rate of compression changes towards the target.
|
||||
const float kCompressionGainStep = 0.05f;
|
||||
constexpr float kCompressionGainStep = 0.05f;
|
||||
|
||||
const int kMaxMicLevel = 255;
|
||||
constexpr int kMaxMicLevel = 255;
|
||||
static_assert(kGainMapSize > kMaxMicLevel, "gain map too small");
|
||||
const int kMinMicLevel = 12;
|
||||
constexpr int kMinMicLevel = 12;
|
||||
|
||||
// Prevent very large microphone level changes.
|
||||
const int kMaxResidualGainChange = 15;
|
||||
constexpr int kMaxResidualGainChange = 15;
|
||||
|
||||
// Maximum additional gain allowed to compensate for microphone level
|
||||
// restrictions from clipping events.
|
||||
const int kSurplusCompressionGain = 6;
|
||||
constexpr int kSurplusCompressionGain = 6;
|
||||
|
||||
// Returns whether a fall-back solution to choose the maximum level should be
|
||||
// chosen.
|
||||
@ -182,19 +175,19 @@ void MonoAgc::Process(const int16_t* audio,
|
||||
}
|
||||
}
|
||||
|
||||
void MonoAgc::HandleClipping() {
|
||||
void MonoAgc::HandleClipping(int clipped_level_step) {
|
||||
// Always decrease the maximum level, even if the current level is below
|
||||
// threshold.
|
||||
SetMaxLevel(std::max(clipped_level_min_, max_level_ - kClippedLevelStep));
|
||||
SetMaxLevel(std::max(clipped_level_min_, max_level_ - clipped_level_step));
|
||||
if (log_to_histograms_) {
|
||||
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.AgcClippingAdjustmentAllowed",
|
||||
level_ - kClippedLevelStep >= clipped_level_min_);
|
||||
level_ - clipped_level_step >= clipped_level_min_);
|
||||
}
|
||||
if (level_ > clipped_level_min_) {
|
||||
// Don't try to adjust the level if we're already below the limit. As
|
||||
// a consequence, if the user has brought the level above the limit, we
|
||||
// will still not react until the postproc updates the level.
|
||||
SetLevel(std::max(clipped_level_min_, level_ - kClippedLevelStep));
|
||||
SetLevel(std::max(clipped_level_min_, level_ - clipped_level_step));
|
||||
// Reset the AGCs for all channels since the level has changed.
|
||||
agc_->Reset();
|
||||
}
|
||||
@ -404,12 +397,18 @@ int AgcManagerDirect::instance_counter_ = 0;
|
||||
AgcManagerDirect::AgcManagerDirect(Agc* agc,
|
||||
int startup_min_level,
|
||||
int clipped_level_min,
|
||||
int sample_rate_hz)
|
||||
int sample_rate_hz,
|
||||
int clipped_level_step,
|
||||
float clipped_ratio_threshold,
|
||||
int clipped_wait_frames)
|
||||
: AgcManagerDirect(/*num_capture_channels*/ 1,
|
||||
startup_min_level,
|
||||
clipped_level_min,
|
||||
/*disable_digital_adaptive*/ false,
|
||||
sample_rate_hz) {
|
||||
sample_rate_hz,
|
||||
clipped_level_step,
|
||||
clipped_ratio_threshold,
|
||||
clipped_wait_frames) {
|
||||
RTC_DCHECK(channel_agcs_[0]);
|
||||
RTC_DCHECK(agc);
|
||||
channel_agcs_[0]->set_agc(agc);
|
||||
@ -419,15 +418,21 @@ AgcManagerDirect::AgcManagerDirect(int num_capture_channels,
|
||||
int startup_min_level,
|
||||
int clipped_level_min,
|
||||
bool disable_digital_adaptive,
|
||||
int sample_rate_hz)
|
||||
int sample_rate_hz,
|
||||
int clipped_level_step,
|
||||
float clipped_ratio_threshold,
|
||||
int clipped_wait_frames)
|
||||
: data_dumper_(
|
||||
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_counter_))),
|
||||
use_min_channel_level_(!UseMaxAnalogChannelLevel()),
|
||||
sample_rate_hz_(sample_rate_hz),
|
||||
num_capture_channels_(num_capture_channels),
|
||||
disable_digital_adaptive_(disable_digital_adaptive),
|
||||
frames_since_clipped_(kClippedWaitFrames),
|
||||
frames_since_clipped_(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),
|
||||
channel_agcs_(num_capture_channels),
|
||||
new_compressions_to_set_(num_capture_channels) {
|
||||
const int min_mic_level = GetMinMicLevel();
|
||||
@ -438,7 +443,13 @@ AgcManagerDirect::AgcManagerDirect(int num_capture_channels,
|
||||
data_dumper_ch, startup_min_level, clipped_level_min,
|
||||
disable_digital_adaptive_, min_mic_level);
|
||||
}
|
||||
RTC_DCHECK_LT(0, channel_agcs_.size());
|
||||
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);
|
||||
|
||||
channel_agcs_[0]->ActivateLogging();
|
||||
}
|
||||
|
||||
@ -489,7 +500,7 @@ void AgcManagerDirect::AnalyzePreProcess(const float* const* audio,
|
||||
return;
|
||||
}
|
||||
|
||||
if (frames_since_clipped_ < kClippedWaitFrames) {
|
||||
if (frames_since_clipped_ < clipped_wait_frames_) {
|
||||
++frames_since_clipped_;
|
||||
return;
|
||||
}
|
||||
@ -506,11 +517,11 @@ void AgcManagerDirect::AnalyzePreProcess(const float* const* audio,
|
||||
float clipped_ratio =
|
||||
ComputeClippedRatio(audio, num_capture_channels_, samples_per_channel);
|
||||
|
||||
if (clipped_ratio > kClippedRatioThreshold) {
|
||||
if (clipped_ratio > clipped_ratio_threshold_) {
|
||||
RTC_DLOG(LS_INFO) << "[agc] Clipping detected. clipped_ratio="
|
||||
<< clipped_ratio;
|
||||
for (auto& state_ch : channel_agcs_) {
|
||||
state_ch->HandleClipping();
|
||||
state_ch->HandleClipping(clipped_level_step_);
|
||||
}
|
||||
frames_since_clipped_ = 0;
|
||||
}
|
||||
|
@ -34,12 +34,20 @@ class AgcManagerDirect final {
|
||||
// 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.
|
||||
// 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.
|
||||
AgcManagerDirect(int num_capture_channels,
|
||||
int startup_min_level,
|
||||
int clipped_level_min,
|
||||
bool disable_digital_adaptive,
|
||||
int sample_rate_hz);
|
||||
int sample_rate_hz,
|
||||
int clipped_level_step,
|
||||
float clipped_ratio_threshold,
|
||||
int clipped_wait_frames);
|
||||
|
||||
~AgcManagerDirect();
|
||||
AgcManagerDirect(const AgcManagerDirect&) = delete;
|
||||
@ -81,13 +89,18 @@ class AgcManagerDirect final {
|
||||
AgcMinMicLevelExperimentEnabled50);
|
||||
FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
|
||||
AgcMinMicLevelExperimentEnabledAboveStartupLevel);
|
||||
FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
|
||||
ClippingParametersVerified);
|
||||
|
||||
// Dependency injection for testing. Don't delete |agc| as the memory is owned
|
||||
// by the manager.
|
||||
AgcManagerDirect(Agc* agc,
|
||||
int startup_min_level,
|
||||
int clipped_level_min,
|
||||
int sample_rate_hz);
|
||||
int sample_rate_hz,
|
||||
int clipped_level_step,
|
||||
float clipped_ratio_threshold,
|
||||
int clipped_wait_frames);
|
||||
|
||||
void AnalyzePreProcess(const float* const* audio, size_t samples_per_channel);
|
||||
|
||||
@ -105,6 +118,10 @@ class AgcManagerDirect final {
|
||||
bool capture_output_used_;
|
||||
int channel_controlling_gain_ = 0;
|
||||
|
||||
const int clipped_level_step_;
|
||||
const float clipped_ratio_threshold_;
|
||||
const int clipped_wait_frames_;
|
||||
|
||||
std::vector<std::unique_ptr<MonoAgc>> channel_agcs_;
|
||||
std::vector<absl::optional<int>> new_compressions_to_set_;
|
||||
};
|
||||
@ -123,7 +140,7 @@ class MonoAgc {
|
||||
void Initialize();
|
||||
void HandleCaptureOutputUsedChange(bool capture_output_used);
|
||||
|
||||
void HandleClipping();
|
||||
void HandleClipping(int clipped_level_step);
|
||||
|
||||
void Process(const int16_t* audio,
|
||||
size_t samples_per_channel,
|
||||
|
@ -26,13 +26,16 @@ using ::testing::SetArgPointee;
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
const int kSampleRateHz = 32000;
|
||||
const int kNumChannels = 1;
|
||||
const int kSamplesPerChannel = kSampleRateHz / 100;
|
||||
const int kInitialVolume = 128;
|
||||
constexpr int kSampleRateHz = 32000;
|
||||
constexpr int kNumChannels = 1;
|
||||
constexpr int kSamplesPerChannel = kSampleRateHz / 100;
|
||||
constexpr int kInitialVolume = 128;
|
||||
constexpr int kClippedMin = 165; // Arbitrary, but different from the default.
|
||||
const float kAboveClippedThreshold = 0.2f;
|
||||
const int kMinMicLevel = 12;
|
||||
constexpr float kAboveClippedThreshold = 0.2f;
|
||||
constexpr int kMinMicLevel = 12;
|
||||
constexpr int kClippedLevelStep = 15;
|
||||
constexpr float kClippedRatioThreshold = 0.1f;
|
||||
constexpr int kClippedWaitFrames = 300;
|
||||
|
||||
class MockGainControl : public GainControl {
|
||||
public:
|
||||
@ -57,10 +60,14 @@ class MockGainControl : public GainControl {
|
||||
};
|
||||
|
||||
std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect(
|
||||
int startup_min_level) {
|
||||
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, kSampleRateHz);
|
||||
/*disable_digital_adaptive=*/true, kSampleRateHz, clipped_level_step,
|
||||
clipped_ratio_threshold, clipped_wait_frames);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -69,7 +76,13 @@ class AgcManagerDirectTest : public ::testing::Test {
|
||||
protected:
|
||||
AgcManagerDirectTest()
|
||||
: agc_(new MockAgc),
|
||||
manager_(agc_, kInitialVolume, kClippedMin, kSampleRateHz),
|
||||
manager_(agc_,
|
||||
kInitialVolume,
|
||||
kClippedMin,
|
||||
kSampleRateHz,
|
||||
kClippedLevelStep,
|
||||
kClippedRatioThreshold,
|
||||
kClippedWaitFrames),
|
||||
audio(kNumChannels),
|
||||
audio_data(kNumChannels * kSamplesPerChannel, 0.f) {
|
||||
ExpectInitialize();
|
||||
@ -705,14 +718,16 @@ TEST(AgcManagerDirectStandaloneTest, DisableDigitalDisablesDigital) {
|
||||
EXPECT_CALL(gctrl, enable_limiter(false));
|
||||
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
manager->Initialize();
|
||||
manager->SetupDigitalGainControl(&gctrl);
|
||||
}
|
||||
|
||||
TEST(AgcManagerDirectStandaloneTest, AgcMinMicLevelExperiment) {
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), kInitialVolume);
|
||||
}
|
||||
@ -721,7 +736,8 @@ TEST(AgcManagerDirectStandaloneTest, AgcMinMicLevelExperimentDisabled) {
|
||||
test::ScopedFieldTrials field_trial(
|
||||
"WebRTC-Audio-AgcMinMicLevelExperiment/Disabled/");
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), kInitialVolume);
|
||||
}
|
||||
@ -732,7 +748,8 @@ TEST(AgcManagerDirectStandaloneTest, AgcMinMicLevelExperimentOutOfRangeAbove) {
|
||||
test::ScopedFieldTrials field_trial(
|
||||
"WebRTC-Audio-AgcMinMicLevelExperiment/Enabled-256/");
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), kInitialVolume);
|
||||
}
|
||||
@ -743,7 +760,8 @@ TEST(AgcManagerDirectStandaloneTest, AgcMinMicLevelExperimentOutOfRangeBelow) {
|
||||
test::ScopedFieldTrials field_trial(
|
||||
"WebRTC-Audio-AgcMinMicLevelExperiment/Enabled--1/");
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), kInitialVolume);
|
||||
}
|
||||
@ -755,7 +773,8 @@ TEST(AgcManagerDirectStandaloneTest, AgcMinMicLevelExperimentEnabled50) {
|
||||
test::ScopedFieldTrials field_trial(
|
||||
"WebRTC-Audio-AgcMinMicLevelExperiment/Enabled-50/");
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume);
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), 50);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), kInitialVolume);
|
||||
}
|
||||
@ -768,9 +787,33 @@ TEST(AgcManagerDirectStandaloneTest,
|
||||
test::ScopedFieldTrials field_trial(
|
||||
"WebRTC-Audio-AgcMinMicLevelExperiment/Enabled-50/");
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(/*startup_min_level=*/30);
|
||||
CreateAgcManagerDirect(/*startup_min_level=*/30, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), 50);
|
||||
EXPECT_EQ(manager->channel_agcs_[0]->startup_min_level(), 50);
|
||||
}
|
||||
|
||||
// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_level_step`.
|
||||
// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_ratio_threshold`.
|
||||
// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_wait_frames`.
|
||||
// Verifies that configurable clipping parameters are initialized as intended.
|
||||
TEST(AgcManagerDirectStandaloneTest, ClippingParametersVerified) {
|
||||
std::unique_ptr<AgcManagerDirect> manager =
|
||||
CreateAgcManagerDirect(kInitialVolume, kClippedLevelStep,
|
||||
kClippedRatioThreshold, kClippedWaitFrames);
|
||||
manager->Initialize();
|
||||
EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep);
|
||||
EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold);
|
||||
EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames);
|
||||
std::unique_ptr<AgcManagerDirect> manager_custom =
|
||||
CreateAgcManagerDirect(kInitialVolume,
|
||||
/*clipped_level_step*/ 10,
|
||||
/*clipped_ratio_threshold*/ 0.2f,
|
||||
/*clipped_wait_frames*/ 50);
|
||||
manager_custom->Initialize();
|
||||
EXPECT_EQ(manager_custom->clipped_level_step_, 10);
|
||||
EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f);
|
||||
EXPECT_EQ(manager_custom->clipped_wait_frames_, 50);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -1918,7 +1918,10 @@ void AudioProcessingImpl::InitializeGainController1() {
|
||||
config_.gain_controller1.analog_gain_controller.clipped_level_min,
|
||||
!config_.gain_controller1.analog_gain_controller
|
||||
.enable_digital_adaptive,
|
||||
capture_nonlocked_.split_rate));
|
||||
capture_nonlocked_.split_rate,
|
||||
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));
|
||||
if (re_creation) {
|
||||
submodules_.agc_manager->set_stream_analog_level(stream_analog_level);
|
||||
}
|
||||
|
@ -77,7 +77,11 @@ bool Agc1Config::operator==(const Agc1Config& rhs) const {
|
||||
analog_lhs.startup_min_volume == analog_rhs.startup_min_volume &&
|
||||
analog_lhs.clipped_level_min == analog_rhs.clipped_level_min &&
|
||||
analog_lhs.enable_digital_adaptive ==
|
||||
analog_rhs.enable_digital_adaptive;
|
||||
analog_rhs.enable_digital_adaptive &&
|
||||
analog_lhs.clipped_level_step == analog_rhs.clipped_level_step &&
|
||||
analog_lhs.clipped_ratio_threshold ==
|
||||
analog_rhs.clipped_ratio_threshold &&
|
||||
analog_lhs.clipped_wait_frames == analog_rhs.clipped_wait_frames;
|
||||
}
|
||||
|
||||
bool Agc2Config::AdaptiveDigital::operator==(
|
||||
@ -157,6 +161,12 @@ std::string AudioProcessing::Config::ToString() const {
|
||||
<< gain_controller1.analog_gain_controller.clipped_level_min
|
||||
<< ", enable_digital_adaptive: "
|
||||
<< gain_controller1.analog_gain_controller.enable_digital_adaptive
|
||||
<< ", clipped_level_step: "
|
||||
<< gain_controller1.analog_gain_controller.clipped_level_step
|
||||
<< ", clipped_ratio_threshold: "
|
||||
<< gain_controller1.analog_gain_controller.clipped_ratio_threshold
|
||||
<< ", clipped_wait_frames: "
|
||||
<< gain_controller1.analog_gain_controller.clipped_wait_frames
|
||||
<< " }}, gain_controller2: { enabled: " << gain_controller2.enabled
|
||||
<< ", fixed_digital: { gain_db: "
|
||||
<< gain_controller2.fixed_digital.gain_db
|
||||
|
@ -59,9 +59,9 @@ class CustomProcessing;
|
||||
//
|
||||
// Must be provided through AudioProcessingBuilder().Create(config).
|
||||
#if defined(WEBRTC_CHROMIUM_BUILD)
|
||||
static const int kAgcStartupMinVolume = 85;
|
||||
static constexpr int kAgcStartupMinVolume = 85;
|
||||
#else
|
||||
static const int kAgcStartupMinVolume = 0;
|
||||
static constexpr int kAgcStartupMinVolume = 0;
|
||||
#endif // defined(WEBRTC_CHROMIUM_BUILD)
|
||||
static constexpr int kClippedLevelMin = 70;
|
||||
|
||||
@ -334,6 +334,15 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface {
|
||||
// clipping.
|
||||
int clipped_level_min = kClippedLevelMin;
|
||||
bool enable_digital_adaptive = true;
|
||||
// Amount the microphone level is lowered with every clipping event.
|
||||
// Limited to (0, 255].
|
||||
int clipped_level_step = 15;
|
||||
// Proportion of clipped samples required to declare a clipping event.
|
||||
// Limited to (0.f, 1.f).
|
||||
float clipped_ratio_threshold = 0.1f;
|
||||
// Time in frames to wait after a clipping event before checking again.
|
||||
// Limited to values higher than 0.
|
||||
int clipped_wait_frames = 300;
|
||||
} analog_gain_controller;
|
||||
} gain_controller1;
|
||||
|
||||
|
Reference in New Issue
Block a user