/*
 *  Copyright (c) 2012 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 "api/audio/audio_processing.h"

#include <stdio.h>

#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/audio/audio_processing_statistics.h"
#include "api/audio/audio_view.h"
#include "api/audio/builtin_audio_processing_builder.h"
#include "api/audio/echo_control.h"
#include "api/audio/echo_detector_creator.h"
#include "api/audio/neural_residual_echo_estimator.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "common_audio/channel_buffer.h"
#include "common_audio/include/audio_util.h"
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "modules/audio_processing/test/protobuf_utils.h"
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/cpu_info.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/numerics/safe_minmax.h"
#include "rtc_base/protobuf_utils.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/swap_queue.h"
#include "rtc_base/system/file_wrapper.h"
#include "rtc_base/task_queue_for_test.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
#include "external/webrtc/webrtc/modules/audio_processing/test/unittest.pb.h"
#else
#include "modules/audio_processing/debug.pb.h"
#include "modules/audio_processing/test/unittest.pb.h"
#endif

ABSL_FLAG(bool,
          write_apm_ref_data,
          false,
          "Write ApmTest.Process results to file, instead of comparing results "
          "to the existing reference data file.");

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::WithoutArgs;

// All sample rates used by APM internally during processing. Other input /
// output rates are resampled to / from one of these.
constexpr int kProcessSampleRates[] = {16000, 32000, 48000};

enum StreamDirection { kForward = 0, kReverse };

void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
  ChannelBuffer<int16_t> cb_int(cb->num_frames(), cb->num_channels());
  Deinterleave(int_data, cb->num_frames(), cb->num_channels(),
               cb_int.channels());
  for (size_t i = 0; i < cb->num_channels(); ++i) {
    S16ToFloat(cb_int.channels()[i], cb->num_frames(), cb->channels()[i]);
  }
}

void ConvertToFloat(const Int16FrameData& frame, ChannelBuffer<float>* cb) {
  ConvertToFloat(frame.data.data(), cb);
}

void MixStereoToMono(const float* stereo,
                     float* mono,
                     size_t samples_per_channel) {
  for (size_t i = 0; i < samples_per_channel; ++i)
    mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) / 2;
}

void MixStereoToMono(const int16_t* stereo,
                     int16_t* mono,
                     size_t samples_per_channel) {
  for (size_t i = 0; i < samples_per_channel; ++i)
    mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1;
}

void CopyLeftToRightChannel(int16_t* stereo, size_t samples_per_channel) {
  for (size_t i = 0; i < samples_per_channel; i++) {
    stereo[i * 2 + 1] = stereo[i * 2];
  }
}

void VerifyChannelsAreEqual(const int16_t* stereo, size_t samples_per_channel) {
  for (size_t i = 0; i < samples_per_channel; i++) {
    EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]);
  }
}

void EnableAllAPComponents(AudioProcessing* ap) {
  AudioProcessing::Config apm_config = ap->GetConfig();
  apm_config.echo_canceller.enabled = true;

  apm_config.gain_controller1.enabled = true;
  apm_config.gain_controller1.mode =
      AudioProcessing::Config::GainController1::kAdaptiveAnalog;

  apm_config.noise_suppression.enabled = true;

  apm_config.high_pass_filter.enabled = true;
  apm_config.pipeline.maximum_internal_processing_rate = 48000;
  ap->ApplyConfig(apm_config);
}

// These functions are only used by ApmTest.Process.
template <class T>
T AbsValue(T a) {
  return a > 0 ? a : -a;
}

int16_t MaxAudioFrame(const Int16FrameData& frame) {
  int16_t max_data = AbsValue(frame.data[0]);
  for (size_t i = 1; i < frame.size(); i++) {
    max_data = std::max(max_data, AbsValue(frame.data[i]));
  }

  return max_data;
}

void OpenFileAndWriteMessage(absl::string_view filename,
                             const MessageLite& msg) {
  FILE* file = fopen(std::string(filename).c_str(), "wb");
  ASSERT_TRUE(file != nullptr);

  int32_t size = checked_cast<int32_t>(msg.ByteSizeLong());
  ASSERT_GT(size, 0);
  std::unique_ptr<uint8_t[]> array(new uint8_t[size]);
  ASSERT_TRUE(msg.SerializeToArray(array.get(), size));

  ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file));
  ASSERT_EQ(static_cast<size_t>(size),
            fwrite(array.get(), sizeof(array[0]), size, file));
  fclose(file);
}

std::string ResourceFilePath(absl::string_view name, int sample_rate_hz) {
  StringBuilder ss;
  // Resource files are all stereo.
  ss << name << sample_rate_hz / 1000 << "_stereo";
  return test::ResourcePath(ss.str(), "pcm");
}

// Temporary filenames unique to this process. Used to be able to run these
// tests in parallel as each process needs to be running in isolation they can't
// have competing filenames.
std::map<std::string, std::string> temp_filenames;

std::string OutputFilePath(absl::string_view name,
                           int input_rate,
                           int output_rate,
                           int reverse_input_rate,
                           int reverse_output_rate,
                           size_t num_input_channels,
                           size_t num_output_channels,
                           size_t num_reverse_input_channels,
                           size_t num_reverse_output_channels,
                           StreamDirection file_direction) {
  StringBuilder ss;
  ss << name << "_i" << num_input_channels << "_" << input_rate / 1000 << "_ir"
     << num_reverse_input_channels << "_" << reverse_input_rate / 1000 << "_";
  if (num_output_channels == 1) {
    ss << "mono";
  } else if (num_output_channels == 2) {
    ss << "stereo";
  } else {
    RTC_DCHECK_NOTREACHED();
  }
  ss << output_rate / 1000;
  if (num_reverse_output_channels == 1) {
    ss << "_rmono";
  } else if (num_reverse_output_channels == 2) {
    ss << "_rstereo";
  } else {
    RTC_DCHECK_NOTREACHED();
  }
  ss << reverse_output_rate / 1000;
  ss << "_d" << file_direction << "_pcm";

  std::string filename = ss.str();
  if (temp_filenames[filename].empty())
    temp_filenames[filename] = test::TempFilename(test::OutputPath(), filename);
  return temp_filenames[filename];
}

void ClearTempFiles() {
  for (auto& kv : temp_filenames)
    remove(kv.second.c_str());
}

void OpenFileAndReadMessage(absl::string_view filename, MessageLite* msg) {
  FILE* file = fopen(std::string(filename).c_str(), "rb");
  ASSERT_TRUE(file != nullptr);
  ReadMessageFromFile(file, msg);
  fclose(file);
}

// Reads a 10 ms chunk (actually AudioProcessing::GetFrameSize() samples per
// channel) of int16 interleaved audio from the given (assumed stereo) file,
// converts to deinterleaved float (optionally downmixing) and returns the
// result in `cb`. Returns false if the file ended (or on error) and true
// otherwise.
//
// `int_data` and `float_data` are just temporary space that must be
// sufficiently large to hold the 10 ms chunk.
bool ReadChunk(FILE* file,
               int16_t* int_data,
               float* float_data,
               ChannelBuffer<float>* cb) {
  // The files always contain stereo audio.
  size_t frame_size = cb->num_frames() * 2;
  size_t read_count = fread(int_data, sizeof(int16_t), frame_size, file);
  if (read_count != frame_size) {
    // Check that the file really ended.
    RTC_DCHECK(feof(file));
    return false;  // This is expected.
  }

  S16ToFloat(int_data, frame_size, float_data);
  if (cb->num_channels() == 1) {
    MixStereoToMono(float_data, cb->channels()[0], cb->num_frames());
  } else {
    Deinterleave(float_data, cb->num_frames(), 2, cb->channels());
  }

  return true;
}

// Returns the reference file name that matches the current CPU
// architecture/optimizations.
std::string GetReferenceFilename() {
  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
    return test::ResourcePath("audio_processing/output_data_float_avx2", "pb");
  }
  return test::ResourcePath("audio_processing/output_data_float", "pb");
}

// Flag that can temporarily be enabled for local debugging to inspect
// `ApmTest.VerifyDebugDump(Int|Float)` failures. Do not upload code changes
// with this flag set to true.
constexpr bool kDumpWhenExpectMessageEqFails = false;

// Checks the debug constants values used in this file so that no code change is
// submitted with values temporarily used for local debugging.
TEST(ApmUnitTests, CheckDebugConstants) {
  ASSERT_FALSE(kDumpWhenExpectMessageEqFails);
}

// Expects the equality of `actual` and `expected` by inspecting a hard-coded
// subset of `audioproc::Stream` fields.
void ExpectStreamFieldsEq(const audioproc::Stream& actual,
                          const audioproc::Stream& expected) {
  EXPECT_EQ(actual.input_data(), expected.input_data());
  EXPECT_EQ(actual.output_data(), expected.output_data());
  EXPECT_EQ(actual.delay(), expected.delay());
  EXPECT_EQ(actual.drift(), expected.drift());
  EXPECT_EQ(actual.applied_input_volume(), expected.applied_input_volume());
  EXPECT_EQ(actual.keypress(), expected.keypress());
}

// Expects the equality of `actual` and `expected` by inspecting a hard-coded
// subset of `audioproc::Event` fields.
void ExpectEventFieldsEq(const audioproc::Event& actual,
                         const audioproc::Event& expected) {
  EXPECT_EQ(actual.type(), expected.type());
  if (actual.type() != expected.type()) {
    return;
  }
  switch (actual.type()) {
    case audioproc::Event::STREAM:
      ExpectStreamFieldsEq(actual.stream(), expected.stream());
      break;
    default:
      // Not implemented.
      break;
  }
}

// Returns true if the `actual` and `expected` byte streams share the same size
// and contain the same data. If they differ and `kDumpWhenExpectMessageEqFails`
// is true, checks the equality of a subset of `audioproc::Event` (nested)
// fields.
bool ExpectMessageEq(ArrayView<const uint8_t> actual,
                     ArrayView<const uint8_t> expected) {
  EXPECT_EQ(actual.size(), expected.size());
  if (actual.size() != expected.size()) {
    return false;
  }
  if (memcmp(actual.data(), expected.data(), actual.size()) == 0) {
    // Same message. No need to parse.
    return true;
  }
  if (kDumpWhenExpectMessageEqFails) {
    // Parse differing messages and expect equality to produce detailed error
    // messages.
    audioproc::Event event_actual, event_expected;
    RTC_DCHECK(event_actual.ParseFromArray(actual.data(), actual.size()));
    RTC_DCHECK(event_expected.ParseFromArray(expected.data(), expected.size()));
    ExpectEventFieldsEq(event_actual, event_expected);
  }
  return false;
}

class ApmTest : public ::testing::Test {
 protected:
  ApmTest();
  void SetUp() override;
  void TearDown() override;

  static void SetUpTestSuite() {}

  static void TearDownTestSuite() { ClearTempFiles(); }

  // Used to select between int and float interface tests.
  enum Format { kIntFormat, kFloatFormat };

  void Init(int sample_rate_hz,
            int output_sample_rate_hz,
            int reverse_sample_rate_hz,
            size_t num_input_channels,
            size_t num_output_channels,
            size_t num_reverse_channels,
            bool open_output_file);
  void Init(AudioProcessing* ap);
  void EnableAllComponents();
  bool ReadFrame(FILE* file, Int16FrameData* frame);
  bool ReadFrame(FILE* file, Int16FrameData* frame, ChannelBuffer<float>* cb);
  void ReadFrameWithRewind(FILE* file, Int16FrameData* frame);
  void ReadFrameWithRewind(FILE* file,
                           Int16FrameData* frame,
                           ChannelBuffer<float>* cb);
  void ProcessDelayVerificationTest(int delay_ms,
                                    int system_delay_ms,
                                    int delay_min,
                                    int delay_max);
  void TestChangingChannelsInt16Interface(
      size_t num_channels,
      AudioProcessing::Error expected_return);
  void TestChangingForwardChannels(size_t num_in_channels,
                                   size_t num_out_channels,
                                   AudioProcessing::Error expected_return);
  void TestChangingReverseChannels(size_t num_rev_channels,
                                   AudioProcessing::Error expected_return);
  void RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate);
  void RunManualVolumeChangeIsPossibleTest(int sample_rate);
  void StreamParametersTest(Format format);
  int ProcessStreamChooser(Format format);
  int AnalyzeReverseStreamChooser(Format format);
  void ProcessDebugDump(absl::string_view in_filename,
                        absl::string_view out_filename,
                        Format format,
                        int max_size_bytes);
  void VerifyDebugDumpTest(Format format);

  const std::string output_path_;
  const std::string ref_filename_;
  scoped_refptr<AudioProcessing> apm_;
  Int16FrameData frame_;
  Int16FrameData revframe_;
  std::unique_ptr<ChannelBuffer<float>> float_cb_;
  std::unique_ptr<ChannelBuffer<float>> revfloat_cb_;
  int output_sample_rate_hz_;
  size_t num_output_channels_;
  FILE* far_file_;
  FILE* near_file_;
  FILE* out_file_;
};

ApmTest::ApmTest()
    : output_path_(test::OutputPath()),
      ref_filename_(GetReferenceFilename()),
      output_sample_rate_hz_(0),
      num_output_channels_(0),
      far_file_(nullptr),
      near_file_(nullptr),
      out_file_(nullptr) {
  apm_ = BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  AudioProcessing::Config apm_config = apm_->GetConfig();
  apm_config.gain_controller1.analog_gain_controller.enabled = false;
  apm_config.pipeline.maximum_internal_processing_rate = 48000;
  apm_->ApplyConfig(apm_config);
}

void ApmTest::SetUp() {
  ASSERT_TRUE(apm_.get() != nullptr);

  Init(32000, 32000, 32000, 2, 2, 2, false);
}

void ApmTest::TearDown() {
  if (far_file_) {
    ASSERT_EQ(0, fclose(far_file_));
  }
  far_file_ = nullptr;

  if (near_file_) {
    ASSERT_EQ(0, fclose(near_file_));
  }
  near_file_ = nullptr;

  if (out_file_) {
    ASSERT_EQ(0, fclose(out_file_));
  }
  out_file_ = nullptr;
}

void ApmTest::Init(AudioProcessing* ap) {
  ASSERT_EQ(
      AudioProcessing::kNoError,
      ap->Initialize({{{frame_.sample_rate_hz, frame_.num_channels()},
                       {output_sample_rate_hz_, num_output_channels_},
                       {revframe_.sample_rate_hz, revframe_.num_channels()},
                       {revframe_.sample_rate_hz, revframe_.num_channels()}}}));
}

void ApmTest::Init(int sample_rate_hz,
                   int output_sample_rate_hz,
                   int reverse_sample_rate_hz,
                   size_t num_input_channels,
                   size_t num_output_channels,
                   size_t num_reverse_channels,
                   bool open_output_file) {
  SetContainerFormat(sample_rate_hz, num_input_channels, &frame_, &float_cb_);
  output_sample_rate_hz_ = output_sample_rate_hz;
  num_output_channels_ = num_output_channels;

  SetContainerFormat(reverse_sample_rate_hz, num_reverse_channels, &revframe_,
                     &revfloat_cb_);
  Init(apm_.get());

  if (far_file_) {
    ASSERT_EQ(0, fclose(far_file_));
  }
  std::string filename = ResourceFilePath("far", sample_rate_hz);
  far_file_ = fopen(filename.c_str(), "rb");
  ASSERT_TRUE(far_file_ != nullptr)
      << "Could not open file " << filename << "\n";

  if (near_file_) {
    ASSERT_EQ(0, fclose(near_file_));
  }
  filename = ResourceFilePath("near", sample_rate_hz);
  near_file_ = fopen(filename.c_str(), "rb");
  ASSERT_TRUE(near_file_ != nullptr)
      << "Could not open file " << filename << "\n";

  if (open_output_file) {
    if (out_file_) {
      ASSERT_EQ(0, fclose(out_file_));
    }
    filename = OutputFilePath(
        "out", sample_rate_hz, output_sample_rate_hz, reverse_sample_rate_hz,
        reverse_sample_rate_hz, num_input_channels, num_output_channels,
        num_reverse_channels, num_reverse_channels, kForward);
    out_file_ = fopen(filename.c_str(), "wb");
    ASSERT_TRUE(out_file_ != nullptr)
        << "Could not open file " << filename << "\n";
  }
}

void ApmTest::EnableAllComponents() {
  EnableAllAPComponents(apm_.get());
}

bool ApmTest::ReadFrame(FILE* file,
                        Int16FrameData* frame,
                        ChannelBuffer<float>* cb) {
  // The files always contain stereo audio.
  size_t frame_size = frame->samples_per_channel() * 2;
  size_t read_count =
      fread(frame->data.data(), sizeof(int16_t), frame_size, file);
  if (read_count != frame_size) {
    // Check that the file really ended.
    EXPECT_NE(0, feof(file));
    return false;  // This is expected.
  }

  if (frame->num_channels() == 1) {
    MixStereoToMono(frame->data.data(), frame->data.data(),
                    frame->samples_per_channel());
  }

  if (cb) {
    ConvertToFloat(*frame, cb);
  }
  return true;
}

bool ApmTest::ReadFrame(FILE* file, Int16FrameData* frame) {
  return ReadFrame(file, frame, nullptr);
}

// If the end of the file has been reached, rewind it and attempt to read the
// frame again.
void ApmTest::ReadFrameWithRewind(FILE* /* file */,
                                  Int16FrameData* /* frame */,
                                  ChannelBuffer<float>* cb) {
  if (!ReadFrame(near_file_, &frame_, cb)) {
    rewind(near_file_);
    ASSERT_TRUE(ReadFrame(near_file_, &frame_, cb));
  }
}

void ApmTest::ReadFrameWithRewind(FILE* file, Int16FrameData* frame) {
  ReadFrameWithRewind(file, frame, nullptr);
}

int ApmTest::ProcessStreamChooser(Format format) {
  if (format == kIntFormat) {
    return apm_->ProcessStream(
        frame_.data.data(),
        StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
        StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
        frame_.data.data());
  }
  return apm_->ProcessStream(
      float_cb_->channels(),
      StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
      StreamConfig(output_sample_rate_hz_, num_output_channels_),
      float_cb_->channels());
}

int ApmTest::AnalyzeReverseStreamChooser(Format format) {
  if (format == kIntFormat) {
    return apm_->ProcessReverseStream(
        revframe_.data.data(),
        StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
        StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
        revframe_.data.data());
  }
  return apm_->AnalyzeReverseStream(
      revfloat_cb_->channels(),
      StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()));
}

void ApmTest::ProcessDelayVerificationTest(int delay_ms,
                                           int system_delay_ms,
                                           int delay_min,
                                           int delay_max) {
  // The `revframe_` and `frame_` should include the proper frame information,
  // hence can be used for extracting information.
  Int16FrameData tmp_frame;
  std::queue<Int16FrameData*> frame_queue;
  bool causal = true;

  tmp_frame.CopyFrom(revframe_);
  tmp_frame.FillData(0);

  EXPECT_EQ(AudioProcessing::kNoError, apm_->Initialize());
  // Initialize the `frame_queue` with empty frames.
  int frame_delay = delay_ms / 10;
  while (frame_delay < 0) {
    Int16FrameData* frame = new Int16FrameData();
    frame->CopyFrom(tmp_frame);
    frame_queue.push(frame);
    frame_delay++;
    causal = false;
  }
  while (frame_delay > 0) {
    Int16FrameData* frame = new Int16FrameData();
    frame->CopyFrom(tmp_frame);
    frame_queue.push(frame);
    frame_delay--;
  }
  // Run for 4.5 seconds, skipping statistics from the first 2.5 seconds.  We
  // need enough frames with audio to have reliable estimates, but as few as
  // possible to keep processing time down.  4.5 seconds seemed to be a good
  // compromise for this recording.
  for (int frame_count = 0; frame_count < 450; ++frame_count) {
    Int16FrameData* frame = new Int16FrameData();
    frame->CopyFrom(tmp_frame);
    // Use the near end recording, since that has more speech in it.
    ASSERT_TRUE(ReadFrame(near_file_, frame));
    frame_queue.push(frame);
    Int16FrameData* reverse_frame = frame;
    Int16FrameData* process_frame = frame_queue.front();
    if (!causal) {
      reverse_frame = frame_queue.front();
      // When we call ProcessStream() the frame is modified, so we can't use the
      // pointer directly when things are non-causal. Use an intermediate frame
      // and copy the data.
      process_frame = &tmp_frame;
      process_frame->CopyFrom(*frame);
    }
    EXPECT_EQ(
        AudioProcessing::kNoError,
        apm_->ProcessReverseStream(reverse_frame->data.data(),
                                   StreamConfig(reverse_frame->sample_rate_hz,
                                                reverse_frame->num_channels()),
                                   StreamConfig(reverse_frame->sample_rate_hz,
                                                reverse_frame->num_channels()),
                                   reverse_frame->data.data()));
    EXPECT_EQ(AudioProcessing::kNoError,
              apm_->set_stream_delay_ms(system_delay_ms));
    EXPECT_EQ(AudioProcessing::kNoError,
              apm_->ProcessStream(process_frame->data.data(),
                                  StreamConfig(process_frame->sample_rate_hz,
                                               process_frame->num_channels()),
                                  StreamConfig(process_frame->sample_rate_hz,
                                               process_frame->num_channels()),
                                  process_frame->data.data()));
    frame = frame_queue.front();
    frame_queue.pop();
    delete frame;

    if (frame_count == 250) {
      // Discard the first delay metrics to avoid convergence effects.
      static_cast<void>(apm_->GetStatistics());
    }
  }

  rewind(near_file_);
  while (!frame_queue.empty()) {
    Int16FrameData* frame = frame_queue.front();
    frame_queue.pop();
    delete frame;
  }
  // Calculate expected delay estimate and acceptable regions. Further,
  // limit them w.r.t. AEC delay estimation support.
  const size_t samples_per_ms =
      SafeMin<size_t>(16u, frame_.samples_per_channel() / 10);
  const int expected_median =
      SafeClamp<int>(delay_ms - system_delay_ms, delay_min, delay_max);
  const int expected_median_high =
      SafeClamp<int>(expected_median + dchecked_cast<int>(96 / samples_per_ms),
                     delay_min, delay_max);
  const int expected_median_low =
      SafeClamp<int>(expected_median - dchecked_cast<int>(96 / samples_per_ms),
                     delay_min, delay_max);
  // Verify delay metrics.
  AudioProcessingStats stats = apm_->GetStatistics();
  ASSERT_TRUE(stats.delay_median_ms.has_value());
  int32_t median = *stats.delay_median_ms;
  EXPECT_GE(expected_median_high, median);
  EXPECT_LE(expected_median_low, median);
}

void ApmTest::StreamParametersTest(Format format) {
  // No errors when the components are disabled.
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));

  // -- Missing AGC level --
  AudioProcessing::Config apm_config = apm_->GetConfig();
  apm_config.gain_controller1.enabled = true;
  apm_->ApplyConfig(apm_config);
  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));

  // Resets after successful ProcessStream().
  apm_->set_stream_analog_level(127);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));

  // Other stream parameters set correctly.
  apm_config.echo_canceller.enabled = true;
  apm_->ApplyConfig(apm_config);
  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
  EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
  apm_config.gain_controller1.enabled = false;
  apm_->ApplyConfig(apm_config);

  // -- Missing delay --
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));

  // Resets after successful ProcessStream().
  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));

  // Other stream parameters set correctly.
  apm_config.gain_controller1.enabled = true;
  apm_->ApplyConfig(apm_config);
  apm_->set_stream_analog_level(127);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
  apm_config.gain_controller1.enabled = false;
  apm_->ApplyConfig(apm_config);

  // -- No stream parameters --
  EXPECT_EQ(AudioProcessing::kNoError, AnalyzeReverseStreamChooser(format));
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));

  // -- All there --
  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
  apm_->set_stream_analog_level(127);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(format));
}

TEST_F(ApmTest, StreamParametersInt) {
  StreamParametersTest(kIntFormat);
}

TEST_F(ApmTest, StreamParametersFloat) {
  StreamParametersTest(kFloatFormat);
}

void ApmTest::TestChangingChannelsInt16Interface(
    size_t num_channels,
    AudioProcessing::Error expected_return) {
  frame_.set_num_channels(num_channels);

  EXPECT_EQ(expected_return,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_EQ(expected_return,
            apm_->ProcessReverseStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
}

void ApmTest::TestChangingForwardChannels(
    size_t num_in_channels,
    size_t num_out_channels,
    AudioProcessing::Error expected_return) {
  const StreamConfig input_stream = {frame_.sample_rate_hz, num_in_channels};
  const StreamConfig output_stream = {output_sample_rate_hz_, num_out_channels};

  EXPECT_EQ(expected_return,
            apm_->ProcessStream(float_cb_->channels(), input_stream,
                                output_stream, float_cb_->channels()));
}

void ApmTest::TestChangingReverseChannels(
    size_t num_rev_channels,
    AudioProcessing::Error expected_return) {
  const ProcessingConfig processing_config = {
      {{frame_.sample_rate_hz, apm_->num_input_channels()},
       {output_sample_rate_hz_, apm_->num_output_channels()},
       {frame_.sample_rate_hz, num_rev_channels},
       {frame_.sample_rate_hz, num_rev_channels}}};

  EXPECT_EQ(
      expected_return,
      apm_->ProcessReverseStream(
          float_cb_->channels(), processing_config.reverse_input_stream(),
          processing_config.reverse_output_stream(), float_cb_->channels()));
}

TEST_F(ApmTest, ChannelsInt16Interface) {
  // Testing number of invalid and valid channels.
  Init(16000, 16000, 16000, 4, 4, 4, false);

  TestChangingChannelsInt16Interface(0,
                                     AudioProcessing::kBadNumberChannelsError);

  for (size_t i = 1; i < 4; i++) {
    TestChangingChannelsInt16Interface(i, AudioProcessing::kNoError);
    EXPECT_EQ(i, apm_->num_input_channels());
  }
}

TEST_F(ApmTest, Channels) {
  // Testing number of invalid and valid channels.
  Init(16000, 16000, 16000, 4, 4, 4, false);

  TestChangingForwardChannels(0, 1, AudioProcessing::kBadNumberChannelsError);
  TestChangingReverseChannels(0, AudioProcessing::kBadNumberChannelsError);

  for (size_t i = 1; i < 4; ++i) {
    for (size_t j = 0; j < 1; ++j) {
      // Output channels much be one or match input channels.
      if (j == 1 || i == j) {
        TestChangingForwardChannels(i, j, AudioProcessing::kNoError);
        TestChangingReverseChannels(i, AudioProcessing::kNoError);

        EXPECT_EQ(i, apm_->num_input_channels());
        EXPECT_EQ(j, apm_->num_output_channels());
        // The number of reverse channels used for processing to is always 1.
        EXPECT_EQ(1u, apm_->num_reverse_channels());
      } else {
        TestChangingForwardChannels(i, j,
                                    AudioProcessing::kBadNumberChannelsError);
      }
    }
  }
}

TEST_F(ApmTest, SampleRatesInt) {
  // Testing some valid sample rates.
  for (int sample_rate : {8000, 12000, 16000, 32000, 44100, 48000, 96000}) {
    SetContainerFormat(sample_rate, 2, &frame_, &float_cb_);
    EXPECT_NOERR(ProcessStreamChooser(kIntFormat));
  }
}

// This test repeatedly reconfigures the pre-amplifier in APM, processes a
// number of frames, and checks that output signal has the right level.
TEST_F(ApmTest, PreAmplifier) {
  // Fill the audio frame with a sawtooth pattern.
  InterleavedView<int16_t> frame_data = frame_.view();
  const size_t samples_per_channel = frame_.samples_per_channel();
  for (size_t i = 0; i < samples_per_channel; i++) {
    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
      frame_data[i + ch * samples_per_channel] = 10000 * ((i % 3) - 1);
    }
  }
  // Cache the frame in tmp_frame.
  Int16FrameData tmp_frame;
  tmp_frame.CopyFrom(frame_);

  auto compute_power = [](const Int16FrameData& frame) {
    ArrayView<const int16_t> data = frame.view().data();
    return std::accumulate(data.begin(), data.end(), 0.0f,
                           [](float a, float b) { return a + b * b; }) /
           data.size() / 32768 / 32768;
  };

  const float input_power = compute_power(tmp_frame);
  // Double-check that the input data is large compared to the error kEpsilon.
  constexpr float kEpsilon = 1e-4f;
  RTC_DCHECK_GE(input_power, 10 * kEpsilon);

  // 1. Enable pre-amp with 0 dB gain.
  AudioProcessing::Config config = apm_->GetConfig();
  config.pre_amplifier.enabled = true;
  config.pre_amplifier.fixed_gain_factor = 1.0f;
  apm_->ApplyConfig(config);

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  float output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, input_power, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 1.0f);

  // 2. Change pre-amp gain via ApplyConfig.
  config.pre_amplifier.fixed_gain_factor = 2.0f;
  apm_->ApplyConfig(config);

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, 4 * input_power, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 2.0f);

  // 3. Change pre-amp gain via a RuntimeSetting.
  apm_->SetRuntimeSetting(
      AudioProcessing::RuntimeSetting::CreateCapturePreGain(1.5f));

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, 2.25 * input_power, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.pre_amplifier.fixed_gain_factor, 1.5f);
}

// Ensures that the emulated analog mic gain functionality runs without
// crashing.
TEST_F(ApmTest, AnalogMicGainEmulation) {
  // Fill the audio frame with a sawtooth pattern.
  InterleavedView<int16_t> frame_data = frame_.view();
  const size_t samples_per_channel = frame_.samples_per_channel();
  for (size_t i = 0; i < samples_per_channel; i++) {
    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
      frame_data[i + ch * samples_per_channel] = 100 * ((i % 3) - 1);
    }
  }
  // Cache the frame in tmp_frame.
  Int16FrameData tmp_frame;
  tmp_frame.CopyFrom(frame_);

  // Enable the analog gain emulation.
  AudioProcessing::Config config = apm_->GetConfig();
  config.capture_level_adjustment.enabled = true;
  config.capture_level_adjustment.analog_mic_gain_emulation.enabled = true;
  config.capture_level_adjustment.analog_mic_gain_emulation.initial_level = 21;
  config.gain_controller1.enabled = true;
  config.gain_controller1.mode =
      AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog;
  config.gain_controller1.analog_gain_controller.enabled = true;
  apm_->ApplyConfig(config);

  // Process a number of frames to ensure that the code runs without crashes.
  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
}

// This test repeatedly reconfigures the capture level adjustment functionality
// in APM, processes a number of frames, and checks that output signal has the
// right level.
TEST_F(ApmTest, CaptureLevelAdjustment) {
  // Fill the audio frame with a sawtooth pattern.
  InterleavedView<int16_t> frame_data = frame_.view();
  const size_t samples_per_channel = frame_.samples_per_channel();
  for (size_t i = 0; i < samples_per_channel; i++) {
    for (size_t ch = 0; ch < frame_.num_channels(); ++ch) {
      frame_data[i + ch * samples_per_channel] = 100 * ((i % 3) - 1);
    }
  }
  // Cache the frame in tmp_frame.
  Int16FrameData tmp_frame;
  tmp_frame.CopyFrom(frame_);

  auto compute_power = [](const Int16FrameData& frame) {
    ArrayView<const int16_t> data = frame.view().data();
    return std::accumulate(data.begin(), data.end(), 0.0f,
                           [](float a, float b) { return a + b * b; }) /
           data.size() / 32768 / 32768;
  };

  const float input_power = compute_power(tmp_frame);
  // Double-check that the input data is large compared to the error kEpsilon.
  constexpr float kEpsilon = 1e-20f;
  RTC_DCHECK_GE(input_power, 10 * kEpsilon);

  // 1. Enable pre-amp with 0 dB gain.
  AudioProcessing::Config config = apm_->GetConfig();
  config.capture_level_adjustment.enabled = true;
  config.capture_level_adjustment.pre_gain_factor = 0.5f;
  config.capture_level_adjustment.post_gain_factor = 4.f;
  const float expected_output_power1 =
      config.capture_level_adjustment.pre_gain_factor *
      config.capture_level_adjustment.pre_gain_factor *
      config.capture_level_adjustment.post_gain_factor *
      config.capture_level_adjustment.post_gain_factor * input_power;
  apm_->ApplyConfig(config);

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  float output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, expected_output_power1, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 0.5f);
  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 4.f);

  // 2. Change pre-amp gain via ApplyConfig.
  config.capture_level_adjustment.pre_gain_factor = 1.0f;
  config.capture_level_adjustment.post_gain_factor = 2.f;
  const float expected_output_power2 =
      config.capture_level_adjustment.pre_gain_factor *
      config.capture_level_adjustment.pre_gain_factor *
      config.capture_level_adjustment.post_gain_factor *
      config.capture_level_adjustment.post_gain_factor * input_power;
  apm_->ApplyConfig(config);

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, expected_output_power2, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 1.0f);
  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 2.f);

  // 3. Change pre-amp gain via a RuntimeSetting.
  constexpr float kPreGain3 = 0.5f;
  constexpr float kPostGain3 = 3.f;
  const float expected_output_power3 =
      kPreGain3 * kPreGain3 * kPostGain3 * kPostGain3 * input_power;

  apm_->SetRuntimeSetting(
      AudioProcessing::RuntimeSetting::CreateCapturePreGain(kPreGain3));
  apm_->SetRuntimeSetting(
      AudioProcessing::RuntimeSetting::CreateCapturePostGain(kPostGain3));

  for (int i = 0; i < 20; ++i) {
    frame_.CopyFrom(tmp_frame);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kIntFormat));
  }
  output_power = compute_power(frame_);
  EXPECT_NEAR(output_power, expected_output_power3, kEpsilon);
  config = apm_->GetConfig();
  EXPECT_EQ(config.capture_level_adjustment.pre_gain_factor, 0.5f);
  EXPECT_EQ(config.capture_level_adjustment.post_gain_factor, 3.f);
}

TEST_F(ApmTest, GainControl) {
  AudioProcessing::Config config = apm_->GetConfig();
  config.gain_controller1.enabled = false;
  apm_->ApplyConfig(config);
  config.gain_controller1.enabled = true;
  apm_->ApplyConfig(config);

  // Testing gain modes
  for (auto mode :
       {AudioProcessing::Config::GainController1::kAdaptiveDigital,
        AudioProcessing::Config::GainController1::kFixedDigital,
        AudioProcessing::Config::GainController1::kAdaptiveAnalog}) {
    config.gain_controller1.mode = mode;
    apm_->ApplyConfig(config);
    apm_->set_stream_analog_level(100);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  }

  // Testing target levels
  for (int target_level_dbfs : {0, 15, 31}) {
    config.gain_controller1.target_level_dbfs = target_level_dbfs;
    apm_->ApplyConfig(config);
    apm_->set_stream_analog_level(100);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  }

  // Testing compression gains
  for (int compression_gain_db : {0, 10, 90}) {
    config.gain_controller1.compression_gain_db = compression_gain_db;
    apm_->ApplyConfig(config);
    apm_->set_stream_analog_level(100);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  }

  // Testing limiter off/on
  for (bool enable : {false, true}) {
    config.gain_controller1.enable_limiter = enable;
    apm_->ApplyConfig(config);
    apm_->set_stream_analog_level(100);
    EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  }

  // Testing level limits.
  constexpr int kMinLevel = 0;
  constexpr int kMaxLevel = 255;
  apm_->set_stream_analog_level(kMinLevel);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  apm_->set_stream_analog_level((kMinLevel + kMaxLevel) / 2);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
  apm_->set_stream_analog_level(kMaxLevel);
  EXPECT_EQ(AudioProcessing::kNoError, ProcessStreamChooser(kFloatFormat));
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
using ApmDeathTest = ApmTest;

TEST_F(ApmDeathTest, GainControlDiesOnTooLowTargetLevelDbfs) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.target_level_dbfs = -1;
  EXPECT_DEATH(apm_->ApplyConfig(config), "");
}

TEST_F(ApmDeathTest, GainControlDiesOnTooHighTargetLevelDbfs) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.target_level_dbfs = 32;
  EXPECT_DEATH(apm_->ApplyConfig(config), "");
}

TEST_F(ApmDeathTest, GainControlDiesOnTooLowCompressionGainDb) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.compression_gain_db = -1;
  EXPECT_DEATH(apm_->ApplyConfig(config), "");
}

TEST_F(ApmDeathTest, GainControlDiesOnTooHighCompressionGainDb) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.compression_gain_db = 91;
  EXPECT_DEATH(apm_->ApplyConfig(config), "");
}

TEST_F(ApmDeathTest, ApmDiesOnTooLowAnalogLevel) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  apm_->ApplyConfig(config);
  EXPECT_DEATH(apm_->set_stream_analog_level(-1), "");
}

TEST_F(ApmDeathTest, ApmDiesOnTooHighAnalogLevel) {
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  apm_->ApplyConfig(config);
  EXPECT_DEATH(apm_->set_stream_analog_level(256), "");
}
#endif

void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
  Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.mode =
      AudioProcessing::Config::GainController1::kAdaptiveAnalog;
  apm_->ApplyConfig(config);

  int out_analog_level = 0;
  for (int i = 0; i < 2000; ++i) {
    ReadFrameWithRewind(near_file_, &frame_);
    // Ensure the audio is at a low level, so the AGC will try to increase it.
    frame_.Scale(0.25f);

    // Always pass in the same volume.
    apm_->set_stream_analog_level(100);
    EXPECT_EQ(AudioProcessing::kNoError,
              apm_->ProcessStream(
                  frame_.data.data(),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  frame_.data.data()));
    out_analog_level = apm_->recommended_stream_analog_level();
  }

  // Ensure the AGC is still able to reach the maximum.
  EXPECT_EQ(255, out_analog_level);
}

// Verifies that despite volume slider quantization, the AGC can continue to
// increase its volume.
TEST_F(ApmTest, QuantizedVolumeDoesNotGetStuck) {
  for (size_t sample_rate_hz : kProcessSampleRates) {
    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
    RunQuantizedVolumeDoesNotGetStuckTest(sample_rate_hz);
  }
}

void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
  Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
  auto config = apm_->GetConfig();
  config.gain_controller1.enabled = true;
  config.gain_controller1.mode =
      AudioProcessing::Config::GainController1::kAdaptiveAnalog;
  apm_->ApplyConfig(config);

  int out_analog_level = 100;
  for (int i = 0; i < 1000; ++i) {
    ReadFrameWithRewind(near_file_, &frame_);
    // Ensure the audio is at a low level, so the AGC will try to increase it.
    frame_.Scale(0.25f);

    apm_->set_stream_analog_level(out_analog_level);
    EXPECT_EQ(AudioProcessing::kNoError,
              apm_->ProcessStream(
                  frame_.data.data(),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  frame_.data.data()));
    out_analog_level = apm_->recommended_stream_analog_level();
  }

  // Ensure the volume was raised.
  EXPECT_GT(out_analog_level, 100);
  int highest_level_reached = out_analog_level;
  // Simulate a user manual volume change.
  out_analog_level = 100;

  for (int i = 0; i < 300; ++i) {
    ReadFrameWithRewind(near_file_, &frame_);
    frame_.Scale(0.25f);

    apm_->set_stream_analog_level(out_analog_level);
    EXPECT_EQ(AudioProcessing::kNoError,
              apm_->ProcessStream(
                  frame_.data.data(),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                  frame_.data.data()));
    out_analog_level = apm_->recommended_stream_analog_level();
    // Check that AGC respected the manually adjusted volume.
    EXPECT_LT(out_analog_level, highest_level_reached);
  }
  // Check that the volume was still raised.
  EXPECT_GT(out_analog_level, 100);
}

TEST_F(ApmTest, ManualVolumeChangeIsPossible) {
  for (size_t sample_rate_hz : kProcessSampleRates) {
    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
    RunManualVolumeChangeIsPossibleTest(sample_rate_hz);
  }
}

TEST_F(ApmTest, HighPassFilter) {
  // Turn HP filter on/off
  AudioProcessing::Config apm_config;
  apm_config.high_pass_filter.enabled = true;
  apm_->ApplyConfig(apm_config);
  apm_config.high_pass_filter.enabled = false;
  apm_->ApplyConfig(apm_config);
}

TEST_F(ApmTest, AllProcessingDisabledByDefault) {
  AudioProcessing::Config config = apm_->GetConfig();
  EXPECT_FALSE(config.echo_canceller.enabled);
  EXPECT_FALSE(config.high_pass_filter.enabled);
  EXPECT_FALSE(config.gain_controller1.enabled);
  EXPECT_FALSE(config.noise_suppression.enabled);
}

TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabledInt) {
  // Test that ProcessStream simply copies input to output when all components
  // are disabled.
  // Runs over all processing rates, and some particularly common or special
  // rates.
  // - 8000 Hz: lowest sample rate seen in Chrome metrics,
  // - 22050 Hz: APM input/output frames are not exactly 10 ms,
  // - 44100 Hz: very common desktop sample rate.
  constexpr int kSampleRatesHz[] = {8000, 16000, 22050, 32000, 44100, 48000};
  for (size_t sample_rate_hz : kSampleRatesHz) {
    SCOPED_TRACE(::testing::Message() << "sample_rate_hz=" << sample_rate_hz);
    Init(sample_rate_hz, sample_rate_hz, sample_rate_hz, 2, 2, 2, false);
    frame_.FillStereoData(1000, 2000);
    Int16FrameData frame_copy;
    frame_copy.CopyFrom(frame_);
    for (int j = 0; j < 1000; j++) {
      EXPECT_EQ(AudioProcessing::kNoError,
                apm_->ProcessStream(
                    frame_.data.data(),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    frame_.data.data()));
      EXPECT_TRUE(frame_.IsEqual(frame_copy));
      EXPECT_EQ(AudioProcessing::kNoError,
                apm_->ProcessReverseStream(
                    frame_.data.data(),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    frame_.data.data()));
      EXPECT_TRUE(frame_.IsEqual(frame_copy));
    }
  }
}

TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabledFloat) {
  // Test that ProcessStream simply copies input to output when all components
  // are disabled.
  const size_t kSamples = 160;
  const int sample_rate = 16000;
  const float src[kSamples] = {-1.0f, 0.0f, 1.0f};
  float dest[kSamples] = {};

  auto src_channels = &src[0];
  auto dest_channels = &dest[0];

  apm_ = BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  EXPECT_NOERR(apm_->ProcessStream(&src_channels, StreamConfig(sample_rate, 1),
                                   StreamConfig(sample_rate, 1),
                                   &dest_channels));

  for (size_t i = 0; i < kSamples; ++i) {
    EXPECT_EQ(src[i], dest[i]);
  }

  // Same for ProcessReverseStream.
  float rev_dest[kSamples] = {};
  auto rev_dest_channels = &rev_dest[0];

  StreamConfig input_stream = {sample_rate, 1};
  StreamConfig output_stream = {sample_rate, 1};
  EXPECT_NOERR(apm_->ProcessReverseStream(&src_channels, input_stream,
                                          output_stream, &rev_dest_channels));

  for (size_t i = 0; i < kSamples; ++i) {
    EXPECT_EQ(src[i], rev_dest[i]);
  }
}

TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
  EnableAllComponents();

  for (int sample_rate_hz : kProcessSampleRates) {
    Init(sample_rate_hz, sample_rate_hz, sample_rate_hz, 2, 2, 2, false);
    int analog_level = 127;
    ASSERT_EQ(0, feof(far_file_));
    ASSERT_EQ(0, feof(near_file_));
    while (ReadFrame(far_file_, &revframe_) && ReadFrame(near_file_, &frame_)) {
      CopyLeftToRightChannel(revframe_.data.data(),
                             revframe_.samples_per_channel());

      ASSERT_EQ(
          AudioProcessing::kNoError,
          apm_->ProcessReverseStream(
              revframe_.data.data(),
              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
              revframe_.data.data()));

      CopyLeftToRightChannel(frame_.data.data(), frame_.samples_per_channel());

      ASSERT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
      apm_->set_stream_analog_level(analog_level);
      ASSERT_EQ(AudioProcessing::kNoError,
                apm_->ProcessStream(
                    frame_.data.data(),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    frame_.data.data()));
      analog_level = apm_->recommended_stream_analog_level();

      VerifyChannelsAreEqual(frame_.data.data(), frame_.samples_per_channel());
    }
    rewind(far_file_);
    rewind(near_file_);
  }
}

TEST_F(ApmTest, SplittingFilter) {
  // Verify the filter is not active through undistorted audio when:
  // 1. No components are enabled...
  frame_.FillData(1000);
  Int16FrameData frame_copy;
  frame_copy.CopyFrom(frame_);
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_TRUE(frame_.IsEqual(frame_copy));

  // 2. Only the level estimator is enabled...
  auto apm_config = apm_->GetConfig();
  frame_.FillData(1000);
  frame_copy.CopyFrom(frame_);
  apm_->ApplyConfig(apm_config);
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_TRUE(frame_.IsEqual(frame_copy));
  apm_->ApplyConfig(apm_config);

  // Check the test is valid. We should have distortion from the filter
  // when AEC is enabled (which won't affect the audio).
  apm_config.echo_canceller.enabled = true;
  apm_->ApplyConfig(apm_config);
  frame_.SetProperties(/* samples_per_channel=*/320, /* num_channels=*/2);
  frame_.FillData(1000);
  frame_copy.CopyFrom(frame_);
  EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_FALSE(frame_.IsEqual(frame_copy));
}

#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
void ApmTest::ProcessDebugDump(absl::string_view in_filename,
                               absl::string_view out_filename,
                               Format format,
                               int max_size_bytes) {
  TaskQueueForTest worker_queue("ApmTest_worker_queue");
  FILE* in_file = fopen(std::string(in_filename).c_str(), "rb");
  ASSERT_TRUE(in_file != nullptr);
  audioproc::Event event_msg;
  bool first_init = true;

  while (ReadMessageFromFile(in_file, &event_msg)) {
    if (event_msg.type() == audioproc::Event::INIT) {
      const audioproc::Init msg = event_msg.init();
      int reverse_sample_rate = msg.sample_rate();
      if (msg.has_reverse_sample_rate()) {
        reverse_sample_rate = msg.reverse_sample_rate();
      }
      int output_sample_rate = msg.sample_rate();
      if (msg.has_output_sample_rate()) {
        output_sample_rate = msg.output_sample_rate();
      }

      Init(msg.sample_rate(), output_sample_rate, reverse_sample_rate,
           msg.num_input_channels(), msg.num_output_channels(),
           msg.num_reverse_channels(), false);
      if (first_init) {
        // AttachAecDump() writes an additional init message. Don't start
        // recording until after the first init to avoid the extra message.
        auto aec_dump = AecDumpFactory::Create(out_filename, max_size_bytes,
                                               worker_queue.Get());
        EXPECT_TRUE(aec_dump);
        apm_->AttachAecDump(std::move(aec_dump));
        first_init = false;
      }

    } else if (event_msg.type() == audioproc::Event::REVERSE_STREAM) {
      const audioproc::ReverseStream msg = event_msg.reverse_stream();

      if (msg.channel_size() > 0) {
        ASSERT_EQ(revframe_.num_channels(),
                  static_cast<size_t>(msg.channel_size()));
        for (int i = 0; i < msg.channel_size(); ++i) {
          memcpy(revfloat_cb_->channels()[i], msg.channel(i).data(),
                 msg.channel(i).size());
        }
      } else {
        memcpy(revframe_.data.data(), msg.data().data(), msg.data().size());
        if (format == kFloatFormat) {
          // We're using an int16 input file; convert to float.
          ConvertToFloat(revframe_, revfloat_cb_.get());
        }
      }
      AnalyzeReverseStreamChooser(format);

    } else if (event_msg.type() == audioproc::Event::STREAM) {
      const audioproc::Stream msg = event_msg.stream();
      // ProcessStream could have changed this for the output frame.
      frame_.set_num_channels(apm_->num_input_channels());

      apm_->set_stream_analog_level(msg.applied_input_volume());
      EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
      if (msg.has_keypress()) {
        apm_->set_stream_key_pressed(msg.keypress());
      } else {
        apm_->set_stream_key_pressed(true);
      }

      if (msg.input_channel_size() > 0) {
        ASSERT_EQ(frame_.num_channels(),
                  static_cast<size_t>(msg.input_channel_size()));
        for (int i = 0; i < msg.input_channel_size(); ++i) {
          memcpy(float_cb_->channels()[i], msg.input_channel(i).data(),
                 msg.input_channel(i).size());
        }
      } else {
        memcpy(frame_.data.data(), msg.input_data().data(),
               msg.input_data().size());
        if (format == kFloatFormat) {
          // We're using an int16 input file; convert to float.
          ConvertToFloat(frame_, float_cb_.get());
        }
      }
      ProcessStreamChooser(format);
    }
  }
  apm_->DetachAecDump();
  fclose(in_file);
}

void ApmTest::VerifyDebugDumpTest(Format format) {
  ScopedFakeClock fake_clock;
  const std::string in_filename = test::ResourcePath("ref03", "aecdump");
  std::string format_string;
  switch (format) {
    case kIntFormat:
      format_string = "_int";
      break;
    case kFloatFormat:
      format_string = "_float";
      break;
  }
  const std::string ref_filename = test::TempFilename(
      test::OutputPath(), std::string("ref") + format_string + "_aecdump");
  const std::string out_filename = test::TempFilename(
      test::OutputPath(), std::string("out") + format_string + "_aecdump");
  const std::string limited_filename = test::TempFilename(
      test::OutputPath(), std::string("limited") + format_string + "_aecdump");
  const size_t logging_limit_bytes = 100000;
  // We expect at least this many bytes in the created logfile.
  const size_t logging_expected_bytes = 95000;
  EnableAllComponents();
  ProcessDebugDump(in_filename, ref_filename, format, -1);
  ProcessDebugDump(ref_filename, out_filename, format, -1);
  ProcessDebugDump(ref_filename, limited_filename, format, logging_limit_bytes);

  FILE* ref_file = fopen(ref_filename.c_str(), "rb");
  FILE* out_file = fopen(out_filename.c_str(), "rb");
  FILE* limited_file = fopen(limited_filename.c_str(), "rb");
  ASSERT_TRUE(ref_file != nullptr);
  ASSERT_TRUE(out_file != nullptr);
  ASSERT_TRUE(limited_file != nullptr);
  std::unique_ptr<uint8_t[]> ref_bytes;
  std::unique_ptr<uint8_t[]> out_bytes;
  std::unique_ptr<uint8_t[]> limited_bytes;

  size_t ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
  size_t out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
  size_t limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes);
  size_t bytes_read = 0;
  size_t bytes_read_limited = 0;
  while (ref_size > 0 && out_size > 0) {
    bytes_read += ref_size;
    bytes_read_limited += limited_size;
    EXPECT_EQ(ref_size, out_size);
    EXPECT_GE(ref_size, limited_size);
    EXPECT_TRUE(ExpectMessageEq(/*actual=*/{out_bytes.get(), out_size},
                                /*expected=*/{ref_bytes.get(), ref_size}));
    if (limited_size > 0) {
      EXPECT_TRUE(
          ExpectMessageEq(/*actual=*/{limited_bytes.get(), limited_size},
                          /*expected=*/{ref_bytes.get(), ref_size}));
    }
    ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
    out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
    limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes);
  }
  EXPECT_GT(bytes_read, 0u);
  EXPECT_GT(bytes_read_limited, logging_expected_bytes);
  EXPECT_LE(bytes_read_limited, logging_limit_bytes);
  EXPECT_NE(0, feof(ref_file));
  EXPECT_NE(0, feof(out_file));
  EXPECT_NE(0, feof(limited_file));
  ASSERT_EQ(0, fclose(ref_file));
  ASSERT_EQ(0, fclose(out_file));
  ASSERT_EQ(0, fclose(limited_file));
  remove(ref_filename.c_str());
  remove(out_filename.c_str());
  remove(limited_filename.c_str());
}

TEST_F(ApmTest, VerifyDebugDumpInt) {
  VerifyDebugDumpTest(kIntFormat);
}

TEST_F(ApmTest, VerifyDebugDumpFloat) {
  VerifyDebugDumpTest(kFloatFormat);
}
#endif

// TODO(andrew): expand test to verify output.
TEST_F(ApmTest, DebugDump) {
  TaskQueueForTest worker_queue("ApmTest_worker_queue");
  const std::string filename =
      test::TempFilename(test::OutputPath(), "debug_aec");
  {
    auto aec_dump = AecDumpFactory::Create("", -1, worker_queue.Get());
    EXPECT_FALSE(aec_dump);
  }

#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
  // Stopping without having started should be OK.
  apm_->DetachAecDump();

  auto aec_dump = AecDumpFactory::Create(filename, -1, worker_queue.Get());
  EXPECT_TRUE(aec_dump);
  apm_->AttachAecDump(std::move(aec_dump));
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  EXPECT_EQ(
      AudioProcessing::kNoError,
      apm_->ProcessReverseStream(
          revframe_.data.data(),
          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
          revframe_.data.data()));
  apm_->DetachAecDump();

  // Verify the file has been written.
  FILE* fid = fopen(filename.c_str(), "r");
  ASSERT_TRUE(fid != nullptr);

  // Clean it up.
  ASSERT_EQ(0, fclose(fid));
  ASSERT_EQ(0, remove(filename.c_str()));
#else
  // Verify the file has NOT been written.
  ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
}

// TODO(andrew): expand test to verify output.
TEST_F(ApmTest, DebugDumpFromFileHandle) {
  TaskQueueForTest worker_queue("ApmTest_worker_queue");

  const std::string filename =
      test::TempFilename(test::OutputPath(), "debug_aec");
  FileWrapper f = FileWrapper::OpenWriteOnly(filename);
  ASSERT_TRUE(f.is_open());

#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
  // Stopping without having started should be OK.
  apm_->DetachAecDump();

  auto aec_dump = AecDumpFactory::Create(std::move(f), -1, worker_queue.Get());
  EXPECT_TRUE(aec_dump);
  apm_->AttachAecDump(std::move(aec_dump));
  EXPECT_EQ(
      AudioProcessing::kNoError,
      apm_->ProcessReverseStream(
          revframe_.data.data(),
          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
          StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
          revframe_.data.data()));
  EXPECT_EQ(AudioProcessing::kNoError,
            apm_->ProcessStream(
                frame_.data.data(),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                frame_.data.data()));
  apm_->DetachAecDump();

  // Verify the file has been written.
  FILE* fid = fopen(filename.c_str(), "r");
  ASSERT_TRUE(fid != nullptr);

  // Clean it up.
  ASSERT_EQ(0, fclose(fid));
  ASSERT_EQ(0, remove(filename.c_str()));
#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
}

// TODO(andrew): Add a test to process a few frames with different combinations
// of enabled components.

TEST_F(ApmTest, Process) {
  audioproc::OutputData ref_data;

  if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
    OpenFileAndReadMessage(ref_filename_, &ref_data);
  } else {
    const int kChannels[] = {1, 2};
    // Write the desired tests to the protobuf reference file.
    for (int num_reverse_channels : kChannels) {
      for (int num_channels : kChannels) {
        for (int sample_rate_hz : AudioProcessing::kNativeSampleRatesHz) {
          audioproc::Test* test = ref_data.add_test();
          test->set_num_reverse_channels(num_reverse_channels);
          test->set_num_input_channels(num_channels);
          test->set_num_output_channels(num_channels);
          test->set_sample_rate(sample_rate_hz);
          test->set_use_aec_extended_filter(false);
        }
      }
    }
    // To test the extended filter mode.
    audioproc::Test* test = ref_data.add_test();
    test->set_num_reverse_channels(2);
    test->set_num_input_channels(2);
    test->set_num_output_channels(2);
    test->set_sample_rate(AudioProcessing::kSampleRate32kHz);
    test->set_use_aec_extended_filter(true);
  }

  for (int i = 0; i < ref_data.test_size(); i++) {
    printf("Running test %d of %d...\n", i + 1, ref_data.test_size());

    audioproc::Test* test = ref_data.mutable_test(i);
    // TODO(ajm): We no longer allow different input and output channels. Skip
    // these tests for now, but they should be removed from the set.
    if (test->num_input_channels() != test->num_output_channels())
      continue;

    apm_ = BuiltinAudioProcessingBuilder()
               .SetEchoDetector(CreateEchoDetector())
               .Build(CreateEnvironment());
    AudioProcessing::Config apm_config = apm_->GetConfig();
    apm_config.gain_controller1.analog_gain_controller.enabled = false;
    apm_->ApplyConfig(apm_config);

    EnableAllComponents();

    Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
         static_cast<size_t>(test->num_input_channels()),
         static_cast<size_t>(test->num_output_channels()),
         static_cast<size_t>(test->num_reverse_channels()), true);

    int frame_count = 0;
    int analog_level = 127;
    int analog_level_average = 0;
    int max_output_average = 0;
    int stats_index = 0;

    while (ReadFrame(far_file_, &revframe_) && ReadFrame(near_file_, &frame_)) {
      EXPECT_EQ(
          AudioProcessing::kNoError,
          apm_->ProcessReverseStream(
              revframe_.data.data(),
              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
              StreamConfig(revframe_.sample_rate_hz, revframe_.num_channels()),
              revframe_.data.data()));

      EXPECT_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(0));
      apm_->set_stream_analog_level(analog_level);

      EXPECT_EQ(AudioProcessing::kNoError,
                apm_->ProcessStream(
                    frame_.data.data(),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    StreamConfig(frame_.sample_rate_hz, frame_.num_channels()),
                    frame_.data.data()));

      // Ensure the frame was downmixed properly.
      EXPECT_EQ(static_cast<size_t>(test->num_output_channels()),
                frame_.num_channels());

      max_output_average += MaxAudioFrame(frame_);

      analog_level = apm_->recommended_stream_analog_level();
      analog_level_average += analog_level;
      AudioProcessingStats stats = apm_->GetStatistics();

      size_t write_count =
          fwrite(frame_.data.data(), sizeof(int16_t), frame_.size(), out_file_);
      ASSERT_EQ(frame_.size(), write_count);

      // Reset in case of downmixing.
      frame_.set_num_channels(static_cast<size_t>(test->num_input_channels()));
      frame_count++;

      const int kStatsAggregationFrameNum = 100;  // 1 second.
      if (frame_count % kStatsAggregationFrameNum == 0) {
        // Get echo and delay metrics.
        AudioProcessingStats stats2 = apm_->GetStatistics();

        // Echo metrics.
        const float echo_return_loss = stats2.echo_return_loss.value_or(-1.0f);
        const float echo_return_loss_enhancement =
            stats2.echo_return_loss_enhancement.value_or(-1.0f);
        const float residual_echo_likelihood =
            stats2.residual_echo_likelihood.value_or(-1.0f);
        const float residual_echo_likelihood_recent_max =
            stats2.residual_echo_likelihood_recent_max.value_or(-1.0f);

        if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
          const audioproc::Test::EchoMetrics& reference =
              test->echo_metrics(stats_index);
          constexpr float kEpsilon = 0.01;
          EXPECT_NEAR(echo_return_loss, reference.echo_return_loss(), kEpsilon);
          EXPECT_NEAR(echo_return_loss_enhancement,
                      reference.echo_return_loss_enhancement(), kEpsilon);
          EXPECT_NEAR(residual_echo_likelihood,
                      reference.residual_echo_likelihood(), kEpsilon);
          EXPECT_NEAR(residual_echo_likelihood_recent_max,
                      reference.residual_echo_likelihood_recent_max(),
                      kEpsilon);
          ++stats_index;
        } else {
          audioproc::Test::EchoMetrics* message_echo = test->add_echo_metrics();
          message_echo->set_echo_return_loss(echo_return_loss);
          message_echo->set_echo_return_loss_enhancement(
              echo_return_loss_enhancement);
          message_echo->set_residual_echo_likelihood(residual_echo_likelihood);
          message_echo->set_residual_echo_likelihood_recent_max(
              residual_echo_likelihood_recent_max);
        }
      }
    }
    max_output_average /= frame_count;
    analog_level_average /= frame_count;

    if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
      const int kIntNear = 1;
      // All numbers being consistently higher on N7 compare to the reference
      // data.
      // TODO(bjornv): If we start getting more of these offsets on Android we
      // should consider a different approach. Either using one slack for all,
      // or generate a separate android reference.
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
      const int kMaxOutputAverageOffset = 9;
      const int kMaxOutputAverageNear = 26;
#else
      const int kMaxOutputAverageOffset = 0;
      const int kMaxOutputAverageNear = 7;
#endif
      EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
      EXPECT_NEAR(test->max_output_average(),
                  max_output_average - kMaxOutputAverageOffset,
                  kMaxOutputAverageNear);
    } else {
      test->set_analog_level_average(analog_level_average);
      test->set_max_output_average(max_output_average);
    }

    rewind(far_file_);
    rewind(near_file_);
  }

  if (absl::GetFlag(FLAGS_write_apm_ref_data)) {
    OpenFileAndWriteMessage(ref_filename_, ref_data);
  }
}

// Used to test a multitude of sample rate and channel combinations.
typedef std::tuple<int, int, int, int> AudioProcessingTestData;
class AudioProcessingTest
    : public ::testing::TestWithParam<AudioProcessingTestData> {
 public:
  AudioProcessingTest()
      : input_rate_(std::get<0>(GetParam())),
        output_rate_(std::get<1>(GetParam())),
        reverse_input_rate_(std::get<2>(GetParam())),
        reverse_output_rate_(std::get<3>(GetParam())) {}

  ~AudioProcessingTest() override {}

  // Runs a process pass on files with the given parameters.
  static void ProcessFormat(int input_rate,
                            int output_rate,
                            int reverse_input_rate,
                            int reverse_output_rate,
                            size_t num_input_channels,
                            size_t num_output_channels,
                            size_t num_reverse_input_channels,
                            size_t num_reverse_output_channels) {
    AudioProcessing::Config apm_config;
    apm_config.gain_controller1.analog_gain_controller.enabled = false;
    scoped_refptr<AudioProcessing> ap = BuiltinAudioProcessingBuilder()
                                            .SetConfig(apm_config)
                                            .Build(CreateEnvironment());

    EnableAllAPComponents(ap.get());

    ProcessingConfig processing_config = {
        {{input_rate, num_input_channels},
         {output_rate, num_output_channels},
         {reverse_input_rate, num_reverse_input_channels},
         {reverse_output_rate, num_reverse_output_channels}}};
    ap->Initialize(processing_config);

    FILE* far_file =
        fopen(ResourceFilePath("far", reverse_input_rate).c_str(), "rb");
    FILE* near_file = fopen(ResourceFilePath("near", input_rate).c_str(), "rb");
    ASSERT_TRUE(far_file != nullptr);
    ASSERT_TRUE(near_file != nullptr);

    ChannelBuffer<float> fwd_cb(AudioProcessing::GetFrameSize(input_rate),
                                num_input_channels);
    ChannelBuffer<float> rev_cb(
        AudioProcessing::GetFrameSize(reverse_input_rate),
        num_reverse_input_channels);
    ChannelBuffer<float> out_cb(AudioProcessing::GetFrameSize(output_rate),
                                num_output_channels);
    ChannelBuffer<float> rev_out_cb(
        AudioProcessing::GetFrameSize(reverse_output_rate),
        num_reverse_output_channels);

    // Temporary buffers.
    const int max_length =
        2 * std::max(std::max(out_cb.num_frames(), rev_out_cb.num_frames()),
                     std::max(fwd_cb.num_frames(), rev_cb.num_frames()));
    std::unique_ptr<float[]> float_data(new float[max_length]);
    std::unique_ptr<int16_t[]> int_data(new int16_t[max_length]);

    int analog_level = 127;
    while (ReadChunk(far_file, int_data.get(), float_data.get(), &rev_cb) &&
           ReadChunk(near_file, int_data.get(), float_data.get(), &fwd_cb)) {
      EXPECT_NOERR(ap->ProcessReverseStream(
          rev_cb.channels(), processing_config.reverse_input_stream(),
          processing_config.reverse_output_stream(), rev_out_cb.channels()));

      EXPECT_NOERR(ap->set_stream_delay_ms(0));
      ap->set_stream_analog_level(analog_level);

      EXPECT_NOERR(ap->ProcessStream(
          fwd_cb.channels(), StreamConfig(input_rate, num_input_channels),
          StreamConfig(output_rate, num_output_channels), out_cb.channels()));
    }
    fclose(far_file);
    fclose(near_file);
  }

 protected:
  int input_rate_;
  int output_rate_;
  int reverse_input_rate_;
  int reverse_output_rate_;
};

TEST_P(AudioProcessingTest, Formats) {
  struct ChannelFormat {
    int num_input;
    int num_output;
    int num_reverse_input;
    int num_reverse_output;
  };
  ChannelFormat cf[] = {
      {.num_input = 1,
       .num_output = 1,
       .num_reverse_input = 1,
       .num_reverse_output = 1},
      {.num_input = 1,
       .num_output = 1,
       .num_reverse_input = 2,
       .num_reverse_output = 1},
      {.num_input = 2,
       .num_output = 1,
       .num_reverse_input = 1,
       .num_reverse_output = 1},
      {.num_input = 2,
       .num_output = 1,
       .num_reverse_input = 2,
       .num_reverse_output = 1},
      {.num_input = 2,
       .num_output = 2,
       .num_reverse_input = 1,
       .num_reverse_output = 1},
      {.num_input = 2,
       .num_output = 2,
       .num_reverse_input = 2,
       .num_reverse_output = 2},
  };

  for (auto [num_input, num_output, num_reverse_input, num_reverse_output] :
       cf) {
    ProcessFormat(input_rate_, output_rate_, reverse_input_rate_,
                  reverse_output_rate_, num_input, num_output,
                  num_reverse_input, num_reverse_output);
  }
}

INSTANTIATE_TEST_SUITE_P(
    CommonFormats,
    AudioProcessingTest,
    // Internal processing rates and the particularly common sample rate 44100
    // Hz are tested in a grid of combinations (capture in, render in, out).
    ::testing::Values(std::make_tuple(48000, 48000, 48000, 48000),
                      std::make_tuple(48000, 48000, 32000, 48000),
                      std::make_tuple(48000, 48000, 16000, 48000),
                      std::make_tuple(48000, 44100, 48000, 44100),
                      std::make_tuple(48000, 44100, 32000, 44100),
                      std::make_tuple(48000, 44100, 16000, 44100),
                      std::make_tuple(48000, 32000, 48000, 32000),
                      std::make_tuple(48000, 32000, 32000, 32000),
                      std::make_tuple(48000, 32000, 16000, 32000),
                      std::make_tuple(48000, 16000, 48000, 16000),
                      std::make_tuple(48000, 16000, 32000, 16000),
                      std::make_tuple(48000, 16000, 16000, 16000),

                      std::make_tuple(44100, 48000, 48000, 48000),
                      std::make_tuple(44100, 48000, 32000, 48000),
                      std::make_tuple(44100, 48000, 16000, 48000),
                      std::make_tuple(44100, 44100, 48000, 44100),
                      std::make_tuple(44100, 44100, 32000, 44100),
                      std::make_tuple(44100, 44100, 16000, 44100),
                      std::make_tuple(44100, 32000, 48000, 32000),
                      std::make_tuple(44100, 32000, 32000, 32000),
                      std::make_tuple(44100, 32000, 16000, 32000),
                      std::make_tuple(44100, 16000, 48000, 16000),
                      std::make_tuple(44100, 16000, 32000, 16000),
                      std::make_tuple(44100, 16000, 16000, 16000),

                      std::make_tuple(32000, 48000, 48000, 48000),
                      std::make_tuple(32000, 48000, 32000, 48000),
                      std::make_tuple(32000, 48000, 16000, 48000),
                      std::make_tuple(32000, 44100, 48000, 44100),
                      std::make_tuple(32000, 44100, 32000, 44100),
                      std::make_tuple(32000, 44100, 16000, 44100),
                      std::make_tuple(32000, 32000, 48000, 32000),
                      std::make_tuple(32000, 32000, 32000, 32000),
                      std::make_tuple(32000, 32000, 16000, 32000),
                      std::make_tuple(32000, 16000, 48000, 16000),
                      std::make_tuple(32000, 16000, 32000, 16000),
                      std::make_tuple(32000, 16000, 16000, 16000),

                      std::make_tuple(16000, 48000, 48000, 48000),
                      std::make_tuple(16000, 48000, 32000, 48000),
                      std::make_tuple(16000, 48000, 16000, 48000),
                      std::make_tuple(16000, 44100, 48000, 44100),
                      std::make_tuple(16000, 44100, 32000, 44100),
                      std::make_tuple(16000, 44100, 16000, 44100),
                      std::make_tuple(16000, 32000, 48000, 32000),
                      std::make_tuple(16000, 32000, 32000, 32000),
                      std::make_tuple(16000, 32000, 16000, 32000),
                      std::make_tuple(16000, 16000, 48000, 16000),
                      std::make_tuple(16000, 16000, 32000, 16000),
                      std::make_tuple(16000, 16000, 16000, 16000),

                      // Other sample rates are not tested exhaustively, to keep
                      // the test runtime manageable.
                      //
                      // Testing most other sample rates logged by Chrome UMA:
                      //  - WebRTC.AudioInputSampleRate
                      //  - WebRTC.AudioOutputSampleRate
                      // ApmConfiguration.HandlingOfRateCombinations covers
                      // remaining sample rates.
                      std::make_tuple(192000, 192000, 48000, 192000),
                      std::make_tuple(176400, 176400, 48000, 176400),
                      std::make_tuple(96000, 96000, 48000, 96000),
                      std::make_tuple(88200, 88200, 48000, 88200),
                      std::make_tuple(44100, 44100, 48000, 44100)));

// Produces a scoped trace debug output.
std::string ProduceDebugText(int render_input_sample_rate_hz,
                             int render_output_sample_rate_hz,
                             int capture_input_sample_rate_hz,
                             int capture_output_sample_rate_hz,
                             size_t render_input_num_channels,
                             size_t render_output_num_channels,
                             size_t capture_input_num_channels,
                             size_t capture_output_num_channels) {
  StringBuilder ss;
  ss << "Sample rates:"
        "\n Render input: "
     << render_input_sample_rate_hz
     << " Hz"
        "\n Render output: "
     << render_output_sample_rate_hz
     << " Hz"
        "\n Capture input: "
     << capture_input_sample_rate_hz
     << " Hz"
        "\n Capture output: "
     << capture_output_sample_rate_hz
     << " Hz"
        "\nNumber of channels:"
        "\n Render input: "
     << render_input_num_channels
     << "\n Render output: " << render_output_num_channels
     << "\n Capture input: " << capture_input_num_channels
     << "\n Capture output: " << capture_output_num_channels;
  return ss.Release();
}

// Validates that running the audio processing module using various combinations
// of sample rates and number of channels works as intended.
void RunApmRateAndChannelTest(ArrayView<const int> sample_rates_hz,
                              ArrayView<const int> render_channel_counts,
                              ArrayView<const int> capture_channel_counts,
                              ArrayView<const bool> mono_capture_output) {
  AudioProcessing::Config apm_config;
  apm_config.pipeline.multi_channel_render = true;
  apm_config.pipeline.multi_channel_capture = true;
  apm_config.echo_canceller.enabled = true;
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder(apm_config).Build(CreateEnvironment());

  StreamConfig render_input_stream_config;
  StreamConfig render_output_stream_config;
  StreamConfig capture_input_stream_config;
  StreamConfig capture_output_stream_config;

  std::vector<float> render_input_frame_channels;
  std::vector<float*> render_input_frame;
  std::vector<float> render_output_frame_channels;
  std::vector<float*> render_output_frame;
  std::vector<float> capture_input_frame_channels;
  std::vector<float*> capture_input_frame;
  std::vector<float> capture_output_frame_channels;
  std::vector<float*> capture_output_frame;

  for (auto render_input_sample_rate_hz : sample_rates_hz) {
    for (auto render_output_sample_rate_hz : sample_rates_hz) {
      for (auto capture_input_sample_rate_hz : sample_rates_hz) {
        for (auto capture_output_sample_rate_hz : sample_rates_hz) {
          for (size_t render_input_num_channels : render_channel_counts) {
            for (size_t capture_input_num_channels : capture_channel_counts) {
              for (bool use_mono_capture_output : mono_capture_output) {
                size_t render_output_num_channels = render_input_num_channels;
                size_t capture_output_num_channels =
                    use_mono_capture_output ? 1 : capture_input_num_channels;
                auto populate_audio_frame =
                    [](int sample_rate_hz, size_t num_channels,
                       StreamConfig* cfg, std::vector<float>* channels_data,
                       std::vector<float*>* frame_data) {
                      cfg->set_sample_rate_hz(sample_rate_hz);
                      cfg->set_num_channels(num_channels);

                      size_t max_frame_size =
                          AudioProcessing::GetFrameSize(sample_rate_hz);
                      channels_data->resize(num_channels * max_frame_size);
                      std::fill(channels_data->begin(), channels_data->end(),
                                0.5f);
                      frame_data->resize(num_channels);
                      for (size_t channel = 0; channel < num_channels;
                           ++channel) {
                        (*frame_data)[channel] =
                            &(*channels_data)[channel * max_frame_size];
                      }
                    };

                populate_audio_frame(
                    render_input_sample_rate_hz, render_input_num_channels,
                    &render_input_stream_config, &render_input_frame_channels,
                    &render_input_frame);
                populate_audio_frame(
                    render_output_sample_rate_hz, render_output_num_channels,
                    &render_output_stream_config, &render_output_frame_channels,
                    &render_output_frame);
                populate_audio_frame(
                    capture_input_sample_rate_hz, capture_input_num_channels,
                    &capture_input_stream_config, &capture_input_frame_channels,
                    &capture_input_frame);
                populate_audio_frame(
                    capture_output_sample_rate_hz, capture_output_num_channels,
                    &capture_output_stream_config,
                    &capture_output_frame_channels, &capture_output_frame);

                for (size_t frame = 0; frame < 2; ++frame) {
                  SCOPED_TRACE(ProduceDebugText(
                      render_input_sample_rate_hz, render_output_sample_rate_hz,
                      capture_input_sample_rate_hz,
                      capture_output_sample_rate_hz, render_input_num_channels,
                      render_output_num_channels, render_input_num_channels,
                      capture_output_num_channels));

                  int result = apm->ProcessReverseStream(
                      &render_input_frame[0], render_input_stream_config,
                      render_output_stream_config, &render_output_frame[0]);
                  EXPECT_EQ(result, AudioProcessing::kNoError);
                  result = apm->ProcessStream(
                      &capture_input_frame[0], capture_input_stream_config,
                      capture_output_stream_config, &capture_output_frame[0]);
                  EXPECT_EQ(result, AudioProcessing::kNoError);
                }
              }
            }
          }
        }
      }
    }
  }
}

constexpr void Toggle(bool& b) {
  b ^= true;
}

TEST(RuntimeSettingTest, TestDefaultCtor) {
  auto s = AudioProcessing::RuntimeSetting();
  EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kNotSpecified, s.type());
}

TEST(RuntimeSettingTest, TestUsageWithSwapQueue) {
  SwapQueue<AudioProcessing::RuntimeSetting> q(1);
  auto s = AudioProcessing::RuntimeSetting();
  ASSERT_TRUE(q.Insert(&s));
  ASSERT_TRUE(q.Remove(&s));
  EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kNotSpecified, s.type());
}

TEST(ApmConfiguration, EnablePostProcessing) {
  // Verify that apm uses a capture post processing module if one is provided.
  auto mock_post_processor_ptr =
      new ::testing::NiceMock<test::MockCustomProcessing>();
  auto mock_post_processor =
      std::unique_ptr<CustomProcessing>(mock_post_processor_ptr);
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetCapturePostProcessing(std::move(mock_post_processor))
          .Build(CreateEnvironment());

  Int16FrameData audio;
  audio.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);

  EXPECT_CALL(*mock_post_processor_ptr, Process(::testing::_)).Times(1);
  apm->ProcessStream(audio.data.data(),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     audio.data.data());
}

TEST(ApmConfiguration, EnablePreProcessing) {
  // Verify that apm uses a capture post processing module if one is provided.
  auto mock_pre_processor_ptr =
      new ::testing::NiceMock<test::MockCustomProcessing>();
  auto mock_pre_processor =
      std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetRenderPreProcessing(std::move(mock_pre_processor))
          .Build(CreateEnvironment());

  Int16FrameData audio;
  audio.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);

  EXPECT_CALL(*mock_pre_processor_ptr, Process(::testing::_)).Times(1);
  apm->ProcessReverseStream(
      audio.data.data(),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      audio.data.data());
}

TEST(ApmConfiguration, EnableCaptureAnalyzer) {
  // Verify that apm uses a capture analyzer if one is provided.
  auto mock_capture_analyzer_ptr =
      new ::testing::NiceMock<test::MockCustomAudioAnalyzer>();
  auto mock_capture_analyzer =
      std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetCaptureAnalyzer(std::move(mock_capture_analyzer))
          .Build(CreateEnvironment());

  Int16FrameData audio;
  audio.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);

  EXPECT_CALL(*mock_capture_analyzer_ptr, Analyze(::testing::_)).Times(1);
  apm->ProcessStream(audio.data.data(),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     audio.data.data());
}

TEST(ApmConfiguration, PreProcessingReceivesRuntimeSettings) {
  auto mock_pre_processor_ptr =
      new ::testing::NiceMock<test::MockCustomProcessing>();
  auto mock_pre_processor =
      std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetRenderPreProcessing(std::move(mock_pre_processor))
          .Build(CreateEnvironment());
  apm->SetRuntimeSetting(
      AudioProcessing::RuntimeSetting::CreateCustomRenderSetting(0));

  // RuntimeSettings forwarded during 'Process*Stream' calls.
  // Therefore we have to make one such call.
  Int16FrameData audio;
  audio.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);

  EXPECT_CALL(*mock_pre_processor_ptr, SetRuntimeSetting(::testing::_))
      .Times(1);
  apm->ProcessReverseStream(
      audio.data.data(),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      audio.data.data());
}

class MockEchoControlFactory : public EchoControlFactory {
 public:
  MOCK_METHOD(std::unique_ptr<EchoControl>,
              Create,
              (const Environment&, int, int, int),
              (override));
  MOCK_METHOD(std::unique_ptr<EchoControl>,
              Create,
              (const Environment&, int, int, int, NeuralResidualEchoEstimator*),
              (override));
};

TEST(ApmConfiguration, EchoControlInjection) {
  // Verify that apm uses an injected echo controller if one is provided.
  auto echo_control_factory = std::make_unique<MockEchoControlFactory>();
  EXPECT_CALL(*echo_control_factory, Create(_, _, _, _, _))
      .WillOnce(WithoutArgs([] {
        auto ec = std::make_unique<test::MockEchoControl>();
        EXPECT_CALL(*ec, AnalyzeRender).Times(1);
        EXPECT_CALL(*ec, AnalyzeCapture).Times(2);
        EXPECT_CALL(*ec, ProcessCapture(_, _, _)).Times(2);
        return ec;
      }));

  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetEchoControlFactory(std::move(echo_control_factory))
          .Build(CreateEnvironment());

  Int16FrameData audio;
  audio.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);
  apm->ProcessStream(audio.data.data(),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     audio.data.data());
  apm->ProcessReverseStream(
      audio.data.data(),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      StreamConfig(audio.sample_rate_hz, audio.num_channels()),
      audio.data.data());
  apm->ProcessStream(audio.data.data(),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     StreamConfig(audio.sample_rate_hz, audio.num_channels()),
                     audio.data.data());
}

TEST(ApmConfiguration, EchoDetectorInjection) {
  using ::testing::_;
  scoped_refptr<test::MockEchoDetector> mock_echo_detector =
      make_ref_counted<::testing::StrictMock<test::MockEchoDetector>>();
  EXPECT_CALL(*mock_echo_detector,
              Initialize(/*capture_sample_rate_hz=*/16000, _,
                         /*render_sample_rate_hz=*/16000, _))
      .Times(1);
  scoped_refptr<AudioProcessing> apm = BuiltinAudioProcessingBuilder()
                                           .SetEchoDetector(mock_echo_detector)
                                           .Build(CreateEnvironment());

  // The echo detector is included in processing when enabled.
  EXPECT_CALL(*mock_echo_detector, AnalyzeRenderAudio(_))
      .WillOnce([](ArrayView<const float> render_audio) {
        EXPECT_EQ(render_audio.size(), 160u);
      });
  EXPECT_CALL(*mock_echo_detector, AnalyzeCaptureAudio(_))
      .WillOnce([](ArrayView<const float> capture_audio) {
        EXPECT_EQ(capture_audio.size(), 160u);
      });
  EXPECT_CALL(*mock_echo_detector, GetMetrics()).Times(1);

  Int16FrameData frame;
  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate16kHz),
                      /* num_channels=*/1);

  apm->ProcessReverseStream(frame.data.data(), StreamConfig(16000, 1),
                            StreamConfig(16000, 1), frame.data.data());
  apm->ProcessStream(frame.data.data(), StreamConfig(16000, 1),
                     StreamConfig(16000, 1), frame.data.data());

  // When processing rates change, the echo detector is also reinitialized to
  // match those.
  EXPECT_CALL(*mock_echo_detector,
              Initialize(/*capture_sample_rate_hz=*/48000, _,
                         /*render_sample_rate_hz=*/16000, _))
      .Times(1);
  EXPECT_CALL(*mock_echo_detector,
              Initialize(/*capture_sample_rate_hz=*/48000, _,
                         /*render_sample_rate_hz=*/48000, _))
      .Times(1);
  EXPECT_CALL(*mock_echo_detector, AnalyzeRenderAudio(_))
      .WillOnce([](ArrayView<const float> render_audio) {
        EXPECT_EQ(render_audio.size(), 480u);
      });
  EXPECT_CALL(*mock_echo_detector, AnalyzeCaptureAudio(_))
      .Times(2)
      .WillRepeatedly([](ArrayView<const float> capture_audio) {
        EXPECT_EQ(capture_audio.size(), 480u);
      });
  EXPECT_CALL(*mock_echo_detector, GetMetrics()).Times(2);

  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate48kHz),
                      frame.num_channels());
  apm->ProcessStream(frame.data.data(), StreamConfig(48000, 1),
                     StreamConfig(48000, 1), frame.data.data());
  apm->ProcessReverseStream(frame.data.data(), StreamConfig(48000, 1),
                            StreamConfig(48000, 1), frame.data.data());
  apm->ProcessStream(frame.data.data(), StreamConfig(48000, 1),
                     StreamConfig(48000, 1), frame.data.data());
}

scoped_refptr<AudioProcessing> CreateApm() {
  // Enable residual echo detection, for stats.
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetEchoDetector(CreateEchoDetector())
          .Build(CreateEnvironment());
  if (!apm) {
    return apm;
  }

  ProcessingConfig processing_config = {
      {{32000, 1}, {32000, 1}, {32000, 1}, {32000, 1}}};

  if (apm->Initialize(processing_config) != 0) {
    return nullptr;
  }

  // Disable all components except for an AEC.
  AudioProcessing::Config apm_config;
  apm_config.high_pass_filter.enabled = false;
  apm_config.gain_controller1.enabled = false;
  apm_config.gain_controller2.enabled = false;
  apm_config.echo_canceller.enabled = true;
  apm_config.noise_suppression.enabled = false;
  apm->ApplyConfig(apm_config);
  return apm;
}

#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_MAC)
#define MAYBE_ApmStatistics DISABLED_ApmStatistics
#else
#define MAYBE_ApmStatistics ApmStatistics
#endif

TEST(MAYBE_ApmStatistics, AECEnabledTest) {
  // Set up APM with AEC3 and process some audio.
  scoped_refptr<AudioProcessing> apm = CreateApm();
  ASSERT_TRUE(apm);
  AudioProcessing::Config apm_config;
  apm_config.echo_canceller.enabled = true;
  apm->ApplyConfig(apm_config);

  // Set up an audioframe.
  Int16FrameData frame;
  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate32kHz),
                      /* num_channels=*/1);

  // Fill the audio frame with a sawtooth pattern.
  int16_t* ptr = frame.data.data();
  for (size_t i = 0; i < Int16FrameData::kMaxDataSizeSamples; i++) {
    ptr[i] = 10000 * ((i % 3) - 1);
  }

  // Do some processing.
  for (int i = 0; i < 200; i++) {
    EXPECT_EQ(apm->ProcessReverseStream(
                  frame.data.data(),
                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                  frame.data.data()),
              0);
    EXPECT_EQ(apm->set_stream_delay_ms(0), 0);
    EXPECT_EQ(apm->ProcessStream(
                  frame.data.data(),
                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                  StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                  frame.data.data()),
              0);
  }

  // Test statistics interface.
  AudioProcessingStats stats = apm->GetStatistics();
  // We expect all statistics to be set and have a sensible value.
  ASSERT_TRUE(stats.residual_echo_likelihood.has_value());
  EXPECT_GE(*stats.residual_echo_likelihood, 0.0);
  EXPECT_LE(*stats.residual_echo_likelihood, 1.0);
  ASSERT_TRUE(stats.residual_echo_likelihood_recent_max.has_value());
  EXPECT_GE(*stats.residual_echo_likelihood_recent_max, 0.0);
  EXPECT_LE(*stats.residual_echo_likelihood_recent_max, 1.0);
  ASSERT_TRUE(stats.echo_return_loss.has_value());
  EXPECT_NE(*stats.echo_return_loss, -100.0);
  ASSERT_TRUE(stats.echo_return_loss_enhancement.has_value());
  EXPECT_NE(*stats.echo_return_loss_enhancement, -100.0);
}

TEST(ApmStatistics, DoNotReportVoiceDetectedStat) {
  ProcessingConfig processing_config = {
      {{32000, 1}, {32000, 1}, {32000, 1}, {32000, 1}}};

  // Set up an audioframe.
  Int16FrameData frame;
  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate32kHz),
                      /* num_channels=*/1);

  // Fill the audio frame with a sawtooth pattern.
  int16_t* ptr = frame.data.data();
  for (size_t i = 0; i < Int16FrameData::kMaxDataSizeSamples; i++) {
    ptr[i] = 10000 * ((i % 3) - 1);
  }

  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  apm->Initialize(processing_config);

  // No metric should be reported.
  EXPECT_EQ(apm->ProcessStream(
                frame.data.data(),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                frame.data.data()),
            0);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  EXPECT_FALSE(apm->GetStatistics().voice_detected.has_value());
#pragma clang diagnostic pop
}

TEST(ApmStatistics, GetStatisticsReportsNoEchoDetectorStatsWhenDisabled) {
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  Int16FrameData frame;
  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate32kHz),
                      /* num_channels=*/1);
  ASSERT_EQ(apm->ProcessStream(
                frame.data.data(),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                frame.data.data()),
            0);
  // Echo detector is disabled by default, no stats reported.
  AudioProcessingStats stats = apm->GetStatistics();
  EXPECT_FALSE(stats.residual_echo_likelihood.has_value());
  EXPECT_FALSE(stats.residual_echo_likelihood_recent_max.has_value());
}

TEST(ApmStatistics, GetStatisticsReportsEchoDetectorStatsWhenEnabled) {
  // Create APM with an echo detector injected.
  scoped_refptr<AudioProcessing> apm =
      BuiltinAudioProcessingBuilder()
          .SetEchoDetector(CreateEchoDetector())
          .Build(CreateEnvironment());
  Int16FrameData frame;
  frame.SetProperties(AudioProcessing::GetFrameSize(
                          AudioProcessing::NativeRate::kSampleRate32kHz),
                      /* num_channels=*/1);
  // Echo detector enabled: Report stats.
  ASSERT_EQ(apm->ProcessStream(
                frame.data.data(),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                StreamConfig(frame.sample_rate_hz, frame.num_channels()),
                frame.data.data()),
            0);
  AudioProcessingStats stats = apm->GetStatistics();
  EXPECT_TRUE(stats.residual_echo_likelihood.has_value());
  EXPECT_TRUE(stats.residual_echo_likelihood_recent_max.has_value());
}

TEST(ApmConfiguration, HandlingOfRateAndChannelCombinations) {
  std::array<int, 3> sample_rates_hz = {16000, 32000, 48000};
  std::array<int, 2> render_channel_counts = {1, 7};
  std::array<int, 2> capture_channel_counts = {1, 7};
  std::array<bool, 2> mono_capture_output = {true, false};
  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
                           capture_channel_counts, mono_capture_output);
}

TEST(ApmConfiguration, HandlingOfChannelCombinations) {
  std::array<int, 1> sample_rates_hz = {48000};
  std::array<int, 8> render_channel_counts = {1, 2, 3, 4, 5, 6, 7, 8};
  std::array<int, 8> capture_channel_counts = {1, 2, 3, 4, 5, 6, 7, 8};
  std::array<bool, 2> mono_capture_output = {true, false};
  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
                           capture_channel_counts, mono_capture_output);
}

TEST(ApmConfiguration, HandlingOfRateCombinations) {
  // Test rates <= 96000 logged by Chrome UMA:
  //  - WebRTC.AudioInputSampleRate
  //  - WebRTC.AudioOutputSampleRate
  // Higher rates are tested in AudioProcessingTest.Format, to keep the number
  // of combinations in this test manageable.
  std::array<int, 9> sample_rates_hz = {8000,  11025, 16000, 22050, 32000,
                                        44100, 48000, 88200, 96000};
  std::array<int, 1> render_channel_counts = {2};
  std::array<int, 1> capture_channel_counts = {2};
  std::array<bool, 2> mono_capture_output = {true, false};
  RunApmRateAndChannelTest(sample_rates_hz, render_channel_counts,
                           capture_channel_counts, mono_capture_output);
}

TEST(ApmConfiguration, SelfAssignment) {
  // At some point memory sanitizer was complaining about self-assigment.
  // Make sure we don't regress.
  AudioProcessing::Config config;
  AudioProcessing::Config* config2 = &config;
  *config2 = *config2;  // Workaround -Wself-assign-overloaded
  SUCCEED();  // Real success is absence of defects from asan/msan/ubsan.
}

TEST(AudioProcessing, GainController1ConfigEqual) {
  AudioProcessing::Config::GainController1 a;
  AudioProcessing::Config::GainController1 b;
  EXPECT_EQ(a, b);

  Toggle(a.enabled);
  b.enabled = a.enabled;
  EXPECT_EQ(a, b);

  a.mode = AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
  b.mode = a.mode;
  EXPECT_EQ(a, b);

  a.target_level_dbfs++;
  b.target_level_dbfs = a.target_level_dbfs;
  EXPECT_EQ(a, b);

  a.compression_gain_db++;
  b.compression_gain_db = a.compression_gain_db;
  EXPECT_EQ(a, b);

  Toggle(a.enable_limiter);
  b.enable_limiter = a.enable_limiter;
  EXPECT_EQ(a, b);

  auto& a_analog = a.analog_gain_controller;
  auto& b_analog = b.analog_gain_controller;

  Toggle(a_analog.enabled);
  b_analog.enabled = a_analog.enabled;
  EXPECT_EQ(a, b);

  a_analog.startup_min_volume++;
  b_analog.startup_min_volume = a_analog.startup_min_volume;
  EXPECT_EQ(a, b);

  a_analog.clipped_level_min++;
  b_analog.clipped_level_min = a_analog.clipped_level_min;
  EXPECT_EQ(a, b);

  Toggle(a_analog.enable_digital_adaptive);
  b_analog.enable_digital_adaptive = a_analog.enable_digital_adaptive;
  EXPECT_EQ(a, b);
}

// Checks that one differing parameter is sufficient to make two configs
// different.
TEST(AudioProcessing, GainController1ConfigNotEqual) {
  AudioProcessing::Config::GainController1 a;
  const AudioProcessing::Config::GainController1 b;

  Toggle(a.enabled);
  EXPECT_NE(a, b);
  a = b;

  a.mode = AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
  EXPECT_NE(a, b);
  a = b;

  a.target_level_dbfs++;
  EXPECT_NE(a, b);
  a = b;

  a.compression_gain_db++;
  EXPECT_NE(a, b);
  a = b;

  Toggle(a.enable_limiter);
  EXPECT_NE(a, b);
  a = b;

  auto& a_analog = a.analog_gain_controller;
  const auto& b_analog = b.analog_gain_controller;

  Toggle(a_analog.enabled);
  EXPECT_NE(a, b);
  a_analog = b_analog;

  a_analog.startup_min_volume++;
  EXPECT_NE(a, b);
  a_analog = b_analog;

  a_analog.clipped_level_min++;
  EXPECT_NE(a, b);
  a_analog = b_analog;

  Toggle(a_analog.enable_digital_adaptive);
  EXPECT_NE(a, b);
  a_analog = b_analog;
}

TEST(AudioProcessing, GainController2ConfigEqual) {
  AudioProcessing::Config::GainController2 a;
  AudioProcessing::Config::GainController2 b;
  EXPECT_EQ(a, b);

  Toggle(a.enabled);
  b.enabled = a.enabled;
  EXPECT_EQ(a, b);

  a.fixed_digital.gain_db += 1.0f;
  b.fixed_digital.gain_db = a.fixed_digital.gain_db;
  EXPECT_EQ(a, b);

  auto& a_adaptive = a.adaptive_digital;
  auto& b_adaptive = b.adaptive_digital;

  Toggle(a_adaptive.enabled);
  b_adaptive.enabled = a_adaptive.enabled;
  EXPECT_EQ(a, b);

  a_adaptive.headroom_db += 1.0f;
  b_adaptive.headroom_db = a_adaptive.headroom_db;
  EXPECT_EQ(a, b);

  a_adaptive.max_gain_db += 1.0f;
  b_adaptive.max_gain_db = a_adaptive.max_gain_db;
  EXPECT_EQ(a, b);

  a_adaptive.initial_gain_db += 1.0f;
  b_adaptive.initial_gain_db = a_adaptive.initial_gain_db;
  EXPECT_EQ(a, b);

  a_adaptive.max_gain_change_db_per_second += 1.0f;
  b_adaptive.max_gain_change_db_per_second =
      a_adaptive.max_gain_change_db_per_second;
  EXPECT_EQ(a, b);

  a_adaptive.max_output_noise_level_dbfs += 1.0f;
  b_adaptive.max_output_noise_level_dbfs =
      a_adaptive.max_output_noise_level_dbfs;
  EXPECT_EQ(a, b);
}

// Checks that one differing parameter is sufficient to make two configs
// different.
TEST(AudioProcessing, GainController2ConfigNotEqual) {
  AudioProcessing::Config::GainController2 a;
  const AudioProcessing::Config::GainController2 b;

  Toggle(a.enabled);
  EXPECT_NE(a, b);
  a = b;

  a.fixed_digital.gain_db += 1.0f;
  EXPECT_NE(a, b);
  a.fixed_digital = b.fixed_digital;

  auto& a_adaptive = a.adaptive_digital;
  const auto& b_adaptive = b.adaptive_digital;

  Toggle(a_adaptive.enabled);
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;

  a_adaptive.headroom_db += 1.0f;
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;

  a_adaptive.max_gain_db += 1.0f;
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;

  a_adaptive.initial_gain_db += 1.0f;
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;

  a_adaptive.max_gain_change_db_per_second += 1.0f;
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;

  a_adaptive.max_output_noise_level_dbfs += 1.0f;
  EXPECT_NE(a, b);
  a_adaptive = b_adaptive;
}

struct ApmFormatHandlingTestParams {
  enum class ExpectedOutput {
    kErrorAndUnmodified,
    kErrorAndSilence,
    kErrorAndCopyOfFirstChannel,
    kErrorAndExactCopy,
    kNoError
  };

  StreamConfig input_config;
  StreamConfig output_config;
  ExpectedOutput expected_output;
};

class ApmFormatHandlingTest
    : public ::testing::TestWithParam<
          std::tuple<StreamDirection, ApmFormatHandlingTestParams>> {
 public:
  ApmFormatHandlingTest()
      : stream_direction_(std::get<0>(GetParam())),
        test_params_(std::get<1>(GetParam())) {}

 protected:
  ::testing::Message ProduceDebugMessage() {
    return ::testing::Message()
           << "input sample_rate_hz="
           << test_params_.input_config.sample_rate_hz()
           << " num_channels=" << test_params_.input_config.num_channels()
           << ", output sample_rate_hz="
           << test_params_.output_config.sample_rate_hz()
           << " num_channels=" << test_params_.output_config.num_channels()
           << ", stream_direction=" << stream_direction_ << ", expected_output="
           << static_cast<int>(test_params_.expected_output);
  }

  StreamDirection stream_direction_;
  ApmFormatHandlingTestParams test_params_;
};

INSTANTIATE_TEST_SUITE_P(
    FormatValidation,
    ApmFormatHandlingTest,
    testing::Combine(
        ::testing::Values(kForward, kReverse),
        ::testing::Values(
            // Test cases with values on the boundary of legal ranges.
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 1), StreamConfig(8000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
            ApmFormatHandlingTestParams{
                StreamConfig(8000, 1), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
            ApmFormatHandlingTestParams{
                StreamConfig(384000, 1), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 1), StreamConfig(384000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 2), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 3), StreamConfig(16000, 3),
                ApmFormatHandlingTestParams::ExpectedOutput::kNoError},

            // Supported but incompatible formats.
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 3), StreamConfig(16000, 2),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndCopyOfFirstChannel},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 3), StreamConfig(16000, 4),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndCopyOfFirstChannel},

            // Unsupported format and input / output mismatch.
            ApmFormatHandlingTestParams{
                StreamConfig(7900, 1), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 1), StreamConfig(7900, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
            ApmFormatHandlingTestParams{
                StreamConfig(390000, 1), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 1), StreamConfig(390000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},
            ApmFormatHandlingTestParams{
                StreamConfig(-16000, 1), StreamConfig(16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence},

            // Unsupported format but input / output formats match.
            ApmFormatHandlingTestParams{StreamConfig(7900, 1),
                                        StreamConfig(7900, 1),
                                        ApmFormatHandlingTestParams::
                                            ExpectedOutput::kErrorAndExactCopy},
            ApmFormatHandlingTestParams{StreamConfig(390000, 1),
                                        StreamConfig(390000, 1),
                                        ApmFormatHandlingTestParams::
                                            ExpectedOutput::kErrorAndExactCopy},

            // Unsupported but identical sample rate, channel mismatch.
            ApmFormatHandlingTestParams{
                StreamConfig(7900, 1), StreamConfig(7900, 2),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndCopyOfFirstChannel},
            ApmFormatHandlingTestParams{
                StreamConfig(7900, 2), StreamConfig(7900, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndCopyOfFirstChannel},

            // Test cases with meaningless output format.
            ApmFormatHandlingTestParams{
                StreamConfig(16000, 1), StreamConfig(-16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndUnmodified},
            ApmFormatHandlingTestParams{
                StreamConfig(-16000, 1), StreamConfig(-16000, 1),
                ApmFormatHandlingTestParams::ExpectedOutput::
                    kErrorAndUnmodified})));

TEST_P(ApmFormatHandlingTest, IntApi) {
  SCOPED_TRACE(ProduceDebugMessage());

  // Set up input and output data.
  const size_t num_input_samples =
      test_params_.input_config.num_channels() *
      std::abs(test_params_.input_config.sample_rate_hz() / 100);
  const size_t num_output_samples =
      test_params_.output_config.num_channels() *
      std::abs(test_params_.output_config.sample_rate_hz() / 100);
  std::vector<int16_t> input_block(num_input_samples);
  for (int i = 0; i < static_cast<int>(input_block.size()); ++i) {
    input_block[i] = i;
  }
  std::vector<int16_t> output_block(num_output_samples);
  constexpr int kUnlikelyOffset = 37;
  for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
    output_block[i] = i - kUnlikelyOffset;
  }

  // Call APM.
  scoped_refptr<AudioProcessing> ap =
      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  int error;
  if (stream_direction_ == kForward) {
    error = ap->ProcessStream(input_block.data(), test_params_.input_config,
                              test_params_.output_config, output_block.data());
  } else {
    error = ap->ProcessReverseStream(
        input_block.data(), test_params_.input_config,
        test_params_.output_config, output_block.data());
  }

  // Check output.
  switch (test_params_.expected_output) {
    case ApmFormatHandlingTestParams::ExpectedOutput::kNoError:
      EXPECT_EQ(error, AudioProcessing::kNoError);
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndUnmodified:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
        EXPECT_EQ(output_block[i], i - kUnlikelyOffset);
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
        EXPECT_EQ(output_block[i], 0);
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::
        kErrorAndCopyOfFirstChannel:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (size_t ch = 0; ch < test_params_.output_config.num_channels();
           ++ch) {
        for (size_t i = 0; i < test_params_.output_config.num_frames(); ++i) {
          EXPECT_EQ(
              output_block[ch + i * test_params_.output_config.num_channels()],
              static_cast<int16_t>(i *
                                   test_params_.input_config.num_channels()));
        }
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndExactCopy:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (int i = 0; i < static_cast<int>(output_block.size()); ++i) {
        EXPECT_EQ(output_block[i], i);
      }
      break;
  }
}

TEST_P(ApmFormatHandlingTest, FloatApi) {
  SCOPED_TRACE(ProduceDebugMessage());

  // Set up input and output data.
  const size_t input_samples_per_channel =
      std::abs(test_params_.input_config.sample_rate_hz()) / 100;
  const size_t output_samples_per_channel =
      std::abs(test_params_.output_config.sample_rate_hz()) / 100;
  const size_t input_num_channels = test_params_.input_config.num_channels();
  const size_t output_num_channels = test_params_.output_config.num_channels();
  ChannelBuffer<float> input_block(input_samples_per_channel,
                                   input_num_channels);
  ChannelBuffer<float> output_block(output_samples_per_channel,
                                    output_num_channels);
  for (size_t ch = 0; ch < input_num_channels; ++ch) {
    for (size_t i = 0; i < input_samples_per_channel; ++i) {
      input_block.channels()[ch][i] = ch + i * input_num_channels;
    }
  }
  constexpr int kUnlikelyOffset = 37;
  for (size_t ch = 0; ch < output_num_channels; ++ch) {
    for (size_t i = 0; i < output_samples_per_channel; ++i) {
      output_block.channels()[ch][i] =
          ch + i * output_num_channels - kUnlikelyOffset;
    }
  }

  // Call APM.
  scoped_refptr<AudioProcessing> ap =
      BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
  int error;
  if (stream_direction_ == kForward) {
    error =
        ap->ProcessStream(input_block.channels(), test_params_.input_config,
                          test_params_.output_config, output_block.channels());
  } else {
    error = ap->ProcessReverseStream(
        input_block.channels(), test_params_.input_config,
        test_params_.output_config, output_block.channels());
  }

  // Check output.
  switch (test_params_.expected_output) {
    case ApmFormatHandlingTestParams::ExpectedOutput::kNoError:
      EXPECT_EQ(error, AudioProcessing::kNoError);
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndUnmodified:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (size_t ch = 0; ch < output_num_channels; ++ch) {
        for (size_t i = 0; i < output_samples_per_channel; ++i) {
          EXPECT_EQ(output_block.channels()[ch][i],
                    ch + i * output_num_channels - kUnlikelyOffset);
        }
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndSilence:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (size_t ch = 0; ch < output_num_channels; ++ch) {
        for (size_t i = 0; i < output_samples_per_channel; ++i) {
          EXPECT_EQ(output_block.channels()[ch][i], 0);
        }
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::
        kErrorAndCopyOfFirstChannel:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (size_t ch = 0; ch < output_num_channels; ++ch) {
        for (size_t i = 0; i < output_samples_per_channel; ++i) {
          EXPECT_EQ(output_block.channels()[ch][i],
                    input_block.channels()[0][i]);
        }
      }
      break;
    case ApmFormatHandlingTestParams::ExpectedOutput::kErrorAndExactCopy:
      EXPECT_NE(error, AudioProcessing::kNoError);
      for (size_t ch = 0; ch < output_num_channels; ++ch) {
        for (size_t i = 0; i < output_samples_per_channel; ++i) {
          EXPECT_EQ(output_block.channels()[ch][i],
                    input_block.channels()[ch][i]);
        }
      }
      break;
  }
}

TEST(ApmAnalyzeReverseStreamFormatTest, AnalyzeReverseStream) {
  for (auto&& [input_config, expect_error] :
       {std::tuple(StreamConfig(16000, 2), /*expect_error=*/false),
        std::tuple(StreamConfig(8000, 1), /*expect_error=*/false),
        std::tuple(StreamConfig(384000, 1), /*expect_error=*/false),
        std::tuple(StreamConfig(7900, 1), /*expect_error=*/true),
        std::tuple(StreamConfig(390000, 1), /*expect_error=*/true),
        std::tuple(StreamConfig(16000, 0), /*expect_error=*/true),
        std::tuple(StreamConfig(-16000, 0), /*expect_error=*/true)}) {
    SCOPED_TRACE(::testing::Message()
                 << "sample_rate_hz=" << input_config.sample_rate_hz()
                 << " num_channels=" << input_config.num_channels());

    // Set up input data.
    ChannelBuffer<float> input_block(
        std::abs(input_config.sample_rate_hz()) / 100,
        input_config.num_channels());

    // Call APM.
    scoped_refptr<AudioProcessing> ap =
        BuiltinAudioProcessingBuilder().Build(CreateEnvironment());
    int error = ap->AnalyzeReverseStream(input_block.channels(), input_config);

    // Check output.
    if (expect_error) {
      EXPECT_NE(error, AudioProcessing::kNoError);
    } else {
      EXPECT_EQ(error, AudioProcessing::kNoError);
    }
  }
}

}  // namespace
}  // namespace webrtc
