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

#include <array>
#include <utility>

#include "api/array_view.h"
#include "common_audio/resampler/include/push_resampler.h"
#include "modules/audio_processing/agc2/agc2_common.h"
#include "modules/audio_processing/agc2/rnn_vad/common.h"
#include "modules/audio_processing/agc2/rnn_vad/features_extraction.h"
#include "modules/audio_processing/agc2/rnn_vad/rnn.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace {

constexpr int kNumFramesPerSecond = 100;

class MonoVadImpl : public VoiceActivityDetectorWrapper::MonoVad {
 public:
  explicit MonoVadImpl(const AvailableCpuFeatures& cpu_features)
      : features_extractor_(cpu_features), rnn_vad_(cpu_features) {}
  MonoVadImpl(const MonoVadImpl&) = delete;
  MonoVadImpl& operator=(const MonoVadImpl&) = delete;
  ~MonoVadImpl() = default;

  int SampleRateHz() const override { return rnn_vad::kSampleRate24kHz; }
  void Reset() override { rnn_vad_.Reset(); }
  float Analyze(rtc::ArrayView<const float> frame) override {
    RTC_DCHECK_EQ(frame.size(), rnn_vad::kFrameSize10ms24kHz);
    std::array<float, rnn_vad::kFeatureVectorSize> feature_vector;
    const bool is_silence = features_extractor_.CheckSilenceComputeFeatures(
        /*samples=*/{frame.data(), rnn_vad::kFrameSize10ms24kHz},
        feature_vector);
    return rnn_vad_.ComputeVadProbability(feature_vector, is_silence);
  }

 private:
  rnn_vad::FeaturesExtractor features_extractor_;
  rnn_vad::RnnVad rnn_vad_;
};

}  // namespace

VoiceActivityDetectorWrapper::VoiceActivityDetectorWrapper(
    int vad_reset_period_ms,
    const AvailableCpuFeatures& cpu_features,
    int sample_rate_hz)
    : VoiceActivityDetectorWrapper(vad_reset_period_ms,
                                   std::make_unique<MonoVadImpl>(cpu_features),
                                   sample_rate_hz) {}

VoiceActivityDetectorWrapper::VoiceActivityDetectorWrapper(
    int vad_reset_period_ms,
    std::unique_ptr<MonoVad> vad,
    int sample_rate_hz)
    : vad_reset_period_frames_(
          rtc::CheckedDivExact(vad_reset_period_ms, kFrameDurationMs)),
      time_to_vad_reset_(vad_reset_period_frames_),
      vad_(std::move(vad)) {
  RTC_DCHECK(vad_);
  RTC_DCHECK_GT(vad_reset_period_frames_, 1);
  resampled_buffer_.resize(
      rtc::CheckedDivExact(vad_->SampleRateHz(), kNumFramesPerSecond));
  Initialize(sample_rate_hz);
}

VoiceActivityDetectorWrapper::~VoiceActivityDetectorWrapper() = default;

void VoiceActivityDetectorWrapper::Initialize(int sample_rate_hz) {
  RTC_DCHECK_GT(sample_rate_hz, 0);
  frame_size_ = rtc::CheckedDivExact(sample_rate_hz, kNumFramesPerSecond);
  int status =
      resampler_.InitializeIfNeeded(sample_rate_hz, vad_->SampleRateHz(),
                                    /*num_channels=*/1);
  constexpr int kStatusOk = 0;
  RTC_DCHECK_EQ(status, kStatusOk);
  vad_->Reset();
}

float VoiceActivityDetectorWrapper::Analyze(AudioFrameView<const float> frame) {
  // Periodically reset the VAD.
  time_to_vad_reset_--;
  if (time_to_vad_reset_ <= 0) {
    vad_->Reset();
    time_to_vad_reset_ = vad_reset_period_frames_;
  }
  // Resample the first channel of `frame`.
  RTC_DCHECK_EQ(frame.samples_per_channel(), frame_size_);
  resampler_.Resample(frame.channel(0).data(), frame_size_,
                      resampled_buffer_.data(), resampled_buffer_.size());

  return vad_->Analyze(resampled_buffer_);
}

}  // namespace webrtc
