/*
 *  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 "webrtc/modules/audio_processing/level_controller/level_controller.h"

#include <math.h>
#include <algorithm>
#include <numeric>

#include "webrtc/api/array_view.h"
#include "webrtc/modules/audio_processing/audio_buffer.h"
#include "webrtc/modules/audio_processing/level_controller/gain_applier.h"
#include "webrtc/modules/audio_processing/level_controller/gain_selector.h"
#include "webrtc/modules/audio_processing/level_controller/noise_level_estimator.h"
#include "webrtc/modules/audio_processing/level_controller/peak_level_estimator.h"
#include "webrtc/modules/audio_processing/level_controller/saturating_gain_estimator.h"
#include "webrtc/modules/audio_processing/level_controller/signal_classifier.h"
#include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
#include "webrtc/rtc_base/arraysize.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/system_wrappers/include/metrics.h"

namespace webrtc {
namespace {

void UpdateAndRemoveDcLevel(float forgetting_factor,
                            float* dc_level,
                            rtc::ArrayView<float> x) {
  RTC_DCHECK(!x.empty());
  float mean =
      std::accumulate(x.begin(), x.end(), 0.0f) / static_cast<float>(x.size());
  *dc_level += forgetting_factor * (mean - *dc_level);

  for (float& v : x) {
    v -= *dc_level;
  }
}

float FrameEnergy(const AudioBuffer& audio) {
  float energy = 0.f;
  for (size_t k = 0; k < audio.num_channels(); ++k) {
    float channel_energy =
        std::accumulate(audio.channels_const_f()[k],
                        audio.channels_const_f()[k] + audio.num_frames(), 0.f,
                        [](float a, float b) -> float { return a + b * b; });
    energy = std::max(channel_energy, energy);
  }
  return energy;
}

float PeakLevel(const AudioBuffer& audio) {
  float peak_level = 0.f;
  for (size_t k = 0; k < audio.num_channels(); ++k) {
    auto* channel_peak_level = std::max_element(
        audio.channels_const_f()[k],
        audio.channels_const_f()[k] + audio.num_frames(),
        [](float a, float b) { return std::abs(a) < std::abs(b); });
    peak_level = std::max(*channel_peak_level, peak_level);
  }
  return peak_level;
}

const int kMetricsFrameInterval = 1000;

}  // namespace

int LevelController::instance_count_ = 0;

void LevelController::Metrics::Initialize(int sample_rate_hz) {
  RTC_DCHECK(sample_rate_hz == AudioProcessing::kSampleRate8kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate16kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate32kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate48kHz);

  Reset();
  frame_length_ = rtc::CheckedDivExact(sample_rate_hz, 100);
}

void LevelController::Metrics::Reset() {
  metrics_frame_counter_ = 0;
  gain_sum_ = 0.f;
  peak_level_sum_ = 0.f;
  noise_energy_sum_ = 0.f;
  max_gain_ = 0.f;
  max_peak_level_ = 0.f;
  max_noise_energy_ = 0.f;
}

void LevelController::Metrics::Update(float long_term_peak_level,
                                      float noise_energy,
                                      float gain,
                                      float frame_peak_level) {
  const float kdBFSOffset = 90.3090f;
  gain_sum_ += gain;
  peak_level_sum_ += long_term_peak_level;
  noise_energy_sum_ += noise_energy;
  max_gain_ = std::max(max_gain_, gain);
  max_peak_level_ = std::max(max_peak_level_, long_term_peak_level);
  max_noise_energy_ = std::max(max_noise_energy_, noise_energy);

  ++metrics_frame_counter_;
  if (metrics_frame_counter_ == kMetricsFrameInterval) {
    RTC_DCHECK_LT(0, frame_length_);
    RTC_DCHECK_LT(0, kMetricsFrameInterval);

    const int max_noise_power_dbfs = static_cast<int>(
        10 * log10(max_noise_energy_ / frame_length_ + 1e-10f) - kdBFSOffset);
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.MaxNoisePower",
                         max_noise_power_dbfs, -90, 0, 50);

    const int average_noise_power_dbfs = static_cast<int>(
        10 * log10(noise_energy_sum_ / (frame_length_ * kMetricsFrameInterval) +
                   1e-10f) -
        kdBFSOffset);
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.AverageNoisePower",
                         average_noise_power_dbfs, -90, 0, 50);

    const int max_peak_level_dbfs = static_cast<int>(
        10 * log10(max_peak_level_ * max_peak_level_ + 1e-10f) - kdBFSOffset);
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.MaxPeakLevel",
                         max_peak_level_dbfs, -90, 0, 50);

    const int average_peak_level_dbfs = static_cast<int>(
        10 * log10(peak_level_sum_ * peak_level_sum_ /
                       (kMetricsFrameInterval * kMetricsFrameInterval) +
                   1e-10f) -
        kdBFSOffset);
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.AveragePeakLevel",
                         average_peak_level_dbfs, -90, 0, 50);

    RTC_DCHECK_LE(1.f, max_gain_);
    RTC_DCHECK_LE(1.f, gain_sum_ / kMetricsFrameInterval);

    const int max_gain_db = static_cast<int>(10 * log10(max_gain_ * max_gain_));
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.MaxGain", max_gain_db, 0,
                         33, 30);

    const int average_gain_db = static_cast<int>(
        10 * log10(gain_sum_ * gain_sum_ /
                   (kMetricsFrameInterval * kMetricsFrameInterval)));
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.LevelControl.AverageGain",
                         average_gain_db, 0, 33, 30);

    const int long_term_peak_level_dbfs = static_cast<int>(
        10 * log10(long_term_peak_level * long_term_peak_level + 1e-10f) -
        kdBFSOffset);

    const int frame_peak_level_dbfs = static_cast<int>(
        10 * log10(frame_peak_level * frame_peak_level + 1e-10f) - kdBFSOffset);

    LOG(LS_INFO) << "Level Controller metrics: {"
                 << "Max noise power: " << max_noise_power_dbfs << " dBFS, "
                 << "Average noise power: " << average_noise_power_dbfs
                 << " dBFS, "
                 << "Max long term peak level: " << max_peak_level_dbfs
                 << " dBFS, "
                 << "Average long term peak level: " << average_peak_level_dbfs
                 << " dBFS, "
                 << "Max gain: " << max_gain_db << " dB, "
                 << "Average gain: " << average_gain_db << " dB, "
                 << "Long term peak level: " << long_term_peak_level_dbfs
                 << " dBFS, "
                 << "Last frame peak level: " << frame_peak_level_dbfs
                 << " dBFS"
                 << "}";

    Reset();
  }
}

LevelController::LevelController()
    : data_dumper_(new ApmDataDumper(instance_count_)),
      gain_applier_(data_dumper_.get()),
      signal_classifier_(data_dumper_.get()),
      peak_level_estimator_(kTargetLcPeakLeveldBFS) {
  Initialize(AudioProcessing::kSampleRate48kHz);
  ++instance_count_;
}

LevelController::~LevelController() {}

void LevelController::Initialize(int sample_rate_hz) {
  RTC_DCHECK(sample_rate_hz == AudioProcessing::kSampleRate8kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate16kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate32kHz ||
             sample_rate_hz == AudioProcessing::kSampleRate48kHz);
  data_dumper_->InitiateNewSetOfRecordings();
  gain_selector_.Initialize(sample_rate_hz);
  gain_applier_.Initialize(sample_rate_hz);
  signal_classifier_.Initialize(sample_rate_hz);
  noise_level_estimator_.Initialize(sample_rate_hz);
  peak_level_estimator_.Initialize(config_.initial_peak_level_dbfs);
  saturating_gain_estimator_.Initialize();
  metrics_.Initialize(sample_rate_hz);

  last_gain_ = 1.0f;
  sample_rate_hz_ = rtc::Optional<int>(sample_rate_hz);
  dc_forgetting_factor_ = 0.01f * sample_rate_hz / 48000.f;
  std::fill(dc_level_, dc_level_ + arraysize(dc_level_), 0.f);
}

void LevelController::Process(AudioBuffer* audio) {
  RTC_DCHECK_LT(0, audio->num_channels());
  RTC_DCHECK_GE(2, audio->num_channels());
  RTC_DCHECK_NE(0.f, dc_forgetting_factor_);
  RTC_DCHECK(sample_rate_hz_);
  data_dumper_->DumpWav("lc_input", audio->num_frames(),
                        audio->channels_const_f()[0], *sample_rate_hz_, 1);

  // Remove DC level.
  for (size_t k = 0; k < audio->num_channels(); ++k) {
    UpdateAndRemoveDcLevel(
        dc_forgetting_factor_, &dc_level_[k],
        rtc::ArrayView<float>(audio->channels_f()[k], audio->num_frames()));
  }

  SignalClassifier::SignalType signal_type;
  signal_classifier_.Analyze(*audio, &signal_type);
  int tmp = static_cast<int>(signal_type);
  data_dumper_->DumpRaw("lc_signal_type", 1, &tmp);

  // Estimate the noise energy.
  float noise_energy =
      noise_level_estimator_.Analyze(signal_type, FrameEnergy(*audio));

  // Estimate the overall signal peak level.
  const float frame_peak_level = PeakLevel(*audio);
  const float long_term_peak_level =
      peak_level_estimator_.Analyze(signal_type, frame_peak_level);

  float saturating_gain = saturating_gain_estimator_.GetGain();

  // Compute the new gain to apply.
  last_gain_ =
      gain_selector_.GetNewGain(long_term_peak_level, noise_energy,
                                saturating_gain, gain_jumpstart_, signal_type);

  // Unflag the jumpstart of the gain as it should only happen once.
  gain_jumpstart_ = false;

  // Apply the gain to the signal.
  int num_saturations = gain_applier_.Process(last_gain_, audio);

  // Estimate the gain that saturates the overall signal.
  saturating_gain_estimator_.Update(last_gain_, num_saturations);

  // Update the metrics.
  metrics_.Update(long_term_peak_level, noise_energy, last_gain_,
                  frame_peak_level);

  data_dumper_->DumpRaw("lc_selected_gain", 1, &last_gain_);
  data_dumper_->DumpRaw("lc_noise_energy", 1, &noise_energy);
  data_dumper_->DumpRaw("lc_peak_level", 1, &long_term_peak_level);
  data_dumper_->DumpRaw("lc_saturating_gain", 1, &saturating_gain);

  data_dumper_->DumpWav("lc_output", audio->num_frames(),
                        audio->channels_f()[0], *sample_rate_hz_, 1);
}

void LevelController::ApplyConfig(
    const AudioProcessing::Config::LevelController& config) {
  RTC_DCHECK(Validate(config));
  config_ = config;
  peak_level_estimator_.Initialize(config_.initial_peak_level_dbfs);
  gain_jumpstart_ = true;
}

std::string LevelController::ToString(
    const AudioProcessing::Config::LevelController& config) {
  std::stringstream ss;
  ss << "{"
     << "enabled: " << (config.enabled ? "true" : "false") << ", "
     << "initial_peak_level_dbfs: " << config.initial_peak_level_dbfs << "}";
  return ss.str();
}

bool LevelController::Validate(
    const AudioProcessing::Config::LevelController& config) {
  return (config.initial_peak_level_dbfs <
              std::numeric_limits<float>::epsilon() &&
          config.initial_peak_level_dbfs >
              -(100.f + std::numeric_limits<float>::epsilon()));
}

}  // namespace webrtc
