tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gain_controller2_unittest.cc (25475B)


      1 /*
      2 *  Copyright (c) 2017 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 "modules/audio_processing/gain_controller2.h"
     12 
     13 #include <algorithm>
     14 #include <cmath>
     15 #include <cstddef>
     16 #include <memory>
     17 #include <optional>
     18 #include <tuple>
     19 #include <vector>
     20 
     21 #include "api/audio/audio_processing.h"
     22 #include "api/environment/environment.h"
     23 #include "api/environment/environment_factory.h"
     24 #include "modules/audio_coding/neteq/tools/input_audio_file.h"
     25 #include "modules/audio_processing/agc2/agc2_testing_common.h"
     26 #include "modules/audio_processing/agc2/cpu_features.h"
     27 #include "modules/audio_processing/agc2/input_volume_controller.h"
     28 #include "modules/audio_processing/agc2/vad_wrapper.h"
     29 #include "modules/audio_processing/audio_buffer.h"
     30 #include "modules/audio_processing/test/audio_buffer_tools.h"
     31 #include "modules/audio_processing/test/bitexactness_tools.h"
     32 #include "rtc_base/checks.h"
     33 #include "test/gmock.h"
     34 #include "test/gtest.h"
     35 
     36 namespace webrtc {
     37 namespace test {
     38 namespace {
     39 
     40 using ::testing::Eq;
     41 using ::testing::Optional;
     42 
     43 using Agc2Config = AudioProcessing::Config::GainController2;
     44 using InputVolumeControllerConfig = InputVolumeController::Config;
     45 
     46 // Sets all the samples in `ab` to `value`.
     47 void SetAudioBufferSamples(float value, AudioBuffer& ab) {
     48  for (size_t k = 0; k < ab.num_channels(); ++k) {
     49    std::fill(ab.channels()[k], ab.channels()[k] + ab.num_frames(), value);
     50  }
     51 }
     52 
     53 float RunAgc2WithConstantInput(GainController2& agc2,
     54                               float input_level,
     55                               int num_frames,
     56                               int sample_rate_hz,
     57                               int num_channels = 1,
     58                               int applied_initial_volume = 0) {
     59  const int num_samples = CheckedDivExact(sample_rate_hz, 100);
     60  AudioBuffer ab(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
     61                 sample_rate_hz, num_channels);
     62 
     63  // Give time to the level estimator to converge.
     64  for (int i = 0; i < num_frames + 1; ++i) {
     65    SetAudioBufferSamples(input_level, ab);
     66    const auto applied_volume = agc2.recommended_input_volume();
     67    agc2.Analyze(applied_volume.value_or(applied_initial_volume), ab);
     68 
     69    agc2.Process(/*speech_probability=*/std::nullopt,
     70                 /*input_volume_changed=*/false, &ab);
     71  }
     72 
     73  // Return the last sample from the last processed frame.
     74  return ab.channels()[0][num_samples - 1];
     75 }
     76 
     77 std::unique_ptr<GainController2> CreateAgc2FixedDigitalMode(
     78    float fixed_gain_db,
     79    int sample_rate_hz) {
     80  Agc2Config config;
     81  config.adaptive_digital.enabled = false;
     82  config.fixed_digital.gain_db = fixed_gain_db;
     83  EXPECT_TRUE(GainController2::Validate(config));
     84  return std::make_unique<GainController2>(CreateEnvironment(), config,
     85                                           InputVolumeControllerConfig{},
     86                                           sample_rate_hz,
     87                                           /*num_channels=*/1,
     88                                           /*use_internal_vad=*/true);
     89 }
     90 
     91 constexpr InputVolumeControllerConfig kTestInputVolumeControllerConfig{
     92    .clipped_level_min = 20,
     93    .clipped_level_step = 30,
     94    .clipped_ratio_threshold = 0.4,
     95    .clipped_wait_frames = 50,
     96    .enable_clipping_predictor = true,
     97    .target_range_max_dbfs = -6,
     98    .target_range_min_dbfs = -70,
     99    .update_input_volume_wait_frames = 100,
    100    .speech_probability_threshold = 0.9,
    101    .speech_ratio_threshold = 1,
    102 };
    103 
    104 }  // namespace
    105 
    106 TEST(GainController2, CheckDefaultConfig) {
    107  Agc2Config config;
    108  EXPECT_TRUE(GainController2::Validate(config));
    109 }
    110 
    111 TEST(GainController2, CheckFixedDigitalConfig) {
    112  Agc2Config config;
    113  // Attenuation is not allowed.
    114  config.fixed_digital.gain_db = -5.0f;
    115  EXPECT_FALSE(GainController2::Validate(config));
    116  // No gain is allowed.
    117  config.fixed_digital.gain_db = 0.0f;
    118  EXPECT_TRUE(GainController2::Validate(config));
    119  // Positive gain is allowed.
    120  config.fixed_digital.gain_db = 15.0f;
    121  EXPECT_TRUE(GainController2::Validate(config));
    122 }
    123 
    124 TEST(GainController2, CheckHeadroomDb) {
    125  Agc2Config config;
    126  config.adaptive_digital.headroom_db = -1.0f;
    127  EXPECT_FALSE(GainController2::Validate(config));
    128  config.adaptive_digital.headroom_db = 0.0f;
    129  EXPECT_TRUE(GainController2::Validate(config));
    130  config.adaptive_digital.headroom_db = 5.0f;
    131  EXPECT_TRUE(GainController2::Validate(config));
    132 }
    133 
    134 TEST(GainController2, CheckMaxGainDb) {
    135  Agc2Config config;
    136  config.adaptive_digital.max_gain_db = -1.0f;
    137  EXPECT_FALSE(GainController2::Validate(config));
    138  config.adaptive_digital.max_gain_db = 0.0f;
    139  EXPECT_FALSE(GainController2::Validate(config));
    140  config.adaptive_digital.max_gain_db = 5.0f;
    141  EXPECT_TRUE(GainController2::Validate(config));
    142 }
    143 
    144 TEST(GainController2, CheckInitialGainDb) {
    145  Agc2Config config;
    146  config.adaptive_digital.initial_gain_db = -1.0f;
    147  EXPECT_FALSE(GainController2::Validate(config));
    148  config.adaptive_digital.initial_gain_db = 0.0f;
    149  EXPECT_TRUE(GainController2::Validate(config));
    150  config.adaptive_digital.initial_gain_db = 5.0f;
    151  EXPECT_TRUE(GainController2::Validate(config));
    152 }
    153 
    154 TEST(GainController2, CheckAdaptiveDigitalMaxGainChangeSpeedConfig) {
    155  Agc2Config config;
    156  config.adaptive_digital.max_gain_change_db_per_second = -1.0f;
    157  EXPECT_FALSE(GainController2::Validate(config));
    158  config.adaptive_digital.max_gain_change_db_per_second = 0.0f;
    159  EXPECT_FALSE(GainController2::Validate(config));
    160  config.adaptive_digital.max_gain_change_db_per_second = 5.0f;
    161  EXPECT_TRUE(GainController2::Validate(config));
    162 }
    163 
    164 TEST(GainController2, CheckAdaptiveDigitalMaxOutputNoiseLevelConfig) {
    165  Agc2Config config;
    166  config.adaptive_digital.max_output_noise_level_dbfs = 5.0f;
    167  EXPECT_FALSE(GainController2::Validate(config));
    168  config.adaptive_digital.max_output_noise_level_dbfs = 0.0f;
    169  EXPECT_TRUE(GainController2::Validate(config));
    170  config.adaptive_digital.max_output_noise_level_dbfs = -5.0f;
    171  EXPECT_TRUE(GainController2::Validate(config));
    172 }
    173 
    174 TEST(GainController2,
    175     CheckGetRecommendedInputVolumeWhenInputVolumeControllerNotEnabled) {
    176  constexpr float kHighInputLevel = 32767.0f;
    177  constexpr float kLowInputLevel = 1000.0f;
    178  constexpr int kInitialInputVolume = 100;
    179  constexpr int kNumChannels = 2;
    180  constexpr int kNumFrames = 5;
    181  constexpr int kSampleRateHz = 16000;
    182 
    183  Agc2Config config;
    184  config.input_volume_controller.enabled = false;
    185 
    186  auto gain_controller = std::make_unique<GainController2>(
    187      CreateEnvironment(), config, InputVolumeControllerConfig{}, kSampleRateHz,
    188      kNumChannels,
    189      /*use_internal_vad=*/true);
    190 
    191  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    192 
    193  // Run AGC for a signal with no clipping or detected speech.
    194  RunAgc2WithConstantInput(*gain_controller, kLowInputLevel, kNumFrames,
    195                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    196 
    197  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    198 
    199  // Run AGC for a signal with clipping.
    200  RunAgc2WithConstantInput(*gain_controller, kHighInputLevel, kNumFrames,
    201                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    202 
    203  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    204 }
    205 
    206 TEST(
    207    GainController2,
    208    CheckGetRecommendedInputVolumeWhenInputVolumeControllerNotEnabledAndSpecificConfigUsed) {
    209  constexpr float kHighInputLevel = 32767.0f;
    210  constexpr float kLowInputLevel = 1000.0f;
    211  constexpr int kInitialInputVolume = 100;
    212  constexpr int kNumChannels = 2;
    213  constexpr int kNumFrames = 5;
    214  constexpr int kSampleRateHz = 16000;
    215 
    216  Agc2Config config;
    217  config.input_volume_controller.enabled = false;
    218 
    219  auto gain_controller = std::make_unique<GainController2>(
    220      CreateEnvironment(), config, kTestInputVolumeControllerConfig,
    221      kSampleRateHz, kNumChannels,
    222      /*use_internal_vad=*/true);
    223 
    224  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    225 
    226  // Run AGC for a signal with no clipping or detected speech.
    227  RunAgc2WithConstantInput(*gain_controller, kLowInputLevel, kNumFrames,
    228                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    229 
    230  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    231 
    232  // Run AGC for a signal with clipping.
    233  RunAgc2WithConstantInput(*gain_controller, kHighInputLevel, kNumFrames,
    234                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    235 
    236  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    237 }
    238 
    239 TEST(GainController2,
    240     CheckGetRecommendedInputVolumeWhenInputVolumeControllerEnabled) {
    241  constexpr float kHighInputLevel = 32767.0f;
    242  constexpr float kLowInputLevel = 1000.0f;
    243  constexpr int kInitialInputVolume = 100;
    244  constexpr int kNumChannels = 2;
    245  constexpr int kNumFrames = 5;
    246  constexpr int kSampleRateHz = 16000;
    247 
    248  Agc2Config config;
    249  config.input_volume_controller.enabled = true;
    250  config.adaptive_digital.enabled = true;
    251 
    252  auto gain_controller = std::make_unique<GainController2>(
    253      CreateEnvironment(), config, InputVolumeControllerConfig{}, kSampleRateHz,
    254      kNumChannels,
    255      /*use_internal_vad=*/true);
    256 
    257  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    258 
    259  // Run AGC for a signal with no clipping or detected speech.
    260  RunAgc2WithConstantInput(*gain_controller, kLowInputLevel, kNumFrames,
    261                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    262 
    263  EXPECT_TRUE(gain_controller->recommended_input_volume().has_value());
    264 
    265  // Run AGC for a signal with clipping.
    266  RunAgc2WithConstantInput(*gain_controller, kHighInputLevel, kNumFrames,
    267                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    268 
    269  EXPECT_TRUE(gain_controller->recommended_input_volume().has_value());
    270 }
    271 
    272 TEST(
    273    GainController2,
    274    CheckGetRecommendedInputVolumeWhenInputVolumeControllerEnabledAndSpecificConfigUsed) {
    275  constexpr float kHighInputLevel = 32767.0f;
    276  constexpr float kLowInputLevel = 1000.0f;
    277  constexpr int kInitialInputVolume = 100;
    278  constexpr int kNumChannels = 2;
    279  constexpr int kNumFrames = 5;
    280  constexpr int kSampleRateHz = 16000;
    281 
    282  Agc2Config config;
    283  config.input_volume_controller.enabled = true;
    284  config.adaptive_digital.enabled = true;
    285 
    286  auto gain_controller = std::make_unique<GainController2>(
    287      CreateEnvironment(), config, kTestInputVolumeControllerConfig,
    288      kSampleRateHz, kNumChannels,
    289      /*use_internal_vad=*/true);
    290 
    291  EXPECT_FALSE(gain_controller->recommended_input_volume().has_value());
    292 
    293  // Run AGC for a signal with no clipping or detected speech.
    294  RunAgc2WithConstantInput(*gain_controller, kLowInputLevel, kNumFrames,
    295                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    296 
    297  EXPECT_TRUE(gain_controller->recommended_input_volume().has_value());
    298 
    299  // Run AGC for a signal with clipping.
    300  RunAgc2WithConstantInput(*gain_controller, kHighInputLevel, kNumFrames,
    301                           kSampleRateHz, kNumChannels, kInitialInputVolume);
    302 
    303  EXPECT_TRUE(gain_controller->recommended_input_volume().has_value());
    304 }
    305 
    306 // Checks that the default config is applied.
    307 TEST(GainController2, ApplyDefaultConfig) {
    308  auto gain_controller2 = std::make_unique<GainController2>(
    309      CreateEnvironment(), Agc2Config{}, InputVolumeControllerConfig{},
    310      /*sample_rate_hz=*/16000, /*num_channels=*/2,
    311      /*use_internal_vad=*/true);
    312  EXPECT_TRUE(gain_controller2.get());
    313 }
    314 
    315 TEST(GainController2FixedDigital, GainShouldChangeOnSetGain) {
    316  constexpr float kInputLevel = 1000.0f;
    317  constexpr size_t kNumFrames = 5;
    318  constexpr size_t kSampleRateHz = 8000;
    319  constexpr float kGain0Db = 0.0f;
    320  constexpr float kGain20Db = 20.0f;
    321 
    322  auto agc2_fixed = CreateAgc2FixedDigitalMode(kGain0Db, kSampleRateHz);
    323 
    324  // Signal level is unchanged with 0 db gain.
    325  EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel, kNumFrames,
    326                                           kSampleRateHz),
    327                  kInputLevel);
    328 
    329  // +20 db should increase signal by a factor of 10.
    330  agc2_fixed->SetFixedGainDb(kGain20Db);
    331  EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel, kNumFrames,
    332                                           kSampleRateHz),
    333                  kInputLevel * 10);
    334 }
    335 
    336 TEST(GainController2FixedDigital, ChangeFixedGainShouldBeFastAndTimeInvariant) {
    337  // Number of frames required for the fixed gain controller to adapt on the
    338  // input signal when the gain changes.
    339  constexpr size_t kNumFrames = 5;
    340 
    341  constexpr float kInputLevel = 1000.0f;
    342  constexpr size_t kSampleRateHz = 8000;
    343  constexpr float kGainDbLow = 0.0f;
    344  constexpr float kGainDbHigh = 25.0f;
    345  static_assert(kGainDbLow < kGainDbHigh, "");
    346 
    347  auto agc2_fixed = CreateAgc2FixedDigitalMode(kGainDbLow, kSampleRateHz);
    348 
    349  // Start with a lower gain.
    350  const float output_level_pre = RunAgc2WithConstantInput(
    351      *agc2_fixed, kInputLevel, kNumFrames, kSampleRateHz);
    352 
    353  // Increase gain.
    354  agc2_fixed->SetFixedGainDb(kGainDbHigh);
    355  static_cast<void>(RunAgc2WithConstantInput(*agc2_fixed, kInputLevel,
    356                                             kNumFrames, kSampleRateHz));
    357 
    358  // Back to the lower gain.
    359  agc2_fixed->SetFixedGainDb(kGainDbLow);
    360  const float output_level_post = RunAgc2WithConstantInput(
    361      *agc2_fixed, kInputLevel, kNumFrames, kSampleRateHz);
    362 
    363  EXPECT_EQ(output_level_pre, output_level_post);
    364 }
    365 
    366 class FixedDigitalTest
    367    : public ::testing::TestWithParam<std::tuple<float, float, int, bool>> {
    368 protected:
    369  float gain_db_min() const { return std::get<0>(GetParam()); }
    370  float gain_db_max() const { return std::get<1>(GetParam()); }
    371  int sample_rate_hz() const { return std::get<2>(GetParam()); }
    372  bool saturation_expected() const { return std::get<3>(GetParam()); }
    373 };
    374 
    375 TEST_P(FixedDigitalTest, CheckSaturationBehaviorWithLimiter) {
    376  for (const float gain_db : test::LinSpace(gain_db_min(), gain_db_max(), 10)) {
    377    SCOPED_TRACE(gain_db);
    378    auto agc2_fixed = CreateAgc2FixedDigitalMode(gain_db, sample_rate_hz());
    379    const float processed_sample =
    380        RunAgc2WithConstantInput(*agc2_fixed, /*input_level=*/32767.0f,
    381                                 /*num_frames=*/5, sample_rate_hz());
    382    if (saturation_expected()) {
    383      EXPECT_FLOAT_EQ(processed_sample, 32767.0f);
    384    } else {
    385      EXPECT_LT(processed_sample, 32767.0f);
    386    }
    387  }
    388 }
    389 
    390 static_assert(test::kLimiterMaxInputLevelDbFs < 10, "");
    391 INSTANTIATE_TEST_SUITE_P(
    392    GainController2,
    393    FixedDigitalTest,
    394    ::testing::Values(
    395        // When gain < `test::kLimiterMaxInputLevelDbFs`, the limiter will not
    396        // saturate the signal (at any sample rate).
    397        std::make_tuple(0.1f,
    398                        test::kLimiterMaxInputLevelDbFs - 0.01f,
    399                        8000,
    400                        false),
    401        std::make_tuple(0.1,
    402                        test::kLimiterMaxInputLevelDbFs - 0.01f,
    403                        48000,
    404                        false),
    405        // When gain > `test::kLimiterMaxInputLevelDbFs`, the limiter will
    406        // saturate the signal (at any sample rate).
    407        std::make_tuple(test::kLimiterMaxInputLevelDbFs + 0.01f,
    408                        10.0f,
    409                        8000,
    410                        true),
    411        std::make_tuple(test::kLimiterMaxInputLevelDbFs + 0.01f,
    412                        10.0f,
    413                        48000,
    414                        true)));
    415 
    416 // Processes a test audio file and checks that the gain applied at the end of
    417 // the recording is close to the expected value.
    418 TEST(GainController2, CheckFinalGainWithAdaptiveDigitalController) {
    419  constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
    420  constexpr int kStereo = 2;
    421 
    422  // Create AGC2 enabling only the adaptive digital controller.
    423  Agc2Config config;
    424  config.fixed_digital.gain_db = 0.0f;
    425  config.adaptive_digital.enabled = true;
    426  GainController2 agc2(CreateEnvironment(), config,
    427                       /*input_volume_controller_config=*/{}, kSampleRateHz,
    428                       kStereo,
    429                       /*use_internal_vad=*/true);
    430 
    431  test::InputAudioFile input_file(
    432      test::GetApmCaptureTestVectorFileName(kSampleRateHz),
    433      /*loop_at_end=*/true);
    434  const StreamConfig stream_config(kSampleRateHz, kStereo);
    435 
    436  // Init buffers.
    437  constexpr int kFrameDurationMs = 10;
    438  std::vector<float> frame(kStereo * stream_config.num_frames());
    439  AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
    440                           kSampleRateHz, kStereo);
    441 
    442  // Simulate.
    443  constexpr float kGainDb = -6.0f;
    444  const float gain = std::pow(10.0f, kGainDb / 20.0f);
    445  constexpr int kDurationMs = 10000;
    446  constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
    447  for (int i = 0; i < kNumFramesToProcess; ++i) {
    448    ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
    449                                   stream_config.num_channels(), &input_file,
    450                                   frame);
    451    // Apply a fixed gain to the input audio.
    452    for (float& x : frame) {
    453      x *= gain;
    454    }
    455    test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
    456    agc2.Process(/*speech_probability=*/std::nullopt,
    457                 /*input_volume_changed=*/false, &audio_buffer);
    458  }
    459 
    460  // Estimate the applied gain by processing a probing frame.
    461  SetAudioBufferSamples(/*value=*/1.0f, audio_buffer);
    462  agc2.Process(/*speech_probability=*/std::nullopt,
    463               /*input_volume_changed=*/false, &audio_buffer);
    464  const float applied_gain_db =
    465      20.0f * std::log10(audio_buffer.channels_const()[0][0]);
    466 
    467  constexpr float kExpectedGainDb = 7.0f;
    468  constexpr float kToleranceDb = 0.3f;
    469  EXPECT_NEAR(applied_gain_db, kExpectedGainDb, kToleranceDb);
    470 }
    471 
    472 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    473 // Checks that `GainController2` crashes in debug mode if it runs its internal
    474 // VAD and the speech probability values are provided by the caller.
    475 TEST(GainController2DeathTest,
    476     DebugCrashIfUseInternalVadAndSpeechProbabilityGiven) {
    477  constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
    478  constexpr int kStereo = 2;
    479  AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
    480                           kSampleRateHz, kStereo);
    481  // Create AGC2 so that the interval VAD is also created.
    482  GainController2 agc2(
    483      CreateEnvironment(), /*config=*/{.adaptive_digital = {.enabled = true}},
    484      /*input_volume_controller_config=*/{}, kSampleRateHz, kStereo,
    485      /*use_internal_vad=*/true);
    486 
    487  EXPECT_DEATH(agc2.Process(/*speech_probability=*/0.123f,
    488                            /*input_volume_changed=*/false, &audio_buffer),
    489               "");
    490 }
    491 #endif
    492 
    493 // Processes a test audio file and checks that the injected speech probability
    494 // is not ignored when the internal VAD is not used.
    495 TEST(GainController2,
    496     CheckInjectedVadProbabilityUsedWithAdaptiveDigitalController) {
    497  constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
    498  constexpr int kStereo = 2;
    499 
    500  // Create AGC2 enabling only the adaptive digital controller.
    501  const Environment env = CreateEnvironment();
    502  Agc2Config config;
    503  config.fixed_digital.gain_db = 0.0f;
    504  config.adaptive_digital.enabled = true;
    505  GainController2 agc2(env, config, /*input_volume_controller_config=*/{},
    506                       kSampleRateHz, kStereo,
    507                       /*use_internal_vad=*/false);
    508  GainController2 agc2_reference(env, config,
    509                                 /*input_volume_controller_config=*/{},
    510                                 kSampleRateHz, kStereo,
    511                                 /*use_internal_vad=*/true);
    512 
    513  test::InputAudioFile input_file(
    514      test::GetApmCaptureTestVectorFileName(kSampleRateHz),
    515      /*loop_at_end=*/true);
    516  const StreamConfig stream_config(kSampleRateHz, kStereo);
    517 
    518  // Init buffers.
    519  constexpr int kFrameDurationMs = 10;
    520  std::vector<float> frame(kStereo * stream_config.num_frames());
    521  AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
    522                           kSampleRateHz, kStereo);
    523  AudioBuffer audio_buffer_reference(kSampleRateHz, kStereo, kSampleRateHz,
    524                                     kStereo, kSampleRateHz, kStereo);
    525  // Simulate.
    526  constexpr float kGainDb = -6.0f;
    527  const float gain = std::pow(10.0f, kGainDb / 20.0f);
    528  constexpr int kDurationMs = 10000;
    529  constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
    530  constexpr float kSpeechProbabilities[] = {1.0f, 0.3f};
    531  constexpr float kEpsilon = 0.0001f;
    532  bool all_samples_zero = true;
    533  bool all_samples_equal = true;
    534  for (int i = 0, j = 0; i < kNumFramesToProcess; ++i, j = 1 - j) {
    535    ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
    536                                   stream_config.num_channels(), &input_file,
    537                                   frame);
    538    // Apply a fixed gain to the input audio.
    539    for (float& x : frame) {
    540      x *= gain;
    541    }
    542    test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
    543    agc2.Process(kSpeechProbabilities[j], /*input_volume_changed=*/false,
    544                 &audio_buffer);
    545    test::CopyVectorToAudioBuffer(stream_config, frame,
    546                                  &audio_buffer_reference);
    547    agc2_reference.Process(/*speech_probability=*/std::nullopt,
    548                           /*input_volume_changed=*/false,
    549                           &audio_buffer_reference);
    550    // Check the output buffers.
    551    for (int channel = 0; channel < kStereo; ++channel) {
    552      for (int frame_num = 0;
    553           frame_num < static_cast<int>(audio_buffer.num_frames());
    554           ++frame_num) {
    555        all_samples_zero &=
    556            fabs(audio_buffer.channels_const()[channel][frame_num]) < kEpsilon;
    557        all_samples_equal &=
    558            fabs(audio_buffer.channels_const()[channel][frame_num] -
    559                 audio_buffer_reference.channels_const()[channel][frame_num]) <
    560            kEpsilon;
    561      }
    562    }
    563  }
    564  EXPECT_FALSE(all_samples_zero);
    565  EXPECT_FALSE(all_samples_equal);
    566 }
    567 
    568 // Processes a test audio file and checks that the output is equal when
    569 // an injected speech probability from `VoiceActivityDetectorWrapper` and
    570 // the speech probability computed by the internal VAD are the same.
    571 TEST(GainController2,
    572     CheckEqualResultFromInjectedVadProbabilityWithAdaptiveDigitalController) {
    573  constexpr int kSampleRateHz = AudioProcessing::kSampleRate48kHz;
    574  constexpr int kStereo = 2;
    575 
    576  // Create AGC2 enabling only the adaptive digital controller.
    577  const Environment env = CreateEnvironment();
    578  Agc2Config config;
    579  config.fixed_digital.gain_db = 0.0f;
    580  config.adaptive_digital.enabled = true;
    581  GainController2 agc2(env, config, /*input_volume_controller_config=*/{},
    582                       kSampleRateHz, kStereo,
    583                       /*use_internal_vad=*/false);
    584  GainController2 agc2_reference(env, config,
    585                                 /*input_volume_controller_config=*/{},
    586                                 kSampleRateHz, kStereo,
    587                                 /*use_internal_vad=*/true);
    588  VoiceActivityDetectorWrapper vad(GetAvailableCpuFeatures(), kSampleRateHz);
    589  test::InputAudioFile input_file(
    590      test::GetApmCaptureTestVectorFileName(kSampleRateHz),
    591      /*loop_at_end=*/true);
    592  const StreamConfig stream_config(kSampleRateHz, kStereo);
    593 
    594  // Init buffers.
    595  constexpr int kFrameDurationMs = 10;
    596  std::vector<float> frame(kStereo * stream_config.num_frames());
    597  AudioBuffer audio_buffer(kSampleRateHz, kStereo, kSampleRateHz, kStereo,
    598                           kSampleRateHz, kStereo);
    599  AudioBuffer audio_buffer_reference(kSampleRateHz, kStereo, kSampleRateHz,
    600                                     kStereo, kSampleRateHz, kStereo);
    601 
    602  // Simulate.
    603  constexpr float kGainDb = -6.0f;
    604  const float gain = std::pow(10.0f, kGainDb / 20.0f);
    605  constexpr int kDurationMs = 10000;
    606  constexpr int kNumFramesToProcess = kDurationMs / kFrameDurationMs;
    607  for (int i = 0; i < kNumFramesToProcess; ++i) {
    608    ReadFloatSamplesFromStereoFile(stream_config.num_frames(),
    609                                   stream_config.num_channels(), &input_file,
    610                                   frame);
    611    // Apply a fixed gain to the input audio.
    612    for (float& x : frame) {
    613      x *= gain;
    614    }
    615    test::CopyVectorToAudioBuffer(stream_config, frame,
    616                                  &audio_buffer_reference);
    617    agc2_reference.Process(std::nullopt, /*input_volume_changed=*/false,
    618                           &audio_buffer_reference);
    619    test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
    620    float speech_probability = vad.Analyze(audio_buffer.view());
    621    agc2.Process(speech_probability, /*input_volume_changed=*/false,
    622                 &audio_buffer);
    623    // Check the output buffer.
    624    for (int channel = 0; channel < kStereo; ++channel) {
    625      for (int frame_num = 0;
    626           frame_num < static_cast<int>(audio_buffer.num_frames());
    627           ++frame_num) {
    628        EXPECT_FLOAT_EQ(
    629            audio_buffer.channels_const()[channel][frame_num],
    630            audio_buffer_reference.channels_const()[channel][frame_num]);
    631      }
    632    }
    633  }
    634 }
    635 
    636 }  // namespace test
    637 }  // namespace webrtc