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

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

#include "rtc_base/checks.h"

namespace webrtc {

namespace {
constexpr size_t kCounterThreshold = 5;

// Identifies local bands with narrow characteristics.
void IdentifySmallNarrowBandRegions(
    const RenderBuffer& render_buffer,
    const rtc::Optional<size_t>& delay_partitions,
    std::array<size_t, kFftLengthBy2 - 1>* narrow_band_counters) {
  if (!delay_partitions) {
    narrow_band_counters->fill(0);
    return;
  }

  const std::array<float, kFftLengthBy2Plus1>& X2 =
      render_buffer.Spectrum(*delay_partitions);

  for (size_t k = 1; k < (X2.size() - 1); ++k) {
    (*narrow_band_counters)[k - 1] = X2[k] > 3 * std::max(X2[k - 1], X2[k + 1])
                                         ? (*narrow_band_counters)[k - 1] + 1
                                         : 0;
  }
}

// Identifies whether the signal has a single strong narrow-band component.
void IdentifyStrongNarrowBandComponent(const RenderBuffer& render_buffer,
                                       rtc::Optional<int>* narrow_peak_band,
                                       size_t* narrow_peak_counter) {
  const auto X2_latest = render_buffer.Spectrum(0);

  // Identify the spectral peak.
  const int peak_bin = static_cast<int>(
      std::max_element(X2_latest.begin(), X2_latest.end()) - X2_latest.begin());

  // Compute the level around the peak.
  float non_peak_power = 0.f;
  for (int k = std::max(5, peak_bin - 14); k < peak_bin - 4; ++k) {
    non_peak_power = std::max(X2_latest[k], non_peak_power);
  }
  for (int k = peak_bin + 5;
       k < std::min(peak_bin + 15, static_cast<int>(kFftLengthBy2Plus1)); ++k) {
    non_peak_power = std::max(X2_latest[k], non_peak_power);
  }

  // Assess the render signal strength
  const std::vector<std::vector<float>>& x_latest =
      render_buffer.MostRecentBlock();
  auto result0 = std::minmax_element(x_latest[0].begin(), x_latest[0].end());
  float max_abs = std::max(fabs(*result0.first), fabs(*result0.second));

  if (x_latest.size() > 1) {
    const auto result1 =
        std::minmax_element(x_latest[1].begin(), x_latest[1].end());
    max_abs =
        std::max(max_abs, static_cast<float>(std::max(fabs(*result1.first),
                                                      fabs(*result1.second))));
  }

  // Detect whether the spectal peak has as strong narrowband nature.
  if (peak_bin > 6 && max_abs > 100 &&
      X2_latest[peak_bin] > 100 * non_peak_power) {
    *narrow_peak_band = peak_bin;
    *narrow_peak_counter = 0;
  } else {
    if (*narrow_peak_band && ++(*narrow_peak_counter) > 7) {
      *narrow_peak_band = rtc::nullopt;
    }
  }
}

}  // namespace

RenderSignalAnalyzer::RenderSignalAnalyzer() {
  narrow_band_counters_.fill(0);
}
RenderSignalAnalyzer::~RenderSignalAnalyzer() = default;

void RenderSignalAnalyzer::Update(
    const RenderBuffer& render_buffer,
    const rtc::Optional<size_t>& delay_partitions) {
  // Identify bands of narrow nature.
  IdentifySmallNarrowBandRegions(render_buffer, delay_partitions,
                                 &narrow_band_counters_);

  // Identify the presence of a strong narrow band.
  IdentifyStrongNarrowBandComponent(render_buffer, &narrow_peak_band_,
                                    &narrow_peak_counter_);
}

void RenderSignalAnalyzer::MaskRegionsAroundNarrowBands(
    std::array<float, kFftLengthBy2Plus1>* v) const {
  RTC_DCHECK(v);

  // Set v to zero around narrow band signal regions.
  if (narrow_band_counters_[0] > kCounterThreshold) {
    (*v)[1] = (*v)[0] = 0.f;
  }
  for (size_t k = 2; k < kFftLengthBy2 - 1; ++k) {
    if (narrow_band_counters_[k - 1] > kCounterThreshold) {
      (*v)[k - 2] = (*v)[k - 1] = (*v)[k] = (*v)[k + 1] = (*v)[k + 2] = 0.f;
    }
  }
  if (narrow_band_counters_[kFftLengthBy2 - 2] > kCounterThreshold) {
    (*v)[kFftLengthBy2] = (*v)[kFftLengthBy2 - 1] = 0.f;
  }
}

}  // namespace webrtc
