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 |