/*
 *  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 <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
#include <optional>
#include <utility>

#include "api/array_view.h"
#include "api/audio/echo_canceller3_config.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/render_buffer.h"
#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 std::optional<size_t>& delay_partitions,
    std::array<size_t, kFftLengthBy2 - 1>* narrow_band_counters) {
  RTC_DCHECK(narrow_band_counters);

  if (!delay_partitions) {
    narrow_band_counters->fill(0);
    return;
  }

  std::array<size_t, kFftLengthBy2 - 1> channel_counters;
  channel_counters.fill(0);
  ArrayView<const std::array<float, kFftLengthBy2Plus1>> X2 =
      render_buffer.Spectrum(*delay_partitions);
  for (size_t ch = 0; ch < X2.size(); ++ch) {
    for (size_t k = 1; k < kFftLengthBy2; ++k) {
      if (X2[ch][k] > 3 * std::max(X2[ch][k - 1], X2[ch][k + 1])) {
        ++channel_counters[k - 1];
      }
    }
  }
  for (size_t k = 1; k < kFftLengthBy2; ++k) {
    (*narrow_band_counters)[k - 1] =
        channel_counters[k - 1] > 0 ? (*narrow_band_counters)[k - 1] + 1 : 0;
  }
}

// Identifies whether the signal has a single strong narrow-band component.
void IdentifyStrongNarrowBandComponent(const RenderBuffer& render_buffer,
                                       int strong_peak_freeze_duration,
                                       std::optional<int>* narrow_peak_band,
                                       size_t* narrow_peak_counter) {
  RTC_DCHECK(narrow_peak_band);
  RTC_DCHECK(narrow_peak_counter);
  if (*narrow_peak_band &&
      ++(*narrow_peak_counter) >
          static_cast<size_t>(strong_peak_freeze_duration)) {
    *narrow_peak_band = std::nullopt;
  }

  const Block& x_latest = render_buffer.GetBlock(0);
  float max_peak_level = 0.f;
  for (int channel = 0; channel < x_latest.NumChannels(); ++channel) {
    ArrayView<const float, kFftLengthBy2Plus1> X2_latest =
        render_buffer.Spectrum(0)[channel];

    // 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(0, 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.
    auto result0 = std::minmax_element(x_latest.begin(/*band=*/0, channel),
                                       x_latest.end(/*band=*/0, channel));
    float max_abs = std::max(fabs(*result0.first), fabs(*result0.second));

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

    // Detect whether the spectral peak has as strong narrowband nature.
    const float peak_level = X2_latest[peak_bin];
    if (peak_bin > 0 && max_abs > 100 && peak_level > 100 * non_peak_power) {
      // Store the strongest peak across channels.
      if (peak_level > max_peak_level) {
        max_peak_level = peak_level;
        *narrow_peak_band = peak_bin;
        *narrow_peak_counter = 0;
      }
    }
  }
}

}  // namespace

RenderSignalAnalyzer::RenderSignalAnalyzer(const EchoCanceller3Config& config)
    : strong_peak_freeze_duration_(config.filter.refined.length_blocks) {
  narrow_band_counters_.fill(0);
}
RenderSignalAnalyzer::~RenderSignalAnalyzer() = default;

void RenderSignalAnalyzer::Update(
    const RenderBuffer& render_buffer,
    const std::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, strong_peak_freeze_duration_,
                                    &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
