/*
 *  Copyright (c) 2016 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/rms_level.h"

#include <cmath>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <numbers>
#include <vector>

#include "api/array_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"

namespace webrtc {
namespace {
constexpr int kSampleRateHz = 48000;
constexpr size_t kBlockSizeSamples = kSampleRateHz / 100;

std::unique_ptr<RmsLevel> RunTest(ArrayView<const int16_t> input) {
  std::unique_ptr<RmsLevel> level(new RmsLevel);
  for (size_t n = 0; n + kBlockSizeSamples <= input.size();
       n += kBlockSizeSamples) {
    level->Analyze(input.subview(n, kBlockSizeSamples));
  }
  return level;
}

std::unique_ptr<RmsLevel> RunTest(ArrayView<const float> input) {
  std::unique_ptr<RmsLevel> level(new RmsLevel);
  for (size_t n = 0; n + kBlockSizeSamples <= input.size();
       n += kBlockSizeSamples) {
    level->Analyze(input.subview(n, kBlockSizeSamples));
  }
  return level;
}

std::vector<int16_t> CreateInt16Sinusoid(int frequency_hz,
                                         int amplitude,
                                         size_t num_samples) {
  std::vector<int16_t> x(num_samples);
  for (size_t n = 0; n < num_samples; ++n) {
    x[n] = saturated_cast<int16_t>(
        amplitude *
        std::sin(2 * std::numbers::pi * n * frequency_hz / kSampleRateHz));
  }
  return x;
}

std::vector<float> CreateFloatSinusoid(int frequency_hz,
                                       int amplitude,
                                       size_t num_samples) {
  std::vector<int16_t> x16 =
      CreateInt16Sinusoid(frequency_hz, amplitude, num_samples);
  std::vector<float> x(x16.size());
  for (size_t n = 0; n < x.size(); ++n) {
    x[n] = x16[n];
  }
  return x;
}

}  // namespace

TEST(RmsLevelTest, VerifyIndentityBetweenFloatAndFix) {
  auto x_f = CreateFloatSinusoid(1000, INT16_MAX, kSampleRateHz);
  auto x_i = CreateFloatSinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level_f = RunTest(x_f);
  auto level_i = RunTest(x_i);
  int avg_i = level_i->Average();
  int avg_f = level_f->Average();
  EXPECT_EQ(3, avg_i);  // -3 dBFS
  EXPECT_EQ(avg_f, avg_i);
}

TEST(RmsLevelTest, Run1000HzFullScale) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  EXPECT_EQ(3, level->Average());  // -3 dBFS
}

TEST(RmsLevelTest, Run1000HzFullScaleAverageAndPeak) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  auto stats = level->AverageAndPeak();
  EXPECT_EQ(3, stats.average);  // -3 dBFS
  EXPECT_EQ(3, stats.peak);
}

TEST(RmsLevelTest, Run1000HzHalfScale) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX / 2, kSampleRateHz);
  auto level = RunTest(x);
  EXPECT_EQ(9, level->Average());  // -9 dBFS
}

TEST(RmsLevelTest, RunZeros) {
  std::vector<int16_t> x(kSampleRateHz, 0);  // 1 second of pure silence.
  auto level = RunTest(x);
  EXPECT_EQ(127, level->Average());
}

TEST(RmsLevelTest, RunZerosAverageAndPeak) {
  std::vector<int16_t> x(kSampleRateHz, 0);  // 1 second of pure silence.
  auto level = RunTest(x);
  auto stats = level->AverageAndPeak();
  EXPECT_EQ(127, stats.average);
  EXPECT_EQ(127, stats.peak);
}

TEST(RmsLevelTest, NoSamples) {
  RmsLevel level;
  EXPECT_EQ(127, level.Average());  // Return minimum if no samples are given.
}

TEST(RmsLevelTest, NoSamplesAverageAndPeak) {
  RmsLevel level;
  auto stats = level.AverageAndPeak();
  EXPECT_EQ(127, stats.average);
  EXPECT_EQ(127, stats.peak);
}

TEST(RmsLevelTest, PollTwice) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  level->Average();
  EXPECT_EQ(127, level->Average());  // Stats should be reset at this point.
}

TEST(RmsLevelTest, Reset) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  level->Reset();
  EXPECT_EQ(127, level->Average());  // Stats should be reset at this point.
}

// Inserts 1 second of full-scale sinusoid, followed by 1 second of muted.
TEST(RmsLevelTest, ProcessMuted) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  const size_t kBlocksPerSecond =
      CheckedDivExact(static_cast<size_t>(kSampleRateHz), kBlockSizeSamples);
  for (size_t i = 0; i < kBlocksPerSecond; ++i) {
    level->AnalyzeMuted(kBlockSizeSamples);
  }
  EXPECT_EQ(6, level->Average());  // Average RMS halved due to the silence.
}

// Digital silence must yield 127 and anything else should yield 126 or lower.
TEST(RmsLevelTest, OnlyDigitalSilenceIs127) {
  std::vector<int16_t> test_buffer(kSampleRateHz, 0);
  auto level = RunTest(test_buffer);
  EXPECT_EQ(127, level->Average());
  // Change one sample to something other than 0 to make the buffer not strictly
  // represent digital silence.
  test_buffer[0] = 1;
  level = RunTest(test_buffer);
  EXPECT_LT(level->Average(), 127);
}

// Inserts 1 second of half-scale sinusoid, follwed by 10 ms of full-scale, and
// finally 1 second of half-scale again. Expect the average to be -9 dBFS due
// to the vast majority of the signal being half-scale, and the peak to be
// -3 dBFS.
TEST(RmsLevelTest, RunHalfScaleAndInsertFullScale) {
  auto half_scale = CreateInt16Sinusoid(1000, INT16_MAX / 2, kSampleRateHz);
  auto full_scale = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz / 100);
  auto x = half_scale;
  x.insert(x.end(), full_scale.begin(), full_scale.end());
  x.insert(x.end(), half_scale.begin(), half_scale.end());
  ASSERT_EQ(static_cast<size_t>(2 * kSampleRateHz + kSampleRateHz / 100),
            x.size());
  auto level = RunTest(x);
  auto stats = level->AverageAndPeak();
  EXPECT_EQ(9, stats.average);
  EXPECT_EQ(3, stats.peak);
}

TEST(RmsLevelTest, ResetOnBlockSizeChange) {
  auto x = CreateInt16Sinusoid(1000, INT16_MAX, kSampleRateHz);
  auto level = RunTest(x);
  // Create a new signal with half amplitude, but double block length.
  auto y = CreateInt16Sinusoid(1000, INT16_MAX / 2, kBlockSizeSamples * 2);
  level->Analyze(y);
  auto stats = level->AverageAndPeak();
  // Expect all stats to only be influenced by the last signal (y), since the
  // changed block size should reset the stats.
  EXPECT_EQ(9, stats.average);
  EXPECT_EQ(9, stats.peak);
}

}  // namespace webrtc
