/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/aec3/echo_canceller3.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <deque>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "api/audio/echo_canceller3_config.h"
#include "api/audio/echo_control.h"
#include "api/audio/neural_residual_echo_estimator.h"
#include "api/environment/environment.h"
#include "api/field_trials.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/block_processor.h"
#include "modules/audio_processing/aec3/mock/mock_block_processor.h"
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/high_pass_filter.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "test/create_test_environment.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::StrictMock;

// Populates the frame with linearly increasing sample values for each band,
// with a band-specific offset, in order to allow simple bitexactness
// verification for each band.
void PopulateInputFrame(size_t frame_length,
                        size_t num_bands,
                        size_t frame_index,
                        float* const* frame,
                        int offset) {
  for (size_t k = 0; k < num_bands; ++k) {
    for (size_t i = 0; i < frame_length; ++i) {
      float value = static_cast<int>(frame_index * frame_length + i) + offset;
      frame[k][i] = (value > 0 ? 5000 * k + value : 0);
    }
  }
}

// Populates the frame with linearly increasing sample values.
void PopulateInputFrame(size_t frame_length,
                        size_t frame_index,
                        float* frame,
                        int offset) {
  for (size_t i = 0; i < frame_length; ++i) {
    float value = static_cast<int>(frame_index * frame_length + i) + offset;
    frame[i] = std::max(value, 0.f);
  }
}

// Verifies the that samples in the output frame are identical to the samples
// that were produced for the input frame, with an offset in order to compensate
// for buffering delays.
bool VerifyOutputFrameBitexactness(size_t frame_length,
                                   size_t num_bands,
                                   size_t frame_index,
                                   const float* const* frame,
                                   int offset) {
  float reference_frame_data[kMaxNumBands][2 * kSubFrameLength];
  float* reference_frame[kMaxNumBands];
  for (size_t k = 0; k < num_bands; ++k) {
    reference_frame[k] = &reference_frame_data[k][0];
  }

  PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
                     offset);
  for (size_t k = 0; k < num_bands; ++k) {
    for (size_t i = 0; i < frame_length; ++i) {
      if (reference_frame[k][i] != frame[k][i]) {
        return false;
      }
    }
  }

  return true;
}

bool VerifyOutputFrameBitexactness(std::span<const float> reference,
                                   std::span<const float> frame,
                                   int offset) {
  for (size_t k = 0; k < frame.size(); ++k) {
    int reference_index = static_cast<int>(k) + offset;
    if (reference_index >= 0) {
      if (reference[reference_index] != frame[k]) {
        return false;
      }
    }
  }
  return true;
}

// Class for testing that the capture data is properly received by the block
// processor and that the processor data is properly passed to the
// EchoCanceller3 output.
class CaptureTransportVerificationProcessor : public BlockProcessor {
 public:
  explicit CaptureTransportVerificationProcessor(size_t /* num_bands */) {}

  CaptureTransportVerificationProcessor() = delete;
  CaptureTransportVerificationProcessor(
      const CaptureTransportVerificationProcessor&) = delete;
  CaptureTransportVerificationProcessor& operator=(
      const CaptureTransportVerificationProcessor&) = delete;

  ~CaptureTransportVerificationProcessor() override = default;

  void ProcessCapture(bool /* level_change */,
                      bool /* saturated_microphone_signal */,
                      Block* /* linear_output */,
                      Block* /* capture_block */) override {}

  void BufferRender(const Block& /* block */) override {}

  void UpdateEchoLeakageStatus(bool /* leakage_detected */) override {}

  void GetMetrics(EchoControl::Metrics* /* metrics */) const override {}

  void SetAudioBufferDelay(int /* delay_ms */) override {}

  void SetCaptureOutputUsage(bool /* capture_output_used */) override {}
};

// Class for testing that the render data is properly received by the block
// processor.
class RenderTransportVerificationProcessor : public BlockProcessor {
 public:
  explicit RenderTransportVerificationProcessor(size_t /* num_bands */) {}

  RenderTransportVerificationProcessor() = delete;
  RenderTransportVerificationProcessor(
      const RenderTransportVerificationProcessor&) = delete;
  RenderTransportVerificationProcessor& operator=(
      const RenderTransportVerificationProcessor&) = delete;

  ~RenderTransportVerificationProcessor() override = default;

  void ProcessCapture(bool /* level_change */,
                      bool /* saturated_microphone_signal */,
                      Block* /* linear_output */,
                      Block* capture_block) override {
    Block render_block = received_render_blocks_.front();
    received_render_blocks_.pop_front();
    capture_block->Swap(render_block);
  }

  void BufferRender(const Block& block) override {
    received_render_blocks_.push_back(block);
  }

  void UpdateEchoLeakageStatus(bool /* leakage_detected */) override {}

  void GetMetrics(EchoControl::Metrics* /* metrics */) const override {}

  void SetAudioBufferDelay(int /* delay_ms */) override {}

  void SetCaptureOutputUsage(bool /* capture_output_used */) override {}

 private:
  std::deque<Block> received_render_blocks_;
};

std::string ProduceDebugText(int sample_rate_hz) {
  StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.Release();
}

std::string ProduceDebugText(int sample_rate_hz, int variant) {
  StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
  return ss.Release();
}

void RunAecInStereo(AudioBuffer& buffer,
                    EchoCanceller3& aec3,
                    float channel_0_value,
                    float channel_1_value) {
  std::span<float> data_channel_0(&buffer.channels()[0][0],
                                  buffer.num_frames());
  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
  std::span<float> data_channel_1(&buffer.channels()[1][0],
                                  buffer.num_frames());
  std::fill(data_channel_1.begin(), data_channel_1.end(), channel_1_value);
  aec3.AnalyzeRender(&buffer);
  aec3.AnalyzeCapture(&buffer);
  aec3.ProcessCapture(&buffer, /*level_change=*/false);
}

void RunAecInSMono(AudioBuffer& buffer,
                   EchoCanceller3& aec3,
                   float channel_0_value) {
  std::span<float> data_channel_0(&buffer.channels()[0][0],
                                  buffer.num_frames());
  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
  aec3.AnalyzeRender(&buffer);
  aec3.AnalyzeCapture(&buffer);
  aec3.ProcessCapture(&buffer, /*level_change=*/false);
}

}  // namespace

class EchoCanceller3Tester {
 public:
  explicit EchoCanceller3Tester(int sample_rate_hz)
      : sample_rate_hz_(sample_rate_hz),
        num_bands_(NumBandsForRate(sample_rate_hz_)),
        frame_length_(160),
        fullband_frame_length_(CheckedDivExact(sample_rate_hz_, 100)),
        capture_buffer_(fullband_frame_length_ * 100,
                        1,
                        fullband_frame_length_ * 100,
                        1,
                        fullband_frame_length_ * 100,
                        1),
        render_buffer_(fullband_frame_length_ * 100,
                       1,
                       fullband_frame_length_ * 100,
                       1,
                       fullband_frame_length_ * 100,
                       1) {}

  EchoCanceller3Tester() = delete;
  EchoCanceller3Tester(const EchoCanceller3Tester&) = delete;
  EchoCanceller3Tester& operator=(const EchoCanceller3Tester&) = delete;

  // Verifies that the capture data is properly received by the block processor
  // and that the processor data is properly passed to the EchoCanceller3
  // output.
  void RunCaptureTransportVerificationTest() {
    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<CaptureTransportVerificationProcessor>(num_bands_));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
      EXPECT_TRUE(VerifyOutputFrameBitexactness(
          frame_length_, num_bands_, frame_index,
          &capture_buffer_.split_bands(0)[0], -64));
    }
  }

  // Test method for testing that the render data is properly received by the
  // block processor.
  void RunRenderTransportVerificationTest() {
    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<RenderTransportVerificationProcessor>(num_bands_));

    std::vector<std::vector<float>> render_input(1);
    std::vector<float> capture_output;
    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 100);
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      for (size_t k = 0; k < frame_length_; ++k) {
        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
      }
      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
      for (size_t k = 0; k < frame_length_; ++k) {
        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
      }
    }

    EXPECT_TRUE(
        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
  }

  // Verifies that information about echo path changes are properly propagated
  // to the block processor.
  // The cases tested are:
  // -That no set echo path change flags are received when there is no echo path
  // change.
  // -That set echo path change flags are received and continues to be received
  // as long as echo path changes are flagged.
  // -That set echo path change flags are no longer received when echo path
  // change events stop being flagged.
  enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };

  void RunEchoPathChangeVerificationTest(
      EchoPathChangeTestVariant echo_path_change_test_variant) {
    constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    constexpr size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);

    switch (echo_path_change_test_variant) {
      case EchoPathChangeTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case EchoPathChangeTestVariant::kOneSticky:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case EchoPathChangeTestVariant::kOneNonSticky:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
        break;
    }

    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      bool echo_path_change = false;
      switch (echo_path_change_test_variant) {
        case EchoPathChangeTestVariant::kNone:
          break;
        case EchoPathChangeTestVariant::kOneSticky:
          echo_path_change = true;
          break;
        case EchoPathChangeTestVariant::kOneNonSticky:
          if (frame_index == 0) {
            echo_path_change = true;
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, echo_path_change);
    }
  }

  // Test for verifying that echo leakage information is being properly passed
  // to the processor.
  // The cases tested are:
  // -That no method calls are received when they should not.
  // -That false values are received each time they are flagged.
  // -That true values are received each time they are flagged.
  // -That a false value is received when flagged after a true value has been
  // flagged.
  enum class EchoLeakageTestVariant {
    kNone,
    kFalseSticky,
    kTrueSticky,
    kTrueNonSticky
  };

  void RunEchoLeakageVerificationTest(
      EchoLeakageTestVariant leakage_report_variant) {
    constexpr size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
        .Times(kExpectedNumBlocksToProcess);

    switch (leakage_report_variant) {
      case EchoLeakageTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
        break;
      case EchoLeakageTestVariant::kFalseSticky:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
            .Times(1);
        break;
      case EchoLeakageTestVariant::kTrueSticky:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
            .Times(1);
        break;
      case EchoLeakageTestVariant::kTrueNonSticky: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
            .Times(1);
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
            .Times(kNumFramesToProcess - 1);
      } break;
    }

    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      switch (leakage_report_variant) {
        case EchoLeakageTestVariant::kNone:
          break;
        case EchoLeakageTestVariant::kFalseSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(false);
          }
          break;
        case EchoLeakageTestVariant::kTrueSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(true);
          }
          break;
        case EchoLeakageTestVariant::kTrueNonSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(true);
          } else {
            aec3.UpdateEchoLeakageStatus(false);
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
    }
  }

  // This verifies that saturation information is properly passed to the
  // BlockProcessor.
  // The cases tested are:
  // -That no saturation event is passed to the processor if there is no
  // saturation.
  // -That one frame with one negative saturated sample value is reported to be
  // saturated and that following non-saturated frames are properly reported as
  // not being saturated.
  // -That one frame with one positive saturated sample value is reported to be
  // saturated and that following non-saturated frames are properly reported as
  // not being saturated.
  enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };

  void RunCaptureSaturationVerificationTest(
      SaturationTestVariant saturation_variant) {
    const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    const size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);

    switch (saturation_variant) {
      case SaturationTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case SaturationTestVariant::kOneNegative: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
      } break;
      case SaturationTestVariant::kOnePositive: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
      } break;
    }

    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      for (int k = 0; k < fullband_frame_length_; ++k) {
        capture_buffer_.channels()[0][k] = 0.f;
      }
      switch (saturation_variant) {
        case SaturationTestVariant::kNone:
          break;
        case SaturationTestVariant::kOneNegative:
          if (frame_index == 0) {
            capture_buffer_.channels()[0][10] = -32768.f;
          }
          break;
        case SaturationTestVariant::kOnePositive:
          if (frame_index == 0) {
            capture_buffer_.channels()[0][10] = 32767.f;
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
    }
  }

  // This test verifies that the swapqueue is able to handle jitter in the
  // capture and render API calls.
  void RunRenderSwapQueueVerificationTest() {
    const EchoCanceller3Config config;
    EchoCanceller3 aec3(CreateTestEnvironment(), config,
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<RenderTransportVerificationProcessor>(num_bands_));

    std::vector<std::vector<float>> render_input(1);
    std::vector<float> capture_output;

    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
         ++frame_index) {
      if (sample_rate_hz_ > 16000) {
        render_buffer_.SplitIntoFrequencyBands();
      }
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      if (sample_rate_hz_ > 16000) {
        render_buffer_.SplitIntoFrequencyBands();
      }

      for (size_t k = 0; k < frame_length_; ++k) {
        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
      }
      aec3.AnalyzeRender(&render_buffer_);
    }

    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      if (sample_rate_hz_ > 16000) {
        capture_buffer_.SplitIntoFrequencyBands();
      }

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);

      aec3.ProcessCapture(&capture_buffer_, false);
      for (size_t k = 0; k < frame_length_; ++k) {
        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
      }
    }

    EXPECT_TRUE(
        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
  }

  // This test verifies that a buffer overrun in the render swapqueue is
  // properly reported.
  void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);

    constexpr size_t kRenderTransferQueueSize = 30;
    for (size_t k = 0; k < 2; ++k) {
      for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
           ++frame_index) {
        if (sample_rate_hz_ > 16000) {
          render_buffer_.SplitIntoFrequencyBands();
        }
        PopulateInputFrame(frame_length_, frame_index,
                           &render_buffer_.channels()[0][0], 0);

        aec3.AnalyzeRender(&render_buffer_);
      }
    }
  }

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
  // Verifies the that the check for the number of bands in the AnalyzeRender
  // input is correct by adjusting the sample rates of EchoCanceller3 and the
  // input AudioBuffer to have a different number of bands.
  void RunAnalyzeRenderNumBandsCheckVerification() {
    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    // way that the number of bands for the rates are different.
    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        aec3_sample_rate_hz, 1, 1);
    PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);

    EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
  }

  // Verifies the that the check for the number of bands in the ProcessCapture
  // input is correct by adjusting the sample rates of EchoCanceller3 and the
  // input AudioBuffer to have a different number of bands.
  void RunProcessCaptureNumBandsCheckVerification() {
    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    // way that the number of bands for the rates are different.
    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    EchoCanceller3 aec3(CreateTestEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        aec3_sample_rate_hz, 1, 1);
    PopulateInputFrame(frame_length_, num_bands_, 0,
                       &capture_buffer_.split_bands_f(0)[0], 100);
    EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
  }

#endif

 private:
  void OptionalBandSplit() {
    if (sample_rate_hz_ > 16000) {
      capture_buffer_.SplitIntoFrequencyBands();
      render_buffer_.SplitIntoFrequencyBands();
    }
  }

  static constexpr size_t kNumFramesToProcess = 20;
  const int sample_rate_hz_;
  const size_t num_bands_;
  const size_t frame_length_;
  const int fullband_frame_length_;
  AudioBuffer capture_buffer_;
  AudioBuffer render_buffer_;
};

TEST(EchoCanceller3Buffering, CaptureBitexactness) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
  }
}

TEST(EchoCanceller3Buffering, RenderBitexactness) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
  }
}

TEST(EchoCanceller3Buffering, RenderSwapQueue) {
  EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
}

TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate)
        .RunRenderPipelineSwapQueueOverrunReturnValueTest();
  }
}

TEST(EchoCanceller3Messaging, CaptureSaturation) {
  auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
                   EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
                   EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
    }
  }
}

TEST(EchoCanceller3Messaging, EchoPathChange) {
  auto variants = {
      EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
    }
  }
}

TEST(EchoCanceller3Messaging, EchoLeakage) {
  auto variants = {
      EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
      EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
    }
  }
}

// Tests the parameter functionality for the field trial override for the
// anti-howling gain.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, CreateTestFieldTrials());
  ASSERT_EQ(
      default_config.suppressor.high_bands_suppression.anti_howling_gain,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);

  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
  adjusted_config = AdjustConfig(default_config, field_trials);

  ASSERT_NE(
      default_config.suppressor.high_bands_suppression.anti_howling_gain,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
  EXPECT_FLOAT_EQ(
      0.02f,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
}

// Tests the field trial override for the enforcement of a low active render
// limit.
TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, CreateTestFieldTrials());
  ASSERT_EQ(default_config.render_levels.active_render_limit,
            adjusted_config.render_levels.active_render_limit);

  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
  adjusted_config = AdjustConfig(default_config, field_trials);

  ASSERT_NE(default_config.render_levels.active_render_limit,
            adjusted_config.render_levels.active_render_limit);
  EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
}

// Testing the field trial-based override of the suppressor parameters for a
// joint passing of all parameters.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3SuppressorTuningOverride/"
      "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
      "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
      "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
      "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
      "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
      "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
      "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
      "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
      "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
      "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
      "threshold:11/");

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);

  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
            default_config.suppressor.nearend_tuning.max_inc_factor);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
            default_config.suppressor.normal_tuning.max_inc_factor);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
            default_config.suppressor.normal_tuning.max_dec_factor_lf);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
            default_config.suppressor.dominant_nearend_detection.enr_threshold);
  ASSERT_NE(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
            default_config.suppressor.dominant_nearend_detection.snr_threshold);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            default_config.suppressor.dominant_nearend_detection.hold_duration);
  ASSERT_NE(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      default_config.suppressor.dominant_nearend_detection.trigger_threshold);

  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
                  0.5);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
                  0.6);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
                  0.8);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
                  1.0);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
                  1.2);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      1.4);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
  EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            10);
  EXPECT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      11);
}

// Testing the field trial-based override of the suppressor parameters for
// passing one parameter.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);

  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
            default_config.suppressor.normal_tuning.max_inc_factor);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
            default_config.suppressor.normal_tuning.max_dec_factor_lf);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
            default_config.suppressor.dominant_nearend_detection.enr_threshold);
  ASSERT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
            default_config.suppressor.dominant_nearend_detection.snr_threshold);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            default_config.suppressor.dominant_nearend_detection.hold_duration);
  ASSERT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      default_config.suppressor.dominant_nearend_detection.trigger_threshold);

  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
            default_config.suppressor.nearend_tuning.max_inc_factor);

  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
                  0.5);
}

// Testing the field trial-based that override the exponential decay parameters.
TEST(EchoCanceller3FieldTrials, Aec3UseNearendReverb) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3UseNearendReverbLen/default_len:0.9,nearend_len:0.8/");
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);
  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 0.9);
  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.nearend_len, 0.8);
}

// Testing the field trial-based that overrides the maximum allowed ecess render
// blocks in the render buffering.
TEST(EchoCanceller3FieldTrials, Aec3BufferingMaxAllowedExcessRenderBlocks) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3BufferingMaxAllowedExcessRenderBlocksOverride/2/");
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);
  EXPECT_EQ(adjusted_config.buffering.max_allowed_excess_render_blocks, 2ul);
}

TEST(EchoCanceller3, DetectionOfProperStereo) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_threshold = 0.0f;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
  multichannel_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  multichannel_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateTestEnvironment(), mono_config, multichannel_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, DetectionOfProperStereoUsingThreshold) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  constexpr float kStereoDetectionThreshold = 2.0f;
  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_threshold =
      kStereoDetectionThreshold;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
  multichannel_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  multichannel_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateTestEnvironment(), mono_config, multichannel_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f,
                 100.0f + kStereoDetectionThreshold - 1.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f,
                 100.0f + kStereoDetectionThreshold + 10.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, DetectionOfProperStereoUsingHysteresis) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> surround_config;

  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.5f;
  surround_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  surround_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateTestEnvironment(), mono_config, surround_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  constexpr int kNumFramesPerSecond = 100;
  for (int k = 0;
       k < static_cast<int>(
               kNumFramesPerSecond *
               mono_config.multi_channel.stereo_detection_hysteresis_seconds);
       ++k) {
    RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);
  }

  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, StereoContentDetectionForMonoSignals) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  const Environment env = CreateTestEnvironment();
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  for (bool detect_stereo_content : {false, true}) {
    mono_config.multi_channel.detect_stereo_content = detect_stereo_content;
    multichannel_config = mono_config;
    mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
    multichannel_config->filter.coarse_initial.length_blocks =
        kNumBlocksForSurroundConfig;

    AudioBuffer mono_buffer(/*input_rate=*/kSampleRateHz,
                            /*input_num_channels=*/1,
                            /*input_rate=*/kSampleRateHz,
                            /*buffer_num_channels=*/1,
                            /*output_rate=*/kSampleRateHz,
                            /*output_num_channels=*/1);

    EchoCanceller3 aec3(env, mono_config, multichannel_config,
                        /*neural_residual_echo_estimator=*/nullptr,
                        /*sample_rate_hz=*/kSampleRateHz,
                        /*num_render_channels=*/1,
                        /*num_capture_channels=*/1);

    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);

    RunAecInSMono(mono_buffer, aec3, 100.0f);
    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);
  }
}

TEST(EchoCanceller3, InjectedNeuralResidualEchoEstimatorIsUsed) {
  class NeuralResidualEchoEstimatorMock : public NeuralResidualEchoEstimator {
   public:
    NeuralResidualEchoEstimatorMock() {}

    void Estimate(const Block& render,
                  std::span<const std::array<float, 64>> capture,
                  std::span<const std::array<float, 64>> linear_aec_output,
                  std::span<const std::array<float, 65>> S2_linear,
                  std::span<const std::array<float, 65>> Y2,
                  std::span<const std::array<float, 65>> E2,
                  bool dominant_nearend,
                  std::span<std::array<float, 65>> R2,
                  std::span<std::array<float, 65>> R2_unbounded) override {
      residual_echo_estimate_requested_ = true;
      for (auto& R2_ch : R2) {
        R2_ch.fill(0.0f);
      }
      for (auto& R2_ch : R2_unbounded) {
        R2_ch.fill(0.0f);
      }
    }
    bool residual_echo_estimate_requested() const {
      return residual_echo_estimate_requested_;
    }

    EchoCanceller3Config::Suppressor AdjustConfig(
        const EchoCanceller3Config::Suppressor& config) const override {
      return config;
    }

    MOCK_METHOD(void, Reset, (), (override));

   private:
    bool residual_echo_estimate_requested_ = false;
  };

  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 1;
  NeuralResidualEchoEstimatorMock neural_residual_echo_estimator;
  const Environment env = CreateTestEnvironment();
  EchoCanceller3Config config;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*buffer_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);
  EchoCanceller3 aec3(env, config, /*multichannel_config=*/std::nullopt,
                      &neural_residual_echo_estimator,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);
  constexpr int kNumFramesToProcess = 300;
  for (int k = 0; k < kNumFramesToProcess; ++k) {
    RunAecInSMono(buffer, aec3, k);
  }
  EXPECT_TRUE(
      neural_residual_echo_estimator.residual_echo_estimate_requested());
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
  }
}

// Verifiers that the verification for null input to the capture processing api
// call works.
TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
  EXPECT_DEATH(
      EchoCanceller3(CreateTestEnvironment(), EchoCanceller3Config(),
                     /*multichannel_config_=*/std::nullopt,
                     /*neural_residual_echo_estimator=*/nullptr, 16000, 1, 1)
          .ProcessCapture(nullptr, false),
      "");
}

// Verifies the check for correct sample rate.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
  ApmDataDumper data_dumper(0);
  EXPECT_DEATH(
      EchoCanceller3(CreateTestEnvironment(), EchoCanceller3Config(),
                     /*multichannel_config_=*/std::nullopt,
                     /*neural_residual_echo_estimator=*/nullptr, 8001, 1, 1),
      "");
}

#endif

}  // namespace webrtc
