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

#include <string.h>

#include <memory>

#include "webrtc/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(
      FIRFilter::Create(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(
      FIRFilter::Create(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(
      FIRFilter::Create(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(
      FIRFilter::Create(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(
      FIRFilter::Create(kCoefficients, kCoefficientsLength, 2));
  filter->Filter(kInput, 2, output);

  EXPECT_FLOAT_EQ(0.2f, output[0]);
  EXPECT_FLOAT_EQ(0.7f, output[1]);
  filter.reset(FIRFilter::Create(
      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(
      FIRFilter::Create(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(
      FIRFilter::Create(kCoefficients, kCoefficientsLength, kInputLength));
  filter->Filter(kInput, kInputLength, output_block_based);

  float output_sample_based[kInputLength];
  filter.reset(FIRFilter::Create(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(FIRFilter::Create(
      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(FIRFilter::Create(
      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(FIRFilter::Create(
      kCoefficients, kCoefficientsLength, kCoefficientsLength));
  // Use kCoefficientsLength for in_length to get same-length outputs.
  filter->Filter(kInput, kCoefficientsLength, output);

  filter.reset(FIRFilter::Create(
      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
