/*
 *  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 "testing/gtest/include/gtest/gtest.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

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])));
}

TEST(FIRFilterTest, FilterAsIdentity) {
  const float kCoefficients[] = {1.f, 0.f, 0.f, 0.f, 0.f};
  float output[kInputLength];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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];
  scoped_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
