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

#include <algorithm>
#include <cstddef>
#include <cstring>

#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 "rtc_base/checks.h"

namespace webrtc {
namespace {

AlignmentMixer::MixingVariant ChooseMixingVariant(bool downmix,
                                                  bool adaptive_selection,
                                                  int num_channels) {
  RTC_DCHECK(!(adaptive_selection && downmix));
  RTC_DCHECK_LT(0, num_channels);

  if (num_channels == 1) {
    return AlignmentMixer::MixingVariant::kFixed;
  }
  if (downmix) {
    return AlignmentMixer::MixingVariant::kDownmix;
  }
  if (adaptive_selection) {
    return AlignmentMixer::MixingVariant::kAdaptive;
  }
  return AlignmentMixer::MixingVariant::kFixed;
}

}  // namespace

AlignmentMixer::AlignmentMixer(
    size_t num_channels,
    const EchoCanceller3Config::Delay::AlignmentMixing& config)
    : AlignmentMixer(num_channels,
                     config.downmix,
                     config.adaptive_selection,
                     config.activity_power_threshold,
                     config.prefer_first_two_channels) {}

AlignmentMixer::AlignmentMixer(size_t num_channels,
                               bool downmix,
                               bool adaptive_selection,
                               float activity_power_threshold,
                               bool prefer_first_two_channels)
    : num_channels_(num_channels),
      one_by_num_channels_(1.f / num_channels_),
      excitation_energy_threshold_(kBlockSize * activity_power_threshold),
      prefer_first_two_channels_(prefer_first_two_channels),
      selection_variant_(
          ChooseMixingVariant(downmix, adaptive_selection, num_channels_)) {
  if (selection_variant_ == MixingVariant::kAdaptive) {
    std::fill(strong_block_counters_.begin(), strong_block_counters_.end(), 0);
    cumulative_energies_.resize(num_channels_);
    std::fill(cumulative_energies_.begin(), cumulative_energies_.end(), 0.f);
  }
}

void AlignmentMixer::ProduceOutput(const Block& x,
                                   ArrayView<float, kBlockSize> y) {
  RTC_DCHECK_EQ(x.NumChannels(), num_channels_);

  if (selection_variant_ == MixingVariant::kDownmix) {
    Downmix(x, y);
    return;
  }

  int ch = selection_variant_ == MixingVariant::kFixed ? 0 : SelectChannel(x);

  RTC_DCHECK_GT(x.NumChannels(), ch);
  std::copy(x.begin(/*band=*/0, ch), x.end(/*band=*/0, ch), y.begin());
}

void AlignmentMixer::Downmix(const Block& x,
                             ArrayView<float, kBlockSize> y) const {
  RTC_DCHECK_EQ(x.NumChannels(), num_channels_);
  RTC_DCHECK_GE(num_channels_, 2);
  std::memcpy(&y[0], x.View(/*band=*/0, /*channel=*/0).data(),
              kBlockSize * sizeof(y[0]));
  for (size_t ch = 1; ch < num_channels_; ++ch) {
    const auto x_ch = x.View(/*band=*/0, ch);
    for (size_t i = 0; i < kBlockSize; ++i) {
      y[i] += x_ch[i];
    }
  }

  for (size_t i = 0; i < kBlockSize; ++i) {
    y[i] *= one_by_num_channels_;
  }
}

int AlignmentMixer::SelectChannel(const Block& x) {
  RTC_DCHECK_EQ(x.NumChannels(), num_channels_);
  RTC_DCHECK_GE(num_channels_, 2);
  RTC_DCHECK_EQ(cumulative_energies_.size(), num_channels_);

  constexpr size_t kBlocksToChooseLeftOrRight =
      static_cast<size_t>(0.5f * kNumBlocksPerSecond);
  const bool good_signal_in_left_or_right =
      prefer_first_two_channels_ &&
      (strong_block_counters_[0] > kBlocksToChooseLeftOrRight ||
       strong_block_counters_[1] > kBlocksToChooseLeftOrRight);

  const int num_ch_to_analyze =
      good_signal_in_left_or_right ? 2 : num_channels_;

  constexpr int kNumBlocksBeforeEnergySmoothing = 60 * kNumBlocksPerSecond;
  ++block_counter_;

  for (int ch = 0; ch < num_ch_to_analyze; ++ch) {
    float x2_sum = 0.f;
    ArrayView<const float, kBlockSize> x_ch = x.View(/*band=*/0, ch);
    for (size_t i = 0; i < kBlockSize; ++i) {
      x2_sum += x_ch[i] * x_ch[i];
    }

    if (ch < 2 && x2_sum > excitation_energy_threshold_) {
      ++strong_block_counters_[ch];
    }

    if (block_counter_ <= kNumBlocksBeforeEnergySmoothing) {
      cumulative_energies_[ch] += x2_sum;
    } else {
      constexpr float kSmoothing = 1.f / (10 * kNumBlocksPerSecond);
      cumulative_energies_[ch] +=
          kSmoothing * (x2_sum - cumulative_energies_[ch]);
    }
  }

  // Normalize the energies to allow the energy computations to from now be
  // based on smoothing.
  if (block_counter_ == kNumBlocksBeforeEnergySmoothing) {
    constexpr float kOneByNumBlocksBeforeEnergySmoothing =
        1.f / kNumBlocksBeforeEnergySmoothing;
    for (int ch = 0; ch < num_ch_to_analyze; ++ch) {
      cumulative_energies_[ch] *= kOneByNumBlocksBeforeEnergySmoothing;
    }
  }

  int strongest_ch = 0;
  for (int ch = 0; ch < num_ch_to_analyze; ++ch) {
    if (cumulative_energies_[ch] > cumulative_energies_[strongest_ch]) {
      strongest_ch = ch;
    }
  }

  if ((good_signal_in_left_or_right && selected_channel_ > 1) ||
      cumulative_energies_[strongest_ch] >
          2.f * cumulative_energies_[selected_channel_]) {
    selected_channel_ = strongest_ch;
  }

  return selected_channel_;
}

}  // namespace webrtc
