Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2410)

Unified Diff: webrtc/modules/audio_processing/agc/agc_manager_direct_unittest.cc

Issue 1299143003: Remove AgcManager. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Initialize volume Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_processing/agc/agc_manager_direct.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_processing/agc/agc_manager_direct_unittest.cc
diff --git a/webrtc/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/webrtc/modules/audio_processing/agc/agc_manager_direct_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9dba2fc9016f47907f7b73fa47169883823aded1
--- /dev/null
+++ b/webrtc/modules/audio_processing/agc/agc_manager_direct_unittest.cc
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/common_types.h"
+#include "webrtc/modules/audio_processing/agc/mock_agc.h"
+#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+#include "webrtc/test/testsupport/trace_to_stderr.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Eq;
+using ::testing::Mock;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::SetArgReferee;
+
+namespace webrtc {
+namespace {
+
+const int kSampleRateHz = 32000;
+const int kNumChannels = 1;
+const int kSamplesPerChannel = kSampleRateHz / 100;
+const int kInitialVolume = 128;
+const float kAboveClippedThreshold = 0.2f;
+
+class TestVolumeCallbacks : public VolumeCallbacks {
+ public:
+ TestVolumeCallbacks() : volume_(0) {}
+ void SetMicVolume(int volume) override { volume_ = volume; }
+ int GetMicVolume() override { return volume_; }
+
+ private:
+ int volume_;
+};
+
+} // namespace
+
+class AgcManagerDirectTest : public ::testing::Test {
+ protected:
+ AgcManagerDirectTest()
+ : agc_(new MockAgc), manager_(agc_, &gctrl_, &volume_, kInitialVolume) {
+ ExpectInitialize();
+ manager_.Initialize();
+ }
+
+ void FirstProcess() {
+ EXPECT_CALL(*agc_, Reset());
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false));
+ CallProcess(1);
+ }
+
+ void SetVolumeAndProcess(int volume) {
+ volume_.SetMicVolume(volume);
+ FirstProcess();
+ }
+
+ void ExpectCheckVolumeAndReset(int volume) {
+ volume_.SetMicVolume(volume);
+ EXPECT_CALL(*agc_, Reset());
+ }
+
+ void ExpectInitialize() {
+ EXPECT_CALL(gctrl_, set_mode(GainControl::kFixedDigital));
+ EXPECT_CALL(gctrl_, set_target_level_dbfs(2));
+ EXPECT_CALL(gctrl_, set_compression_gain_db(7));
+ EXPECT_CALL(gctrl_, enable_limiter(true));
+ }
+
+ void CallProcess(int num_calls) {
+ for (int i = 0; i < num_calls; ++i) {
+ EXPECT_CALL(*agc_, Process(_, _, _)).WillOnce(Return(0));
+ manager_.Process(nullptr, kSamplesPerChannel, kSampleRateHz);
+ }
+ }
+
+ void CallPreProc(int num_calls) {
+ for (int i = 0; i < num_calls; ++i) {
+ manager_.AnalyzePreProcess(nullptr, kNumChannels, kSamplesPerChannel);
+ }
+ }
+
+ MockAgc* agc_;
+ MockGainControl gctrl_;
+ TestVolumeCallbacks volume_;
+ AgcManagerDirect manager_;
+ test::TraceToStderr trace_to_stderr;
+};
+
+TEST_F(AgcManagerDirectTest, StartupMinVolumeConfigurationIsRespected) {
+ FirstProcess();
+ EXPECT_EQ(kInitialVolume, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, MicVolumeResponseToRmsError) {
+ FirstProcess();
+
+ // Compressor default; no residual error.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)));
+ CallProcess(1);
+
+ // Inside the compressor's window; no change of volume.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)));
+ CallProcess(1);
+
+ // Above the compressor's window; volume should be increased.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(130, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(168, volume_.GetMicVolume());
+
+ // Inside the compressor's window; no change of volume.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)));
+ CallProcess(1);
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
+ CallProcess(1);
+
+ // Below the compressor's window; volume should be decreased.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(167, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(163, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-9), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(129, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, MicVolumeIsLimited) {
+ FirstProcess();
+
+ // Maximum upwards change is limited.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(183, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(243, volume_.GetMicVolume());
+
+ // Won't go higher than the maximum.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(255, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(254, volume_.GetMicVolume());
+
+ // Maximum downwards change is limited.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(194, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(137, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(88, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(54, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(33, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(18, volume_.GetMicVolume());
+
+ // Won't go lower than the minimum.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(12, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, CompressorStepsTowardsTarget) {
+ FirstProcess();
+
+ // Compressor default; no call to set_compression_gain_db.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(20);
+
+ // Moves slowly upwards.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(9), Return(true)))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(1);
+
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0));
+ CallProcess(1);
+
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(20);
+
+ // Moves slowly downward, then reverses before reaching the original target.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(1);
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(9), Return(true)))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0));
+ CallProcess(1);
+
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(20);
+}
+
+TEST_F(AgcManagerDirectTest, CompressorErrorIsDeemphasized) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0));
+ CallProcess(1);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(20);
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(7)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(6)).WillOnce(Return(0));
+ CallProcess(1);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0);
+ CallProcess(20);
+}
+
+TEST_F(AgcManagerDirectTest, CompressorReachesMaximum) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(10)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(11)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(12)).WillOnce(Return(0));
+ CallProcess(1);
+}
+
+TEST_F(AgcManagerDirectTest, CompressorReachesMinimum) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(6)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(5)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(4)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(3)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(2)).WillOnce(Return(0));
+ CallProcess(1);
+}
+
+TEST_F(AgcManagerDirectTest, NoActionWhileMuted) {
+ manager_.SetCaptureMuted(true);
+ manager_.Process(nullptr, kSamplesPerChannel, kSampleRateHz);
+}
+
+TEST_F(AgcManagerDirectTest, UnmutingChecksVolumeWithoutRaising) {
+ FirstProcess();
+
+ manager_.SetCaptureMuted(true);
+ manager_.SetCaptureMuted(false);
+ ExpectCheckVolumeAndReset(127);
+ // SetMicVolume should not be called.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false));
+ CallProcess(1);
+ EXPECT_EQ(127, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, UnmutingRaisesTooLowVolume) {
+ FirstProcess();
+
+ manager_.SetCaptureMuted(true);
+ manager_.SetCaptureMuted(false);
+ ExpectCheckVolumeAndReset(11);
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false));
+ CallProcess(1);
+ EXPECT_EQ(12, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ManualLevelChangeResultsInNoSetMicCall) {
+ FirstProcess();
+
+ // Change outside of compressor's range, which would normally trigger a call
+ // to SetMicVolume.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
+ // GetMicVolume returns a value outside of the quantization slack, indicating
+ // a manual volume change.
+ volume_.SetMicVolume(154);
+ // SetMicVolume should not be called.
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallProcess(1);
+ EXPECT_EQ(154, volume_.GetMicVolume());
+
+ // Do the same thing, except downwards now.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ volume_.SetMicVolume(100);
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallProcess(1);
+ EXPECT_EQ(100, volume_.GetMicVolume());
+
+ // And finally verify the AGC continues working without a manual change.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(99, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeFromMax) {
+ FirstProcess();
+
+ // Force the mic up to max volume. Takes a few steps due to the residual
+ // gain limitation.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(183, volume_.GetMicVolume());
+ CallProcess(1);
+ EXPECT_EQ(243, volume_.GetMicVolume());
+ CallProcess(1);
+ EXPECT_EQ(255, volume_.GetMicVolume());
+
+ // Manual change does not result in SetMicVolume call.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
+ volume_.SetMicVolume(50);
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallProcess(1);
+ EXPECT_EQ(50, volume_.GetMicVolume());
+
+ // Continues working as usual afterwards.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(69, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeBelowMin) {
+ FirstProcess();
+
+ // Manual change below min.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .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);
+ CallProcess(1);
+ EXPECT_EQ(1, volume_.GetMicVolume());
+
+ // Continues working as usual afterwards.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(2, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(11, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(18, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, NoClippingHasNoImpact) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillRepeatedly(Return(0));
+ CallPreProc(100);
+ EXPECT_EQ(128, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingUnderThresholdHasNoImpact) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.099));
+ CallPreProc(1);
+ EXPECT_EQ(128, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingLowersVolume) {
+ SetVolumeAndProcess(255);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.101));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, WaitingPeriodBetweenClippingChecks) {
+ SetVolumeAndProcess(255);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillRepeatedly(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(0);
+ CallPreProc(300);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(225, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingLoweringIsLimited) {
+ SetVolumeAndProcess(180);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(170, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillRepeatedly(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(0);
+ CallPreProc(1000);
+ EXPECT_EQ(170, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenEqualToLevel) {
+ SetVolumeAndProcess(255);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(10);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenHigherThanLevel) {
+ SetVolumeAndProcess(200);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(185, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+ CallProcess(10);
+ EXPECT_EQ(240, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, MaxCompressionIsIncreasedAfterClipping) {
+ SetVolumeAndProcess(210);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(195, volume_.GetMicVolume());
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(10)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(11)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(12)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(13)).WillOnce(Return(0));
+ CallProcess(1);
+
+ // Continue clipping until we hit the maximum surplus compression.
+ CallPreProc(300);
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(180, volume_.GetMicVolume());
+
+ CallPreProc(300);
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(170, volume_.GetMicVolume());
+
+ // Current level is now at the minimum, but the maximum allowed level still
+ // has more to decrease.
+ CallPreProc(300);
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ CallPreProc(1);
+
+ CallPreProc(300);
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ CallPreProc(1);
+
+ CallPreProc(300);
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ CallPreProc(1);
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
+ .WillRepeatedly(Return(false));
+ CallProcess(19);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(14)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(15)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(16)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(17)).WillOnce(Return(0));
+ CallProcess(20);
+ EXPECT_CALL(gctrl_, set_compression_gain_db(18)).WillOnce(Return(0));
+ CallProcess(1);
+}
+
+TEST_F(AgcManagerDirectTest, UserCanRaiseVolumeAfterClipping) {
+ SetVolumeAndProcess(225);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallPreProc(1);
+ EXPECT_EQ(210, volume_.GetMicVolume());
+
+ // High enough error to trigger a volume check.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(14), Return(true)));
+ // User changed the volume.
+ volume_.SetMicVolume(250);
+ EXPECT_CALL(*agc_, Reset()).Times(1);
+ CallProcess(1);
+ EXPECT_EQ(250, volume_.GetMicVolume());
+
+ // Move down...
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(-10), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(210, volume_.GetMicVolume());
+ // And back up to the new max established by the user.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(40), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(250, volume_.GetMicVolume());
+ // Will not move above new maximum.
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
+ CallProcess(1);
+ EXPECT_EQ(250, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, ClippingDoesNotPullLowVolumeBackUp) {
+ SetVolumeAndProcess(80);
+
+ EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
+ .WillOnce(Return(kAboveClippedThreshold));
+ EXPECT_CALL(*agc_, Reset()).Times(0);
+ int initial_volume = volume_.GetMicVolume();
+ CallPreProc(1);
+ EXPECT_EQ(initial_volume, volume_.GetMicVolume());
+}
+
+TEST_F(AgcManagerDirectTest, TakesNoActionOnZeroMicVolume) {
+ FirstProcess();
+
+ EXPECT_CALL(*agc_, GetRmsErrorDb(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
+ volume_.SetMicVolume(0);
+ CallProcess(10);
+ EXPECT_EQ(0, volume_.GetMicVolume());
+}
+
+} // namespace webrtc
« no previous file with comments | « webrtc/modules/audio_processing/agc/agc_manager_direct.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698