/*
 *  Copyright (c) 2018 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/agc2/rnn_vad/spectral_features.h"

#include <algorithm>

#include "modules/audio_processing/agc2/rnn_vad/test_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_compare.h"
// TODO(bugs.webrtc.org/8948): Add when the issue is fixed.
// #include "test/fpe_observer.h"
#include "test/gtest.h"

namespace webrtc {
namespace rnn_vad {
namespace test {
namespace {

constexpr int kTestFeatureVectorSize = kNumBands + 3 * kNumLowerBands + 1;

// Writes non-zero sample values.
void WriteTestData(rtc::ArrayView<float> samples) {
  for (int i = 0; rtc::SafeLt(i, samples.size()); ++i) {
    samples[i] = i % 100;
  }
}

rtc::ArrayView<float, kNumBands - kNumLowerBands> GetHigherBandsSpectrum(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return {feature_vector->data() + kNumLowerBands, kNumBands - kNumLowerBands};
}

rtc::ArrayView<float, kNumLowerBands> GetAverage(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return {feature_vector->data(), kNumLowerBands};
}

rtc::ArrayView<float, kNumLowerBands> GetFirstDerivative(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return {feature_vector->data() + kNumBands, kNumLowerBands};
}

rtc::ArrayView<float, kNumLowerBands> GetSecondDerivative(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return {feature_vector->data() + kNumBands + kNumLowerBands, kNumLowerBands};
}

rtc::ArrayView<float, kNumLowerBands> GetCepstralCrossCorrelation(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return {feature_vector->data() + kNumBands + 2 * kNumLowerBands,
          kNumLowerBands};
}

float* GetCepstralVariability(
    std::array<float, kTestFeatureVectorSize>* feature_vector) {
  return feature_vector->data() + kNumBands + 3 * kNumLowerBands;
}

constexpr float kInitialFeatureVal = -9999.f;

}  // namespace

// Checks that silence is detected when the input signal is 0 and that the
// feature vector is written only if the input signal is not tagged as silence.
TEST(RnnVadTest, SpectralFeaturesWithAndWithoutSilence) {
  // Initialize.
  SpectralFeaturesExtractor sfe;
  std::array<float, kFrameSize20ms24kHz> samples;
  rtc::ArrayView<float, kFrameSize20ms24kHz> samples_view(samples);
  bool is_silence;
  std::array<float, kTestFeatureVectorSize> feature_vector;

  // Write an initial value in the feature vector to detect changes.
  std::fill(feature_vector.begin(), feature_vector.end(), kInitialFeatureVal);

  // TODO(bugs.webrtc.org/8948): Add when the issue is fixed.
  // FloatingPointExceptionObserver fpe_observer;

  // With silence.
  std::fill(samples.begin(), samples.end(), 0.f);
  is_silence = sfe.CheckSilenceComputeFeatures(
      samples_view, samples_view, GetHigherBandsSpectrum(&feature_vector),
      GetAverage(&feature_vector), GetFirstDerivative(&feature_vector),
      GetSecondDerivative(&feature_vector),
      GetCepstralCrossCorrelation(&feature_vector),
      GetCepstralVariability(&feature_vector));
  // Silence is expected, the output won't be overwritten.
  EXPECT_TRUE(is_silence);
  EXPECT_TRUE(std::all_of(feature_vector.begin(), feature_vector.end(),
                          [](float x) { return x == kInitialFeatureVal; }));

  // With no silence.
  WriteTestData(samples);
  is_silence = sfe.CheckSilenceComputeFeatures(
      samples_view, samples_view, GetHigherBandsSpectrum(&feature_vector),
      GetAverage(&feature_vector), GetFirstDerivative(&feature_vector),
      GetSecondDerivative(&feature_vector),
      GetCepstralCrossCorrelation(&feature_vector),
      GetCepstralVariability(&feature_vector));
  // Silence is not expected, the output will be overwritten.
  EXPECT_FALSE(is_silence);
  EXPECT_FALSE(std::all_of(feature_vector.begin(), feature_vector.end(),
                           [](float x) { return x == kInitialFeatureVal; }));
}

// Feeds a constant input signal and checks that:
// - the cepstral coefficients average does not change;
// - the derivatives are zero;
// - the cepstral variability score does not change.
TEST(RnnVadTest, CepstralFeaturesConstantAverageZeroDerivative) {
  // Initialize.
  SpectralFeaturesExtractor sfe;
  std::array<float, kFrameSize20ms24kHz> samples;
  rtc::ArrayView<float, kFrameSize20ms24kHz> samples_view(samples);
  WriteTestData(samples);
  bool is_silence;

  // Fill the spectral features with test data.
  std::array<float, kTestFeatureVectorSize> feature_vector;
  for (int i = 0; i < kCepstralCoeffsHistorySize; ++i) {
    is_silence = sfe.CheckSilenceComputeFeatures(
        samples_view, samples_view, GetHigherBandsSpectrum(&feature_vector),
        GetAverage(&feature_vector), GetFirstDerivative(&feature_vector),
        GetSecondDerivative(&feature_vector),
        GetCepstralCrossCorrelation(&feature_vector),
        GetCepstralVariability(&feature_vector));
  }

  // Feed the test data one last time but using a different output vector.
  std::array<float, kTestFeatureVectorSize> feature_vector_last;
  is_silence = sfe.CheckSilenceComputeFeatures(
      samples_view, samples_view, GetHigherBandsSpectrum(&feature_vector_last),
      GetAverage(&feature_vector_last),
      GetFirstDerivative(&feature_vector_last),
      GetSecondDerivative(&feature_vector_last),
      GetCepstralCrossCorrelation(&feature_vector_last),
      GetCepstralVariability(&feature_vector_last));

  // Average is unchanged.
  ExpectEqualFloatArray({feature_vector.data(), kNumLowerBands},
                        {feature_vector_last.data(), kNumLowerBands});
  // First and second derivatives are zero.
  constexpr std::array<float, kNumLowerBands> zeros{};
  ExpectEqualFloatArray(
      {feature_vector_last.data() + kNumBands, kNumLowerBands}, zeros);
  ExpectEqualFloatArray(
      {feature_vector_last.data() + kNumBands + kNumLowerBands, kNumLowerBands},
      zeros);
  // Variability is unchanged.
  EXPECT_FLOAT_EQ(feature_vector[kNumBands + 3 * kNumLowerBands],
                  feature_vector_last[kNumBands + 3 * kNumLowerBands]);
}

}  // namespace test
}  // namespace rnn_vad
}  // namespace webrtc
