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

#include <math.h>

#include <algorithm>
#include <array>
#include <numeric>

#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/render_buffer.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace {

size_t FindPeakIndex(rtc::ArrayView<const float> filter_time_domain,
                     size_t peak_index_in,
                     size_t start_sample,
                     size_t end_sample) {
  size_t peak_index_out = peak_index_in;
  float max_h2 =
      filter_time_domain[peak_index_out] * filter_time_domain[peak_index_out];
  for (size_t k = start_sample; k <= end_sample; ++k) {
    float tmp = filter_time_domain[k] * filter_time_domain[k];
    if (tmp > max_h2) {
      peak_index_out = k;
      max_h2 = tmp;
    }
  }

  return peak_index_out;
}

}  // namespace

std::atomic<int> FilterAnalyzer::instance_count_(0);

FilterAnalyzer::FilterAnalyzer(const EchoCanceller3Config& config,
                               size_t num_capture_channels)
    : data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
      bounded_erl_(config.ep_strength.bounded_erl),
      default_gain_(config.ep_strength.default_gain),
      h_highpass_(num_capture_channels,
                  std::vector<float>(
                      GetTimeDomainLength(config.filter.refined.length_blocks),
                      0.f)),
      filter_analysis_states_(num_capture_channels,
                              FilterAnalysisState(config)),
      filter_delays_blocks_(num_capture_channels, 0) {
  Reset();
}

FilterAnalyzer::~FilterAnalyzer() = default;

void FilterAnalyzer::Reset() {
  blocks_since_reset_ = 0;
  ResetRegion();
  for (auto& state : filter_analysis_states_) {
    state.Reset(default_gain_);
  }
  std::fill(filter_delays_blocks_.begin(), filter_delays_blocks_.end(), 0);
}

void FilterAnalyzer::Update(
    rtc::ArrayView<const std::vector<float>> filters_time_domain,
    const RenderBuffer& render_buffer,
    bool* any_filter_consistent,
    float* max_echo_path_gain) {
  RTC_DCHECK(any_filter_consistent);
  RTC_DCHECK(max_echo_path_gain);
  RTC_DCHECK_EQ(filters_time_domain.size(), filter_analysis_states_.size());
  RTC_DCHECK_EQ(filters_time_domain.size(), h_highpass_.size());

  ++blocks_since_reset_;
  SetRegionToAnalyze(filters_time_domain[0].size());
  AnalyzeRegion(filters_time_domain, render_buffer);

  // Aggregate the results for all capture channels.
  auto& st_ch0 = filter_analysis_states_[0];
  *any_filter_consistent = st_ch0.consistent_estimate;
  *max_echo_path_gain = st_ch0.gain;
  min_filter_delay_blocks_ = filter_delays_blocks_[0];
  for (size_t ch = 1; ch < filters_time_domain.size(); ++ch) {
    auto& st_ch = filter_analysis_states_[ch];
    *any_filter_consistent =
        *any_filter_consistent || st_ch.consistent_estimate;
    *max_echo_path_gain = std::max(*max_echo_path_gain, st_ch.gain);
    min_filter_delay_blocks_ =
        std::min(min_filter_delay_blocks_, filter_delays_blocks_[ch]);
  }
}

void FilterAnalyzer::AnalyzeRegion(
    rtc::ArrayView<const std::vector<float>> filters_time_domain,
    const RenderBuffer& render_buffer) {
  // Preprocess the filter to avoid issues with low-frequency components in the
  // filter.
  PreProcessFilters(filters_time_domain);
  data_dumper_->DumpRaw("aec3_linear_filter_processed_td", h_highpass_[0]);

  constexpr float kOneByBlockSize = 1.f / kBlockSize;
  for (size_t ch = 0; ch < filters_time_domain.size(); ++ch) {
    RTC_DCHECK_LT(region_.start_sample_, filters_time_domain[ch].size());
    RTC_DCHECK_LT(region_.end_sample_, filters_time_domain[ch].size());

    auto& st_ch = filter_analysis_states_[ch];
    RTC_DCHECK_EQ(h_highpass_[ch].size(), filters_time_domain[ch].size());
    RTC_DCHECK_GT(h_highpass_[ch].size(), 0);
    st_ch.peak_index = std::min(st_ch.peak_index, h_highpass_[ch].size() - 1);

    st_ch.peak_index =
        FindPeakIndex(h_highpass_[ch], st_ch.peak_index, region_.start_sample_,
                      region_.end_sample_);
    filter_delays_blocks_[ch] = st_ch.peak_index >> kBlockSizeLog2;
    UpdateFilterGain(h_highpass_[ch], &st_ch);
    st_ch.filter_length_blocks =
        filters_time_domain[ch].size() * kOneByBlockSize;

    st_ch.consistent_estimate = st_ch.consistent_filter_detector.Detect(
        h_highpass_[ch], region_,
        render_buffer.GetBlock(-filter_delays_blocks_[ch]), st_ch.peak_index,
        filter_delays_blocks_[ch]);
  }
}

void FilterAnalyzer::UpdateFilterGain(
    rtc::ArrayView<const float> filter_time_domain,
    FilterAnalysisState* st) {
  bool sufficient_time_to_converge =
      blocks_since_reset_ > 5 * kNumBlocksPerSecond;

  if (sufficient_time_to_converge && st->consistent_estimate) {
    st->gain = fabsf(filter_time_domain[st->peak_index]);
  } else {
    // TODO(peah): Verify whether this check against a float is ok.
    if (st->gain) {
      st->gain = std::max(st->gain, fabsf(filter_time_domain[st->peak_index]));
    }
  }

  if (bounded_erl_ && st->gain) {
    st->gain = std::max(st->gain, 0.01f);
  }
}

void FilterAnalyzer::PreProcessFilters(
    rtc::ArrayView<const std::vector<float>> filters_time_domain) {
  for (size_t ch = 0; ch < filters_time_domain.size(); ++ch) {
    RTC_DCHECK_LT(region_.start_sample_, filters_time_domain[ch].size());
    RTC_DCHECK_LT(region_.end_sample_, filters_time_domain[ch].size());

    RTC_DCHECK_GE(h_highpass_[ch].capacity(), filters_time_domain[ch].size());
    h_highpass_[ch].resize(filters_time_domain[ch].size());
    // Minimum phase high-pass filter with cutoff frequency at about 600 Hz.
    constexpr std::array<float, 3> h = {
        {0.7929742f, -0.36072128f, -0.47047766f}};

    std::fill(h_highpass_[ch].begin() + region_.start_sample_,
              h_highpass_[ch].begin() + region_.end_sample_ + 1, 0.f);
    float* h_highpass_ch = h_highpass_[ch].data();
    const float* filters_time_domain_ch = filters_time_domain[ch].data();
    const size_t region_end = region_.end_sample_;
    for (size_t k = std::max(h.size() - 1, region_.start_sample_);
         k <= region_end; ++k) {
      float tmp = h_highpass_ch[k];
      for (size_t j = 0; j < h.size(); ++j) {
        tmp += filters_time_domain_ch[k - j] * h[j];
      }
      h_highpass_ch[k] = tmp;
    }
  }
}

void FilterAnalyzer::ResetRegion() {
  region_.start_sample_ = 0;
  region_.end_sample_ = 0;
}

void FilterAnalyzer::SetRegionToAnalyze(size_t filter_size) {
  constexpr size_t kNumberBlocksToUpdate = 1;
  auto& r = region_;
  r.start_sample_ = r.end_sample_ >= filter_size - 1 ? 0 : r.end_sample_ + 1;
  r.end_sample_ =
      std::min(r.start_sample_ + kNumberBlocksToUpdate * kBlockSize - 1,
               filter_size - 1);

  // Check range.
  RTC_DCHECK_LT(r.start_sample_, filter_size);
  RTC_DCHECK_LT(r.end_sample_, filter_size);
  RTC_DCHECK_LE(r.start_sample_, r.end_sample_);
}

FilterAnalyzer::ConsistentFilterDetector::ConsistentFilterDetector(
    const EchoCanceller3Config& config)
    : active_render_threshold_(config.render_levels.active_render_limit *
                               config.render_levels.active_render_limit *
                               kFftLengthBy2) {
  Reset();
}

void FilterAnalyzer::ConsistentFilterDetector::Reset() {
  significant_peak_ = false;
  filter_floor_accum_ = 0.f;
  filter_secondary_peak_ = 0.f;
  filter_floor_low_limit_ = 0;
  filter_floor_high_limit_ = 0;
  consistent_estimate_counter_ = 0;
  consistent_delay_reference_ = -10;
}

bool FilterAnalyzer::ConsistentFilterDetector::Detect(
    rtc::ArrayView<const float> filter_to_analyze,
    const FilterRegion& region,
    const Block& x_block,
    size_t peak_index,
    int delay_blocks) {
  if (region.start_sample_ == 0) {
    filter_floor_accum_ = 0.f;
    filter_secondary_peak_ = 0.f;
    filter_floor_low_limit_ = peak_index < 64 ? 0 : peak_index - 64;
    filter_floor_high_limit_ =
        peak_index > filter_to_analyze.size() - 129 ? 0 : peak_index + 128;
  }

  float filter_floor_accum = filter_floor_accum_;
  float filter_secondary_peak = filter_secondary_peak_;
  for (size_t k = region.start_sample_;
       k < std::min(region.end_sample_ + 1, filter_floor_low_limit_); ++k) {
    float abs_h = fabsf(filter_to_analyze[k]);
    filter_floor_accum += abs_h;
    filter_secondary_peak = std::max(filter_secondary_peak, abs_h);
  }

  for (size_t k = std::max(filter_floor_high_limit_, region.start_sample_);
       k <= region.end_sample_; ++k) {
    float abs_h = fabsf(filter_to_analyze[k]);
    filter_floor_accum += abs_h;
    filter_secondary_peak = std::max(filter_secondary_peak, abs_h);
  }
  filter_floor_accum_ = filter_floor_accum;
  filter_secondary_peak_ = filter_secondary_peak;

  if (region.end_sample_ == filter_to_analyze.size() - 1) {
    float filter_floor = filter_floor_accum_ /
                         (filter_floor_low_limit_ + filter_to_analyze.size() -
                          filter_floor_high_limit_);

    float abs_peak = fabsf(filter_to_analyze[peak_index]);
    significant_peak_ = abs_peak > 10.f * filter_floor &&
                        abs_peak > 2.f * filter_secondary_peak_;
  }

  if (significant_peak_) {
    bool active_render_block = false;
    for (int ch = 0; ch < x_block.NumChannels(); ++ch) {
      rtc::ArrayView<const float, kBlockSize> x_channel =
          x_block.View(/*band=*/0, ch);
      const float x_energy = std::inner_product(
          x_channel.begin(), x_channel.end(), x_channel.begin(), 0.f);
      if (x_energy > active_render_threshold_) {
        active_render_block = true;
        break;
      }
    }

    if (consistent_delay_reference_ == delay_blocks) {
      if (active_render_block) {
        ++consistent_estimate_counter_;
      }
    } else {
      consistent_estimate_counter_ = 0;
      consistent_delay_reference_ = delay_blocks;
    }
  }
  return consistent_estimate_counter_ > 1.5f * kNumBlocksPerSecond;
}

}  // namespace webrtc
