/*
 *  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 <atomic>
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/audio/echo_canceller3_config.h"
#include "api/audio/echo_control.h"
#include "api/audio/neural_residual_echo_estimator.h"
#include "api/environment/environment.h"
#include "api/field_trials_view.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/block_delay_buffer.h"
#include "modules/audio_processing/aec3/block_framer.h"
#include "modules/audio_processing/aec3/block_processor.h"
#include "modules/audio_processing/aec3/frame_blocker.h"
#include "modules/audio_processing/high_pass_filter.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/swap_queue.h"

namespace webrtc {

namespace {

enum class EchoCanceller3ApiCall { kCapture, kRender };

bool DetectSaturation(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(const FieldTrialsView& field_trials,
                             absl::string_view trial_name,
                             float min,
                             float max,
                             float* value_to_update) {
  const std::string field_trial_str = field_trials.Lookup(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(const FieldTrialsView& field_trials,
                             absl::string_view trial_name,
                             int min,
                             int max,
                             int* value_to_update) {
  const std::string field_trial_str = field_trials.Lookup(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<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] = 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<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] = 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] = 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<ArrayView<float>>>* linear_output_sub_frame_view,
    Block* capture_block,
    std::vector<std::vector<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<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) {
      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,
                                  const FieldTrialsView& field_trials) {
  EchoCanceller3Config adjusted_cfg = config;

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

  if (field_trials.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_trials.IsEnabled("WebRTC-Aec3UseShortConfigChangeDuration")) {
    adjusted_cfg.filter.config_change_duration_blocks = 10;
  }

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

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

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

  const std::string use_nearend_reverb_len_tunings =
      field_trials.Lookup("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_trials.IsEnabled("WebRTC-Aec3ConservativeTailFreqResponse")) {
    adjusted_cfg.ep_strength.use_conservative_tail_frequency_response = true;
  }

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

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

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

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

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

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

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

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

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

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

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

  if (field_trials.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_trials.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_trials.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_trials.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_trials.IsEnabled(
          "WebRTC-Aec3EnforceRapidlyAdjustingNormalSuppressorTunings")) {
    adjusted_cfg.suppressor.normal_tuning.max_inc_factor = 2.5f;
  }

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

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

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

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

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

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

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

  if (field_trials.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_trials.Lookup("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(
      field_trials, "WebRTC-Aec3SuppressorNearendLfMaskTransparentOverride",
      0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_transparent);
  RetrieveFieldTrialValue(
      field_trials, "WebRTC-Aec3SuppressorNearendLfMaskSuppressOverride", 0.f,
      10.f, &adjusted_cfg.suppressor.nearend_tuning.mask_lf.enr_suppress);
  RetrieveFieldTrialValue(
      field_trials, "WebRTC-Aec3SuppressorNearendHfMaskTransparentOverride",
      0.f, 10.f,
      &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_transparent);
  RetrieveFieldTrialValue(
      field_trials, "WebRTC-Aec3SuppressorNearendHfMaskSuppressOverride", 0.f,
      10.f, &adjusted_cfg.suppressor.nearend_tuning.mask_hf.enr_suppress);
  RetrieveFieldTrialValue(
      field_trials, "WebRTC-Aec3SuppressorNearendMaxIncFactorOverride", 0.f,
      10.f, &adjusted_cfg.suppressor.nearend_tuning.max_inc_factor);
  RetrieveFieldTrialValue(
      field_trials, "WebRTC-Aec3SuppressorNearendMaxDecFactorLfOverride", 0.f,
      10.f, &adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf);

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

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

  RetrieveFieldTrialValue(
      field_trials, "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(field_trials,
                          "WebRTC-Aec3DelayEstimateSmoothingOverride", 0.f, 1.f,
                          &adjusted_cfg.delay.delay_estimate_smoothing);
  RetrieveFieldTrialValue(
      field_trials, "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(
      field_trials, "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());

  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 Environment& env,
    const EchoCanceller3Config& config,
    const std::optional<EchoCanceller3Config>& multichannel_config,
    NeuralResidualEchoEstimator* neural_residual_echo_estimator,
    int sample_rate_hz,
    size_t num_render_channels,
    size_t num_capture_channels)
    : env_(env),
      data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
      config_(AdjustConfig(config, env.field_trials())),
      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_(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),
      neural_residual_echo_estimator_(neural_residual_echo_estimator),
      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<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<ArrayView<float>>>(
        1, std::vector<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_ = BlockProcessor::Create(
      env_, config_selector_.active_config(), sample_rate_hz_,
      num_render_channels_to_aec_, num_capture_channels_,
      neural_residual_echo_estimator_);

  render_sub_frame_view_ = std::vector<std::vector<ArrayView<float>>>(
      num_bands_, std::vector<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(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);
  }

  ArrayView<float> capture_lower_band = 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;
}

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
