/*
 *  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 <cmath>
#include <cstring>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/include/audio_util.h"
#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
#include "webrtc/common_audio/resampler/sinusoidal_linear_chirp_source.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/typedefs.h"

namespace webrtc {
namespace {

// Almost all conversions have an RMS error of around -14 dbFS.
const 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<
    ::testing::tuple<int, int, double, double>> {
 public:
  PushSincResamplerTest()
      : input_rate_(::testing::get<0>(GetParam())),
        output_rate_(::testing::get<1>(GetParam())),
        rms_error_(::testing::get<2>(GetParam())),
        low_freq_error_(::testing::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) {
    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;

  rtc::scoped_ptr<float[]> resampled_destination(new float[output_samples]);
  rtc::scoped_ptr<float[]> source(new float[input_samples]);
  rtc::scoped_ptr<int16_t[]> source_int(new int16_t[input_samples]);
  rtc::scoped_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);
  TickTime start = TickTime::Now();
  for (int i = 0; i < kResampleIterations; ++i) {
    sinc_resampler.Resample(output_samples, resampled_destination.get());
  }
  double total_time_sinc_us = (TickTime::Now() - start).Microseconds();
  printf("SincResampler took %.2f us per frame.\n",
         total_time_sinc_us / kResampleIterations);

  PushSincResampler resampler(input_samples, output_samples);
  start = TickTime::Now();
  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 = (TickTime::Now() - start).Microseconds();
  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.
  rtc::scoped_ptr<float[]> resampled_destination(new float[output_samples]);
  rtc::scoped_ptr<float[]> pure_destination(new float[output_samples]);
  rtc::scoped_ptr<float[]> source(new float[input_samples]);
  rtc::scoped_ptr<int16_t[]> source_int(new int16_t[input_block_size]);
  rtc::scoped_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.02;
  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_CASE_P(
    PushSincResamplerTest,
    PushSincResamplerTest,
    ::testing::Values(
        // First run through the rates tested in SincResamplerTest. The
        // thresholds are identical.
        //
        // We don't test rates which fail to provide an integer number of
        // samples in a 10 ms block (22050 and 11025 Hz). WebRTC doesn't support
        // these rates in any case (for the same reason).

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

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

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

        // To 192kHz
        ::testing::make_tuple(8000, 192000, kResamplingRMSError, -63.10),
        ::testing::make_tuple(16000, 192000, kResamplingRMSError, -63.14),
        ::testing::make_tuple(32000, 192000, kResamplingRMSError, -63.38),
        ::testing::make_tuple(44100, 192000, kResamplingRMSError, -62.63),
        ::testing::make_tuple(48000, 192000, kResamplingRMSError, -73.44),
        ::testing::make_tuple(96000, 192000, kResamplingRMSError, -73.52),
        ::testing::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
        ::testing::make_tuple(8000, 8000, kResamplingRMSError, -75.50),
        ::testing::make_tuple(16000, 8000, -18.56, -28.79),
        ::testing::make_tuple(32000, 8000, -20.36, -14.13),
        ::testing::make_tuple(44100, 8000, -21.00, -11.39),
        ::testing::make_tuple(48000, 8000, -20.96, -11.04),

        // To 16 kHz
        ::testing::make_tuple(8000, 16000, kResamplingRMSError, -70.30),
        ::testing::make_tuple(16000, 16000, kResamplingRMSError, -75.51),
        ::testing::make_tuple(32000, 16000, -18.48, -28.59),
        ::testing::make_tuple(44100, 16000, -19.30, -19.67),
        ::testing::make_tuple(48000, 16000, -19.81, -18.11),
        ::testing::make_tuple(96000, 16000, -20.95, -10.96),

        // To 32 kHz
        ::testing::make_tuple(8000, 32000, kResamplingRMSError, -70.30),
        ::testing::make_tuple(16000, 32000, kResamplingRMSError, -75.51),
        ::testing::make_tuple(32000, 32000, kResamplingRMSError, -75.51),
        ::testing::make_tuple(44100, 32000, -16.44, -51.10),
        ::testing::make_tuple(48000, 32000, -16.90, -44.03),
        ::testing::make_tuple(96000, 32000, -19.61, -18.04),
        ::testing::make_tuple(192000, 32000, -21.02, -10.94)));

}  // namespace webrtc
