/*
 *  Copyright (c) 2013 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/resampler/push_sinc_resampler.h"

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <memory>
#include <tuple>

#include "common_audio/include/audio_util.h"
#include "common_audio/resampler/sinc_resampler.h"
#include "common_audio/resampler/sinusoidal_linear_chirp_source.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

// Almost all conversions have an RMS error of around -14 dbFS.
constexpr double kResamplingRMSError = -14.42;

// Used to convert errors to dbFS.
template <typename T>
T DBFS(T x) {
  return 20 * std::log10(x);
}

}  // namespace

class PushSincResamplerTest
    : public ::testing::TestWithParam<std::tuple<int, int, double, double>> {
 public:
  PushSincResamplerTest()
      : input_rate_(std::get<0>(GetParam())),
        output_rate_(std::get<1>(GetParam())),
        rms_error_(std::get<2>(GetParam())),
        low_freq_error_(std::get<3>(GetParam())) {}

  ~PushSincResamplerTest() override {}

 protected:
  void ResampleBenchmarkTest(bool int_format);
  void ResampleTest(bool int_format);

  int input_rate_;
  int output_rate_;
  double rms_error_;
  double low_freq_error_;
};

class ZeroSource : public SincResamplerCallback {
 public:
  void Run(size_t frames, float* destination) override {
    std::memset(destination, 0, sizeof(float) * frames);
  }
};

void PushSincResamplerTest::ResampleBenchmarkTest(bool int_format) {
  const size_t input_samples = static_cast<size_t>(input_rate_ / 100);
  const size_t output_samples = static_cast<size_t>(output_rate_ / 100);
  const int kResampleIterations = 500000;

  // Source for data to be resampled.
  ZeroSource resampler_source;

  std::unique_ptr<float[]> resampled_destination(new float[output_samples]);
  std::unique_ptr<float[]> source(new float[input_samples]);
  std::unique_ptr<int16_t[]> source_int(new int16_t[input_samples]);
  std::unique_ptr<int16_t[]> destination_int(new int16_t[output_samples]);

  resampler_source.Run(input_samples, source.get());
  for (size_t i = 0; i < input_samples; ++i) {
    source_int[i] = static_cast<int16_t>(floor(32767 * source[i] + 0.5));
  }

  printf("Benchmarking %d iterations of %d Hz -> %d Hz:\n", kResampleIterations,
         input_rate_, output_rate_);
  const double io_ratio = input_rate_ / static_cast<double>(output_rate_);
  SincResampler sinc_resampler(io_ratio, SincResampler::kDefaultRequestSize,
                               &resampler_source);
  int64_t start = TimeNanos();
  for (int i = 0; i < kResampleIterations; ++i) {
    sinc_resampler.Resample(output_samples, resampled_destination.get());
  }
  double total_time_sinc_us = (TimeNanos() - start) / kNumNanosecsPerMicrosec;
  printf("SincResampler took %.2f us per frame.\n",
         total_time_sinc_us / kResampleIterations);

  PushSincResampler resampler(input_samples, output_samples);
  start = TimeNanos();
  if (int_format) {
    for (int i = 0; i < kResampleIterations; ++i) {
      EXPECT_EQ(output_samples,
                resampler.Resample(source_int.get(), input_samples,
                                   destination_int.get(), output_samples));
    }
  } else {
    for (int i = 0; i < kResampleIterations; ++i) {
      EXPECT_EQ(output_samples, resampler.Resample(source.get(), input_samples,
                                                   resampled_destination.get(),
                                                   output_samples));
    }
  }
  double total_time_us = (TimeNanos() - start) / kNumNanosecsPerMicrosec;
  printf(
      "PushSincResampler took %.2f us per frame; which is a %.1f%% overhead "
      "on SincResampler.\n\n",
      total_time_us / kResampleIterations,
      (total_time_us - total_time_sinc_us) / total_time_sinc_us * 100);
}

// Disabled because it takes too long to run routinely. Use for performance
// benchmarking when needed.
TEST_P(PushSincResamplerTest, DISABLED_BenchmarkInt) {
  ResampleBenchmarkTest(true);
}

TEST_P(PushSincResamplerTest, DISABLED_BenchmarkFloat) {
  ResampleBenchmarkTest(false);
}

// Tests resampling using a given input and output sample rate.
void PushSincResamplerTest::ResampleTest(bool int_format) {
  // Make comparisons using one second of data.
  static const double kTestDurationSecs = 1;
  // 10 ms blocks.
  const size_t kNumBlocks = static_cast<size_t>(kTestDurationSecs * 100);
  const size_t input_block_size = static_cast<size_t>(input_rate_ / 100);
  const size_t output_block_size = static_cast<size_t>(output_rate_ / 100);
  const size_t input_samples =
      static_cast<size_t>(kTestDurationSecs * input_rate_);
  const size_t output_samples =
      static_cast<size_t>(kTestDurationSecs * output_rate_);

  // Nyquist frequency for the input sampling rate.
  const double input_nyquist_freq = 0.5 * input_rate_;

  // Source for data to be resampled.
  SinusoidalLinearChirpSource resampler_source(input_rate_, input_samples,
                                               input_nyquist_freq, 0);

  PushSincResampler resampler(input_block_size, output_block_size);

  // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to
  // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes.
  std::unique_ptr<float[]> resampled_destination(new float[output_samples]);
  std::unique_ptr<float[]> pure_destination(new float[output_samples]);
  std::unique_ptr<float[]> source(new float[input_samples]);
  std::unique_ptr<int16_t[]> source_int(new int16_t[input_block_size]);
  std::unique_ptr<int16_t[]> destination_int(new int16_t[output_block_size]);

  // The sinc resampler has an implicit delay of approximately half the kernel
  // size at the input sample rate. By moving to a push model, this delay
  // becomes explicit and is managed by zero-stuffing in PushSincResampler. We
  // deal with it in the test by delaying the "pure" source to match. It must be
  // checked before the first call to Resample(), because ChunkSize() will
  // change afterwards.
  const size_t output_delay_samples =
      output_block_size - resampler.get_resampler_for_testing()->ChunkSize();

  // Generate resampled signal.
  // With the PushSincResampler, we produce the signal block-by-10ms-block
  // rather than in a single pass, to exercise how it will be used in WebRTC.
  resampler_source.Run(input_samples, source.get());
  if (int_format) {
    for (size_t i = 0; i < kNumBlocks; ++i) {
      FloatToS16(&source[i * input_block_size], input_block_size,
                 source_int.get());
      EXPECT_EQ(output_block_size,
                resampler.Resample(source_int.get(), input_block_size,
                                   destination_int.get(), output_block_size));
      S16ToFloat(destination_int.get(), output_block_size,
                 &resampled_destination[i * output_block_size]);
    }
  } else {
    for (size_t i = 0; i < kNumBlocks; ++i) {
      EXPECT_EQ(
          output_block_size,
          resampler.Resample(&source[i * input_block_size], input_block_size,
                             &resampled_destination[i * output_block_size],
                             output_block_size));
    }
  }

  // Generate pure signal.
  SinusoidalLinearChirpSource pure_source(
      output_rate_, output_samples, input_nyquist_freq, output_delay_samples);
  pure_source.Run(output_samples, pure_destination.get());

  // Range of the Nyquist frequency (0.5 * min(input rate, output_rate)) which
  // we refer to as low and high.
  static const double kLowFrequencyNyquistRange = 0.7;
  static const double kHighFrequencyNyquistRange = 0.9;

  // Calculate Root-Mean-Square-Error and maximum error for the resampling.
  double sum_of_squares = 0;
  double low_freq_max_error = 0;
  double high_freq_max_error = 0;
  int minimum_rate = std::min(input_rate_, output_rate_);
  double low_frequency_range = kLowFrequencyNyquistRange * 0.5 * minimum_rate;
  double high_frequency_range = kHighFrequencyNyquistRange * 0.5 * minimum_rate;

  for (size_t i = 0; i < output_samples; ++i) {
    double error = fabs(resampled_destination[i] - pure_destination[i]);

    if (pure_source.Frequency(i) < low_frequency_range) {
      if (error > low_freq_max_error)
        low_freq_max_error = error;
    } else if (pure_source.Frequency(i) < high_frequency_range) {
      if (error > high_freq_max_error)
        high_freq_max_error = error;
    }
    // TODO(dalecurtis): Sanity check frequencies > kHighFrequencyNyquistRange.

    sum_of_squares += error * error;
  }

  double rms_error = sqrt(sum_of_squares / output_samples);

  rms_error = DBFS(rms_error);
  // In order to keep the thresholds in this test identical to SincResamplerTest
  // we must account for the quantization error introduced by truncating from
  // float to int. This happens twice (once at input and once at output) and we
  // allow for the maximum possible error (1 / 32767) for each step.
  //
  // The quantization error is insignificant in the RMS calculation so does not
  // need to be accounted for there.
  low_freq_max_error = DBFS(low_freq_max_error - 2.0 / 32767);
  high_freq_max_error = DBFS(high_freq_max_error - 2.0 / 32767);

  EXPECT_LE(rms_error, rms_error_);
  EXPECT_LE(low_freq_max_error, low_freq_error_);

  // All conversions currently have a high frequency error around -6 dbFS.
  static const double kHighFrequencyMaxError = -6.01;
  EXPECT_LE(high_freq_max_error, kHighFrequencyMaxError);
}

TEST_P(PushSincResamplerTest, ResampleInt) {
  ResampleTest(true);
}

TEST_P(PushSincResamplerTest, ResampleFloat) {
  ResampleTest(false);
}

// Thresholds chosen arbitrarily based on what each resampling reported during
// testing.  All thresholds are in dbFS, http://en.wikipedia.org/wiki/DBFS.
INSTANTIATE_TEST_SUITE_P(
    PushSincResamplerTest,
    PushSincResamplerTest,
    ::testing::Values(
        // First run through the rates tested in SincResamplerTest. The
        // thresholds are identical.
        //
        // We don't directly test rates which fail to provide an integer number
        // of samples in a 10 ms block (22050 and 11025 Hz), they are replaced
        // by nearby rates in order to simplify testing.
        //
        // The PushSincResampler is in practice sample rate agnostic and derives
        // resampling ratios from the block size, which for WebRTC purposes are
        // blocks of floor(sample_rate/100) samples. So the 22050 Hz case is
        // treated identically to the 22000 Hz case. Direct tests of 22050 Hz
        // have to account for the simulated clock drift induced by the
        // resampler inferring an incorrect sample rate ratio, without testing
        // anything new within the resampler itself.

        // To 22kHz
        std::make_tuple(8000, 22000, kResamplingRMSError, -62.73),
        std::make_tuple(11000, 22000, kResamplingRMSError, -74.17),
        std::make_tuple(16000, 22000, kResamplingRMSError, -62.54),
        std::make_tuple(22000, 22000, kResamplingRMSError, -73.53),
        std::make_tuple(32000, 22000, kResamplingRMSError, -46.45),
        std::make_tuple(44100, 22000, kResamplingRMSError, -28.34),
        std::make_tuple(48000, 22000, -15.01, -25.56),
        std::make_tuple(96000, 22000, -18.49, -13.30),
        std::make_tuple(192000, 22000, -20.50, -9.20),

        // To 44.1kHz
        std::make_tuple(8000, 44100, kResamplingRMSError, -62.73),
        std::make_tuple(11000, 44100, kResamplingRMSError, -63.57),
        std::make_tuple(16000, 44100, kResamplingRMSError, -62.54),
        std::make_tuple(22000, 44100, kResamplingRMSError, -62.73),
        std::make_tuple(32000, 44100, kResamplingRMSError, -63.32),
        std::make_tuple(44100, 44100, kResamplingRMSError, -73.53),
        std::make_tuple(48000, 44100, -15.01, -64.04),
        std::make_tuple(96000, 44100, -18.49, -25.51),
        std::make_tuple(192000, 44100, -20.50, -13.31),

        // To 48kHz
        std::make_tuple(8000, 48000, kResamplingRMSError, -63.43),
        std::make_tuple(11000, 48000, kResamplingRMSError, -63.96),
        std::make_tuple(16000, 48000, kResamplingRMSError, -63.96),
        std::make_tuple(22000, 48000, kResamplingRMSError, -63.80),
        std::make_tuple(32000, 48000, kResamplingRMSError, -64.04),
        std::make_tuple(44100, 48000, kResamplingRMSError, -62.63),
        std::make_tuple(48000, 48000, kResamplingRMSError, -73.52),
        std::make_tuple(96000, 48000, -18.40, -28.44),
        std::make_tuple(192000, 48000, -20.43, -14.11),

        // To 96kHz
        std::make_tuple(8000, 96000, kResamplingRMSError, -63.19),
        std::make_tuple(11000, 96000, kResamplingRMSError, -63.89),
        std::make_tuple(16000, 96000, kResamplingRMSError, -63.39),
        std::make_tuple(22000, 96000, kResamplingRMSError, -63.39),
        std::make_tuple(32000, 96000, kResamplingRMSError, -63.95),
        std::make_tuple(44100, 96000, kResamplingRMSError, -62.63),
        std::make_tuple(48000, 96000, kResamplingRMSError, -73.52),
        std::make_tuple(96000, 96000, kResamplingRMSError, -73.52),
        std::make_tuple(192000, 96000, kResamplingRMSError, -28.41),

        // To 192kHz
        std::make_tuple(8000, 192000, kResamplingRMSError, -63.10),
        std::make_tuple(11000, 192000, kResamplingRMSError, -63.17),
        std::make_tuple(16000, 192000, kResamplingRMSError, -63.14),
        std::make_tuple(22000, 192000, kResamplingRMSError, -63.14),
        std::make_tuple(32000, 192000, kResamplingRMSError, -63.38),
        std::make_tuple(44100, 192000, kResamplingRMSError, -62.63),
        std::make_tuple(48000, 192000, kResamplingRMSError, -73.44),
        std::make_tuple(96000, 192000, kResamplingRMSError, -73.52),
        std::make_tuple(192000, 192000, kResamplingRMSError, -73.52),

        // Next run through some additional cases interesting for WebRTC.
        // We skip some extreme downsampled cases (192 -> {8, 16}, 96 -> 8)
        // because they violate `kHighFrequencyMaxError`, which is not
        // unexpected. It's very unlikely that we'll see these conversions in
        // practice anyway.

        // To 8 kHz
        std::make_tuple(8000, 8000, kResamplingRMSError, -75.50),
        std::make_tuple(16000, 8000, -18.56, -28.79),
        std::make_tuple(32000, 8000, -20.36, -14.13),
        std::make_tuple(44100, 8000, -21.00, -11.39),
        std::make_tuple(48000, 8000, -20.96, -11.04),

        // To 16 kHz
        std::make_tuple(8000, 16000, kResamplingRMSError, -70.30),
        std::make_tuple(11000, 16000, kResamplingRMSError, -72.31),
        std::make_tuple(16000, 16000, kResamplingRMSError, -75.51),
        std::make_tuple(22000, 16000, kResamplingRMSError, -52.08),
        std::make_tuple(32000, 16000, -18.48, -28.59),
        std::make_tuple(44100, 16000, -19.30, -19.67),
        std::make_tuple(48000, 16000, -19.81, -18.11),
        std::make_tuple(96000, 16000, -20.95, -10.9596),

        // To 32 kHz
        std::make_tuple(8000, 32000, kResamplingRMSError, -70.30),
        std::make_tuple(11000, 32000, kResamplingRMSError, -71.34),
        std::make_tuple(16000, 32000, kResamplingRMSError, -75.51),
        std::make_tuple(22000, 32000, kResamplingRMSError, -72.05),
        std::make_tuple(32000, 32000, kResamplingRMSError, -75.51),
        std::make_tuple(44100, 32000, -16.44, -51.0349),
        std::make_tuple(48000, 32000, -16.90, -43.9967),
        std::make_tuple(96000, 32000, -19.61, -18.04),
        std::make_tuple(192000, 32000, -21.02, -10.94)));

}  // namespace webrtc
