Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Unified Diff: webrtc/modules/audio_processing/aec3/aec_state.cc

Issue 2678423005: Finalization of the first version of EchoCanceller 3 (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/aec3/aec_state.cc
diff --git a/webrtc/modules/audio_processing/aec3/aec_state.cc b/webrtc/modules/audio_processing/aec3/aec_state.cc
new file mode 100644
index 0000000000000000000000000000000000000000..aca8b89c2a1374a6daae67a63a21534dbdea6730
--- /dev/null
+++ b/webrtc/modules/audio_processing/aec3/aec_state.cc
@@ -0,0 +1,106 @@
+/*
+ * 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/aec_state.h"
+
+#include <math.h>
+#include <numeric>
+#include <vector>
+
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+namespace {
+
+// Updates the bands where the filter performs reliable.
+void UpdateBandsWithReliableFilter(
+ rtc::ArrayView<const float> E2_main,
+ rtc::ArrayView<const float> E2_shadow,
+ rtc::ArrayView<const float> X2,
+ rtc::ArrayView<const float> Y2,
+ rtc::ArrayView<bool> bands_with_reliable_filter) {
+ const float kX2Min = 44015068.0f / 1000.f;
ivoc 2017/02/10 13:52:33 A comment about where this value comes from would
peah-webrtc 2017/02/20 07:37:15 Good point! It has now been removed though. Done.
ivoc 2017/02/21 17:26:00 Acknowledged.
peah-webrtc 2017/02/21 23:00:39 Acknowledged.
+ for (size_t k = 1; k < kFftLengthBy2 - 5; ++k) {
+ if (X2[k] > kX2Min) {
+ if (E2_main[k] > Y2[k]) {
+ bands_with_reliable_filter[k] = false;
+ } else {
ivoc 2017/02/10 13:52:33 this can be "else if" to avoid the nested if. One
peah-webrtc 2017/02/20 07:37:15 You definitely have a point. And in the tuning, th
ivoc 2017/02/21 17:26:00 Acknowledged.
peah-webrtc 2017/02/21 23:00:39 Acknowledged.
+ if ((2 * E2_main[k] < Y2[k]) || (E2_shadow[k] < E2_main[k])) {
+ bands_with_reliable_filter[k] = true;
+ }
+ }
+ }
+ }
+
+ bands_with_reliable_filter[0] = bands_with_reliable_filter[1];
+ std::fill(bands_with_reliable_filter.begin() + kFftLengthBy2 - 5,
+ bands_with_reliable_filter.end(),
+ bands_with_reliable_filter[kFftLengthBy2 - 6]);
+}
+
+constexpr int kActiveRenderCounterInitial = 50;
+constexpr int kActiveRenderCounterMax = 200;
+constexpr int kEchoPathChangeCounterInitial = 50;
+constexpr int kEchoPathChangeCounterMax = 200;
+
+} // namespace
+
+AecState::AecState()
+ : echo_path_change_counter_(kEchoPathChangeCounterInitial),
+ active_render_counter_(kActiveRenderCounterInitial) {
+ bands_with_reliable_filter_.fill(false);
+}
+
+AecState::~AecState() = default;
+
+void AecState::Update(const FftBuffer& X_buffer,
+ const std::array<float, kFftLengthBy2Plus1>& E2_main,
+ const std::array<float, kFftLengthBy2Plus1>& E2_shadow,
+ const std::array<float, kFftLengthBy2Plus1>& Y2,
+ rtc::ArrayView<const float> x,
+ const DelayHandler& delay_handler,
+ const EchoPathVariability& echo_path_variability,
+ bool echo_leakage_detected) {
+ const rtc::Optional<size_t> linear_filter_based_delay =
+ delay_handler.FilterDelay();
+
+ const float x_energy =
+ std::accumulate(x.begin(), x.end(), 0.f,
+ [](float a, float b) -> float { return a + b * b; });
+ echo_path_change_counter_ = echo_path_variability.AudioPathChanged()
+ ? kEchoPathChangeCounterMax
+ : echo_path_change_counter_ - 1;
+ active_render_counter_ = x_energy > 10000 * kFftLengthBy2
+ ? kActiveRenderCounterMax
+ : active_render_counter_ - 1;
+
+ usable_linear_estimate_ =
+ linear_filter_based_delay && echo_path_change_counter_ <= 0;
+
+ echo_leakage_detected_ = echo_leakage_detected;
+
+ model_based_aec_feasible_ =
+ usable_linear_estimate_ ||
+ (delay_handler.ExternalDelay() && echo_path_change_counter_ <= 0);
+
+ if (usable_linear_estimate_) {
+ const std::array<float, kFftLengthBy2Plus1>& X2 =
+ X_buffer.Spectrum(*linear_filter_based_delay);
+
+ UpdateBandsWithReliableFilter(E2_main, E2_shadow, X2, Y2,
+ bands_with_reliable_filter_);
+
+ // TODO(peah): Expose these as stats.
+ erle_estimator_.Update(X2, Y2, E2_main);
+ erl_estimator_.Update(X2, Y2);
+ }
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698