Reset level estimator when analog gain changes.

In AgcManagerDirect::UpdateGain(), Agc::GetRmsErrorDb() is
called. Depending on the result of that call, the analog gain may be
changed. After an analog gain change, the Agc should be reset, because
it's memory contains now invalid loudness levels.

The Agc in modules/audio_processing/agc/agc.cc resets itself at every
successful Agc::GetRmsErrorDb call. The AdaptiveModeLevelEstimatorAgc
does not. This change makes sure all Agcs are reset from
AgcManagerDirect.

It will cause some Agcs to be reset twice. This is fine, because
Agc::Reset() is cheap and idempotent.

Bug: webrtc:7494
Change-Id: Iee7495d699cbdb9d69b2ae0cb07034c6e2761e22
Reviewed-on: https://webrtc-review.googlesource.com/89040
Commit-Queue: Alex Loiko <aleloi@webrtc.org>
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24054}
This commit is contained in:
Alex Loiko 2018-07-19 16:39:39 +02:00 committed by Commit Bot
parent 682aac5103
commit 99f1e0d008
2 changed files with 30 additions and 20 deletions

View File

@ -115,13 +115,15 @@ AgcManagerDirect::AgcManagerDirect(GainControl* gctrl,
int clipped_level_min,
bool use_agc2_level_estimation,
bool use_agc2_digital_adaptive)
: AgcManagerDirect(new Agc(),
: AgcManagerDirect(use_agc2_level_estimation ? nullptr : new Agc(),
gctrl,
volume_callbacks,
startup_min_level,
clipped_level_min,
use_agc2_level_estimation,
use_agc2_digital_adaptive) {}
use_agc2_digital_adaptive) {
RTC_DCHECK(agc_);
}
AgcManagerDirect::AgcManagerDirect(Agc* agc,
GainControl* gctrl,
@ -134,7 +136,9 @@ AgcManagerDirect::AgcManagerDirect(Agc* agc,
startup_min_level,
clipped_level_min,
false,
false) {}
false) {
RTC_DCHECK(agc_);
}
AgcManagerDirect::AgcManagerDirect(Agc* agc,
GainControl* gctrl,
@ -437,6 +441,8 @@ void AgcManagerDirect::UpdateGain() {
// level_ was updated by SetLevel; log the new value.
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.AgcSetLevel", level_, 1,
kMaxMicLevel, 50);
// Reset the AGC since the level has changed.
agc_->Reset();
}
}

View File

@ -17,6 +17,7 @@
#include "test/gtest.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;
@ -53,7 +54,7 @@ class AgcManagerDirectTest : public ::testing::Test {
}
void FirstProcess() {
EXPECT_CALL(*agc_, Reset());
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false));
CallProcess(1);
}
@ -366,11 +367,14 @@ TEST_F(AgcManagerDirectTest, ManualLevelChangeResultsInNoSetMicCall) {
// to SetMicVolume.
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
// When the analog volume changes, the gain controller is reset.
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
// GetMicVolume returns a value outside of the quantization slack, indicating
// a manual volume change.
ASSERT_NE(volume_.GetMicVolume(), 154);
volume_.SetMicVolume(154);
// SetMicVolume should not be called.
EXPECT_CALL(*agc_, Reset()).Times(1);
CallProcess(1);
EXPECT_EQ(154, volume_.GetMicVolume());
@ -378,7 +382,7 @@ TEST_F(AgcManagerDirectTest, ManualLevelChangeResultsInNoSetMicCall) {
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
volume_.SetMicVolume(100);
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(100, volume_.GetMicVolume());
@ -407,7 +411,7 @@ TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeFromMax) {
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
volume_.SetMicVolume(50);
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(50, volume_.GetMicVolume());
@ -426,7 +430,7 @@ TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeBelowMin) {
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
// Don't set to zero, which will cause AGC to take no action.
volume_.SetMicVolume(1);
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(1, volume_.GetMicVolume());
@ -467,7 +471,7 @@ TEST_F(AgcManagerDirectTest, ClippingLowersVolume) {
SetVolumeAndProcess(255);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.101));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
}
@ -477,7 +481,7 @@ TEST_F(AgcManagerDirectTest, WaitingPeriodBetweenClippingChecks) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
@ -489,7 +493,7 @@ TEST_F(AgcManagerDirectTest, WaitingPeriodBetweenClippingChecks) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(225, volume_.GetMicVolume());
}
@ -499,7 +503,7 @@ TEST_F(AgcManagerDirectTest, ClippingLoweringIsLimited) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(kClippedMin, volume_.GetMicVolume());
@ -515,7 +519,7 @@ TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenEqualToLevel) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
@ -530,7 +534,7 @@ TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenHigherThanLevel) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(185, volume_.GetMicVolume());
@ -547,7 +551,7 @@ TEST_F(AgcManagerDirectTest, MaxCompressionIsIncreasedAfterClipping) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(195, volume_.GetMicVolume());
@ -576,14 +580,14 @@ TEST_F(AgcManagerDirectTest, MaxCompressionIsIncreasedAfterClipping) {
CallPreProc(300);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(180, volume_.GetMicVolume());
CallPreProc(300);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(kClippedMin, volume_.GetMicVolume());
@ -628,7 +632,7 @@ TEST_F(AgcManagerDirectTest, UserCanRaiseVolumeAfterClipping) {
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(210, volume_.GetMicVolume());
@ -637,7 +641,7 @@ TEST_F(AgcManagerDirectTest, UserCanRaiseVolumeAfterClipping) {
.WillOnce(DoAll(SetArgPointee<0>(14), Return(true)));
// User changed the volume.
volume_.SetMicVolume(250);
EXPECT_CALL(*agc_, Reset()).Times(1);
EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(250, volume_.GetMicVolume());