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

// Defines WEBRTC_ARCH_X86_FAMILY, used below.
#include <math.h>

#include <algorithm>
#include <numeric>
#include <string>

#include "rtc_base/system/arch.h"
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif

#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
#include "modules/audio_processing/aec3/aec3_fft.h"
#include "modules/audio_processing/aec3/aec_state.h"
#include "modules/audio_processing/aec3/coarse_filter_update_gain.h"
#include "modules/audio_processing/aec3/render_delay_buffer.h"
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
#include "modules/audio_processing/utility/cascaded_biquad_filter.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/numerics/safe_minmax.h"
#include "rtc_base/random.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"

namespace webrtc {
namespace aec3 {
namespace {

std::string ProduceDebugText(size_t num_render_channels, size_t delay) {
  rtc::StringBuilder ss;
  ss << "delay: " << delay << ", ";
  ss << "num_render_channels:" << num_render_channels;
  return ss.Release();
}

}  // namespace

class AdaptiveFirFilterOneTwoFourEightRenderChannels
    : public ::testing::Test,
      public ::testing::WithParamInterface<size_t> {};

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         AdaptiveFirFilterOneTwoFourEightRenderChannels,
                         ::testing::Values(1, 2, 4, 8));

#if defined(WEBRTC_HAS_NEON)
// Verifies that the optimized methods for filter adaptation are similar to
// their reference counterparts.
TEST_P(AdaptiveFirFilterOneTwoFourEightRenderChannels,
       FilterAdaptationNeonOptimizations) {
  const size_t num_render_channels = GetParam();
  for (size_t num_partitions : {2, 5, 12, 30, 50}) {
    constexpr int kSampleRateHz = 48000;
    constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);

    std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
        RenderDelayBuffer::Create(EchoCanceller3Config(), kSampleRateHz,
                                  num_render_channels));
    Random random_generator(42U);
    std::vector<std::vector<std::vector<float>>> x(
        kNumBands,
        std::vector<std::vector<float>>(num_render_channels,
                                        std::vector<float>(kBlockSize, 0.f)));
    FftData S_C;
    FftData S_Neon;
    FftData G;
    Aec3Fft fft;
    std::vector<std::vector<FftData>> H_C(
        num_partitions, std::vector<FftData>(num_render_channels));
    std::vector<std::vector<FftData>> H_Neon(
        num_partitions, std::vector<FftData>(num_render_channels));
    for (size_t p = 0; p < num_partitions; ++p) {
      for (size_t ch = 0; ch < num_render_channels; ++ch) {
        H_C[p][ch].Clear();
        H_Neon[p][ch].Clear();
      }
    }

    for (size_t k = 0; k < 30; ++k) {
      for (size_t band = 0; band < x.size(); ++band) {
        for (size_t ch = 0; ch < x[band].size(); ++ch) {
          RandomizeSampleVector(&random_generator, x[band][ch]);
        }
      }
      render_delay_buffer->Insert(x);
      if (k == 0) {
        render_delay_buffer->Reset();
      }
      render_delay_buffer->PrepareCaptureProcessing();
    }
    auto* const render_buffer = render_delay_buffer->GetRenderBuffer();

    for (size_t j = 0; j < G.re.size(); ++j) {
      G.re[j] = j / 10001.f;
    }
    for (size_t j = 1; j < G.im.size() - 1; ++j) {
      G.im[j] = j / 20001.f;
    }
    G.im[0] = 0.f;
    G.im[G.im.size() - 1] = 0.f;

    AdaptPartitions_Neon(*render_buffer, G, num_partitions, &H_Neon);
    AdaptPartitions(*render_buffer, G, num_partitions, &H_C);
    AdaptPartitions_Neon(*render_buffer, G, num_partitions, &H_Neon);
    AdaptPartitions(*render_buffer, G, num_partitions, &H_C);

    for (size_t p = 0; p < num_partitions; ++p) {
      for (size_t ch = 0; ch < num_render_channels; ++ch) {
        for (size_t j = 0; j < H_C[p][ch].re.size(); ++j) {
          EXPECT_FLOAT_EQ(H_C[p][ch].re[j], H_Neon[p][ch].re[j]);
          EXPECT_FLOAT_EQ(H_C[p][ch].im[j], H_Neon[p][ch].im[j]);
        }
      }
    }

    ApplyFilter_Neon(*render_buffer, num_partitions, H_Neon, &S_Neon);
    ApplyFilter(*render_buffer, num_partitions, H_C, &S_C);
    for (size_t j = 0; j < S_C.re.size(); ++j) {
      EXPECT_NEAR(S_C.re[j], S_Neon.re[j], fabs(S_C.re[j] * 0.00001f));
      EXPECT_NEAR(S_C.im[j], S_Neon.im[j], fabs(S_C.re[j] * 0.00001f));
    }
  }
}

// Verifies that the optimized method for frequency response computation is
// bitexact to the reference counterpart.
TEST_P(AdaptiveFirFilterOneTwoFourEightRenderChannels,
       ComputeFrequencyResponseNeonOptimization) {
  const size_t num_render_channels = GetParam();
  for (size_t num_partitions : {2, 5, 12, 30, 50}) {
    std::vector<std::vector<FftData>> H(
        num_partitions, std::vector<FftData>(num_render_channels));
    std::vector<std::array<float, kFftLengthBy2Plus1>> H2(num_partitions);
    std::vector<std::array<float, kFftLengthBy2Plus1>> H2_Neon(num_partitions);

    for (size_t p = 0; p < num_partitions; ++p) {
      for (size_t ch = 0; ch < num_render_channels; ++ch) {
        for (size_t k = 0; k < H[p][ch].re.size(); ++k) {
          H[p][ch].re[k] = k + p / 3.f + ch;
          H[p][ch].im[k] = p + k / 7.f - ch;
        }
      }
    }

    ComputeFrequencyResponse(num_partitions, H, &H2);
    ComputeFrequencyResponse_Neon(num_partitions, H, &H2_Neon);

    for (size_t p = 0; p < num_partitions; ++p) {
      for (size_t k = 0; k < H2[p].size(); ++k) {
        EXPECT_FLOAT_EQ(H2[p][k], H2_Neon[p][k]);
      }
    }
  }
}
#endif

#if defined(WEBRTC_ARCH_X86_FAMILY)
// Verifies that the optimized methods for filter adaptation are bitexact to
// their reference counterparts.
TEST_P(AdaptiveFirFilterOneTwoFourEightRenderChannels,
       FilterAdaptationSse2Optimizations) {
  const size_t num_render_channels = GetParam();
  constexpr int kSampleRateHz = 48000;
  constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);

  bool use_sse2 = (WebRtc_GetCPUInfo(kSSE2) != 0);
  if (use_sse2) {
    for (size_t num_partitions : {2, 5, 12, 30, 50}) {
      std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
          RenderDelayBuffer::Create(EchoCanceller3Config(), kSampleRateHz,
                                    num_render_channels));
      Random random_generator(42U);
      std::vector<std::vector<std::vector<float>>> x(
          kNumBands,
          std::vector<std::vector<float>>(num_render_channels,
                                          std::vector<float>(kBlockSize, 0.f)));
      FftData S_C;
      FftData S_Sse2;
      FftData G;
      Aec3Fft fft;
      std::vector<std::vector<FftData>> H_C(
          num_partitions, std::vector<FftData>(num_render_channels));
      std::vector<std::vector<FftData>> H_Sse2(
          num_partitions, std::vector<FftData>(num_render_channels));
      for (size_t p = 0; p < num_partitions; ++p) {
        for (size_t ch = 0; ch < num_render_channels; ++ch) {
          H_C[p][ch].Clear();
          H_Sse2[p][ch].Clear();
        }
      }

      for (size_t k = 0; k < 500; ++k) {
        for (size_t band = 0; band < x.size(); ++band) {
          for (size_t ch = 0; ch < x[band].size(); ++ch) {
            RandomizeSampleVector(&random_generator, x[band][ch]);
          }
        }
        render_delay_buffer->Insert(x);
        if (k == 0) {
          render_delay_buffer->Reset();
        }
        render_delay_buffer->PrepareCaptureProcessing();
        auto* const render_buffer = render_delay_buffer->GetRenderBuffer();

        ApplyFilter_Sse2(*render_buffer, num_partitions, H_Sse2, &S_Sse2);
        ApplyFilter(*render_buffer, num_partitions, H_C, &S_C);
        for (size_t j = 0; j < S_C.re.size(); ++j) {
          EXPECT_FLOAT_EQ(S_C.re[j], S_Sse2.re[j]);
          EXPECT_FLOAT_EQ(S_C.im[j], S_Sse2.im[j]);
        }

        std::for_each(G.re.begin(), G.re.end(),
                      [&](float& a) { a = random_generator.Rand<float>(); });
        std::for_each(G.im.begin(), G.im.end(),
                      [&](float& a) { a = random_generator.Rand<float>(); });

        AdaptPartitions_Sse2(*render_buffer, G, num_partitions, &H_Sse2);
        AdaptPartitions(*render_buffer, G, num_partitions, &H_C);

        for (size_t p = 0; p < num_partitions; ++p) {
          for (size_t ch = 0; ch < num_render_channels; ++ch) {
            for (size_t j = 0; j < H_C[p][ch].re.size(); ++j) {
              EXPECT_FLOAT_EQ(H_C[p][ch].re[j], H_Sse2[p][ch].re[j]);
              EXPECT_FLOAT_EQ(H_C[p][ch].im[j], H_Sse2[p][ch].im[j]);
            }
          }
        }
      }
    }
  }
}

// Verifies that the optimized method for frequency response computation is
// bitexact to the reference counterpart.
TEST_P(AdaptiveFirFilterOneTwoFourEightRenderChannels,
       ComputeFrequencyResponseSse2Optimization) {
  const size_t num_render_channels = GetParam();
  bool use_sse2 = (WebRtc_GetCPUInfo(kSSE2) != 0);
  if (use_sse2) {
    for (size_t num_partitions : {2, 5, 12, 30, 50}) {
      std::vector<std::vector<FftData>> H(
          num_partitions, std::vector<FftData>(num_render_channels));
      std::vector<std::array<float, kFftLengthBy2Plus1>> H2(num_partitions);
      std::vector<std::array<float, kFftLengthBy2Plus1>> H2_Sse2(
          num_partitions);

      for (size_t p = 0; p < num_partitions; ++p) {
        for (size_t ch = 0; ch < num_render_channels; ++ch) {
          for (size_t k = 0; k < H[p][ch].re.size(); ++k) {
            H[p][ch].re[k] = k + p / 3.f + ch;
            H[p][ch].im[k] = p + k / 7.f - ch;
          }
        }
      }

      ComputeFrequencyResponse(num_partitions, H, &H2);
      ComputeFrequencyResponse_Sse2(num_partitions, H, &H2_Sse2);

      for (size_t p = 0; p < num_partitions; ++p) {
        for (size_t k = 0; k < H2[p].size(); ++k) {
          EXPECT_FLOAT_EQ(H2[p][k], H2_Sse2[p][k]);
        }
      }
    }
  }
}

#endif

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
// Verifies that the check for non-null data dumper works.
TEST(AdaptiveFirFilterDeathTest, NullDataDumper) {
  EXPECT_DEATH(AdaptiveFirFilter(9, 9, 250, 1, DetectOptimization(), nullptr),
               "");
}

// Verifies that the check for non-null filter output works.
TEST(AdaptiveFirFilterDeathTest, NullFilterOutput) {
  ApmDataDumper data_dumper(42);
  AdaptiveFirFilter filter(9, 9, 250, 1, DetectOptimization(), &data_dumper);
  std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
      RenderDelayBuffer::Create(EchoCanceller3Config(), 48000, 1));
  EXPECT_DEATH(filter.Filter(*render_delay_buffer->GetRenderBuffer(), nullptr),
               "");
}

#endif

// Verifies that the filter statistics can be accessed when filter statistics
// are turned on.
TEST(AdaptiveFirFilterTest, FilterStatisticsAccess) {
  ApmDataDumper data_dumper(42);
  Aec3Optimization optimization = DetectOptimization();
  AdaptiveFirFilter filter(9, 9, 250, 1, optimization, &data_dumper);
  std::vector<std::array<float, kFftLengthBy2Plus1>> H2(
      filter.max_filter_size_partitions(),
      std::array<float, kFftLengthBy2Plus1>());
  for (auto& H2_k : H2) {
    H2_k.fill(0.f);
  }

  std::array<float, kFftLengthBy2Plus1> erl;
  ComputeErl(optimization, H2, erl);
  filter.ComputeFrequencyResponse(&H2);
}

// Verifies that the filter size if correctly repported.
TEST(AdaptiveFirFilterTest, FilterSize) {
  ApmDataDumper data_dumper(42);
  for (size_t filter_size = 1; filter_size < 5; ++filter_size) {
    AdaptiveFirFilter filter(filter_size, filter_size, 250, 1,
                             DetectOptimization(), &data_dumper);
    EXPECT_EQ(filter_size, filter.SizePartitions());
  }
}

class AdaptiveFirFilterMultiChannel
    : public ::testing::Test,
      public ::testing::WithParamInterface<std::tuple<size_t, size_t>> {};

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         AdaptiveFirFilterMultiChannel,
                         ::testing::Combine(::testing::Values(1, 4),
                                            ::testing::Values(1, 8)));

// Verifies that the filter is being able to properly filter a signal and to
// adapt its coefficients.
TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) {
  const size_t num_render_channels = std::get<0>(GetParam());
  const size_t num_capture_channels = std::get<1>(GetParam());

  constexpr int kSampleRateHz = 48000;
  constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);
  constexpr size_t kNumBlocksToProcessPerRenderChannel = 1000;

  ApmDataDumper data_dumper(42);
  EchoCanceller3Config config;

  if (num_render_channels == 33) {
    config.filter.refined = {13, 0.00005f, 0.0005f, 0.0001f, 2.f, 20075344.f};
    config.filter.coarse = {13, 0.1f, 20075344.f};
    config.filter.refined_initial = {12, 0.005f, 0.5f, 0.001f, 2.f, 20075344.f};
    config.filter.coarse_initial = {12, 0.7f, 20075344.f};
  }

  AdaptiveFirFilter filter(
      config.filter.refined.length_blocks, config.filter.refined.length_blocks,
      config.filter.config_change_duration_blocks, num_render_channels,
      DetectOptimization(), &data_dumper);
  std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>> H2(
      num_capture_channels, std::vector<std::array<float, kFftLengthBy2Plus1>>(
                                filter.max_filter_size_partitions(),
                                std::array<float, kFftLengthBy2Plus1>()));
  std::vector<std::vector<float>> h(
      num_capture_channels,
      std::vector<float>(
          GetTimeDomainLength(filter.max_filter_size_partitions()), 0.f));
  Aec3Fft fft;
  config.delay.default_delay = 1;
  std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
      RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels));
  CoarseFilterUpdateGain gain(config.filter.coarse,
                              config.filter.config_change_duration_blocks);
  Random random_generator(42U);
  std::vector<std::vector<std::vector<float>>> x(
      kNumBands, std::vector<std::vector<float>>(
                     num_render_channels, std::vector<float>(kBlockSize, 0.f)));
  std::vector<float> n(kBlockSize, 0.f);
  std::vector<float> y(kBlockSize, 0.f);
  AecState aec_state(EchoCanceller3Config{}, num_capture_channels);
  RenderSignalAnalyzer render_signal_analyzer(config);
  absl::optional<DelayEstimate> delay_estimate;
  std::vector<float> e(kBlockSize, 0.f);
  std::array<float, kFftLength> s_scratch;
  std::vector<SubtractorOutput> output(num_capture_channels);
  FftData S;
  FftData G;
  FftData E;
  std::vector<std::array<float, kFftLengthBy2Plus1>> Y2(num_capture_channels);
  std::vector<std::array<float, kFftLengthBy2Plus1>> E2_refined(
      num_capture_channels);
  std::array<float, kFftLengthBy2Plus1> E2_coarse;
  // [B,A] = butter(2,100/8000,'high')
  constexpr CascadedBiQuadFilter::BiQuadCoefficients
      kHighPassFilterCoefficients = {{0.97261f, -1.94523f, 0.97261f},
                                     {-1.94448f, 0.94598f}};
  for (auto& Y2_ch : Y2) {
    Y2_ch.fill(0.f);
  }
  for (auto& E2_refined_ch : E2_refined) {
    E2_refined_ch.fill(0.f);
  }
  E2_coarse.fill(0.f);
  for (auto& subtractor_output : output) {
    subtractor_output.Reset();
  }

  constexpr float kScale = 1.0f / kFftLengthBy2;

  for (size_t delay_samples : {0, 64, 150, 200, 301}) {
    std::vector<DelayBuffer<float>> delay_buffer(
        num_render_channels, DelayBuffer<float>(delay_samples));
    std::vector<std::unique_ptr<CascadedBiQuadFilter>> x_hp_filter(
        num_render_channels);
    for (size_t ch = 0; ch < num_render_channels; ++ch) {
      x_hp_filter[ch] = std::make_unique<CascadedBiQuadFilter>(
          kHighPassFilterCoefficients, 1);
    }
    CascadedBiQuadFilter y_hp_filter(kHighPassFilterCoefficients, 1);

    SCOPED_TRACE(ProduceDebugText(num_render_channels, delay_samples));
    const size_t num_blocks_to_process =
        kNumBlocksToProcessPerRenderChannel * num_render_channels;
    for (size_t j = 0; j < num_blocks_to_process; ++j) {
      std::fill(y.begin(), y.end(), 0.f);
      for (size_t ch = 0; ch < num_render_channels; ++ch) {
        RandomizeSampleVector(&random_generator, x[0][ch]);
        std::array<float, kBlockSize> y_channel;
        delay_buffer[ch].Delay(x[0][ch], y_channel);
        for (size_t k = 0; k < y.size(); ++k) {
          y[k] += y_channel[k] / num_render_channels;
        }
      }

      RandomizeSampleVector(&random_generator, n);
      const float noise_scaling = 1.f / 100.f / num_render_channels;
      for (size_t k = 0; k < y.size(); ++k) {
        y[k] += n[k] * noise_scaling;
      }

      for (size_t ch = 0; ch < num_render_channels; ++ch) {
        x_hp_filter[ch]->Process(x[0][ch]);
      }
      y_hp_filter.Process(y);

      render_delay_buffer->Insert(x);
      if (j == 0) {
        render_delay_buffer->Reset();
      }
      render_delay_buffer->PrepareCaptureProcessing();
      auto* const render_buffer = render_delay_buffer->GetRenderBuffer();

      render_signal_analyzer.Update(*render_buffer,
                                    aec_state.MinDirectPathFilterDelay());

      filter.Filter(*render_buffer, &S);
      fft.Ifft(S, &s_scratch);
      std::transform(y.begin(), y.end(), s_scratch.begin() + kFftLengthBy2,
                     e.begin(),
                     [&](float a, float b) { return a - b * kScale; });
      std::for_each(e.begin(), e.end(),
                    [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); });
      fft.ZeroPaddedFft(e, Aec3Fft::Window::kRectangular, &E);
      for (auto& o : output) {
        for (size_t k = 0; k < kBlockSize; ++k) {
          o.s_refined[k] = kScale * s_scratch[k + kFftLengthBy2];
        }
      }

      std::array<float, kFftLengthBy2Plus1> render_power;
      render_buffer->SpectralSum(filter.SizePartitions(), &render_power);
      gain.Compute(render_power, render_signal_analyzer, E,
                   filter.SizePartitions(), false, &G);
      filter.Adapt(*render_buffer, G, &h[0]);
      aec_state.HandleEchoPathChange(EchoPathVariability(
          false, EchoPathVariability::DelayAdjustment::kNone, false));

      filter.ComputeFrequencyResponse(&H2[0]);
      aec_state.Update(delay_estimate, H2, h, *render_buffer, E2_refined, Y2,
                       output);
    }
    // Verify that the filter is able to perform well.
    EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
              std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
  }
}

}  // namespace aec3
}  // namespace webrtc
