/*
 *  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 "testing/gtest/include/gtest/gtest.h"
extern "C" {
#include "webrtc/modules/audio_processing/aec/aec_core.h"
}
#include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h"
#include "webrtc/modules/audio_processing/aec/echo_cancellation.h"
#include "webrtc/test/testsupport/gtest_disable.h"
#include "webrtc/typedefs.h"

namespace {

class SystemDelayTest : public ::testing::Test {
 protected:
  SystemDelayTest();
  virtual void SetUp();
  virtual void TearDown();

  // Initialization of AEC handle with respect to |sample_rate_hz|. Since the
  // device sample rate is unimportant we set that value to 48000 Hz.
  void Init(int sample_rate_hz);

  // Makes one render call and one capture call in that specific order.
  void RenderAndCapture(int device_buffer_ms);

  // Fills up the far-end buffer with respect to the default device buffer size.
  size_t BufferFillUp();

  // Runs and verifies the behavior in a stable startup procedure.
  void RunStableStartup();

  // Maps buffer size in ms into samples, taking the unprocessed frame into
  // account.
  int MapBufferSizeToSamples(int size_in_ms, bool extended_filter);

  void* handle_;
  Aec* self_;
  size_t samples_per_frame_;
  // Dummy input/output speech data.
  static const int kSamplesPerChunk = 160;
  float far_[kSamplesPerChunk];
  float near_[kSamplesPerChunk];
  float out_[kSamplesPerChunk];
  const float* near_ptr_;
  float* out_ptr_;
};

SystemDelayTest::SystemDelayTest()
    : handle_(NULL), self_(NULL), samples_per_frame_(0) {
  // Dummy input data are set with more or less arbitrary non-zero values.
  for (int i = 0; i < kSamplesPerChunk; i++) {
    far_[i] = 257.0;
    near_[i] = 514.0;
  }
  memset(out_, 0, sizeof(out_));
  near_ptr_ = near_;
  out_ptr_ = out_;
}

void SystemDelayTest::SetUp() {
  handle_ = WebRtcAec_Create();
  ASSERT_TRUE(handle_);
  self_ = reinterpret_cast<Aec*>(handle_);
}

void SystemDelayTest::TearDown() {
  // Free AEC
  WebRtcAec_Free(handle_);
  handle_ = NULL;
}

// In SWB mode nothing is added to the buffer handling with respect to
// functionality compared to WB. We therefore only verify behavior in NB and WB.
static const int kSampleRateHz[] = {8000, 16000};
static const size_t kNumSampleRates =
    sizeof(kSampleRateHz) / sizeof(*kSampleRateHz);

// Default audio device buffer size used.
static const int kDeviceBufMs = 100;

// Requirement for a stable device convergence time in ms. Should converge in
// less than |kStableConvergenceMs|.
static const int kStableConvergenceMs = 100;

// Maximum convergence time in ms. This means that we should leave the startup
// phase after |kMaxConvergenceMs| independent of device buffer stability
// conditions.
static const int kMaxConvergenceMs = 500;

void SystemDelayTest::Init(int sample_rate_hz) {
  // Initialize AEC
  EXPECT_EQ(0, WebRtcAec_Init(handle_, sample_rate_hz, 48000));
  EXPECT_EQ(0, WebRtcAec_system_delay(self_->aec));

  // One frame equals 10 ms of data.
  samples_per_frame_ = static_cast<size_t>(sample_rate_hz / 100);
}

void SystemDelayTest::RenderAndCapture(int device_buffer_ms) {
  EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
  EXPECT_EQ(0,
            WebRtcAec_Process(handle_,
                              &near_ptr_,
                              1,
                              &out_ptr_,
                              samples_per_frame_,
                              device_buffer_ms,
                              0));
}

size_t SystemDelayTest::BufferFillUp() {
  // To make sure we have a full buffer when we verify stability we first fill
  // up the far-end buffer with the same amount as we will report in through
  // Process().
  size_t buffer_size = 0;
  for (int i = 0; i < kDeviceBufMs / 10; i++) {
    EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
    buffer_size += samples_per_frame_;
    EXPECT_EQ(static_cast<int>(buffer_size),
              WebRtcAec_system_delay(self_->aec));
  }
  return buffer_size;
}

void SystemDelayTest::RunStableStartup() {
  // To make sure we have a full buffer when we verify stability we first fill
  // up the far-end buffer with the same amount as we will report in through
  // Process().
  size_t buffer_size = BufferFillUp();

  if (WebRtcAec_delay_agnostic_enabled(self_->aec) == 1) {
    // In extended_filter mode we set the buffer size after the first processed
    // 10 ms chunk. Hence, we don't need to wait for the reported system delay
    // values to become stable.
    RenderAndCapture(kDeviceBufMs);
    buffer_size += samples_per_frame_;
    EXPECT_EQ(0, self_->startup_phase);
  } else {
    // A stable device should be accepted and put in a regular process mode
    // within |kStableConvergenceMs|.
    int process_time_ms = 0;
    for (; process_time_ms < kStableConvergenceMs; process_time_ms += 10) {
      RenderAndCapture(kDeviceBufMs);
      buffer_size += samples_per_frame_;
      if (self_->startup_phase == 0) {
        // We have left the startup phase.
        break;
      }
    }
    // Verify convergence time.
    EXPECT_GT(kStableConvergenceMs, process_time_ms);
  }
  // Verify that the buffer has been flushed.
  EXPECT_GE(static_cast<int>(buffer_size),
            WebRtcAec_system_delay(self_->aec));
}

  int SystemDelayTest::MapBufferSizeToSamples(int size_in_ms,
                                              bool extended_filter) {
  // If extended_filter is disabled we add an extra 10 ms for the unprocessed
  // frame. That is simply how the algorithm is constructed.
  return static_cast<int>(
      (size_in_ms + (extended_filter ? 0 : 10)) * samples_per_frame_ / 10);
}

// The tests should meet basic requirements and not be adjusted to what is
// actually implemented. If we don't get good code coverage this way we either
// lack in tests or have unnecessary code.
// General requirements:
// 1) If we add far-end data the system delay should be increased with the same
//    amount we add.
// 2) If the far-end buffer is full we should flush the oldest data to make room
//    for the new. In this case the system delay is unaffected.
// 3) There should exist a startup phase in which the buffer size is to be
//    determined. In this phase no cancellation should be performed.
// 4) Under stable conditions (small variations in device buffer sizes) the AEC
//    should determine an appropriate local buffer size within
//    |kStableConvergenceMs| ms.
// 5) Under unstable conditions the AEC should make a decision within
//    |kMaxConvergenceMs| ms.
// 6) If the local buffer runs out of data we should stuff the buffer with older
//    frames.
// 7) The system delay should within |kMaxConvergenceMs| ms heal from
//    disturbances like drift, data glitches, toggling events and outliers.
// 8) The system delay should never become negative.

TEST_F(SystemDelayTest, CorrectIncreaseWhenBufferFarend) {
  // When we add data to the AEC buffer the internal system delay should be
  // incremented with the same amount as the size of data.
  // This process should be independent of DA-AEC and extended_filter mode.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        // Loop through a couple of calls to make sure the system delay
        // increments correctly.
        for (int j = 1; j <= 5; j++) {
          EXPECT_EQ(0,
                    WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
          EXPECT_EQ(static_cast<int>(j * samples_per_frame_),
                    WebRtcAec_system_delay(self_->aec));
        }
      }
    }
  }
}

// TODO(bjornv): Add a test to verify behavior if the far-end buffer is full
// when adding new data.

TEST_F(SystemDelayTest, CorrectDelayAfterStableStartup) {
  // We run the system in a stable startup. After that we verify that the system
  // delay meets the requirements.
  // This process should be independent of DA-AEC and extended_filter mode.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        RunStableStartup();

        // Verify system delay with respect to requirements, i.e., the
        // |system_delay| is in the interval [75%, 100%] of what's reported on
        // the average.
        // In extended_filter mode we target 50% and measure after one processed
        // 10 ms chunk.
        int average_reported_delay =
            static_cast<int>(kDeviceBufMs * samples_per_frame_ / 10);
        EXPECT_GE(average_reported_delay, WebRtcAec_system_delay(self_->aec));
        int lower_bound = WebRtcAec_extended_filter_enabled(self_->aec)
                              ? average_reported_delay / 2 - samples_per_frame_
                              : average_reported_delay * 3 / 4;
        EXPECT_LE(lower_bound, WebRtcAec_system_delay(self_->aec));
      }
    }
  }
}

TEST_F(SystemDelayTest, CorrectDelayAfterUnstableStartup) {
  // This test does not apply in extended_filter mode, since we only use the
  // the first 10 ms chunk to determine a reasonable buffer size. Neither does
  // it apply if DA-AEC is on because that overrides the startup procedure.
  WebRtcAec_enable_extended_filter(self_->aec, 0);
  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(self_->aec));
  WebRtcAec_enable_delay_agnostic(self_->aec, 0);
  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(self_->aec));

  // In an unstable system we would start processing after |kMaxConvergenceMs|.
  // On the last frame the AEC buffer is adjusted to 60% of the last reported
  // device buffer size.
  // We construct an unstable system by altering the device buffer size between
  // two values |kDeviceBufMs| +- 25 ms.
  for (size_t i = 0; i < kNumSampleRates; i++) {
    Init(kSampleRateHz[i]);

    // To make sure we have a full buffer when we verify stability we first fill
    // up the far-end buffer with the same amount as we will report in on the
    // average through Process().
    size_t buffer_size = BufferFillUp();

    int buffer_offset_ms = 25;
    int reported_delay_ms = 0;
    int process_time_ms = 0;
    for (; process_time_ms <= kMaxConvergenceMs; process_time_ms += 10) {
      reported_delay_ms = kDeviceBufMs + buffer_offset_ms;
      RenderAndCapture(reported_delay_ms);
      buffer_size += samples_per_frame_;
      buffer_offset_ms = -buffer_offset_ms;
      if (self_->startup_phase == 0) {
        // We have left the startup phase.
        break;
      }
    }
    // Verify convergence time.
    EXPECT_GE(kMaxConvergenceMs, process_time_ms);
    // Verify that the buffer has been flushed.
    EXPECT_GE(static_cast<int>(buffer_size),
              WebRtcAec_system_delay(self_->aec));

    // Verify system delay with respect to requirements, i.e., the
    // |system_delay| is in the interval [60%, 100%] of what's last reported.
    EXPECT_GE(static_cast<int>(reported_delay_ms * samples_per_frame_ / 10),
              WebRtcAec_system_delay(self_->aec));
    EXPECT_LE(
        static_cast<int>(reported_delay_ms * samples_per_frame_ / 10 * 3 / 5),
        WebRtcAec_system_delay(self_->aec));
  }
}

TEST_F(SystemDelayTest, CorrectDelayAfterStableBufferBuildUp) {
  // This test does not apply in extended_filter mode, since we only use the
  // the first 10 ms chunk to determine a reasonable buffer size. Neither does
  // it apply if DA-AEC is on because that overrides the startup procedure.
  WebRtcAec_enable_extended_filter(self_->aec, 0);
  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(self_->aec));
  WebRtcAec_enable_delay_agnostic(self_->aec, 0);
  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(self_->aec));

  // In this test we start by establishing the device buffer size during stable
  // conditions, but with an empty internal far-end buffer. Once that is done we
  // verify that the system delay is increased correctly until we have reach an
  // internal buffer size of 75% of what's been reported.
  for (size_t i = 0; i < kNumSampleRates; i++) {
    Init(kSampleRateHz[i]);

    // We assume that running |kStableConvergenceMs| calls will put the
    // algorithm in a state where the device buffer size has been determined. We
    // can make that assumption since we have a separate stability test.
    int process_time_ms = 0;
    for (; process_time_ms < kStableConvergenceMs; process_time_ms += 10) {
      EXPECT_EQ(0,
                WebRtcAec_Process(handle_,
                                  &near_ptr_,
                                  1,
                                  &out_ptr_,
                                  samples_per_frame_,
                                  kDeviceBufMs,
                                  0));
    }
    // Verify that a buffer size has been established.
    EXPECT_EQ(0, self_->checkBuffSize);

    // We now have established the required buffer size. Let us verify that we
    // fill up before leaving the startup phase for normal processing.
    size_t buffer_size = 0;
    size_t target_buffer_size = kDeviceBufMs * samples_per_frame_ / 10 * 3 / 4;
    process_time_ms = 0;
    for (; process_time_ms <= kMaxConvergenceMs; process_time_ms += 10) {
      RenderAndCapture(kDeviceBufMs);
      buffer_size += samples_per_frame_;
      if (self_->startup_phase == 0) {
        // We have left the startup phase.
        break;
      }
    }
    // Verify convergence time.
    EXPECT_GT(kMaxConvergenceMs, process_time_ms);
    // Verify that the buffer has reached the desired size.
    EXPECT_LE(static_cast<int>(target_buffer_size),
              WebRtcAec_system_delay(self_->aec));

    // Verify normal behavior (system delay is kept constant) after startup by
    // running a couple of calls to BufferFarend() and Process().
    for (int j = 0; j < 6; j++) {
      int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
      RenderAndCapture(kDeviceBufMs);
      EXPECT_EQ(system_delay_before_calls, WebRtcAec_system_delay(self_->aec));
    }
  }
}

TEST_F(SystemDelayTest, CorrectDelayWhenBufferUnderrun) {
  // Here we test a buffer under run scenario. If we keep on calling
  // WebRtcAec_Process() we will finally run out of data, but should
  // automatically stuff the buffer. We verify this behavior by checking if the
  // system delay goes negative.
  // This process should be independent of DA-AEC and extended_filter mode.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        RunStableStartup();

        // The AEC has now left the Startup phase. We now have at most
        // |kStableConvergenceMs| in the buffer. Keep on calling Process() until
        // we run out of data and verify that the system delay is non-negative.
        for (int j = 0; j <= kStableConvergenceMs; j += 10) {
          EXPECT_EQ(0, WebRtcAec_Process(handle_, &near_ptr_, 1, &out_ptr_,
                                         samples_per_frame_, kDeviceBufMs, 0));
          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
        }
      }
    }
  }
}

TEST_F(SystemDelayTest, CorrectDelayDuringDrift) {
  // This drift test should verify that the system delay is never exceeding the
  // device buffer. The drift is simulated by decreasing the reported device
  // buffer size by 1 ms every 100 ms. If the device buffer size goes below 30
  // ms we jump (add) 10 ms to give a repeated pattern.

  // This process should be independent of DA-AEC and extended_filter mode.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        RunStableStartup();

        // We have left the startup phase and proceed with normal processing.
        int jump = 0;
        for (int j = 0; j < 1000; j++) {
          // Drift = -1 ms per 100 ms of data.
          int device_buf_ms = kDeviceBufMs - (j / 10) + jump;
          int device_buf = MapBufferSizeToSamples(device_buf_ms,
                                                  extended_filter == 1);

          if (device_buf_ms < 30) {
            // Add 10 ms data, taking affect next frame.
            jump += 10;
          }
          RenderAndCapture(device_buf_ms);

          // Verify that the system delay does not exceed the device buffer.
          EXPECT_GE(device_buf, WebRtcAec_system_delay(self_->aec));

          // Verify that the system delay is non-negative.
          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
        }
      }
    }
  }
}

TEST_F(SystemDelayTest, ShouldRecoverAfterGlitch) {
  // This glitch test should verify that the system delay recovers if there is
  // a glitch in data. The data glitch is constructed as 200 ms of buffering
  // after which the stable procedure continues. The glitch is never reported by
  // the device.
  // The system is said to be in a non-causal state if the difference between
  // the device buffer and system delay is less than a block (64 samples).

  // This process should be independent of DA-AEC and extended_filter mode.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        RunStableStartup();
        int device_buf = MapBufferSizeToSamples(kDeviceBufMs,
                                                extended_filter == 1);
        // Glitch state.
        for (int j = 0; j < 20; j++) {
          EXPECT_EQ(0,
                    WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
          // No need to verify system delay, since that is done in a separate
          // test.
        }
        // Verify that we are in a non-causal state, i.e.,
        // |system_delay| > |device_buf|.
        EXPECT_LT(device_buf, WebRtcAec_system_delay(self_->aec));

        // Recover state. Should recover at least 4 ms of data per 10 ms, hence
        // a glitch of 200 ms will take at most 200 * 10 / 4 = 500 ms to recover
        // from.
        bool non_causal = true;  // We are currently in a non-causal state.
        for (int j = 0; j < 50; j++) {
          int system_delay_before = WebRtcAec_system_delay(self_->aec);
          RenderAndCapture(kDeviceBufMs);
          int system_delay_after = WebRtcAec_system_delay(self_->aec);
          // We have recovered if
          // |device_buf| - |system_delay_after| >= PART_LEN (1 block).
          // During recovery, |system_delay_after| < |system_delay_before|,
          // otherwise they are equal.
          if (non_causal) {
            EXPECT_LT(system_delay_after, system_delay_before);
            if (device_buf - system_delay_after >= PART_LEN) {
              non_causal = false;
            }
          } else {
            EXPECT_EQ(system_delay_before, system_delay_after);
          }
          // Verify that the system delay is non-negative.
          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
        }
        // Check that we have recovered.
        EXPECT_FALSE(non_causal);
      }
    }
  }
}

TEST_F(SystemDelayTest, UnaffectedWhenSpuriousDeviceBufferValues) {
  // This test does not apply in extended_filter mode, since we only use the
  // the first 10 ms chunk to determine a reasonable buffer size.
  const int extended_filter = 0;
  WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
  EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));

  // Should be DA-AEC independent.
  for (int da_aec = 0; da_aec <= 1; ++da_aec) {
    WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
    EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
    // This spurious device buffer data test aims at verifying that the system
    // delay is unaffected by large outliers.
    // The system is said to be in a non-causal state if the difference between
    // the device buffer and system delay is less than a block (64 samples).
    for (size_t i = 0; i < kNumSampleRates; i++) {
      Init(kSampleRateHz[i]);
      RunStableStartup();
      int device_buf = MapBufferSizeToSamples(kDeviceBufMs,
                                              extended_filter == 1);

      // Normal state. We are currently not in a non-causal state.
      bool non_causal = false;

      // Run 1 s and replace device buffer size with 500 ms every 100 ms.
      for (int j = 0; j < 100; j++) {
        int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
        int device_buf_ms = j % 10 == 0 ? 500 : kDeviceBufMs;
        RenderAndCapture(device_buf_ms);

        // Check for non-causality.
        if (device_buf - WebRtcAec_system_delay(self_->aec) < PART_LEN) {
          non_causal = true;
        }
        EXPECT_FALSE(non_causal);
        EXPECT_EQ(system_delay_before_calls,
                  WebRtcAec_system_delay(self_->aec));

        // Verify that the system delay is non-negative.
        EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
      }
    }
  }
}

TEST_F(SystemDelayTest, CorrectImpactWhenTogglingDeviceBufferValues) {
  // This test aims at verifying that the system delay is "unaffected" by
  // toggling values reported by the device.
  // The test is constructed such that every other device buffer value is zero
  // and then 2 * |kDeviceBufMs|, hence the size is constant on the average. The
  // zero values will force us into a non-causal state and thereby lowering the
  // system delay until we basically run out of data. Once that happens the
  // buffer will be stuffed.
  // TODO(bjornv): This test will have a better impact if we verified that the
  // delay estimate goes up when the system delay goes down to meet the average
  // device buffer size.

  // This test does not apply if DA-AEC is enabled and extended_filter mode
  // disabled.
  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
      if (extended_filter == 0 && da_aec == 1) {
        continue;
      }
      for (size_t i = 0; i < kNumSampleRates; i++) {
        Init(kSampleRateHz[i]);
        RunStableStartup();
        const int device_buf = MapBufferSizeToSamples(kDeviceBufMs,
                                                      extended_filter == 1);

        // Normal state. We are currently not in a non-causal state.
        bool non_causal = false;

        // Loop through 100 frames (both render and capture), which equals 1 s
        // of data. Every odd frame we set the device buffer size to
        // 2 * |kDeviceBufMs| and even frames we set the device buffer size to
        // zero.
        for (int j = 0; j < 100; j++) {
          int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
          int device_buf_ms = 2 * (j % 2) * kDeviceBufMs;
          RenderAndCapture(device_buf_ms);

          // Check for non-causality, compared with the average device buffer
          // size.
          non_causal |= (device_buf - WebRtcAec_system_delay(self_->aec) < 64);
          EXPECT_GE(system_delay_before_calls,
                    WebRtcAec_system_delay(self_->aec));

          // Verify that the system delay is non-negative.
          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
        }
        // Verify we are not in a non-causal state.
        EXPECT_FALSE(non_causal);
      }
    }
  }
}

}  // namespace
