tor-browser

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

echo_canceller3_unittest.cc (53113B)


      1 /*
      2 *  Copyright (c) 2016 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/aec3/echo_canceller3.h"
     12 
     13 #include <algorithm>
     14 #include <cstddef>
     15 #include <deque>
     16 #include <memory>
     17 #include <optional>
     18 #include <string>
     19 #include <utility>
     20 #include <vector>
     21 
     22 #include "api/array_view.h"
     23 #include "api/audio/echo_canceller3_config.h"
     24 #include "api/audio/echo_control.h"
     25 #include "api/environment/environment.h"
     26 #include "api/environment/environment_factory.h"
     27 #include "api/field_trials.h"
     28 #include "modules/audio_processing/aec3/aec3_common.h"
     29 #include "modules/audio_processing/aec3/block.h"
     30 #include "modules/audio_processing/aec3/block_processor.h"
     31 #include "modules/audio_processing/aec3/mock/mock_block_processor.h"
     32 #include "modules/audio_processing/audio_buffer.h"
     33 #include "modules/audio_processing/high_pass_filter.h"
     34 #include "modules/audio_processing/logging/apm_data_dumper.h"
     35 #include "rtc_base/checks.h"
     36 #include "rtc_base/strings/string_builder.h"
     37 #include "test/create_test_field_trials.h"
     38 #include "test/gmock.h"
     39 #include "test/gtest.h"
     40 
     41 namespace webrtc {
     42 namespace {
     43 
     44 using ::testing::_;
     45 using ::testing::StrictMock;
     46 
     47 // Populates the frame with linearly increasing sample values for each band,
     48 // with a band-specific offset, in order to allow simple bitexactness
     49 // verification for each band.
     50 void PopulateInputFrame(size_t frame_length,
     51                        size_t num_bands,
     52                        size_t frame_index,
     53                        float* const* frame,
     54                        int offset) {
     55  for (size_t k = 0; k < num_bands; ++k) {
     56    for (size_t i = 0; i < frame_length; ++i) {
     57      float value = static_cast<int>(frame_index * frame_length + i) + offset;
     58      frame[k][i] = (value > 0 ? 5000 * k + value : 0);
     59    }
     60  }
     61 }
     62 
     63 // Populates the frame with linearly increasing sample values.
     64 void PopulateInputFrame(size_t frame_length,
     65                        size_t frame_index,
     66                        float* frame,
     67                        int offset) {
     68  for (size_t i = 0; i < frame_length; ++i) {
     69    float value = static_cast<int>(frame_index * frame_length + i) + offset;
     70    frame[i] = std::max(value, 0.f);
     71  }
     72 }
     73 
     74 // Verifies the that samples in the output frame are identical to the samples
     75 // that were produced for the input frame, with an offset in order to compensate
     76 // for buffering delays.
     77 bool VerifyOutputFrameBitexactness(size_t frame_length,
     78                                   size_t num_bands,
     79                                   size_t frame_index,
     80                                   const float* const* frame,
     81                                   int offset) {
     82  float reference_frame_data[kMaxNumBands][2 * kSubFrameLength];
     83  float* reference_frame[kMaxNumBands];
     84  for (size_t k = 0; k < num_bands; ++k) {
     85    reference_frame[k] = &reference_frame_data[k][0];
     86  }
     87 
     88  PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
     89                     offset);
     90  for (size_t k = 0; k < num_bands; ++k) {
     91    for (size_t i = 0; i < frame_length; ++i) {
     92      if (reference_frame[k][i] != frame[k][i]) {
     93        return false;
     94      }
     95    }
     96  }
     97 
     98  return true;
     99 }
    100 
    101 bool VerifyOutputFrameBitexactness(ArrayView<const float> reference,
    102                                   ArrayView<const float> frame,
    103                                   int offset) {
    104  for (size_t k = 0; k < frame.size(); ++k) {
    105    int reference_index = static_cast<int>(k) + offset;
    106    if (reference_index >= 0) {
    107      if (reference[reference_index] != frame[k]) {
    108        return false;
    109      }
    110    }
    111  }
    112  return true;
    113 }
    114 
    115 // Class for testing that the capture data is properly received by the block
    116 // processor and that the processor data is properly passed to the
    117 // EchoCanceller3 output.
    118 class CaptureTransportVerificationProcessor : public BlockProcessor {
    119 public:
    120  explicit CaptureTransportVerificationProcessor(size_t /* num_bands */) {}
    121 
    122  CaptureTransportVerificationProcessor() = delete;
    123  CaptureTransportVerificationProcessor(
    124      const CaptureTransportVerificationProcessor&) = delete;
    125  CaptureTransportVerificationProcessor& operator=(
    126      const CaptureTransportVerificationProcessor&) = delete;
    127 
    128  ~CaptureTransportVerificationProcessor() override = default;
    129 
    130  void ProcessCapture(bool /* level_change */,
    131                      bool /* saturated_microphone_signal */,
    132                      Block* /* linear_output */,
    133                      Block* /* capture_block */) override {}
    134 
    135  void BufferRender(const Block& /* block */) override {}
    136 
    137  void UpdateEchoLeakageStatus(bool /* leakage_detected */) override {}
    138 
    139  void GetMetrics(EchoControl::Metrics* /* metrics */) const override {}
    140 
    141  void SetAudioBufferDelay(int /* delay_ms */) override {}
    142 
    143  void SetCaptureOutputUsage(bool /* capture_output_used */) override {}
    144 };
    145 
    146 // Class for testing that the render data is properly received by the block
    147 // processor.
    148 class RenderTransportVerificationProcessor : public BlockProcessor {
    149 public:
    150  explicit RenderTransportVerificationProcessor(size_t /* num_bands */) {}
    151 
    152  RenderTransportVerificationProcessor() = delete;
    153  RenderTransportVerificationProcessor(
    154      const RenderTransportVerificationProcessor&) = delete;
    155  RenderTransportVerificationProcessor& operator=(
    156      const RenderTransportVerificationProcessor&) = delete;
    157 
    158  ~RenderTransportVerificationProcessor() override = default;
    159 
    160  void ProcessCapture(bool /* level_change */,
    161                      bool /* saturated_microphone_signal */,
    162                      Block* /* linear_output */,
    163                      Block* capture_block) override {
    164    Block render_block = received_render_blocks_.front();
    165    received_render_blocks_.pop_front();
    166    capture_block->Swap(render_block);
    167  }
    168 
    169  void BufferRender(const Block& block) override {
    170    received_render_blocks_.push_back(block);
    171  }
    172 
    173  void UpdateEchoLeakageStatus(bool /* leakage_detected */) override {}
    174 
    175  void GetMetrics(EchoControl::Metrics* /* metrics */) const override {}
    176 
    177  void SetAudioBufferDelay(int /* delay_ms */) override {}
    178 
    179  void SetCaptureOutputUsage(bool /* capture_output_used */) override {}
    180 
    181 private:
    182  std::deque<Block> received_render_blocks_;
    183 };
    184 
    185 std::string ProduceDebugText(int sample_rate_hz) {
    186  StringBuilder ss;
    187  ss << "Sample rate: " << sample_rate_hz;
    188  return ss.Release();
    189 }
    190 
    191 std::string ProduceDebugText(int sample_rate_hz, int variant) {
    192  StringBuilder ss;
    193  ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
    194  return ss.Release();
    195 }
    196 
    197 void RunAecInStereo(AudioBuffer& buffer,
    198                    EchoCanceller3& aec3,
    199                    float channel_0_value,
    200                    float channel_1_value) {
    201  ArrayView<float> data_channel_0(&buffer.channels()[0][0],
    202                                  buffer.num_frames());
    203  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
    204  ArrayView<float> data_channel_1(&buffer.channels()[1][0],
    205                                  buffer.num_frames());
    206  std::fill(data_channel_1.begin(), data_channel_1.end(), channel_1_value);
    207  aec3.AnalyzeRender(&buffer);
    208  aec3.AnalyzeCapture(&buffer);
    209  aec3.ProcessCapture(&buffer, /*level_change=*/false);
    210 }
    211 
    212 void RunAecInSMono(AudioBuffer& buffer,
    213                   EchoCanceller3& aec3,
    214                   float channel_0_value) {
    215  ArrayView<float> data_channel_0(&buffer.channels()[0][0],
    216                                  buffer.num_frames());
    217  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
    218  aec3.AnalyzeRender(&buffer);
    219  aec3.AnalyzeCapture(&buffer);
    220  aec3.ProcessCapture(&buffer, /*level_change=*/false);
    221 }
    222 
    223 }  // namespace
    224 
    225 class EchoCanceller3Tester {
    226 public:
    227  explicit EchoCanceller3Tester(int sample_rate_hz)
    228      : sample_rate_hz_(sample_rate_hz),
    229        num_bands_(NumBandsForRate(sample_rate_hz_)),
    230        frame_length_(160),
    231        fullband_frame_length_(CheckedDivExact(sample_rate_hz_, 100)),
    232        capture_buffer_(fullband_frame_length_ * 100,
    233                        1,
    234                        fullband_frame_length_ * 100,
    235                        1,
    236                        fullband_frame_length_ * 100,
    237                        1),
    238        render_buffer_(fullband_frame_length_ * 100,
    239                       1,
    240                       fullband_frame_length_ * 100,
    241                       1,
    242                       fullband_frame_length_ * 100,
    243                       1) {}
    244 
    245  EchoCanceller3Tester() = delete;
    246  EchoCanceller3Tester(const EchoCanceller3Tester&) = delete;
    247  EchoCanceller3Tester& operator=(const EchoCanceller3Tester&) = delete;
    248 
    249  // Verifies that the capture data is properly received by the block processor
    250  // and that the processor data is properly passed to the EchoCanceller3
    251  // output.
    252  void RunCaptureTransportVerificationTest() {
    253    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    254                        /*multichannel_config=*/std::nullopt,
    255                        /*neural_residual_echo_estimator=*/nullptr,
    256                        sample_rate_hz_, 1, 1);
    257    aec3.SetBlockProcessorForTesting(
    258        std::make_unique<CaptureTransportVerificationProcessor>(num_bands_));
    259 
    260    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
    261         ++frame_index) {
    262      aec3.AnalyzeCapture(&capture_buffer_);
    263      OptionalBandSplit();
    264      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    265                         &capture_buffer_.split_bands(0)[0], 0);
    266      PopulateInputFrame(frame_length_, frame_index,
    267                         &render_buffer_.channels()[0][0], 0);
    268 
    269      aec3.AnalyzeRender(&render_buffer_);
    270      aec3.ProcessCapture(&capture_buffer_, false);
    271      EXPECT_TRUE(VerifyOutputFrameBitexactness(
    272          frame_length_, num_bands_, frame_index,
    273          &capture_buffer_.split_bands(0)[0], -64));
    274    }
    275  }
    276 
    277  // Test method for testing that the render data is properly received by the
    278  // block processor.
    279  void RunRenderTransportVerificationTest() {
    280    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    281                        /*multichannel_config=*/std::nullopt,
    282                        /*neural_residual_echo_estimator=*/nullptr,
    283                        sample_rate_hz_, 1, 1);
    284    aec3.SetBlockProcessorForTesting(
    285        std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
    286 
    287    std::vector<std::vector<float>> render_input(1);
    288    std::vector<float> capture_output;
    289    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
    290         ++frame_index) {
    291      aec3.AnalyzeCapture(&capture_buffer_);
    292      OptionalBandSplit();
    293      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    294                         &capture_buffer_.split_bands(0)[0], 100);
    295      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    296                         &render_buffer_.split_bands(0)[0], 0);
    297 
    298      for (size_t k = 0; k < frame_length_; ++k) {
    299        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
    300      }
    301      aec3.AnalyzeRender(&render_buffer_);
    302      aec3.ProcessCapture(&capture_buffer_, false);
    303      for (size_t k = 0; k < frame_length_; ++k) {
    304        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
    305      }
    306    }
    307 
    308    EXPECT_TRUE(
    309        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
    310  }
    311 
    312  // Verifies that information about echo path changes are properly propagated
    313  // to the block processor.
    314  // The cases tested are:
    315  // -That no set echo path change flags are received when there is no echo path
    316  // change.
    317  // -That set echo path change flags are received and continues to be received
    318  // as long as echo path changes are flagged.
    319  // -That set echo path change flags are no longer received when echo path
    320  // change events stop being flagged.
    321  enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
    322 
    323  void RunEchoPathChangeVerificationTest(
    324      EchoPathChangeTestVariant echo_path_change_test_variant) {
    325    constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    326    constexpr size_t kExpectedNumBlocksToProcess =
    327        (kNumFramesToProcess * 160) / kBlockSize;
    328    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
    329        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    330    EXPECT_CALL(*block_processor_mock, BufferRender(_))
    331        .Times(kExpectedNumBlocksToProcess);
    332    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
    333 
    334    switch (echo_path_change_test_variant) {
    335      case EchoPathChangeTestVariant::kNone:
    336        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
    337            .Times(kExpectedNumBlocksToProcess);
    338        break;
    339      case EchoPathChangeTestVariant::kOneSticky:
    340        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
    341            .Times(kExpectedNumBlocksToProcess);
    342        break;
    343      case EchoPathChangeTestVariant::kOneNonSticky:
    344        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
    345            .Times(kNumFullBlocksPerFrame);
    346        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
    347            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
    348        break;
    349    }
    350 
    351    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    352                        /*multichannel_config=*/std::nullopt,
    353                        /*neural_residual_echo_estimator=*/nullptr,
    354                        sample_rate_hz_, 1, 1);
    355    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
    356 
    357    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
    358         ++frame_index) {
    359      bool echo_path_change = false;
    360      switch (echo_path_change_test_variant) {
    361        case EchoPathChangeTestVariant::kNone:
    362          break;
    363        case EchoPathChangeTestVariant::kOneSticky:
    364          echo_path_change = true;
    365          break;
    366        case EchoPathChangeTestVariant::kOneNonSticky:
    367          if (frame_index == 0) {
    368            echo_path_change = true;
    369          }
    370          break;
    371      }
    372 
    373      aec3.AnalyzeCapture(&capture_buffer_);
    374      OptionalBandSplit();
    375 
    376      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    377                         &capture_buffer_.split_bands(0)[0], 0);
    378      PopulateInputFrame(frame_length_, frame_index,
    379                         &render_buffer_.channels()[0][0], 0);
    380 
    381      aec3.AnalyzeRender(&render_buffer_);
    382      aec3.ProcessCapture(&capture_buffer_, echo_path_change);
    383    }
    384  }
    385 
    386  // Test for verifying that echo leakage information is being properly passed
    387  // to the processor.
    388  // The cases tested are:
    389  // -That no method calls are received when they should not.
    390  // -That false values are received each time they are flagged.
    391  // -That true values are received each time they are flagged.
    392  // -That a false value is received when flagged after a true value has been
    393  // flagged.
    394  enum class EchoLeakageTestVariant {
    395    kNone,
    396    kFalseSticky,
    397    kTrueSticky,
    398    kTrueNonSticky
    399  };
    400 
    401  void RunEchoLeakageVerificationTest(
    402      EchoLeakageTestVariant leakage_report_variant) {
    403    constexpr size_t kExpectedNumBlocksToProcess =
    404        (kNumFramesToProcess * 160) / kBlockSize;
    405    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
    406        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    407    EXPECT_CALL(*block_processor_mock, BufferRender(_))
    408        .Times(kExpectedNumBlocksToProcess);
    409    EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
    410        .Times(kExpectedNumBlocksToProcess);
    411 
    412    switch (leakage_report_variant) {
    413      case EchoLeakageTestVariant::kNone:
    414        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
    415        break;
    416      case EchoLeakageTestVariant::kFalseSticky:
    417        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
    418            .Times(1);
    419        break;
    420      case EchoLeakageTestVariant::kTrueSticky:
    421        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
    422            .Times(1);
    423        break;
    424      case EchoLeakageTestVariant::kTrueNonSticky: {
    425        ::testing::InSequence s;
    426        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
    427            .Times(1);
    428        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
    429            .Times(kNumFramesToProcess - 1);
    430      } break;
    431    }
    432 
    433    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    434                        /*multichannel_config=*/std::nullopt,
    435                        /*neural_residual_echo_estimator=*/nullptr,
    436                        sample_rate_hz_, 1, 1);
    437    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
    438 
    439    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
    440         ++frame_index) {
    441      switch (leakage_report_variant) {
    442        case EchoLeakageTestVariant::kNone:
    443          break;
    444        case EchoLeakageTestVariant::kFalseSticky:
    445          if (frame_index == 0) {
    446            aec3.UpdateEchoLeakageStatus(false);
    447          }
    448          break;
    449        case EchoLeakageTestVariant::kTrueSticky:
    450          if (frame_index == 0) {
    451            aec3.UpdateEchoLeakageStatus(true);
    452          }
    453          break;
    454        case EchoLeakageTestVariant::kTrueNonSticky:
    455          if (frame_index == 0) {
    456            aec3.UpdateEchoLeakageStatus(true);
    457          } else {
    458            aec3.UpdateEchoLeakageStatus(false);
    459          }
    460          break;
    461      }
    462 
    463      aec3.AnalyzeCapture(&capture_buffer_);
    464      OptionalBandSplit();
    465 
    466      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    467                         &capture_buffer_.split_bands(0)[0], 0);
    468      PopulateInputFrame(frame_length_, frame_index,
    469                         &render_buffer_.channels()[0][0], 0);
    470 
    471      aec3.AnalyzeRender(&render_buffer_);
    472      aec3.ProcessCapture(&capture_buffer_, false);
    473    }
    474  }
    475 
    476  // This verifies that saturation information is properly passed to the
    477  // BlockProcessor.
    478  // The cases tested are:
    479  // -That no saturation event is passed to the processor if there is no
    480  // saturation.
    481  // -That one frame with one negative saturated sample value is reported to be
    482  // saturated and that following non-saturated frames are properly reported as
    483  // not being saturated.
    484  // -That one frame with one positive saturated sample value is reported to be
    485  // saturated and that following non-saturated frames are properly reported as
    486  // not being saturated.
    487  enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
    488 
    489  void RunCaptureSaturationVerificationTest(
    490      SaturationTestVariant saturation_variant) {
    491    const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    492    const size_t kExpectedNumBlocksToProcess =
    493        (kNumFramesToProcess * 160) / kBlockSize;
    494    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
    495        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    496    EXPECT_CALL(*block_processor_mock, BufferRender(_))
    497        .Times(kExpectedNumBlocksToProcess);
    498    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
    499 
    500    switch (saturation_variant) {
    501      case SaturationTestVariant::kNone:
    502        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
    503            .Times(kExpectedNumBlocksToProcess);
    504        break;
    505      case SaturationTestVariant::kOneNegative: {
    506        ::testing::InSequence s;
    507        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
    508            .Times(kNumFullBlocksPerFrame);
    509        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
    510            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
    511      } break;
    512      case SaturationTestVariant::kOnePositive: {
    513        ::testing::InSequence s;
    514        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
    515            .Times(kNumFullBlocksPerFrame);
    516        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
    517            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
    518      } break;
    519    }
    520 
    521    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    522                        /*multichannel_config=*/std::nullopt,
    523                        /*neural_residual_echo_estimator=*/nullptr,
    524                        sample_rate_hz_, 1, 1);
    525    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
    526    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
    527         ++frame_index) {
    528      for (int k = 0; k < fullband_frame_length_; ++k) {
    529        capture_buffer_.channels()[0][k] = 0.f;
    530      }
    531      switch (saturation_variant) {
    532        case SaturationTestVariant::kNone:
    533          break;
    534        case SaturationTestVariant::kOneNegative:
    535          if (frame_index == 0) {
    536            capture_buffer_.channels()[0][10] = -32768.f;
    537          }
    538          break;
    539        case SaturationTestVariant::kOnePositive:
    540          if (frame_index == 0) {
    541            capture_buffer_.channels()[0][10] = 32767.f;
    542          }
    543          break;
    544      }
    545 
    546      aec3.AnalyzeCapture(&capture_buffer_);
    547      OptionalBandSplit();
    548 
    549      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    550                         &capture_buffer_.split_bands(0)[0], 0);
    551      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    552                         &render_buffer_.split_bands(0)[0], 0);
    553 
    554      aec3.AnalyzeRender(&render_buffer_);
    555      aec3.ProcessCapture(&capture_buffer_, false);
    556    }
    557  }
    558 
    559  // This test verifies that the swapqueue is able to handle jitter in the
    560  // capture and render API calls.
    561  void RunRenderSwapQueueVerificationTest() {
    562    const EchoCanceller3Config config;
    563    EchoCanceller3 aec3(CreateEnvironment(), config,
    564                        /*multichannel_config=*/std::nullopt,
    565                        /*neural_residual_echo_estimator=*/nullptr,
    566                        sample_rate_hz_, 1, 1);
    567    aec3.SetBlockProcessorForTesting(
    568        std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
    569 
    570    std::vector<std::vector<float>> render_input(1);
    571    std::vector<float> capture_output;
    572 
    573    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
    574         ++frame_index) {
    575      if (sample_rate_hz_ > 16000) {
    576        render_buffer_.SplitIntoFrequencyBands();
    577      }
    578      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    579                         &render_buffer_.split_bands(0)[0], 0);
    580 
    581      if (sample_rate_hz_ > 16000) {
    582        render_buffer_.SplitIntoFrequencyBands();
    583      }
    584 
    585      for (size_t k = 0; k < frame_length_; ++k) {
    586        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
    587      }
    588      aec3.AnalyzeRender(&render_buffer_);
    589    }
    590 
    591    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
    592         ++frame_index) {
    593      aec3.AnalyzeCapture(&capture_buffer_);
    594      if (sample_rate_hz_ > 16000) {
    595        capture_buffer_.SplitIntoFrequencyBands();
    596      }
    597 
    598      PopulateInputFrame(frame_length_, num_bands_, frame_index,
    599                         &capture_buffer_.split_bands(0)[0], 0);
    600 
    601      aec3.ProcessCapture(&capture_buffer_, false);
    602      for (size_t k = 0; k < frame_length_; ++k) {
    603        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
    604      }
    605    }
    606 
    607    EXPECT_TRUE(
    608        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
    609  }
    610 
    611  // This test verifies that a buffer overrun in the render swapqueue is
    612  // properly reported.
    613  void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
    614    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    615                        /*multichannel_config=*/std::nullopt,
    616                        /*neural_residual_echo_estimator=*/nullptr,
    617                        sample_rate_hz_, 1, 1);
    618 
    619    constexpr size_t kRenderTransferQueueSize = 30;
    620    for (size_t k = 0; k < 2; ++k) {
    621      for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
    622           ++frame_index) {
    623        if (sample_rate_hz_ > 16000) {
    624          render_buffer_.SplitIntoFrequencyBands();
    625        }
    626        PopulateInputFrame(frame_length_, frame_index,
    627                           &render_buffer_.channels()[0][0], 0);
    628 
    629        aec3.AnalyzeRender(&render_buffer_);
    630      }
    631    }
    632  }
    633 
    634 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    635  // Verifies the that the check for the number of bands in the AnalyzeRender
    636  // input is correct by adjusting the sample rates of EchoCanceller3 and the
    637  // input AudioBuffer to have a different number of bands.
    638  void RunAnalyzeRenderNumBandsCheckVerification() {
    639    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    640    // way that the number of bands for the rates are different.
    641    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    642    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    643                        /*multichannel_config=*/std::nullopt,
    644                        /*neural_residual_echo_estimator=*/nullptr,
    645                        aec3_sample_rate_hz, 1, 1);
    646    PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
    647 
    648    EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
    649  }
    650 
    651  // Verifies the that the check for the number of bands in the ProcessCapture
    652  // input is correct by adjusting the sample rates of EchoCanceller3 and the
    653  // input AudioBuffer to have a different number of bands.
    654  void RunProcessCaptureNumBandsCheckVerification() {
    655    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    656    // way that the number of bands for the rates are different.
    657    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    658    EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
    659                        /*multichannel_config=*/std::nullopt,
    660                        /*neural_residual_echo_estimator=*/nullptr,
    661                        aec3_sample_rate_hz, 1, 1);
    662    PopulateInputFrame(frame_length_, num_bands_, 0,
    663                       &capture_buffer_.split_bands_f(0)[0], 100);
    664    EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
    665  }
    666 
    667 #endif
    668 
    669 private:
    670  void OptionalBandSplit() {
    671    if (sample_rate_hz_ > 16000) {
    672      capture_buffer_.SplitIntoFrequencyBands();
    673      render_buffer_.SplitIntoFrequencyBands();
    674    }
    675  }
    676 
    677  static constexpr size_t kNumFramesToProcess = 20;
    678  const int sample_rate_hz_;
    679  const size_t num_bands_;
    680  const size_t frame_length_;
    681  const int fullband_frame_length_;
    682  AudioBuffer capture_buffer_;
    683  AudioBuffer render_buffer_;
    684 };
    685 
    686 TEST(EchoCanceller3Buffering, CaptureBitexactness) {
    687  for (auto rate : {16000, 32000, 48000}) {
    688    SCOPED_TRACE(ProduceDebugText(rate));
    689    EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
    690  }
    691 }
    692 
    693 TEST(EchoCanceller3Buffering, RenderBitexactness) {
    694  for (auto rate : {16000, 32000, 48000}) {
    695    SCOPED_TRACE(ProduceDebugText(rate));
    696    EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
    697  }
    698 }
    699 
    700 TEST(EchoCanceller3Buffering, RenderSwapQueue) {
    701  EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
    702 }
    703 
    704 TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
    705  for (auto rate : {16000, 32000, 48000}) {
    706    SCOPED_TRACE(ProduceDebugText(rate));
    707    EchoCanceller3Tester(rate)
    708        .RunRenderPipelineSwapQueueOverrunReturnValueTest();
    709  }
    710 }
    711 
    712 TEST(EchoCanceller3Messaging, CaptureSaturation) {
    713  auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
    714                   EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
    715                   EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
    716  for (auto rate : {16000, 32000, 48000}) {
    717    for (auto variant : variants) {
    718      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
    719      EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
    720    }
    721  }
    722 }
    723 
    724 TEST(EchoCanceller3Messaging, EchoPathChange) {
    725  auto variants = {
    726      EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
    727      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
    728      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
    729  for (auto rate : {16000, 32000, 48000}) {
    730    for (auto variant : variants) {
    731      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
    732      EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
    733    }
    734  }
    735 }
    736 
    737 TEST(EchoCanceller3Messaging, EchoLeakage) {
    738  auto variants = {
    739      EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
    740      EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
    741      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
    742      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
    743  for (auto rate : {16000, 32000, 48000}) {
    744    for (auto variant : variants) {
    745      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
    746      EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
    747    }
    748  }
    749 }
    750 
    751 // Tests the parameter functionality for the field trial override for the
    752 // anti-howling gain.
    753 TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
    754  EchoCanceller3Config default_config;
    755  EchoCanceller3Config adjusted_config =
    756      AdjustConfig(default_config, CreateTestFieldTrials());
    757  ASSERT_EQ(
    758      default_config.suppressor.high_bands_suppression.anti_howling_gain,
    759      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
    760 
    761  FieldTrials field_trials = CreateTestFieldTrials(
    762      "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
    763  adjusted_config = AdjustConfig(default_config, field_trials);
    764 
    765  ASSERT_NE(
    766      default_config.suppressor.high_bands_suppression.anti_howling_gain,
    767      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
    768  EXPECT_FLOAT_EQ(
    769      0.02f,
    770      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
    771 }
    772 
    773 // Tests the field trial override for the enforcement of a low active render
    774 // limit.
    775 TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
    776  EchoCanceller3Config default_config;
    777  EchoCanceller3Config adjusted_config =
    778      AdjustConfig(default_config, CreateTestFieldTrials());
    779  ASSERT_EQ(default_config.render_levels.active_render_limit,
    780            adjusted_config.render_levels.active_render_limit);
    781 
    782  FieldTrials field_trials =
    783      CreateTestFieldTrials("WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
    784  adjusted_config = AdjustConfig(default_config, field_trials);
    785 
    786  ASSERT_NE(default_config.render_levels.active_render_limit,
    787            adjusted_config.render_levels.active_render_limit);
    788  EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
    789 }
    790 
    791 // Testing the field trial-based override of the suppressor parameters for a
    792 // joint passing of all parameters.
    793 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
    794  FieldTrials field_trials = CreateTestFieldTrials(
    795      "WebRTC-Aec3SuppressorTuningOverride/"
    796      "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
    797      "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
    798      "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
    799      "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
    800      "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
    801      "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
    802      "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
    803      "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
    804      "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
    805      "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
    806      "threshold:11/");
    807 
    808  EchoCanceller3Config default_config;
    809  EchoCanceller3Config adjusted_config =
    810      AdjustConfig(default_config, field_trials);
    811 
    812  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
    813            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
    814  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
    815            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
    816  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
    817            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
    818  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
    819            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
    820  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
    821            default_config.suppressor.nearend_tuning.max_inc_factor);
    822  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
    823            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
    824  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
    825            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
    826  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
    827            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
    828  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
    829            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
    830  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
    831            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
    832  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
    833            default_config.suppressor.normal_tuning.max_inc_factor);
    834  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
    835            default_config.suppressor.normal_tuning.max_dec_factor_lf);
    836  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
    837            default_config.suppressor.dominant_nearend_detection.enr_threshold);
    838  ASSERT_NE(
    839      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
    840      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
    841  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
    842            default_config.suppressor.dominant_nearend_detection.snr_threshold);
    843  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
    844            default_config.suppressor.dominant_nearend_detection.hold_duration);
    845  ASSERT_NE(
    846      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
    847      default_config.suppressor.dominant_nearend_detection.trigger_threshold);
    848 
    849  EXPECT_FLOAT_EQ(
    850      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
    851  EXPECT_FLOAT_EQ(
    852      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
    853  EXPECT_FLOAT_EQ(
    854      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
    855  EXPECT_FLOAT_EQ(
    856      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
    857  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
    858                  0.5);
    859  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
    860                  0.6);
    861  EXPECT_FLOAT_EQ(
    862      adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
    863  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
    864                  0.8);
    865  EXPECT_FLOAT_EQ(
    866      adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
    867  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
    868                  1.0);
    869  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
    870  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
    871                  1.2);
    872  EXPECT_FLOAT_EQ(
    873      adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
    874  EXPECT_FLOAT_EQ(
    875      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
    876      1.4);
    877  EXPECT_FLOAT_EQ(
    878      adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
    879  EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
    880            10);
    881  EXPECT_EQ(
    882      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
    883      11);
    884 }
    885 
    886 // Testing the field trial-based override of the suppressor parameters for
    887 // passing one parameter.
    888 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
    889  FieldTrials field_trials = CreateTestFieldTrials(
    890      "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");
    891 
    892  EchoCanceller3Config default_config;
    893  EchoCanceller3Config adjusted_config =
    894      AdjustConfig(default_config, field_trials);
    895 
    896  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
    897            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
    898  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
    899            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
    900  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
    901            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
    902  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
    903            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
    904  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
    905            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
    906  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
    907            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
    908  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
    909            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
    910  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
    911            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
    912  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
    913            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
    914  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
    915            default_config.suppressor.normal_tuning.max_inc_factor);
    916  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
    917            default_config.suppressor.normal_tuning.max_dec_factor_lf);
    918  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
    919            default_config.suppressor.dominant_nearend_detection.enr_threshold);
    920  ASSERT_EQ(
    921      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
    922      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
    923  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
    924            default_config.suppressor.dominant_nearend_detection.snr_threshold);
    925  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
    926            default_config.suppressor.dominant_nearend_detection.hold_duration);
    927  ASSERT_EQ(
    928      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
    929      default_config.suppressor.dominant_nearend_detection.trigger_threshold);
    930 
    931  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
    932            default_config.suppressor.nearend_tuning.max_inc_factor);
    933 
    934  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
    935                  0.5);
    936 }
    937 
    938 // Testing the field trial-based that override the exponential decay parameters.
    939 TEST(EchoCanceller3FieldTrials, Aec3UseNearendReverb) {
    940  FieldTrials field_trials = CreateTestFieldTrials(
    941      "WebRTC-Aec3UseNearendReverbLen/default_len:0.9,nearend_len:0.8/");
    942  EchoCanceller3Config default_config;
    943  EchoCanceller3Config adjusted_config =
    944      AdjustConfig(default_config, field_trials);
    945  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 0.9);
    946  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.nearend_len, 0.8);
    947 }
    948 
    949 // Testing the field trial-based that overrides the maximum allowed ecess render
    950 // blocks in the render buffering.
    951 TEST(EchoCanceller3FieldTrials, Aec3BufferingMaxAllowedExcessRenderBlocks) {
    952  FieldTrials field_trials = CreateTestFieldTrials(
    953      "WebRTC-Aec3BufferingMaxAllowedExcessRenderBlocksOverride/2/");
    954  EchoCanceller3Config default_config;
    955  EchoCanceller3Config adjusted_config =
    956      AdjustConfig(default_config, field_trials);
    957  EXPECT_EQ(adjusted_config.buffering.max_allowed_excess_render_blocks, 2ul);
    958 }
    959 
    960 TEST(EchoCanceller3, DetectionOfProperStereo) {
    961  constexpr int kSampleRateHz = 16000;
    962  constexpr int kNumChannels = 2;
    963  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
    964                     /*input_num_channels=*/kNumChannels,
    965                     /*input_rate=*/kSampleRateHz,
    966                     /*buffer_num_channels=*/kNumChannels,
    967                     /*output_rate=*/kSampleRateHz,
    968                     /*output_num_channels=*/kNumChannels);
    969 
    970  constexpr size_t kNumBlocksForMonoConfig = 1;
    971  constexpr size_t kNumBlocksForSurroundConfig = 2;
    972  EchoCanceller3Config mono_config;
    973  std::optional<EchoCanceller3Config> multichannel_config;
    974 
    975  mono_config.multi_channel.detect_stereo_content = true;
    976  mono_config.multi_channel.stereo_detection_threshold = 0.0f;
    977  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
    978  multichannel_config = mono_config;
    979  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
    980  multichannel_config->filter.coarse_initial.length_blocks =
    981      kNumBlocksForSurroundConfig;
    982 
    983  EchoCanceller3 aec3(CreateEnvironment(), mono_config, multichannel_config,
    984                      /*neural_residual_echo_estimator=*/nullptr,
    985                      /*sample_rate_hz=*/kSampleRateHz,
    986                      /*num_render_channels=*/kNumChannels,
    987                      /*num_capture_channels=*/kNumChannels);
    988 
    989  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    990  EXPECT_EQ(
    991      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
    992      kNumBlocksForMonoConfig);
    993 
    994  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
    995  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    996  EXPECT_EQ(
    997      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
    998      kNumBlocksForMonoConfig);
    999 
   1000  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
   1001  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
   1002  EXPECT_EQ(
   1003      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1004      kNumBlocksForSurroundConfig);
   1005 }
   1006 
   1007 TEST(EchoCanceller3, DetectionOfProperStereoUsingThreshold) {
   1008  constexpr int kSampleRateHz = 16000;
   1009  constexpr int kNumChannels = 2;
   1010  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
   1011                     /*input_num_channels=*/kNumChannels,
   1012                     /*input_rate=*/kSampleRateHz,
   1013                     /*buffer_num_channels=*/kNumChannels,
   1014                     /*output_rate=*/kSampleRateHz,
   1015                     /*output_num_channels=*/kNumChannels);
   1016 
   1017  constexpr size_t kNumBlocksForMonoConfig = 1;
   1018  constexpr size_t kNumBlocksForSurroundConfig = 2;
   1019  EchoCanceller3Config mono_config;
   1020  std::optional<EchoCanceller3Config> multichannel_config;
   1021 
   1022  constexpr float kStereoDetectionThreshold = 2.0f;
   1023  mono_config.multi_channel.detect_stereo_content = true;
   1024  mono_config.multi_channel.stereo_detection_threshold =
   1025      kStereoDetectionThreshold;
   1026  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
   1027  multichannel_config = mono_config;
   1028  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
   1029  multichannel_config->filter.coarse_initial.length_blocks =
   1030      kNumBlocksForSurroundConfig;
   1031 
   1032  EchoCanceller3 aec3(CreateEnvironment(), mono_config, multichannel_config,
   1033                      /*neural_residual_echo_estimator=*/nullptr,
   1034                      /*sample_rate_hz=*/kSampleRateHz,
   1035                      /*num_render_channels=*/kNumChannels,
   1036                      /*num_capture_channels=*/kNumChannels);
   1037 
   1038  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1039  EXPECT_EQ(
   1040      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1041      kNumBlocksForMonoConfig);
   1042 
   1043  RunAecInStereo(buffer, aec3, 100.0f,
   1044                 100.0f + kStereoDetectionThreshold - 1.0f);
   1045  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1046  EXPECT_EQ(
   1047      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1048      kNumBlocksForMonoConfig);
   1049 
   1050  RunAecInStereo(buffer, aec3, 100.0f,
   1051                 100.0f + kStereoDetectionThreshold + 10.0f);
   1052  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
   1053  EXPECT_EQ(
   1054      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1055      kNumBlocksForSurroundConfig);
   1056 }
   1057 
   1058 TEST(EchoCanceller3, DetectionOfProperStereoUsingHysteresis) {
   1059  constexpr int kSampleRateHz = 16000;
   1060  constexpr int kNumChannels = 2;
   1061  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
   1062                     /*input_num_channels=*/kNumChannels,
   1063                     /*input_rate=*/kSampleRateHz,
   1064                     /*buffer_num_channels=*/kNumChannels,
   1065                     /*output_rate=*/kSampleRateHz,
   1066                     /*output_num_channels=*/kNumChannels);
   1067 
   1068  constexpr size_t kNumBlocksForMonoConfig = 1;
   1069  constexpr size_t kNumBlocksForSurroundConfig = 2;
   1070  EchoCanceller3Config mono_config;
   1071  std::optional<EchoCanceller3Config> surround_config;
   1072 
   1073  mono_config.multi_channel.detect_stereo_content = true;
   1074  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.5f;
   1075  surround_config = mono_config;
   1076  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
   1077  surround_config->filter.coarse_initial.length_blocks =
   1078      kNumBlocksForSurroundConfig;
   1079 
   1080  EchoCanceller3 aec3(CreateEnvironment(), mono_config, surround_config,
   1081                      /*neural_residual_echo_estimator=*/nullptr,
   1082                      /*sample_rate_hz=*/kSampleRateHz,
   1083                      /*num_render_channels=*/kNumChannels,
   1084                      /*num_capture_channels=*/kNumChannels);
   1085 
   1086  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1087  EXPECT_EQ(
   1088      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1089      kNumBlocksForMonoConfig);
   1090 
   1091  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
   1092  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1093  EXPECT_EQ(
   1094      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1095      kNumBlocksForMonoConfig);
   1096 
   1097  constexpr int kNumFramesPerSecond = 100;
   1098  for (int k = 0;
   1099       k < static_cast<int>(
   1100               kNumFramesPerSecond *
   1101               mono_config.multi_channel.stereo_detection_hysteresis_seconds);
   1102       ++k) {
   1103    RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
   1104    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1105    EXPECT_EQ(
   1106        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1107        kNumBlocksForMonoConfig);
   1108  }
   1109 
   1110  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
   1111  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
   1112  EXPECT_EQ(
   1113      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1114      kNumBlocksForSurroundConfig);
   1115 }
   1116 
   1117 TEST(EchoCanceller3, StereoContentDetectionForMonoSignals) {
   1118  constexpr int kSampleRateHz = 16000;
   1119  constexpr int kNumChannels = 2;
   1120  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
   1121                     /*input_num_channels=*/kNumChannels,
   1122                     /*input_rate=*/kSampleRateHz,
   1123                     /*buffer_num_channels=*/kNumChannels,
   1124                     /*output_rate=*/kSampleRateHz,
   1125                     /*output_num_channels=*/kNumChannels);
   1126 
   1127  constexpr size_t kNumBlocksForMonoConfig = 1;
   1128  constexpr size_t kNumBlocksForSurroundConfig = 2;
   1129  const Environment env = CreateEnvironment();
   1130  EchoCanceller3Config mono_config;
   1131  std::optional<EchoCanceller3Config> multichannel_config;
   1132 
   1133  for (bool detect_stereo_content : {false, true}) {
   1134    mono_config.multi_channel.detect_stereo_content = detect_stereo_content;
   1135    multichannel_config = mono_config;
   1136    mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
   1137    multichannel_config->filter.coarse_initial.length_blocks =
   1138        kNumBlocksForSurroundConfig;
   1139 
   1140    AudioBuffer mono_buffer(/*input_rate=*/kSampleRateHz,
   1141                            /*input_num_channels=*/1,
   1142                            /*input_rate=*/kSampleRateHz,
   1143                            /*buffer_num_channels=*/1,
   1144                            /*output_rate=*/kSampleRateHz,
   1145                            /*output_num_channels=*/1);
   1146 
   1147    EchoCanceller3 aec3(env, mono_config, multichannel_config,
   1148                        /*neural_residual_echo_estimator=*/nullptr,
   1149                        /*sample_rate_hz=*/kSampleRateHz,
   1150                        /*num_render_channels=*/1,
   1151                        /*num_capture_channels=*/1);
   1152 
   1153    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1154    EXPECT_EQ(
   1155        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1156        kNumBlocksForMonoConfig);
   1157 
   1158    RunAecInSMono(mono_buffer, aec3, 100.0f);
   1159    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
   1160    EXPECT_EQ(
   1161        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
   1162        kNumBlocksForMonoConfig);
   1163  }
   1164 }
   1165 
   1166 TEST(EchoCanceller3, InjectedNeuralResidualEchoEstimatorIsUsed) {
   1167  class NeuralResidualEchoEstimatorImpl : public NeuralResidualEchoEstimator {
   1168   public:
   1169    NeuralResidualEchoEstimatorImpl() {}
   1170 
   1171    void Estimate(ArrayView<const float> render,
   1172                  ArrayView<const std::array<float, 64>> capture,
   1173                  ArrayView<const std::array<float, 64>> linear_aec_output,
   1174                  ArrayView<const std::array<float, 65>> S2_linear,
   1175                  ArrayView<const std::array<float, 65>> Y2,
   1176                  ArrayView<const std::array<float, 65>> E2,
   1177                  ArrayView<std::array<float, 65>> R2,
   1178                  ArrayView<std::array<float, 65>> R2_unbounded) override {
   1179      residual_echo_estimate_requested_ = true;
   1180      for (auto& R2_ch : R2) {
   1181        R2_ch.fill(0.0f);
   1182      }
   1183      for (auto& R2_ch : R2_unbounded) {
   1184        R2_ch.fill(0.0f);
   1185      }
   1186    }
   1187    bool residual_echo_estimate_requested() const {
   1188      return residual_echo_estimate_requested_;
   1189    }
   1190 
   1191   private:
   1192    bool residual_echo_estimate_requested_ = false;
   1193  };
   1194 
   1195  constexpr int kSampleRateHz = 16000;
   1196  constexpr int kNumChannels = 1;
   1197  NeuralResidualEchoEstimatorImpl neural_residual_echo_estimator;
   1198  const Environment env = CreateEnvironment();
   1199  EchoCanceller3Config config;
   1200  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
   1201                     /*input_num_channels=*/kNumChannels,
   1202                     /*buffer_rate=*/kSampleRateHz,
   1203                     /*buffer_num_channels=*/kNumChannels,
   1204                     /*output_rate=*/kSampleRateHz,
   1205                     /*output_num_channels=*/kNumChannels);
   1206  EchoCanceller3 aec3(env, config, /*multichannel_config=*/std::nullopt,
   1207                      &neural_residual_echo_estimator,
   1208                      /*sample_rate_hz=*/kSampleRateHz,
   1209                      /*num_render_channels=*/kNumChannels,
   1210                      /*num_capture_input_channels=*/kNumChannels);
   1211  constexpr int kNumFramesToProcess = 300;
   1212  for (int k = 0; k < kNumFramesToProcess; ++k) {
   1213    RunAecInSMono(buffer, aec3, k);
   1214  }
   1215  EXPECT_TRUE(
   1216      neural_residual_echo_estimator.residual_echo_estimate_requested());
   1217 }
   1218 
   1219 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
   1220 
   1221 TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
   1222  for (auto rate : {16000, 32000, 48000}) {
   1223    SCOPED_TRACE(ProduceDebugText(rate));
   1224    EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
   1225  }
   1226 }
   1227 
   1228 // Verifiers that the verification for null input to the capture processing api
   1229 // call works.
   1230 TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
   1231  EXPECT_DEATH(
   1232      EchoCanceller3(CreateEnvironment(), EchoCanceller3Config(),
   1233                     /*multichannel_config_=*/std::nullopt,
   1234                     /*neural_residual_echo_estimator=*/nullptr, 16000, 1, 1)
   1235          .ProcessCapture(nullptr, false),
   1236      "");
   1237 }
   1238 
   1239 // Verifies the check for correct sample rate.
   1240 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
   1241 // tests on test bots has been fixed.
   1242 TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
   1243  ApmDataDumper data_dumper(0);
   1244  EXPECT_DEATH(
   1245      EchoCanceller3(CreateEnvironment(), EchoCanceller3Config(),
   1246                     /*multichannel_config_=*/std::nullopt,
   1247                     /*neural_residual_echo_estimator=*/nullptr, 8001, 1, 1),
   1248      "");
   1249 }
   1250 
   1251 #endif
   1252 
   1253 }  // namespace webrtc