/*
 *  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/suppression_filter.h"

#include <math.h>
#include <algorithm>
#include <cmath>
#include <numeric>

#include "test/gtest.h"

namespace webrtc {
namespace {

constexpr float kPi = 3.141592f;

void ProduceSinusoid(int sample_rate_hz,
                     float sinusoidal_frequency_hz,
                     size_t* sample_counter,
                     rtc::ArrayView<float> x) {
  // Produce a sinusoid of the specified frequency.
  for (size_t k = *sample_counter, j = 0; k < (*sample_counter + kBlockSize);
       ++k, ++j) {
    x[j] = 32767.f *
           std::sin(2.f * kPi * sinusoidal_frequency_hz * k / sample_rate_hz);
  }
  *sample_counter = *sample_counter + kBlockSize;
}

}  // namespace

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

// Verifies the check for null suppressor output.
TEST(SuppressionFilter, NullOutput) {
  FftData cn;
  FftData cn_high_bands;
  FftData E;
  std::array<float, kFftLengthBy2Plus1> gain;

  EXPECT_DEATH(SuppressionFilter(Aec3Optimization::kNone, 16000)
                   .ApplyGain(cn, cn_high_bands, gain, 1.0f, E, nullptr),
               "");
}

// Verifies the check for allowed sample rate.
TEST(SuppressionFilter, ProperSampleRate) {
  EXPECT_DEATH(SuppressionFilter(Aec3Optimization::kNone, 16001), "");
}

#endif

// Verifies that no comfort noise is added when the gain is 1.
TEST(SuppressionFilter, ComfortNoiseInUnityGain) {
  SuppressionFilter filter(Aec3Optimization::kNone, 48000);
  FftData cn;
  FftData cn_high_bands;
  std::array<float, kFftLengthBy2Plus1> gain;
  std::array<float, kFftLengthBy2> e_old_;
  Aec3Fft fft;

  e_old_.fill(0.f);
  gain.fill(1.f);
  cn.re.fill(1.f);
  cn.im.fill(1.f);
  cn_high_bands.re.fill(1.f);
  cn_high_bands.im.fill(1.f);

  std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
  std::vector<std::vector<float>> e_ref = e;

  FftData E;
  fft.PaddedFft(e[0], e_old_, Aec3Fft::Window::kSqrtHanning, &E);
  std::copy(e[0].begin(), e[0].end(), e_old_.begin());

  filter.ApplyGain(cn, cn_high_bands, gain, 1.f, E, &e);

  for (size_t k = 0; k < e.size(); ++k) {
    EXPECT_EQ(e_ref[k], e[k]);
  }
}

// Verifies that the suppressor is able to suppress a signal.
TEST(SuppressionFilter, SignalSuppression) {
  SuppressionFilter filter(Aec3Optimization::kNone, 48000);
  FftData cn;
  FftData cn_high_bands;
  std::array<float, kFftLengthBy2> e_old_;
  Aec3Fft fft;
  std::array<float, kFftLengthBy2Plus1> gain;
  std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
  e_old_.fill(0.f);

  gain.fill(1.f);
  std::for_each(gain.begin() + 10, gain.end(), [](float& a) { a = 0.f; });

  cn.re.fill(0.f);
  cn.im.fill(0.f);
  cn_high_bands.re.fill(0.f);
  cn_high_bands.im.fill(0.f);

  size_t sample_counter = 0;

  float e0_input = 0.f;
  float e0_output = 0.f;
  for (size_t k = 0; k < 100; ++k) {
    ProduceSinusoid(16000, 16000 * 40 / kFftLengthBy2 / 2, &sample_counter,
                    e[0]);
    e0_input =
        std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_input);

    FftData E;
    fft.PaddedFft(e[0], e_old_, Aec3Fft::Window::kSqrtHanning, &E);
    std::copy(e[0].begin(), e[0].end(), e_old_.begin());

    filter.ApplyGain(cn, cn_high_bands, gain, 1.f, E, &e);
    e0_output =
        std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_output);
  }

  EXPECT_LT(e0_output, e0_input / 1000.f);
}

// Verifies that the suppressor is able to pass through a desired signal while
// applying suppressing for some frequencies.
TEST(SuppressionFilter, SignalTransparency) {
  SuppressionFilter filter(Aec3Optimization::kNone, 48000);
  FftData cn;
  std::array<float, kFftLengthBy2> e_old_;
  Aec3Fft fft;
  FftData cn_high_bands;
  std::array<float, kFftLengthBy2Plus1> gain;
  std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
  e_old_.fill(0.f);
  gain.fill(1.f);
  std::for_each(gain.begin() + 30, gain.end(), [](float& a) { a = 0.f; });

  cn.re.fill(0.f);
  cn.im.fill(0.f);
  cn_high_bands.re.fill(0.f);
  cn_high_bands.im.fill(0.f);

  size_t sample_counter = 0;

  float e0_input = 0.f;
  float e0_output = 0.f;
  for (size_t k = 0; k < 100; ++k) {
    ProduceSinusoid(16000, 16000 * 10 / kFftLengthBy2 / 2, &sample_counter,
                    e[0]);
    e0_input =
        std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_input);

    FftData E;
    fft.PaddedFft(e[0], e_old_, Aec3Fft::Window::kSqrtHanning, &E);
    std::copy(e[0].begin(), e[0].end(), e_old_.begin());

    filter.ApplyGain(cn, cn_high_bands, gain, 1.f, E, &e);
    e0_output =
        std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_output);
  }

  EXPECT_LT(0.9f * e0_input, e0_output);
}

// Verifies that the suppressor delay.
TEST(SuppressionFilter, Delay) {
  SuppressionFilter filter(Aec3Optimization::kNone, 48000);
  FftData cn;
  FftData cn_high_bands;
  std::array<float, kFftLengthBy2> e_old_;
  Aec3Fft fft;
  std::array<float, kFftLengthBy2Plus1> gain;
  std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));

  gain.fill(1.f);

  cn.re.fill(0.f);
  cn.im.fill(0.f);
  cn_high_bands.re.fill(0.f);
  cn_high_bands.im.fill(0.f);

  for (size_t k = 0; k < 100; ++k) {
    for (size_t j = 0; j < 3; ++j) {
      for (size_t i = 0; i < kBlockSize; ++i) {
        e[j][i] = k * kBlockSize + i;
      }
    }

    FftData E;
    fft.PaddedFft(e[0], e_old_, Aec3Fft::Window::kSqrtHanning, &E);
    std::copy(e[0].begin(), e[0].end(), e_old_.begin());

    filter.ApplyGain(cn, cn_high_bands, gain, 1.f, E, &e);
    if (k > 2) {
      for (size_t j = 0; j < 2; ++j) {
        for (size_t i = 0; i < kBlockSize; ++i) {
          EXPECT_NEAR(k * kBlockSize + i - kBlockSize, e[j][i], 0.01);
        }
      }
    }
  }
}

}  // namespace webrtc
