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

#include "modules/audio_processing/aec3/erle_estimator.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

constexpr int kLowFrequencyLimit = kFftLengthBy2 / 2;
constexpr float kMaxErleLf = 8.f;
constexpr float kMaxErleHf = 1.5f;
constexpr float kMinErle = 1.0f;
constexpr float kTrueErle = 10.f;
constexpr float kTrueErleOnsets = 1.0f;

void VerifyErleBands(const std::array<float, kFftLengthBy2Plus1>& erle,
                     float reference_lf,
                     float reference_hf) {
  std::for_each(
      erle.begin(), erle.begin() + kLowFrequencyLimit,
      [reference_lf](float a) { EXPECT_NEAR(reference_lf, a, 0.001); });
  std::for_each(
      erle.begin() + kLowFrequencyLimit, erle.end(),
      [reference_hf](float a) { EXPECT_NEAR(reference_hf, a, 0.001); });
}

void VerifyErle(const std::array<float, kFftLengthBy2Plus1>& erle,
                float erle_time_domain,
                float reference_lf,
                float reference_hf) {
  VerifyErleBands(erle, reference_lf, reference_hf);
  EXPECT_NEAR(reference_lf, erle_time_domain, 0.001);
}

void FormFarendFrame(std::array<float, kFftLengthBy2Plus1>* X2,
                     std::array<float, kFftLengthBy2Plus1>* E2,
                     std::array<float, kFftLengthBy2Plus1>* Y2,
                     float erle) {
  X2->fill(500 * 1000.f * 1000.f);
  E2->fill(1000.f * 1000.f);
  Y2->fill(erle * (*E2)[0]);
}

void FormNearendFrame(std::array<float, kFftLengthBy2Plus1>* X2,
                      std::array<float, kFftLengthBy2Plus1>* E2,
                      std::array<float, kFftLengthBy2Plus1>* Y2) {
  X2->fill(0.f);
  Y2->fill(500.f * 1000.f * 1000.f);
  E2->fill((*Y2)[0]);
}

}  // namespace

TEST(ErleEstimator, VerifyErleIncreaseAndHold) {
  std::array<float, kFftLengthBy2Plus1> X2;
  std::array<float, kFftLengthBy2Plus1> E2;
  std::array<float, kFftLengthBy2Plus1> Y2;

  ErleEstimator estimator(kMinErle, kMaxErleLf, kMaxErleHf);

  // Verifies that the ERLE estimate is properly increased to higher values.
  FormFarendFrame(&X2, &E2, &Y2, kTrueErle);

  for (size_t k = 0; k < 200; ++k) {
    estimator.Update(X2, Y2, E2);
  }
  VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 8.f, 1.5f);

  FormNearendFrame(&X2, &E2, &Y2);
  // Verifies that the ERLE is not immediately decreased during nearend
  // activity.
  for (size_t k = 0; k < 98; ++k) {
    estimator.Update(X2, Y2, E2);
  }
  VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 8.f, 1.5f);
}

TEST(ErleEstimator, VerifyErleTrackingOnOnsets) {
  std::array<float, kFftLengthBy2Plus1> X2;
  std::array<float, kFftLengthBy2Plus1> E2;
  std::array<float, kFftLengthBy2Plus1> Y2;

  ErleEstimator estimator(kMinErle, kMaxErleLf, kMaxErleHf);

  for (size_t burst = 0; burst < 20; ++burst) {
    FormFarendFrame(&X2, &E2, &Y2, kTrueErleOnsets);
    for (size_t k = 0; k < 10; ++k) {
      estimator.Update(X2, Y2, E2);
    }
    FormFarendFrame(&X2, &E2, &Y2, kTrueErle);
    for (size_t k = 0; k < 200; ++k) {
      estimator.Update(X2, Y2, E2);
    }
    FormNearendFrame(&X2, &E2, &Y2);
    for (size_t k = 0; k < 100; ++k) {
      estimator.Update(X2, Y2, E2);
    }
  }
  VerifyErleBands(estimator.ErleOnsets(), kMinErle, kMinErle);
  FormNearendFrame(&X2, &E2, &Y2);
  for (size_t k = 0; k < 1000; k++) {
    estimator.Update(X2, Y2, E2);
  }
  // Verifies that during ne activity, Erle converges to the Erle for onsets.
  VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), kMinErle, kMinErle);
}

TEST(ErleEstimator, VerifyNoErleUpdateDuringLowActivity) {
  std::array<float, kFftLengthBy2Plus1> X2;
  std::array<float, kFftLengthBy2Plus1> E2;
  std::array<float, kFftLengthBy2Plus1> Y2;
  ErleEstimator estimator(kMinErle, kMaxErleLf, kMaxErleHf);

  // Verifies that the ERLE estimate is is not updated for low-level render
  // signals.
  X2.fill(1000.f * 1000.f);
  Y2.fill(10 * E2[0]);
  for (size_t k = 0; k < 200; ++k) {
    estimator.Update(X2, Y2, E2);
  }
  VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), kMinErle, kMinErle);
}

}  // namespace webrtc
