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

#include <string.h>

#include <memory>

#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
