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

#include <algorithm>
#include <memory>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/numerics/safe_minmax.h"
#include "system_wrappers/include/field_trial.h"

namespace webrtc {

namespace {
constexpr int kPointsToAccumulate = 6;
constexpr float kX2BandEnergyThreshold = 44015068.0f;
constexpr int kErleHold = 100;
constexpr int kBlocksForOnsetDetection = kErleHold + 150;

bool EnableAdaptErleOnLowRender() {
  return !field_trial::IsEnabled("WebRTC-Aec3AdaptErleOnLowRenderKillSwitch");
}

}  // namespace

SubbandErleEstimator::SubbandErleEstimator(float min_erle,
                                           float max_erle_lf,
                                           float max_erle_hf)
    : min_erle_(min_erle),
      max_erle_lf_(max_erle_lf),
      max_erle_hf_(max_erle_hf),
      adapt_on_low_render_(EnableAdaptErleOnLowRender()) {
  Reset();
}

SubbandErleEstimator::~SubbandErleEstimator() = default;

void SubbandErleEstimator::Reset() {
  erle_.fill(min_erle_);
  erle_onsets_.fill(min_erle_);
  hold_counters_.fill(0);
  coming_onset_.fill(true);
}

void SubbandErleEstimator::Update(rtc::ArrayView<const float> X2,
                                  rtc::ArrayView<const float> Y2,
                                  rtc::ArrayView<const float> E2,
                                  bool converged_filter,
                                  bool onset_detection) {
  if (converged_filter) {
    // Note that the use of the converged_filter flag already imposed
    // a minimum of the erle that can be estimated as that flag would
    // be false if the filter is performing poorly.
    constexpr size_t kFftLengthBy4 = kFftLengthBy2 / 2;
    UpdateBands(X2, Y2, E2, 1, kFftLengthBy4, max_erle_lf_, onset_detection);
    UpdateBands(X2, Y2, E2, kFftLengthBy4, kFftLengthBy2, max_erle_hf_,
                onset_detection);
  }

  if (onset_detection) {
    DecreaseErlePerBandForLowRenderSignals();
  }

  erle_[0] = erle_[1];
  erle_[kFftLengthBy2] = erle_[kFftLengthBy2 - 1];
}

void SubbandErleEstimator::Dump(
    const std::unique_ptr<ApmDataDumper>& data_dumper) const {
  data_dumper->DumpRaw("aec3_erle", Erle());
  data_dumper->DumpRaw("aec3_erle_onset", ErleOnsets());
}

void SubbandErleEstimator::UpdateBands(rtc::ArrayView<const float> X2,
                                       rtc::ArrayView<const float> Y2,
                                       rtc::ArrayView<const float> E2,
                                       size_t start,
                                       size_t stop,
                                       float max_erle,
                                       bool onset_detection) {
  auto erle_band_update = [](float erle_band, float new_erle,
                             bool low_render_energy, float alpha_inc,
                             float alpha_dec, float min_erle, float max_erle) {
    if (new_erle < erle_band && low_render_energy) {
      // Decreases are not allowed if low render energy signals were used for
      // the erle computation.
      return erle_band;
    }
    float alpha = new_erle > erle_band ? alpha_inc : alpha_dec;
    float erle_band_out = erle_band;
    erle_band_out = erle_band + alpha * (new_erle - erle_band);
    erle_band_out = rtc::SafeClamp(erle_band_out, min_erle, max_erle);
    return erle_band_out;
  };

  for (size_t k = start; k < stop; ++k) {
    if (adapt_on_low_render_ || X2[k] > kX2BandEnergyThreshold) {
      bool low_render_energy = false;
      absl::optional<float> new_erle = instantaneous_erle_.Update(
          X2[k], Y2[k], E2[k], k, &low_render_energy);
      if (new_erle) {
        RTC_DCHECK(adapt_on_low_render_ || !low_render_energy);
        if (onset_detection && !low_render_energy) {
          if (coming_onset_[k]) {
            coming_onset_[k] = false;
            erle_onsets_[k] = erle_band_update(
                erle_onsets_[k], new_erle.value(), low_render_energy, 0.15f,
                0.3f, min_erle_, max_erle);
          }
          hold_counters_[k] = kBlocksForOnsetDetection;
        }

        erle_[k] =
            erle_band_update(erle_[k], new_erle.value(), low_render_energy,
                             0.05f, 0.1f, min_erle_, max_erle);
      }
    }
  }
}

void SubbandErleEstimator::DecreaseErlePerBandForLowRenderSignals() {
  for (size_t k = 1; k < kFftLengthBy2; ++k) {
    hold_counters_[k]--;
    if (hold_counters_[k] <= (kBlocksForOnsetDetection - kErleHold)) {
      if (erle_[k] > erle_onsets_[k]) {
        erle_[k] = std::max(erle_onsets_[k], 0.97f * erle_[k]);
        RTC_DCHECK_LE(min_erle_, erle_[k]);
      }
      if (hold_counters_[k] <= 0) {
        coming_onset_[k] = true;
        hold_counters_[k] = 0;
      }
    }
  }
}

SubbandErleEstimator::ErleInstantaneous::ErleInstantaneous() {
  Reset();
}

SubbandErleEstimator::ErleInstantaneous::~ErleInstantaneous() = default;

absl::optional<float> SubbandErleEstimator::ErleInstantaneous::Update(
    float X2,
    float Y2,
    float E2,
    size_t band,
    bool* low_render_energy) {
  absl::optional<float> erle_instantaneous = absl::nullopt;
  RTC_DCHECK_LT(band, kFftLengthBy2Plus1);
  Y2_acum_[band] += Y2;
  E2_acum_[band] += E2;
  low_render_energy_[band] =
      low_render_energy_[band] || X2 < kX2BandEnergyThreshold;
  if (++num_points_[band] == kPointsToAccumulate) {
    if (E2_acum_[band]) {
      erle_instantaneous = Y2_acum_[band] / E2_acum_[band];
    }
    *low_render_energy = low_render_energy_[band];
    num_points_[band] = 0;
    Y2_acum_[band] = 0.f;
    E2_acum_[band] = 0.f;
    low_render_energy_[band] = false;
  }

  return erle_instantaneous;
}

void SubbandErleEstimator::ErleInstantaneous::Reset() {
  Y2_acum_.fill(0.f);
  E2_acum_.fill(0.f);
  low_render_energy_.fill(false);
  num_points_.fill(0);
}

}  // namespace webrtc
