1/* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" 12 13#include "testing/gmock/include/gmock/gmock.h" 14#include "testing/gtest/include/gtest/gtest.h" 15#include "webrtc/common_types.h" 16#include "webrtc/modules/audio_processing/agc/mock_agc.h" 17#include "webrtc/modules/audio_processing/include/mock_audio_processing.h" 18#include "webrtc/system_wrappers/include/trace.h" 19#include "webrtc/test/testsupport/trace_to_stderr.h" 20 21using ::testing::_; 22using ::testing::DoAll; 23using ::testing::Eq; 24using ::testing::Mock; 25using ::testing::Return; 26using ::testing::SetArgPointee; 27using ::testing::SetArgReferee; 28 29namespace webrtc { 30namespace { 31 32const int kSampleRateHz = 32000; 33const int kNumChannels = 1; 34const int kSamplesPerChannel = kSampleRateHz / 100; 35const int kInitialVolume = 128; 36const float kAboveClippedThreshold = 0.2f; 37 38class TestVolumeCallbacks : public VolumeCallbacks { 39 public: 40 TestVolumeCallbacks() : volume_(0) {} 41 void SetMicVolume(int volume) override { volume_ = volume; } 42 int GetMicVolume() override { return volume_; } 43 44 private: 45 int volume_; 46}; 47 48} // namespace 49 50class AgcManagerDirectTest : public ::testing::Test { 51 protected: 52 AgcManagerDirectTest() 53 : agc_(new MockAgc), manager_(agc_, &gctrl_, &volume_, kInitialVolume) { 54 ExpectInitialize(); 55 manager_.Initialize(); 56 } 57 58 void FirstProcess() { 59 EXPECT_CALL(*agc_, Reset()); 60 EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false)); 61 CallProcess(1); 62 } 63 64 void SetVolumeAndProcess(int volume) { 65 volume_.SetMicVolume(volume); 66 FirstProcess(); 67 } 68 69 void ExpectCheckVolumeAndReset(int volume) { 70 volume_.SetMicVolume(volume); 71 EXPECT_CALL(*agc_, Reset()); 72 } 73 74 void ExpectInitialize() { 75 EXPECT_CALL(gctrl_, set_mode(GainControl::kFixedDigital)); 76 EXPECT_CALL(gctrl_, set_target_level_dbfs(2)); 77 EXPECT_CALL(gctrl_, set_compression_gain_db(7)); 78 EXPECT_CALL(gctrl_, enable_limiter(true)); 79 } 80 81 void CallProcess(int num_calls) { 82 for (int i = 0; i < num_calls; ++i) { 83 EXPECT_CALL(*agc_, Process(_, _, _)).WillOnce(Return(0)); 84 manager_.Process(nullptr, kSamplesPerChannel, kSampleRateHz); 85 } 86 } 87 88 void CallPreProc(int num_calls) { 89 for (int i = 0; i < num_calls; ++i) { 90 manager_.AnalyzePreProcess(nullptr, kNumChannels, kSamplesPerChannel); 91 } 92 } 93 94 MockAgc* agc_; 95 MockGainControl gctrl_; 96 TestVolumeCallbacks volume_; 97 AgcManagerDirect manager_; 98 test::TraceToStderr trace_to_stderr; 99}; 100 101TEST_F(AgcManagerDirectTest, StartupMinVolumeConfigurationIsRespected) { 102 FirstProcess(); 103 EXPECT_EQ(kInitialVolume, volume_.GetMicVolume()); 104} 105 106TEST_F(AgcManagerDirectTest, MicVolumeResponseToRmsError) { 107 FirstProcess(); 108 109 // Compressor default; no residual error. 110 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 111 .WillOnce(DoAll(SetArgPointee<0>(5), Return(true))); 112 CallProcess(1); 113 114 // Inside the compressor's window; no change of volume. 115 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 116 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))); 117 CallProcess(1); 118 119 // Above the compressor's window; volume should be increased. 120 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 121 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))); 122 CallProcess(1); 123 EXPECT_EQ(130, volume_.GetMicVolume()); 124 125 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 126 .WillOnce(DoAll(SetArgPointee<0>(20), Return(true))); 127 CallProcess(1); 128 EXPECT_EQ(168, volume_.GetMicVolume()); 129 130 // Inside the compressor's window; no change of volume. 131 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 132 .WillOnce(DoAll(SetArgPointee<0>(5), Return(true))); 133 CallProcess(1); 134 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 135 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))); 136 CallProcess(1); 137 138 // Below the compressor's window; volume should be decreased. 139 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 140 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 141 CallProcess(1); 142 EXPECT_EQ(167, volume_.GetMicVolume()); 143 144 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 145 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 146 CallProcess(1); 147 EXPECT_EQ(163, volume_.GetMicVolume()); 148 149 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 150 .WillOnce(DoAll(SetArgPointee<0>(-9), Return(true))); 151 CallProcess(1); 152 EXPECT_EQ(129, volume_.GetMicVolume()); 153} 154 155TEST_F(AgcManagerDirectTest, MicVolumeIsLimited) { 156 FirstProcess(); 157 158 // Maximum upwards change is limited. 159 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 160 .WillOnce(DoAll(SetArgPointee<0>(30), Return(true))); 161 CallProcess(1); 162 EXPECT_EQ(183, volume_.GetMicVolume()); 163 164 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 165 .WillOnce(DoAll(SetArgPointee<0>(30), Return(true))); 166 CallProcess(1); 167 EXPECT_EQ(243, volume_.GetMicVolume()); 168 169 // Won't go higher than the maximum. 170 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 171 .WillOnce(DoAll(SetArgPointee<0>(30), Return(true))); 172 CallProcess(1); 173 EXPECT_EQ(255, volume_.GetMicVolume()); 174 175 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 176 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 177 CallProcess(1); 178 EXPECT_EQ(254, volume_.GetMicVolume()); 179 180 // Maximum downwards change is limited. 181 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 182 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 183 CallProcess(1); 184 EXPECT_EQ(194, volume_.GetMicVolume()); 185 186 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 187 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 188 CallProcess(1); 189 EXPECT_EQ(137, volume_.GetMicVolume()); 190 191 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 192 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 193 CallProcess(1); 194 EXPECT_EQ(88, volume_.GetMicVolume()); 195 196 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 197 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 198 CallProcess(1); 199 EXPECT_EQ(54, volume_.GetMicVolume()); 200 201 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 202 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 203 CallProcess(1); 204 EXPECT_EQ(33, volume_.GetMicVolume()); 205 206 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 207 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 208 CallProcess(1); 209 EXPECT_EQ(18, volume_.GetMicVolume()); 210 211 // Won't go lower than the minimum. 212 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 213 .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true))); 214 CallProcess(1); 215 EXPECT_EQ(12, volume_.GetMicVolume()); 216} 217 218TEST_F(AgcManagerDirectTest, CompressorStepsTowardsTarget) { 219 FirstProcess(); 220 221 // Compressor default; no call to set_compression_gain_db. 222 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 223 .WillOnce(DoAll(SetArgPointee<0>(5), Return(true))) 224 .WillRepeatedly(Return(false)); 225 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 226 CallProcess(20); 227 228 // Moves slowly upwards. 229 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 230 .WillOnce(DoAll(SetArgPointee<0>(9), Return(true))) 231 .WillRepeatedly(Return(false)); 232 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 233 CallProcess(19); 234 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 235 CallProcess(1); 236 237 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 238 CallProcess(19); 239 EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0)); 240 CallProcess(1); 241 242 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 243 CallProcess(20); 244 245 // Moves slowly downward, then reverses before reaching the original target. 246 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 247 .WillOnce(DoAll(SetArgPointee<0>(5), Return(true))) 248 .WillRepeatedly(Return(false)); 249 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 250 CallProcess(19); 251 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 252 CallProcess(1); 253 254 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 255 .WillOnce(DoAll(SetArgPointee<0>(9), Return(true))) 256 .WillRepeatedly(Return(false)); 257 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 258 CallProcess(19); 259 EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0)); 260 CallProcess(1); 261 262 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 263 CallProcess(20); 264} 265 266TEST_F(AgcManagerDirectTest, CompressorErrorIsDeemphasized) { 267 FirstProcess(); 268 269 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 270 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))) 271 .WillRepeatedly(Return(false)); 272 CallProcess(19); 273 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 274 CallProcess(20); 275 EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0)); 276 CallProcess(1); 277 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 278 CallProcess(20); 279 280 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 281 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))) 282 .WillRepeatedly(Return(false)); 283 CallProcess(19); 284 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 285 CallProcess(20); 286 EXPECT_CALL(gctrl_, set_compression_gain_db(7)).WillOnce(Return(0)); 287 CallProcess(20); 288 EXPECT_CALL(gctrl_, set_compression_gain_db(6)).WillOnce(Return(0)); 289 CallProcess(1); 290 EXPECT_CALL(gctrl_, set_compression_gain_db(_)).Times(0); 291 CallProcess(20); 292} 293 294TEST_F(AgcManagerDirectTest, CompressorReachesMaximum) { 295 FirstProcess(); 296 297 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 298 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))) 299 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))) 300 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))) 301 .WillOnce(DoAll(SetArgPointee<0>(10), Return(true))) 302 .WillRepeatedly(Return(false)); 303 CallProcess(19); 304 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 305 CallProcess(20); 306 EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0)); 307 CallProcess(20); 308 EXPECT_CALL(gctrl_, set_compression_gain_db(10)).WillOnce(Return(0)); 309 CallProcess(20); 310 EXPECT_CALL(gctrl_, set_compression_gain_db(11)).WillOnce(Return(0)); 311 CallProcess(20); 312 EXPECT_CALL(gctrl_, set_compression_gain_db(12)).WillOnce(Return(0)); 313 CallProcess(1); 314} 315 316TEST_F(AgcManagerDirectTest, CompressorReachesMinimum) { 317 FirstProcess(); 318 319 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 320 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))) 321 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))) 322 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))) 323 .WillOnce(DoAll(SetArgPointee<0>(0), Return(true))) 324 .WillRepeatedly(Return(false)); 325 CallProcess(19); 326 EXPECT_CALL(gctrl_, set_compression_gain_db(6)).WillOnce(Return(0)); 327 CallProcess(20); 328 EXPECT_CALL(gctrl_, set_compression_gain_db(5)).WillOnce(Return(0)); 329 CallProcess(20); 330 EXPECT_CALL(gctrl_, set_compression_gain_db(4)).WillOnce(Return(0)); 331 CallProcess(20); 332 EXPECT_CALL(gctrl_, set_compression_gain_db(3)).WillOnce(Return(0)); 333 CallProcess(20); 334 EXPECT_CALL(gctrl_, set_compression_gain_db(2)).WillOnce(Return(0)); 335 CallProcess(1); 336} 337 338TEST_F(AgcManagerDirectTest, NoActionWhileMuted) { 339 manager_.SetCaptureMuted(true); 340 manager_.Process(nullptr, kSamplesPerChannel, kSampleRateHz); 341} 342 343TEST_F(AgcManagerDirectTest, UnmutingChecksVolumeWithoutRaising) { 344 FirstProcess(); 345 346 manager_.SetCaptureMuted(true); 347 manager_.SetCaptureMuted(false); 348 ExpectCheckVolumeAndReset(127); 349 // SetMicVolume should not be called. 350 EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false)); 351 CallProcess(1); 352 EXPECT_EQ(127, volume_.GetMicVolume()); 353} 354 355TEST_F(AgcManagerDirectTest, UnmutingRaisesTooLowVolume) { 356 FirstProcess(); 357 358 manager_.SetCaptureMuted(true); 359 manager_.SetCaptureMuted(false); 360 ExpectCheckVolumeAndReset(11); 361 EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false)); 362 CallProcess(1); 363 EXPECT_EQ(12, volume_.GetMicVolume()); 364} 365 366TEST_F(AgcManagerDirectTest, ManualLevelChangeResultsInNoSetMicCall) { 367 FirstProcess(); 368 369 // Change outside of compressor's range, which would normally trigger a call 370 // to SetMicVolume. 371 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 372 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))); 373 // GetMicVolume returns a value outside of the quantization slack, indicating 374 // a manual volume change. 375 volume_.SetMicVolume(154); 376 // SetMicVolume should not be called. 377 EXPECT_CALL(*agc_, Reset()).Times(1); 378 CallProcess(1); 379 EXPECT_EQ(154, volume_.GetMicVolume()); 380 381 // Do the same thing, except downwards now. 382 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 383 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 384 volume_.SetMicVolume(100); 385 EXPECT_CALL(*agc_, Reset()).Times(1); 386 CallProcess(1); 387 EXPECT_EQ(100, volume_.GetMicVolume()); 388 389 // And finally verify the AGC continues working without a manual change. 390 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 391 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 392 CallProcess(1); 393 EXPECT_EQ(99, volume_.GetMicVolume()); 394} 395 396TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeFromMax) { 397 FirstProcess(); 398 399 // Force the mic up to max volume. Takes a few steps due to the residual 400 // gain limitation. 401 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 402 .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true))); 403 CallProcess(1); 404 EXPECT_EQ(183, volume_.GetMicVolume()); 405 CallProcess(1); 406 EXPECT_EQ(243, volume_.GetMicVolume()); 407 CallProcess(1); 408 EXPECT_EQ(255, volume_.GetMicVolume()); 409 410 // Manual change does not result in SetMicVolume call. 411 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 412 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 413 volume_.SetMicVolume(50); 414 EXPECT_CALL(*agc_, Reset()).Times(1); 415 CallProcess(1); 416 EXPECT_EQ(50, volume_.GetMicVolume()); 417 418 // Continues working as usual afterwards. 419 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 420 .WillOnce(DoAll(SetArgPointee<0>(20), Return(true))); 421 CallProcess(1); 422 EXPECT_EQ(69, volume_.GetMicVolume()); 423} 424 425TEST_F(AgcManagerDirectTest, RecoveryAfterManualLevelChangeBelowMin) { 426 FirstProcess(); 427 428 // Manual change below min. 429 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 430 .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true))); 431 // Don't set to zero, which will cause AGC to take no action. 432 volume_.SetMicVolume(1); 433 EXPECT_CALL(*agc_, Reset()).Times(1); 434 CallProcess(1); 435 EXPECT_EQ(1, volume_.GetMicVolume()); 436 437 // Continues working as usual afterwards. 438 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 439 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))); 440 CallProcess(1); 441 EXPECT_EQ(2, volume_.GetMicVolume()); 442 443 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 444 .WillOnce(DoAll(SetArgPointee<0>(30), Return(true))); 445 CallProcess(1); 446 EXPECT_EQ(11, volume_.GetMicVolume()); 447 448 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 449 .WillOnce(DoAll(SetArgPointee<0>(20), Return(true))); 450 CallProcess(1); 451 EXPECT_EQ(18, volume_.GetMicVolume()); 452} 453 454TEST_F(AgcManagerDirectTest, NoClippingHasNoImpact) { 455 FirstProcess(); 456 457 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillRepeatedly(Return(0)); 458 CallPreProc(100); 459 EXPECT_EQ(128, volume_.GetMicVolume()); 460} 461 462TEST_F(AgcManagerDirectTest, ClippingUnderThresholdHasNoImpact) { 463 FirstProcess(); 464 465 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.099)); 466 CallPreProc(1); 467 EXPECT_EQ(128, volume_.GetMicVolume()); 468} 469 470TEST_F(AgcManagerDirectTest, ClippingLowersVolume) { 471 SetVolumeAndProcess(255); 472 473 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.101)); 474 EXPECT_CALL(*agc_, Reset()).Times(1); 475 CallPreProc(1); 476 EXPECT_EQ(240, volume_.GetMicVolume()); 477} 478 479TEST_F(AgcManagerDirectTest, WaitingPeriodBetweenClippingChecks) { 480 SetVolumeAndProcess(255); 481 482 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 483 .WillOnce(Return(kAboveClippedThreshold)); 484 EXPECT_CALL(*agc_, Reset()).Times(1); 485 CallPreProc(1); 486 EXPECT_EQ(240, volume_.GetMicVolume()); 487 488 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 489 .WillRepeatedly(Return(kAboveClippedThreshold)); 490 EXPECT_CALL(*agc_, Reset()).Times(0); 491 CallPreProc(300); 492 EXPECT_EQ(240, volume_.GetMicVolume()); 493 494 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 495 .WillOnce(Return(kAboveClippedThreshold)); 496 EXPECT_CALL(*agc_, Reset()).Times(1); 497 CallPreProc(1); 498 EXPECT_EQ(225, volume_.GetMicVolume()); 499} 500 501TEST_F(AgcManagerDirectTest, ClippingLoweringIsLimited) { 502 SetVolumeAndProcess(180); 503 504 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 505 .WillOnce(Return(kAboveClippedThreshold)); 506 EXPECT_CALL(*agc_, Reset()).Times(1); 507 CallPreProc(1); 508 EXPECT_EQ(170, volume_.GetMicVolume()); 509 510 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 511 .WillRepeatedly(Return(kAboveClippedThreshold)); 512 EXPECT_CALL(*agc_, Reset()).Times(0); 513 CallPreProc(1000); 514 EXPECT_EQ(170, volume_.GetMicVolume()); 515} 516 517TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenEqualToLevel) { 518 SetVolumeAndProcess(255); 519 520 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 521 .WillOnce(Return(kAboveClippedThreshold)); 522 EXPECT_CALL(*agc_, Reset()).Times(1); 523 CallPreProc(1); 524 EXPECT_EQ(240, volume_.GetMicVolume()); 525 526 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 527 .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true))); 528 CallProcess(10); 529 EXPECT_EQ(240, volume_.GetMicVolume()); 530} 531 532TEST_F(AgcManagerDirectTest, ClippingMaxIsRespectedWhenHigherThanLevel) { 533 SetVolumeAndProcess(200); 534 535 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 536 .WillOnce(Return(kAboveClippedThreshold)); 537 EXPECT_CALL(*agc_, Reset()).Times(1); 538 CallPreProc(1); 539 EXPECT_EQ(185, volume_.GetMicVolume()); 540 541 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 542 .WillRepeatedly(DoAll(SetArgPointee<0>(40), Return(true))); 543 CallProcess(1); 544 EXPECT_EQ(240, volume_.GetMicVolume()); 545 CallProcess(10); 546 EXPECT_EQ(240, volume_.GetMicVolume()); 547} 548 549TEST_F(AgcManagerDirectTest, MaxCompressionIsIncreasedAfterClipping) { 550 SetVolumeAndProcess(210); 551 552 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 553 .WillOnce(Return(kAboveClippedThreshold)); 554 EXPECT_CALL(*agc_, Reset()).Times(1); 555 CallPreProc(1); 556 EXPECT_EQ(195, volume_.GetMicVolume()); 557 558 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 559 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))) 560 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))) 561 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))) 562 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))) 563 .WillOnce(DoAll(SetArgPointee<0>(11), Return(true))) 564 .WillRepeatedly(Return(false)); 565 CallProcess(19); 566 EXPECT_CALL(gctrl_, set_compression_gain_db(8)).WillOnce(Return(0)); 567 CallProcess(20); 568 EXPECT_CALL(gctrl_, set_compression_gain_db(9)).WillOnce(Return(0)); 569 CallProcess(20); 570 EXPECT_CALL(gctrl_, set_compression_gain_db(10)).WillOnce(Return(0)); 571 CallProcess(20); 572 EXPECT_CALL(gctrl_, set_compression_gain_db(11)).WillOnce(Return(0)); 573 CallProcess(20); 574 EXPECT_CALL(gctrl_, set_compression_gain_db(12)).WillOnce(Return(0)); 575 CallProcess(20); 576 EXPECT_CALL(gctrl_, set_compression_gain_db(13)).WillOnce(Return(0)); 577 CallProcess(1); 578 579 // Continue clipping until we hit the maximum surplus compression. 580 CallPreProc(300); 581 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 582 .WillOnce(Return(kAboveClippedThreshold)); 583 EXPECT_CALL(*agc_, Reset()).Times(1); 584 CallPreProc(1); 585 EXPECT_EQ(180, volume_.GetMicVolume()); 586 587 CallPreProc(300); 588 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 589 .WillOnce(Return(kAboveClippedThreshold)); 590 EXPECT_CALL(*agc_, Reset()).Times(1); 591 CallPreProc(1); 592 EXPECT_EQ(170, volume_.GetMicVolume()); 593 594 // Current level is now at the minimum, but the maximum allowed level still 595 // has more to decrease. 596 CallPreProc(300); 597 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 598 .WillOnce(Return(kAboveClippedThreshold)); 599 CallPreProc(1); 600 601 CallPreProc(300); 602 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 603 .WillOnce(Return(kAboveClippedThreshold)); 604 CallPreProc(1); 605 606 CallPreProc(300); 607 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 608 .WillOnce(Return(kAboveClippedThreshold)); 609 CallPreProc(1); 610 611 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 612 .WillOnce(DoAll(SetArgPointee<0>(16), Return(true))) 613 .WillOnce(DoAll(SetArgPointee<0>(16), Return(true))) 614 .WillOnce(DoAll(SetArgPointee<0>(16), Return(true))) 615 .WillOnce(DoAll(SetArgPointee<0>(16), Return(true))) 616 .WillRepeatedly(Return(false)); 617 CallProcess(19); 618 EXPECT_CALL(gctrl_, set_compression_gain_db(14)).WillOnce(Return(0)); 619 CallProcess(20); 620 EXPECT_CALL(gctrl_, set_compression_gain_db(15)).WillOnce(Return(0)); 621 CallProcess(20); 622 EXPECT_CALL(gctrl_, set_compression_gain_db(16)).WillOnce(Return(0)); 623 CallProcess(20); 624 EXPECT_CALL(gctrl_, set_compression_gain_db(17)).WillOnce(Return(0)); 625 CallProcess(20); 626 EXPECT_CALL(gctrl_, set_compression_gain_db(18)).WillOnce(Return(0)); 627 CallProcess(1); 628} 629 630TEST_F(AgcManagerDirectTest, UserCanRaiseVolumeAfterClipping) { 631 SetVolumeAndProcess(225); 632 633 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 634 .WillOnce(Return(kAboveClippedThreshold)); 635 EXPECT_CALL(*agc_, Reset()).Times(1); 636 CallPreProc(1); 637 EXPECT_EQ(210, volume_.GetMicVolume()); 638 639 // High enough error to trigger a volume check. 640 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 641 .WillOnce(DoAll(SetArgPointee<0>(14), Return(true))); 642 // User changed the volume. 643 volume_.SetMicVolume(250); 644 EXPECT_CALL(*agc_, Reset()).Times(1); 645 CallProcess(1); 646 EXPECT_EQ(250, volume_.GetMicVolume()); 647 648 // Move down... 649 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 650 .WillOnce(DoAll(SetArgPointee<0>(-10), Return(true))); 651 CallProcess(1); 652 EXPECT_EQ(210, volume_.GetMicVolume()); 653 // And back up to the new max established by the user. 654 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 655 .WillOnce(DoAll(SetArgPointee<0>(40), Return(true))); 656 CallProcess(1); 657 EXPECT_EQ(250, volume_.GetMicVolume()); 658 // Will not move above new maximum. 659 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 660 .WillOnce(DoAll(SetArgPointee<0>(30), Return(true))); 661 CallProcess(1); 662 EXPECT_EQ(250, volume_.GetMicVolume()); 663} 664 665TEST_F(AgcManagerDirectTest, ClippingDoesNotPullLowVolumeBackUp) { 666 SetVolumeAndProcess(80); 667 668 EXPECT_CALL(*agc_, AnalyzePreproc(_, _)) 669 .WillOnce(Return(kAboveClippedThreshold)); 670 EXPECT_CALL(*agc_, Reset()).Times(0); 671 int initial_volume = volume_.GetMicVolume(); 672 CallPreProc(1); 673 EXPECT_EQ(initial_volume, volume_.GetMicVolume()); 674} 675 676TEST_F(AgcManagerDirectTest, TakesNoActionOnZeroMicVolume) { 677 FirstProcess(); 678 679 EXPECT_CALL(*agc_, GetRmsErrorDb(_)) 680 .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true))); 681 volume_.SetMicVolume(0); 682 CallProcess(10); 683 EXPECT_EQ(0, volume_.GetMicVolume()); 684} 685 686} // namespace webrtc 687