/*
 *  Copyright (c) 2014 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 "common_audio/fir_filter.h"

#include <string.h>

#include <memory>

#include "common_audio/fir_filter_factory.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

static const float kCoefficients[] = {0.2f, 0.3f, 0.5f, 0.7f, 0.11f};
static const size_t kCoefficientsLength =
    sizeof(kCoefficients) / sizeof(kCoefficients[0]);

static const float kInput[] = {1.f, 2.f, 3.f, 4.f, 5.f,
                               6.f, 7.f, 8.f, 9.f, 10.f};
static const size_t kInputLength = sizeof(kInput) / sizeof(kInput[0]);

void VerifyOutput(const float* expected_output,
                  const float* output,
                  size_t length) {
  EXPECT_EQ(
      0, memcmp(expected_output, output, length * sizeof(expected_output[0])));
}

}  // namespace

TEST(FIRFilterTest, FilterAsIdentity) {
  const float kCoefficients[] = {1.f, 0.f, 0.f, 0.f, 0.f};
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output);

  VerifyOutput(kInput, output, kInputLength);
}

TEST(FIRFilterTest, FilterUsedAsScalarMultiplication) {
  const float kCoefficients[] = {5.f, 0.f, 0.f, 0.f, 0.f};
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output);

  EXPECT_FLOAT_EQ(5.f, output[0]);
  EXPECT_FLOAT_EQ(20.f, output[3]);
  EXPECT_FLOAT_EQ(25.f, output[4]);
  EXPECT_FLOAT_EQ(50.f, output[kInputLength - 1]);
}

TEST(FIRFilterTest, FilterUsedAsInputShifting) {
  const float kCoefficients[] = {0.f, 0.f, 0.f, 0.f, 1.f};
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output);

  EXPECT_FLOAT_EQ(0.f, output[0]);
  EXPECT_FLOAT_EQ(0.f, output[3]);
  EXPECT_FLOAT_EQ(1.f, output[4]);
  EXPECT_FLOAT_EQ(2.f, output[5]);
  EXPECT_FLOAT_EQ(6.f, output[kInputLength - 1]);
}

TEST(FIRFilterTest, FilterUsedAsArbitraryWeighting) {
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output);

  EXPECT_FLOAT_EQ(0.2f, output[0]);
  EXPECT_FLOAT_EQ(3.4f, output[3]);
  EXPECT_FLOAT_EQ(5.21f, output[4]);
  EXPECT_FLOAT_EQ(7.02f, output[5]);
  EXPECT_FLOAT_EQ(14.26f, output[kInputLength - 1]);
}

TEST(FIRFilterTest, FilterInLengthLesserOrEqualToCoefficientsLength) {
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, 2));
  filter->Filter(kInput, 2, output);

  EXPECT_FLOAT_EQ(0.2f, output[0]);
  EXPECT_FLOAT_EQ(0.7f, output[1]);
  filter.reset(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kCoefficientsLength));
  filter->Filter(kInput, kCoefficientsLength, output);

  EXPECT_FLOAT_EQ(0.2f, output[0]);
  EXPECT_FLOAT_EQ(3.4f, output[3]);
  EXPECT_FLOAT_EQ(5.21f, output[4]);
}

TEST(FIRFilterTest, MultipleFilterCalls) {
  float output[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, 3));
  filter->Filter(kInput, 2, output);
  EXPECT_FLOAT_EQ(0.2f, output[0]);
  EXPECT_FLOAT_EQ(0.7f, output[1]);

  filter->Filter(kInput, 2, output);
  EXPECT_FLOAT_EQ(1.3f, output[0]);
  EXPECT_FLOAT_EQ(2.4f, output[1]);

  filter->Filter(kInput, 2, output);
  EXPECT_FLOAT_EQ(2.81f, output[0]);
  EXPECT_FLOAT_EQ(2.62f, output[1]);

  filter->Filter(kInput, 2, output);
  EXPECT_FLOAT_EQ(2.81f, output[0]);
  EXPECT_FLOAT_EQ(2.62f, output[1]);

  filter->Filter(&kInput[3], 3, output);
  EXPECT_FLOAT_EQ(3.41f, output[0]);
  EXPECT_FLOAT_EQ(4.12f, output[1]);
  EXPECT_FLOAT_EQ(6.21f, output[2]);

  filter->Filter(&kInput[3], 3, output);
  EXPECT_FLOAT_EQ(8.12f, output[0]);
  EXPECT_FLOAT_EQ(9.14f, output[1]);
  EXPECT_FLOAT_EQ(9.45f, output[2]);
}

TEST(FIRFilterTest, VerifySampleBasedVsBlockBasedFiltering) {
  float output_block_based[kInputLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output_block_based);

  float output_sample_based[kInputLength];
  filter.reset(CreateFirFilter(kCoefficients, kCoefficientsLength, 1));
  for (size_t i = 0; i < kInputLength; ++i) {
    filter->Filter(&kInput[i], 1, &output_sample_based[i]);
  }

  EXPECT_EQ(0, memcmp(output_sample_based, output_block_based, kInputLength));
}

TEST(FIRFilterTest, SimplestHighPassFilter) {
  const float kCoefficients[] = {1.f, -1.f};
  const size_t kCoefficientsLength =
      sizeof(kCoefficients) / sizeof(kCoefficients[0]);

  float kConstantInput[] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
  const size_t kConstantInputLength =
      sizeof(kConstantInput) / sizeof(kConstantInput[0]);

  float output[kConstantInputLength];
  std::unique_ptr<FIRFilter> filter(CreateFirFilter(
      kCoefficients, kCoefficientsLength, kConstantInputLength));
  filter->Filter(kConstantInput, kConstantInputLength, output);
  EXPECT_FLOAT_EQ(1.f, output[0]);
  for (size_t i = kCoefficientsLength - 1; i < kConstantInputLength; ++i) {
    EXPECT_FLOAT_EQ(0.f, output[i]);
  }
}

TEST(FIRFilterTest, SimplestLowPassFilter) {
  const float kCoefficients[] = {1.f, 1.f};
  const size_t kCoefficientsLength =
      sizeof(kCoefficients) / sizeof(kCoefficients[0]);

  float kHighFrequencyInput[] = {-1.f, 1.f, -1.f, 1.f, -1.f, 1.f, -1.f, 1.f};
  const size_t kHighFrequencyInputLength =
      sizeof(kHighFrequencyInput) / sizeof(kHighFrequencyInput[0]);

  float output[kHighFrequencyInputLength];
  std::unique_ptr<FIRFilter> filter(CreateFirFilter(
      kCoefficients, kCoefficientsLength, kHighFrequencyInputLength));
  filter->Filter(kHighFrequencyInput, kHighFrequencyInputLength, output);
  EXPECT_FLOAT_EQ(-1.f, output[0]);
  for (size_t i = kCoefficientsLength - 1; i < kHighFrequencyInputLength; ++i) {
    EXPECT_FLOAT_EQ(0.f, output[i]);
  }
}

TEST(FIRFilterTest, SameOutputWhenSwapedCoefficientsAndInput) {
  float output[kCoefficientsLength];
  float output_swaped[kCoefficientsLength];
  std::unique_ptr<FIRFilter> filter(
      CreateFirFilter(kCoefficients, kCoefficientsLength, kCoefficientsLength));
  // Use kCoefficientsLength for in_length to get same-length outputs.
  filter->Filter(kInput, kCoefficientsLength, output);

  filter.reset(
      CreateFirFilter(kInput, kCoefficientsLength, kCoefficientsLength));
  filter->Filter(kCoefficients, kCoefficientsLength, output_swaped);

  for (size_t i = 0; i < kCoefficientsLength; ++i) {
    EXPECT_FLOAT_EQ(output[i], output_swaped[i]);
  }
}

}  // namespace webrtc
