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

#include <algorithm>
#include <utility>

#include "absl/strings/string_view.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/high_pass_filter.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h"

namespace webrtc {

namespace {

enum class EchoCanceller3ApiCall { kCapture, kRender };

bool DetectSaturation(rtc::ArrayView<const float> y) {
  for (size_t k = 0; k < y.size(); ++k) {
    if (y[k] >= 32700.0f || y[k] <= -32700.0f) {
      return true;
    }
  }
  return false;
}

// Retrieves a value from a field trial if it is available. If no value is
// present, the default value is returned. If the retrieved value is beyond the
// specified limits, the default value is returned instead.
void RetrieveFieldTrialValue(absl::string_view trial_name,
                             float min,
                             float max,
                             float* value_to_update) {
  const std::string field_trial_str = field_trial::FindFullName(trial_name);

  FieldTrialParameter<double> field_trial_param(/*key=*/"", *value_to_update);

  ParseFieldTrial({&field_trial_param}, field_trial_str);
  float field_trial_value = static_cast<float>(field_trial_param.Get());

  if (field_trial_value >= min && field_trial_value <= max &&
      field_trial_value != *value_to_update) {
    RTC_LOG(LS_INFO) << "Key " << trial_name
                     << " changing AEC3 parameter value from "
                     << *value_to_update << " to " << field_trial_value;
    *value_to_update = field_trial_value;
  }
}

void RetrieveFieldTrialValue(absl::string_view trial_name,
                             int min,
                             int max,
                             int* value_to_update) {
  const std::string field_trial_str = field_trial::FindFullName(trial_name);

  FieldTrialParameter<int> field_trial_param(/*key=*/"", *value_to_update);

  ParseFieldTrial({&field_trial_param}, field_trial_str);
  float field_trial_value = field_trial_param.Get();

  if (field_trial_value >= min && field_trial_value <= max &&
      field_trial_value != *value_to_update) {
    RTC_LOG(LS_INFO) << "Key " << trial_name
                     << " changing AEC3 parameter value from "
                     << *value_to_update << " to " << field_trial_value;
    *value_to_update = field_trial_value;
  }
}

void FillSubFrameView(
    AudioBuffer* frame,
    size_t sub_frame_index,
    std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
  RTC_DCHECK_GE(1, sub_frame_index);
  RTC_DCHECK_LE(0, sub_frame_index);
  RTC_DCHECK_EQ(frame->num_bands(), sub_frame_view->size());
  RTC_DCHECK_EQ(frame->num_channels(), (*sub_frame_view)[0].size());
  for (size_t band = 0; band < sub_frame_view->size(); ++band) {
    for (size_t channel = 0; channel < (*sub_frame_view)[0].size(); ++channel) {
      (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
          &frame->split_bands(channel)[band][sub_frame_index * kSubFrameLength],
          kSubFrameLength);
    }
  }
}

void FillSubFrameView(
    bool proper_downmix_needed,
    std::vector<std::vector<std::vector<float>>>* frame,
    size_t sub_frame_index,
    std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
  RTC_DCHECK_GE(1, sub_frame_index);
  RTC_DCHECK_EQ(frame->size(), sub_frame_view->size());
  const size_t frame_num_channels = (*frame)[0].size();
  const size_t sub_frame_num_channels = (*sub_frame_view)[0].size();
  if (frame_num_channels > sub_frame_num_channels) {
    RTC_DCHECK_EQ(sub_frame_num_channels, 1u);
    if (proper_downmix_needed) {
      // When a proper downmix is needed (which is the case when proper stereo
      // is present in the echo reference signal but the echo canceller does the
      // processing in mono) downmix the echo reference by averaging the channel
      // content (otherwise downmixing is done by selecting channel 0).
      for (size_t band = 0; band < frame->size(); ++band) {
        for (size_t ch = 1; ch < frame_num_channels; ++ch) {
          for (size_t k = 0; k < kSubFrameLength; ++k) {
            (*frame)[band][/*channel=*/0]
                    [sub_frame_index * kSubFrameLength + k] +=
                (*frame)[band][ch][sub_frame_index * kSubFrameLength + k];
          }
        }
        const float one_by_num_channels = 1.0f / frame_num_channels;
        for (size_t k = 0; k < kSubFrameLength; ++k) {
          (*frame)[band][/*channel=*/0][sub_frame_index * kSubFrameLength +
                                        k] *= one_by_num_channels;
        }
      }
    }
    for (size_t band = 0; band < frame->size(); ++band) {
      (*sub_frame_view)[band][/*channel=*/0] = rtc::ArrayView<float>(
          &(*frame)[band][/*channel=*/0][sub_frame_index * kSubFrameLength],
          kSubFrameLength);
    }
  } else {
    RTC_DCHECK_EQ(frame_num_channels, sub_frame_num_channels);
    for (size_t band = 0; band < frame->size(); ++band) {
      for (size_t channel = 0; channel < (*frame)[band].size(); ++channel) {
        (*sub_frame_view)[band][channel] = rtc::ArrayView<float>(
            &(*frame)[band][channel][sub_frame_index * kSubFrameLength],
            kSubFrameLength);
      }
    }
  }
}

void ProcessCaptureFrameContent(
    AudioBuffer* linear_output,
    AudioBuffer* capture,
    bool level_change,
    bool aec_reference_is_downmixed_stereo,
    bool saturated_microphone_signal,
    size_t sub_frame_index,
    FrameBlocker* capture_blocker,
    BlockFramer* linear_output_framer,
    BlockFramer* output_framer,
    BlockProcessor* block_processor,
    Block* linear_output_block,
    std::vector<std::vector<rtc::ArrayView<float>>>*
        linear_output_sub_frame_view,
    Block* capture_block,
    std::vector<std::vector<rtc::ArrayView<float>>>* capture_sub_frame_view) {
  FillSubFrameView(capture, sub_frame_index, capture_sub_frame_view);

  if (linear_output) {
    RTC_DCHECK(linear_output_framer);
    RTC_DCHECK(linear_output_block);
    RTC_DCHECK(linear_output_sub_frame_view);
    FillSubFrameView(linear_output, sub_frame_index,
                     linear_output_sub_frame_view);
  }

  capture_blocker->InsertSubFrameAndExtractBlock(*capture_sub_frame_view,
                                                 capture_block);
  block_processor->ProcessCapture(
      /*echo_path_gain_change=*/level_change ||
          aec_reference_is_downmixed_stereo,
      saturated_microphone_signal, linear_output_block, capture_block);
  output_framer->InsertBlockAndExtractSubFrame(*capture_block,
                                               capture_sub_frame_view);

  if (linear_output) {
    RTC_DCHECK(linear_output_framer);
    linear_output_framer->InsertBlockAndExtractSubFrame(
        *linear_output_block, linear_output_sub_frame_view);
  }
}

void ProcessRemainingCaptureFrameContent(bool level_change,
                                         bool aec_reference_is_downmixed_stereo,
                                         bool saturated_microphone_signal,
                                         FrameBlocker* capture_blocker,
                                         BlockFramer* linear_output_framer,
                                         BlockFramer* output_framer,
                                         BlockProcessor* block_processor,
                                         Block* linear_output_block,
                                         Block* block) {
  if (!capture_blocker->IsBlockAvailable()) {
    return;
  }

  capture_blocker->ExtractBlock(block);
  block_processor->ProcessCapture(
      /*echo_path_gain_change=*/level_change ||
          aec_reference_is_downmixed_stereo,
      saturated_microphone_signal, linear_output_block, block);
  output_framer->InsertBlock(*block);

  if (linear_output_framer) {
    RTC_DCHECK(linear_output_block);
    linear_output_framer->InsertBlock(*linear_output_block);
  }
}

void BufferRenderFrameContent(
    bool proper_downmix_needed,
    std::vector<std::vector<std::vector<float>>>* render_frame,
    size_t sub_frame_index,
    FrameBlocker* render_blocker,
    BlockProcessor* block_processor,
    Block* block,
    std::vector<std::vector<rtc::ArrayView<float>>>* sub_frame_view) {
  FillSubFrameView(proper_downmix_needed, render_frame, sub_frame_index,
                   sub_frame_view);
  render_blocker->InsertSubFrameAndExtractBlock(*sub_frame_view, block);
  block_processor->BufferRender(*block);
}

void BufferRemainingRenderFrameContent(FrameBlocker* render_blocker,
                                       BlockProcessor* block_processor,
                                       Block* block) {
  if (!render_blocker->IsBlockAvailable()) {
    return;
  }
  render_blocker->ExtractBlock(block);
  block_processor->BufferRender(*block);
}

void CopyBufferIntoFrame(const AudioBuffer& buffer,
                         size_t num_bands,
                         size_t num_channels,
                         std::vector<std::vector<std::vector<float>>>* frame) {
  RTC_DCHECK_EQ(num_bands, frame->size());
  RTC_DCHECK_EQ(num_channels, (*frame)[0].size());
  RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, (*frame)[0][0].size());
  for (size_t band = 0; band < num_bands; ++band) {
    for (size_t channel = 0; channel < num_channels; ++channel) {
      rtc::ArrayView<const float> buffer_view(
          &buffer.split_bands_const(channel)[band][0],
          AudioBuffer::kSplitBandSize);
      std::copy(buffer_view.begin(), buffer_view.end(),
                (*frame)[band][channel].begin());
    }
  }
}

}  // namespace

// TODO(webrtc:5298): Move this to a separate file.
EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
  EchoCanceller3Config adjusted_cfg = config;

  if (field_trial::IsEnabled("WebRTC-Aec3StereoContentDetectionKillSwitch")) {
    adjusted_cfg.multi_channel.detect_stereo_content = false;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3AntiHowlingMinimizationKillSwitch")) {
    adjusted_cfg.suppressor.high_bands_suppression
        .anti_howling_activation_threshold = 25.f;
    adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain = 0.01f;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3UseShortConfigChangeDuration")) {
    adjusted_cfg.filter.config_change_duration_blocks = 10;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3UseZeroInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = 0.f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3UseDot1SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = .1f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3UseDot2SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = .2f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3UseDot3SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = .3f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3UseDot6SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = .6f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3UseDot9SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = .9f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3Use1Dot2SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = 1.2f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3Use1Dot6SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = 1.6f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3Use2Dot0SecondsInitialStateDuration")) {
    adjusted_cfg.filter.initial_state_seconds = 2.0f;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3HighPassFilterEchoReference")) {
    adjusted_cfg.filter.high_pass_filter_echo_reference = true;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3EchoSaturationDetectionKillSwitch")) {
    adjusted_cfg.ep_strength.echo_can_saturate = false;
  }

  const std::string use_nearend_reverb_len_tunings =
      field_trial::FindFullName("WebRTC-Aec3UseNearendReverbLen");
  FieldTrialParameter<double> nearend_reverb_default_len(
      "default_len", adjusted_cfg.ep_strength.default_len);
  FieldTrialParameter<double> nearend_reverb_nearend_len(
      "nearend_len", adjusted_cfg.ep_strength.nearend_len);

  ParseFieldTrial({&nearend_reverb_default_len, &nearend_reverb_nearend_len},
                  use_nearend_reverb_len_tunings);
  float default_len = static_cast<float>(nearend_reverb_default_len.Get());
  float nearend_len = static_cast<float>(nearend_reverb_nearend_len.Get());
  if (default_len > -1 && default_len < 1 && nearend_len > -1 &&
      nearend_len < 1) {
    adjusted_cfg.ep_strength.default_len =
        static_cast<float>(nearend_reverb_default_len.Get());
    adjusted_cfg.ep_strength.nearend_len =
        static_cast<float>(nearend_reverb_nearend_len.Get());
  }

  if (field_trial::IsEnabled("WebRTC-Aec3ConservativeTailFreqResponse")) {
    adjusted_cfg.ep_strength.use_conservative_tail_frequency_response = true;
  }

  if (field_trial::IsDisabled("WebRTC-Aec3ConservativeTailFreqResponse")) {
    adjusted_cfg.ep_strength.use_conservative_tail_frequency_response = false;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) {
    // Two blocks headroom.
    adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToZeroKillSwitch")) {
    adjusted_cfg.erle.clamp_quality_estimate_to_zero = false;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3ClampInstQualityToOneKillSwitch")) {
    adjusted_cfg.erle.clamp_quality_estimate_to_one = false;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3OnsetDetectionKillSwitch")) {
    adjusted_cfg.erle.onset_detection = false;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceRenderDelayEstimationDownmixing")) {
    adjusted_cfg.delay.render_alignment_mixing.downmix = true;
    adjusted_cfg.delay.render_alignment_mixing.adaptive_selection = false;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceCaptureDelayEstimationDownmixing")) {
    adjusted_cfg.delay.capture_alignment_mixing.downmix = true;
    adjusted_cfg.delay.capture_alignment_mixing.adaptive_selection = false;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceCaptureDelayEstimationLeftRightPrioritization")) {
    adjusted_cfg.delay.capture_alignment_mixing.prefer_first_two_channels =
        true;
  }

  if (field_trial::IsEnabled(
          "WebRTC-"
          "Aec3RenderDelayEstimationLeftRightPrioritizationKillSwitch")) {
    adjusted_cfg.delay.capture_alignment_mixing.prefer_first_two_channels =
        false;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3SensitiveDominantNearendActivation")) {
    adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold = 0.5f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3VerySensitiveDominantNearendActivation")) {
    adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold = 0.75f;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3TransparentAntiHowlingGain")) {
    adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain = 1.f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceMoreTransparentNormalSuppressorTuning")) {
    adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent = 0.4f;
    adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress = 0.5f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceMoreTransparentNearendSuppressorTuning")) {
    adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent = 1.29f;
    adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress = 1.3f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceMoreTransparentNormalSuppressorHfTuning")) {
    adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent = 0.3f;
    adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress = 0.4f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceMoreTransparentNearendSuppressorHfTuning")) {
    adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent = 1.09f;
    adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress = 1.1f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceRapidlyAdjustingNormalSuppressorTunings")) {
    adjusted_cfg.suppressor.normal_tuning.max_inc_factor = 2.5f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceRapidlyAdjustingNearendSuppressorTunings")) {
    adjusted_cfg.suppressor.nearend_tuning.max_inc_factor = 2.5f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceSlowlyAdjustingNormalSuppressorTunings")) {
    adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf = .2f;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceSlowlyAdjustingNearendSuppressorTunings")) {
    adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf = .2f;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3EnforceConservativeHfSuppression")) {
    adjusted_cfg.suppressor.conservative_hf_suppression = true;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3EnforceStationarityProperties")) {
    adjusted_cfg.echo_audibility.use_stationarity_properties = true;
  }

  if (field_trial::IsEnabled(
          "WebRTC-Aec3EnforceStationarityPropertiesAtInit")) {
    adjusted_cfg.echo_audibility.use_stationarity_properties_at_init = true;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3EnforceLowActiveRenderLimit")) {
    adjusted_cfg.render_levels.active_render_limit = 50.f;
  } else if (field_trial::IsEnabled(
                 "WebRTC-Aec3EnforceVeryLowActiveRenderLimit")) {
    adjusted_cfg.render_levels.active_render_limit = 30.f;
  }

  if (field_trial::IsEnabled("WebRTC-Aec3NonlinearModeReverbKillSwitch")) {
    adjusted_cfg.echo_model.model_reverb_in_nonlinear_mode = false;
  }

  // Field-trial based override for the whole suppressor tuning.
  const std::string suppressor_tuning_override_trial_name =
      field_trial::FindFullName("WebRTC-Aec3SuppressorTuningOverride");

  FieldTrialParameter<double> nearend_tuning_mask_lf_enr_transparent(
      "nearend_tuning_mask_lf_enr_transparent",
      adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent);
  FieldTrialParameter<double> nearend_tuning_mask_lf_enr_suppress(
      "nearend_tuning_mask_lf_enr_suppress",
      adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress);
  FieldTrialParameter<double> nearend_tuning_mask_hf_enr_transparent(
      "nearend_tuning_mask_hf_enr_transparent",
      adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent);
  FieldTrialParameter<double> nearend_tuning_mask_hf_enr_suppress(
      "nearend_tuning_mask_hf_enr_suppress",
      adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress);
  FieldTrialParameter<double> nearend_tuning_max_inc_factor(
      "nearend_tuning_max_inc_factor",
      adjusted_cfg.suppressor.nearend_tuning.max_inc_factor);
  FieldTrialParameter<double> nearend_tuning_max_dec_factor_lf(
      "nearend_tuning_max_dec_factor_lf",
      adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf);
  FieldTrialParameter<double> normal_tuning_mask_lf_enr_transparent(
      "normal_tuning_mask_lf_enr_transparent",
      adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent);
  FieldTrialParameter<double> normal_tuning_mask_lf_enr_suppress(
      "normal_tuning_mask_lf_enr_suppress",
      adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress);
  FieldTrialParameter<double> normal_tuning_mask_hf_enr_transparent(
      "normal_tuning_mask_hf_enr_transparent",
      adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent);
  FieldTrialParameter<double> normal_tuning_mask_hf_enr_suppress(
      "normal_tuning_mask_hf_enr_suppress",
      adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress);
  FieldTrialParameter<double> normal_tuning_max_inc_factor(
      "normal_tuning_max_inc_factor",
      adjusted_cfg.suppressor.normal_tuning.max_inc_factor);
  FieldTrialParameter<double> normal_tuning_max_dec_factor_lf(
      "normal_tuning_max_dec_factor_lf",
      adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf);
  FieldTrialParameter<double> dominant_nearend_detection_enr_threshold(
      "dominant_nearend_detection_enr_threshold",
      adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold);
  FieldTrialParameter<double> dominant_nearend_detection_enr_exit_threshold(
      "dominant_nearend_detection_enr_exit_threshold",
      adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold);
  FieldTrialParameter<double> dominant_nearend_detection_snr_threshold(
      "dominant_nearend_detection_snr_threshold",
      adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold);
  FieldTrialParameter<int> dominant_nearend_detection_hold_duration(
      "dominant_nearend_detection_hold_duration",
      adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration);
  FieldTrialParameter<int> dominant_nearend_detection_trigger_threshold(
      "dominant_nearend_detection_trigger_threshold",
      adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold);

  ParseFieldTrial(
      {&nearend_tuning_mask_lf_enr_transparent,
       &nearend_tuning_mask_lf_enr_suppress,
       &nearend_tuning_mask_hf_enr_transparent,
       &nearend_tuning_mask_hf_enr_suppress, &nearend_tuning_max_inc_factor,
       &nearend_tuning_max_dec_factor_lf,
       &normal_tuning_mask_lf_enr_transparent,
       &normal_tuning_mask_lf_enr_suppress,
       &normal_tuning_mask_hf_enr_transparent,
       &normal_tuning_mask_hf_enr_suppress, &normal_tuning_max_inc_factor,
       &normal_tuning_max_dec_factor_lf,
       &dominant_nearend_detection_enr_threshold,
       &dominant_nearend_detection_enr_exit_threshold,
       &dominant_nearend_detection_snr_threshold,
       &dominant_nearend_detection_hold_duration,
       &dominant_nearend_detection_trigger_threshold},
      suppressor_tuning_override_trial_name);

  adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent =
      static_cast<float>(nearend_tuning_mask_lf_enr_transparent.Get());
  adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress =
      static_cast<float>(nearend_tuning_mask_lf_enr_suppress.Get());
  adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent =
      static_cast<float>(nearend_tuning_mask_hf_enr_transparent.Get());
  adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress =
      static_cast<float>(nearend_tuning_mask_hf_enr_suppress.Get());
  adjusted_cfg.suppressor.nearend_tuning.max_inc_factor =
      static_cast<float>(nearend_tuning_max_inc_factor.Get());
  adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf =
      static_cast<float>(nearend_tuning_max_dec_factor_lf.Get());
  adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent =
      static_cast<float>(normal_tuning_mask_lf_enr_transparent.Get());
  adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress =
      static_cast<float>(normal_tuning_mask_lf_enr_suppress.Get());
  adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent =
      static_cast<float>(normal_tuning_mask_hf_enr_transparent.Get());
  adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress =
      static_cast<float>(normal_tuning_mask_hf_enr_suppress.Get());
  adjusted_cfg.suppressor.normal_tuning.max_inc_factor =
      static_cast<float>(normal_tuning_max_inc_factor.Get());
  adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf =
      static_cast<float>(normal_tuning_max_dec_factor_lf.Get());
  adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold =
      static_cast<float>(dominant_nearend_detection_enr_threshold.Get());
  adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold =
      static_cast<float>(dominant_nearend_detection_enr_exit_threshold.Get());
  adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold =
      static_cast<float>(dominant_nearend_detection_snr_threshold.Get());
  adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration =
      dominant_nearend_detection_hold_duration.Get();
  adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold =
      dominant_nearend_detection_trigger_threshold.Get();

  // Field trial-based overrides of individual suppressor parameters.
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendLfMaskTransparentOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendLfMaskSuppressOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendHfMaskTransparentOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendHfMaskSuppressOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendMaxIncFactorOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.max_inc_factor);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNearendMaxDecFactorLfOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf);

  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalLfMaskTransparentOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_transparent);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalLfMaskSuppressOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.mask_lf.enr_suppress);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalHfMaskTransparentOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_transparent);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalHfMaskSuppressOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.mask_hf.enr_suppress);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalMaxIncFactorOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.max_inc_factor);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorNormalMaxDecFactorLfOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.normal_tuning.max_dec_factor_lf);

  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorDominantNearendEnrThresholdOverride", 0.f, 100.f,
      &adjusted_cfg.suppressor.dominant_nearend_detection.enr_threshold);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorDominantNearendEnrExitThresholdOverride", 0.f,
      100.f,
      &adjusted_cfg.suppressor.dominant_nearend_detection.enr_exit_threshold);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorDominantNearendSnrThresholdOverride", 0.f, 100.f,
      &adjusted_cfg.suppressor.dominant_nearend_detection.snr_threshold);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorDominantNearendHoldDurationOverride", 0, 1000,
      &adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorDominantNearendTriggerThresholdOverride", 0, 1000,
      &adjusted_cfg.suppressor.dominant_nearend_detection.trigger_threshold);

  RetrieveFieldTrialValue(
      "WebRTC-Aec3SuppressorAntiHowlingGainOverride", 0.f, 10.f,
      &adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain);

  // Field trial-based overrides of individual delay estimator parameters.
  RetrieveFieldTrialValue("WebRTC-Aec3DelayEstimateSmoothingOverride", 0.f, 1.f,
                          &adjusted_cfg.delay.delay_estimate_smoothing);
  RetrieveFieldTrialValue(
      "WebRTC-Aec3DelayEstimateSmoothingDelayFoundOverride", 0.f, 1.f,
      &adjusted_cfg.delay.delay_estimate_smoothing_delay_found);

  int max_allowed_excess_render_blocks_override =
      adjusted_cfg.buffering.max_allowed_excess_render_blocks;
  RetrieveFieldTrialValue(
      "WebRTC-Aec3BufferingMaxAllowedExcessRenderBlocksOverride", 0, 20,
      &max_allowed_excess_render_blocks_override);
  adjusted_cfg.buffering.max_allowed_excess_render_blocks =
      max_allowed_excess_render_blocks_override;
  return adjusted_cfg;
}

class EchoCanceller3::RenderWriter {
 public:
  RenderWriter(ApmDataDumper* data_dumper,
               const EchoCanceller3Config& config,
               SwapQueue<std::vector<std::vector<std::vector<float>>>,
                         Aec3RenderQueueItemVerifier>* render_transfer_queue,
               size_t num_bands,
               size_t num_channels);

  RenderWriter() = delete;
  RenderWriter(const RenderWriter&) = delete;
  RenderWriter& operator=(const RenderWriter&) = delete;

  ~RenderWriter();
  void Insert(const AudioBuffer& input);

 private:
  ApmDataDumper* data_dumper_;
  const size_t num_bands_;
  const size_t num_channels_;
  std::unique_ptr<HighPassFilter> high_pass_filter_;
  std::vector<std::vector<std::vector<float>>> render_queue_input_frame_;
  SwapQueue<std::vector<std::vector<std::vector<float>>>,
            Aec3RenderQueueItemVerifier>* render_transfer_queue_;
};

EchoCanceller3::RenderWriter::RenderWriter(
    ApmDataDumper* data_dumper,
    const EchoCanceller3Config& config,
    SwapQueue<std::vector<std::vector<std::vector<float>>>,
              Aec3RenderQueueItemVerifier>* render_transfer_queue,
    size_t num_bands,
    size_t num_channels)
    : data_dumper_(data_dumper),
      num_bands_(num_bands),
      num_channels_(num_channels),
      render_queue_input_frame_(
          num_bands_,
          std::vector<std::vector<float>>(
              num_channels_,
              std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
      render_transfer_queue_(render_transfer_queue) {
  RTC_DCHECK(data_dumper);
  if (config.filter.high_pass_filter_echo_reference) {
    high_pass_filter_ = std::make_unique<HighPassFilter>(16000, num_channels);
  }
}

EchoCanceller3::RenderWriter::~RenderWriter() = default;

void EchoCanceller3::RenderWriter::Insert(const AudioBuffer& input) {
  RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, input.num_frames_per_band());
  RTC_DCHECK_EQ(num_bands_, input.num_bands());
  RTC_DCHECK_EQ(num_channels_, input.num_channels());

  // TODO(bugs.webrtc.org/8759) Temporary work-around.
  if (num_bands_ != input.num_bands())
    return;

  data_dumper_->DumpWav("aec3_render_input", AudioBuffer::kSplitBandSize,
                        &input.split_bands_const(0)[0][0], 16000, 1);

  CopyBufferIntoFrame(input, num_bands_, num_channels_,
                      &render_queue_input_frame_);
  if (high_pass_filter_) {
    high_pass_filter_->Process(&render_queue_input_frame_[0]);
  }

  static_cast<void>(render_transfer_queue_->Insert(&render_queue_input_frame_));
}

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

EchoCanceller3::EchoCanceller3(
    const EchoCanceller3Config& config,
    const absl::optional<EchoCanceller3Config>& multichannel_config,
    int sample_rate_hz,
    size_t num_render_channels,
    size_t num_capture_channels)
    : data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
      config_(AdjustConfig(config)),
      sample_rate_hz_(sample_rate_hz),
      num_bands_(NumBandsForRate(sample_rate_hz_)),
      num_render_input_channels_(num_render_channels),
      num_capture_channels_(num_capture_channels),
      config_selector_(AdjustConfig(config),
                       multichannel_config,
                       num_render_input_channels_),
      multichannel_content_detector_(
          config_selector_.active_config().multi_channel.detect_stereo_content,
          num_render_input_channels_,
          config_selector_.active_config()
              .multi_channel.stereo_detection_threshold,
          config_selector_.active_config()
              .multi_channel.stereo_detection_timeout_threshold_seconds,
          config_selector_.active_config()
              .multi_channel.stereo_detection_hysteresis_seconds),
      output_framer_(num_bands_, num_capture_channels_),
      capture_blocker_(num_bands_, num_capture_channels_),
      render_transfer_queue_(
          kRenderTransferQueueSizeFrames,
          std::vector<std::vector<std::vector<float>>>(
              num_bands_,
              std::vector<std::vector<float>>(
                  num_render_input_channels_,
                  std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
          Aec3RenderQueueItemVerifier(num_bands_,
                                      num_render_input_channels_,
                                      AudioBuffer::kSplitBandSize)),
      render_queue_output_frame_(
          num_bands_,
          std::vector<std::vector<float>>(
              num_render_input_channels_,
              std::vector<float>(AudioBuffer::kSplitBandSize, 0.f))),
      render_block_(num_bands_, num_render_input_channels_),
      capture_block_(num_bands_, num_capture_channels_),
      capture_sub_frame_view_(
          num_bands_,
          std::vector<rtc::ArrayView<float>>(num_capture_channels_)) {
  RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));

  if (config_selector_.active_config().delay.fixed_capture_delay_samples > 0) {
    block_delay_buffer_.reset(new BlockDelayBuffer(
        num_capture_channels_, num_bands_, AudioBuffer::kSplitBandSize,
        config_.delay.fixed_capture_delay_samples));
  }

  render_writer_.reset(new RenderWriter(
      data_dumper_.get(), config_selector_.active_config(),
      &render_transfer_queue_, num_bands_, num_render_input_channels_));

  RTC_DCHECK_EQ(num_bands_, std::max(sample_rate_hz_, 16000) / 16000);
  RTC_DCHECK_GE(kMaxNumBands, num_bands_);

  if (config_selector_.active_config().filter.export_linear_aec_output) {
    linear_output_framer_.reset(
        new BlockFramer(/*num_bands=*/1, num_capture_channels_));
    linear_output_block_ =
        std::make_unique<Block>(/*num_bands=*/1, num_capture_channels_),
    linear_output_sub_frame_view_ =
        std::vector<std::vector<rtc::ArrayView<float>>>(
            1, std::vector<rtc::ArrayView<float>>(num_capture_channels_));
  }

  Initialize();

  RTC_LOG(LS_INFO) << "AEC3 created with sample rate: " << sample_rate_hz_
                   << " Hz, num render channels: " << num_render_input_channels_
                   << ", num capture channels: " << num_capture_channels_;
}

EchoCanceller3::~EchoCanceller3() = default;

void EchoCanceller3::Initialize() {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);

  num_render_channels_to_aec_ =
      multichannel_content_detector_.IsProperMultiChannelContentDetected()
          ? num_render_input_channels_
          : 1;

  config_selector_.Update(
      multichannel_content_detector_.IsProperMultiChannelContentDetected());

  render_block_.SetNumChannels(num_render_channels_to_aec_);

  render_blocker_.reset(
      new FrameBlocker(num_bands_, num_render_channels_to_aec_));

  block_processor_.reset(BlockProcessor::Create(
      config_selector_.active_config(), sample_rate_hz_,
      num_render_channels_to_aec_, num_capture_channels_));

  render_sub_frame_view_ = std::vector<std::vector<rtc::ArrayView<float>>>(
      num_bands_,
      std::vector<rtc::ArrayView<float>>(num_render_channels_to_aec_));
}

void EchoCanceller3::AnalyzeRender(const AudioBuffer& render) {
  RTC_DCHECK_RUNS_SERIALIZED(&render_race_checker_);

  RTC_DCHECK_EQ(render.num_channels(), num_render_input_channels_);
  data_dumper_->DumpRaw("aec3_call_order",
                        static_cast<int>(EchoCanceller3ApiCall::kRender));

  return render_writer_->Insert(render);
}

void EchoCanceller3::AnalyzeCapture(const AudioBuffer& capture) {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  data_dumper_->DumpWav("aec3_capture_analyze_input", capture.num_frames(),
                        capture.channels_const()[0], sample_rate_hz_, 1);
  saturated_microphone_signal_ = false;
  for (size_t channel = 0; channel < capture.num_channels(); ++channel) {
    saturated_microphone_signal_ |=
        DetectSaturation(rtc::ArrayView<const float>(
            capture.channels_const()[channel], capture.num_frames()));
    if (saturated_microphone_signal_) {
      break;
    }
  }
}

void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) {
  ProcessCapture(capture, nullptr, level_change);
}

void EchoCanceller3::ProcessCapture(AudioBuffer* capture,
                                    AudioBuffer* linear_output,
                                    bool level_change) {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  RTC_DCHECK(capture);
  RTC_DCHECK_EQ(num_bands_, capture->num_bands());
  RTC_DCHECK_EQ(AudioBuffer::kSplitBandSize, capture->num_frames_per_band());
  RTC_DCHECK_EQ(capture->num_channels(), num_capture_channels_);
  data_dumper_->DumpRaw("aec3_call_order",
                        static_cast<int>(EchoCanceller3ApiCall::kCapture));

  if (linear_output && !linear_output_framer_) {
    RTC_LOG(LS_ERROR) << "Trying to retrieve the linear AEC output without "
                         "properly configuring AEC3.";
    RTC_DCHECK_NOTREACHED();
  }

  // Report capture call in the metrics and periodically update API call
  // metrics.
  api_call_metrics_.ReportCaptureCall();

  // Optionally delay the capture signal.
  if (config_selector_.active_config().delay.fixed_capture_delay_samples > 0) {
    RTC_DCHECK(block_delay_buffer_);
    block_delay_buffer_->DelaySignal(capture);
  }

  rtc::ArrayView<float> capture_lower_band = rtc::ArrayView<float>(
      &capture->split_bands(0)[0][0], AudioBuffer::kSplitBandSize);

  data_dumper_->DumpWav("aec3_capture_input", capture_lower_band, 16000, 1);

  EmptyRenderQueue();

  ProcessCaptureFrameContent(
      linear_output, capture, level_change,
      multichannel_content_detector_.IsTemporaryMultiChannelContentDetected(),
      saturated_microphone_signal_, 0, &capture_blocker_,
      linear_output_framer_.get(), &output_framer_, block_processor_.get(),
      linear_output_block_.get(), &linear_output_sub_frame_view_,
      &capture_block_, &capture_sub_frame_view_);

  ProcessCaptureFrameContent(
      linear_output, capture, level_change,
      multichannel_content_detector_.IsTemporaryMultiChannelContentDetected(),
      saturated_microphone_signal_, 1, &capture_blocker_,
      linear_output_framer_.get(), &output_framer_, block_processor_.get(),
      linear_output_block_.get(), &linear_output_sub_frame_view_,
      &capture_block_, &capture_sub_frame_view_);

  ProcessRemainingCaptureFrameContent(
      level_change,
      multichannel_content_detector_.IsTemporaryMultiChannelContentDetected(),
      saturated_microphone_signal_, &capture_blocker_,
      linear_output_framer_.get(), &output_framer_, block_processor_.get(),
      linear_output_block_.get(), &capture_block_);

  data_dumper_->DumpWav("aec3_capture_output", AudioBuffer::kSplitBandSize,
                        &capture->split_bands(0)[0][0], 16000, 1);
}

EchoControl::Metrics EchoCanceller3::GetMetrics() const {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  Metrics metrics;
  block_processor_->GetMetrics(&metrics);
  return metrics;
}

void EchoCanceller3::SetAudioBufferDelay(int delay_ms) {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  block_processor_->SetAudioBufferDelay(delay_ms);
}

void EchoCanceller3::SetCaptureOutputUsage(bool capture_output_used) {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  block_processor_->SetCaptureOutputUsage(capture_output_used);
}

bool EchoCanceller3::ActiveProcessing() const {
  return true;
}

EchoCanceller3Config EchoCanceller3::CreateDefaultMultichannelConfig() {
  EchoCanceller3Config cfg;
  // Use shorter and more rapidly adapting coarse filter to compensate for
  // thge increased number of total filter parameters to adapt.
  cfg.filter.coarse.length_blocks = 11;
  cfg.filter.coarse.rate = 0.95f;
  cfg.filter.coarse_initial.length_blocks = 11;
  cfg.filter.coarse_initial.rate = 0.95f;

  // Use more concervative suppressor behavior for non-nearend speech.
  cfg.suppressor.normal_tuning.max_dec_factor_lf = 0.35f;
  cfg.suppressor.normal_tuning.max_inc_factor = 1.5f;
  return cfg;
}

void EchoCanceller3::SetBlockProcessorForTesting(
    std::unique_ptr<BlockProcessor> block_processor) {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  RTC_DCHECK(block_processor);
  block_processor_ = std::move(block_processor);
}

void EchoCanceller3::EmptyRenderQueue() {
  RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_);
  bool frame_to_buffer =
      render_transfer_queue_.Remove(&render_queue_output_frame_);
  while (frame_to_buffer) {
    // Report render call in the metrics.
    api_call_metrics_.ReportRenderCall();

    if (multichannel_content_detector_.UpdateDetection(
            render_queue_output_frame_)) {
      // Reinitialize the AEC when proper stereo is detected.
      Initialize();
    }

    // Buffer frame content.
    BufferRenderFrameContent(
        /*proper_downmix_needed=*/multichannel_content_detector_
            .IsTemporaryMultiChannelContentDetected(),
        &render_queue_output_frame_, 0, render_blocker_.get(),
        block_processor_.get(), &render_block_, &render_sub_frame_view_);

    BufferRenderFrameContent(
        /*proper_downmix_needed=*/multichannel_content_detector_
            .IsTemporaryMultiChannelContentDetected(),
        &render_queue_output_frame_, 1, render_blocker_.get(),
        block_processor_.get(), &render_block_, &render_sub_frame_view_);

    BufferRemainingRenderFrameContent(render_blocker_.get(),
                                      block_processor_.get(), &render_block_);

    frame_to_buffer =
        render_transfer_queue_.Remove(&render_queue_output_frame_);
  }
}
}  // namespace webrtc
