| Index: webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
|
| diff --git a/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e84439dbd9778008372bc8632c8e8d31f0827ec8
|
| --- /dev/null
|
| +++ b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
|
| @@ -0,0 +1,76 @@
|
| +/*
|
| + * 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 "webrtc/modules/audio_processing/aec3/residual_echo_estimator.h"
|
| +
|
| +#include <math.h>
|
| +#include <vector>
|
| +
|
| +#include "webrtc/base/checks.h"
|
| +
|
| +namespace webrtc {
|
| +
|
| +ResidualEchoEstimator::ResidualEchoEstimator() {
|
| + echo_path_gain_.fill(0.f);
|
| +}
|
| +
|
| +ResidualEchoEstimator::~ResidualEchoEstimator() = default;
|
| +
|
| +void ResidualEchoEstimator::Estimate(
|
| + const AecState& aec_state,
|
| + const FftBuffer& X_buffer,
|
| + const std::vector<std::array<float, kFftLengthBy2Plus1>>& H2,
|
| + const std::array<float, kFftLengthBy2Plus1>& E2_main,
|
| + const std::array<float, kFftLengthBy2Plus1>& E2_shadow,
|
| + const std::array<float, kFftLengthBy2Plus1>& S2_linear,
|
| + const std::array<float, kFftLengthBy2Plus1>& S2_fallback,
|
| + const std::array<float, kFftLengthBy2Plus1>& Y2,
|
| + const DelayHandler& delay_handler,
|
| + std::array<float, kFftLengthBy2Plus1>* R2) {
|
| + const rtc::Optional<size_t>& linear_filter_based_delay =
|
| + delay_handler.FilterDelay();
|
| + if (linear_filter_based_delay) {
|
| + std::copy(H2[*linear_filter_based_delay].begin(),
|
| + H2[*linear_filter_based_delay].end(), echo_path_gain_.begin());
|
| + }
|
| +
|
| + const std::array<bool, kFftLengthBy2Plus1>& bands_with_reliable_filter =
|
| + aec_state.BandsWithReliableFilter();
|
| +
|
| + if (aec_state.UsableLinearEstimate()) {
|
| + const std::array<float, kFftLengthBy2Plus1>& erle = aec_state.Erle();
|
| +
|
| + for (size_t k = 0; k < R2->size(); ++k) {
|
| + RTC_DCHECK_LT(0.f, erle[k]);
|
| + (*R2)[k] = bands_with_reliable_filter[k] ? S2_linear[k] / erle[k]
|
| + : S2_fallback[k];
|
| + }
|
| +
|
| + } else if (aec_state.ModelBasedAecFeasible()) {
|
| + const rtc::Optional<size_t>& provided_delay = delay_handler.ExternalDelay();
|
| + RTC_DCHECK(provided_delay);
|
| + const std::array<float, kFftLengthBy2Plus1>& X2 =
|
| + X_buffer.Spectrum(*provided_delay);
|
| + for (size_t k = 0; k < R2->size(); ++k) {
|
| + (*R2)[k] = bands_with_reliable_filter[k] ? echo_path_gain_[k] * X2[k]
|
| + : S2_fallback[k];
|
| + }
|
| + } else if (aec_state.EchoLeakageDetected()) {
|
| + if (aec_state.ActiveRender()) {
|
| + std::copy(Y2.begin(), Y2.end(), R2->begin());
|
| + } else {
|
| + R2->fill(0.f);
|
| + }
|
| + } else {
|
| + R2->fill(0.f);
|
| + }
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|