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

#include <math.h>

#include <algorithm>
#include <array>
#include <cmath>
#include <cstring>
#include <numeric>
#include <string>
#include <vector>

#include "modules/audio_processing/aec3/aec3_common.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

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

constexpr size_t kDownSamplingFactors[] = {2, 4, 8};
constexpr float kPi = 3.141592f;
constexpr size_t kNumStartupBlocks = 50;
constexpr size_t kNumBlocks = 1000;

void ProduceDecimatedSinusoidalOutputPower(int sample_rate_hz,
                                           size_t down_sampling_factor,
                                           float sinusoidal_frequency_hz,
                                           float* input_power,
                                           float* output_power) {
  float input[kBlockSize * kNumBlocks];
  const size_t sub_block_size = kBlockSize / down_sampling_factor;

  // Produce a sinusoid of the specified frequency.
  for (size_t k = 0; k < kBlockSize * kNumBlocks; ++k) {
    input[k] = 32767.f * std::sin(2.f * kPi * sinusoidal_frequency_hz * k /
                                  sample_rate_hz);
  }

  Decimator decimator(down_sampling_factor);
  std::vector<float> output(sub_block_size * kNumBlocks);

  for (size_t k = 0; k < kNumBlocks; ++k) {
    std::vector<float> sub_block(sub_block_size);
    decimator.Decimate(
        rtc::ArrayView<const float>(&input[k * kBlockSize], kBlockSize),
        sub_block);

    std::copy(sub_block.begin(), sub_block.end(),
              output.begin() + k * sub_block_size);
  }

  ASSERT_GT(kNumBlocks, kNumStartupBlocks);
  rtc::ArrayView<const float> input_to_evaluate(
      &input[kNumStartupBlocks * kBlockSize],
      (kNumBlocks - kNumStartupBlocks) * kBlockSize);
  rtc::ArrayView<const float> output_to_evaluate(
      &output[kNumStartupBlocks * sub_block_size],
      (kNumBlocks - kNumStartupBlocks) * sub_block_size);
  *input_power =
      std::inner_product(input_to_evaluate.begin(), input_to_evaluate.end(),
                         input_to_evaluate.begin(), 0.f) /
      input_to_evaluate.size();
  *output_power =
      std::inner_product(output_to_evaluate.begin(), output_to_evaluate.end(),
                         output_to_evaluate.begin(), 0.f) /
      output_to_evaluate.size();
}

}  // namespace

// Verifies that there is little aliasing from upper frequencies in the
// downsampling.
TEST(Decimator, NoLeakageFromUpperFrequencies) {
  float input_power;
  float output_power;
  for (auto rate : {16000, 32000, 48000}) {
    for (auto down_sampling_factor : kDownSamplingFactors) {
      ProduceDebugText(rate);
      ProduceDecimatedSinusoidalOutputPower(rate, down_sampling_factor,
                                            3.f / 8.f * rate, &input_power,
                                            &output_power);
      EXPECT_GT(0.0001f * input_power, output_power);
    }
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
// Verifies the check for the input size.
TEST(Decimator, WrongInputSize) {
  Decimator decimator(4);
  std::vector<float> x(kBlockSize - 1, 0.f);
  std::array<float, kBlockSize / 4> x_downsampled;
  EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
}

// Verifies the check for non-null output parameter.
TEST(Decimator, NullOutput) {
  Decimator decimator(4);
  std::vector<float> x(kBlockSize, 0.f);
  EXPECT_DEATH(decimator.Decimate(x, nullptr), "");
}

// Verifies the check for the output size.
TEST(Decimator, WrongOutputSize) {
  Decimator decimator(4);
  std::vector<float> x(kBlockSize, 0.f);
  std::array<float, kBlockSize / 4 - 1> x_downsampled;
  EXPECT_DEATH(decimator.Decimate(x, x_downsampled), "");
}

// Verifies the check for the correct downsampling factor.
TEST(Decimator, CorrectDownSamplingFactor) {
  EXPECT_DEATH(Decimator(3), "");
}

#endif

}  // namespace webrtc
