summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_processing/echo_detector
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/modules/audio_processing/echo_detector
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/modules/audio_processing/echo_detector')
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.cc49
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.h44
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer_unittest.cc53
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.cc47
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.h33
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator_unittest.cc65
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.cc52
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.h36
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max_unittest.cc68
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.cc43
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.h43
-rw-r--r--third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc41
12 files changed, 574 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.cc
new file mode 100644
index 0000000000..a6d10edfe2
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.cc
@@ -0,0 +1,49 @@
+/*
+ * 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/echo_detector/circular_buffer.h"
+
+#include <algorithm>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+CircularBuffer::CircularBuffer(size_t size) : buffer_(size) {}
+CircularBuffer::~CircularBuffer() = default;
+
+void CircularBuffer::Push(float value) {
+ buffer_[next_insertion_index_] = value;
+ ++next_insertion_index_;
+ next_insertion_index_ %= buffer_.size();
+ RTC_DCHECK_LT(next_insertion_index_, buffer_.size());
+ nr_elements_in_buffer_ = std::min(nr_elements_in_buffer_ + 1, buffer_.size());
+ RTC_DCHECK_LE(nr_elements_in_buffer_, buffer_.size());
+}
+
+absl::optional<float> CircularBuffer::Pop() {
+ if (nr_elements_in_buffer_ == 0) {
+ return absl::nullopt;
+ }
+ const size_t index =
+ (buffer_.size() + next_insertion_index_ - nr_elements_in_buffer_) %
+ buffer_.size();
+ RTC_DCHECK_LT(index, buffer_.size());
+ --nr_elements_in_buffer_;
+ return buffer_[index];
+}
+
+void CircularBuffer::Clear() {
+ std::fill(buffer_.begin(), buffer_.end(), 0.f);
+ next_insertion_index_ = 0;
+ nr_elements_in_buffer_ = 0;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.h b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.h
new file mode 100644
index 0000000000..db1aeaebf6
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_CIRCULAR_BUFFER_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_CIRCULAR_BUFFER_H_
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+// Ring buffer containing floating point values.
+struct CircularBuffer {
+ public:
+ explicit CircularBuffer(size_t size);
+ ~CircularBuffer();
+
+ void Push(float value);
+ absl::optional<float> Pop();
+ size_t Size() const { return nr_elements_in_buffer_; }
+ // This function fills the buffer with zeros, but does not change its size.
+ void Clear();
+
+ private:
+ std::vector<float> buffer_;
+ size_t next_insertion_index_ = 0;
+ // This is the number of elements that have been pushed into the circular
+ // buffer, not the allocated buffer size.
+ size_t nr_elements_in_buffer_ = 0;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_CIRCULAR_BUFFER_H_
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer_unittest.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer_unittest.cc
new file mode 100644
index 0000000000..7a234d4a55
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/circular_buffer_unittest.cc
@@ -0,0 +1,53 @@
+/*
+ * 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/echo_detector/circular_buffer.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(CircularBufferTests, LessThanMaxTest) {
+ CircularBuffer test_buffer(3);
+ test_buffer.Push(1.f);
+ test_buffer.Push(2.f);
+ EXPECT_EQ(1.f, test_buffer.Pop());
+ EXPECT_EQ(2.f, test_buffer.Pop());
+}
+
+TEST(CircularBufferTests, FillTest) {
+ CircularBuffer test_buffer(3);
+ test_buffer.Push(1.f);
+ test_buffer.Push(2.f);
+ test_buffer.Push(3.f);
+ EXPECT_EQ(1.f, test_buffer.Pop());
+ EXPECT_EQ(2.f, test_buffer.Pop());
+ EXPECT_EQ(3.f, test_buffer.Pop());
+}
+
+TEST(CircularBufferTests, OverflowTest) {
+ CircularBuffer test_buffer(3);
+ test_buffer.Push(1.f);
+ test_buffer.Push(2.f);
+ test_buffer.Push(3.f);
+ test_buffer.Push(4.f);
+ // Because the circular buffer has a size of 3, the first insert should have
+ // been forgotten.
+ EXPECT_EQ(2.f, test_buffer.Pop());
+ EXPECT_EQ(3.f, test_buffer.Pop());
+ EXPECT_EQ(4.f, test_buffer.Pop());
+}
+
+TEST(CircularBufferTests, ReadFromEmpty) {
+ CircularBuffer test_buffer(3);
+ EXPECT_EQ(absl::nullopt, test_buffer.Pop());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.cc
new file mode 100644
index 0000000000..a85740387b
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.cc
@@ -0,0 +1,47 @@
+/*
+ * 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/echo_detector/mean_variance_estimator.h"
+
+#include <math.h>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace {
+
+// Parameter controlling the adaptation speed.
+constexpr float kAlpha = 0.001f;
+
+} // namespace
+
+void MeanVarianceEstimator::Update(float value) {
+ mean_ = (1.f - kAlpha) * mean_ + kAlpha * value;
+ variance_ =
+ (1.f - kAlpha) * variance_ + kAlpha * (value - mean_) * (value - mean_);
+ RTC_DCHECK(isfinite(mean_));
+ RTC_DCHECK(isfinite(variance_));
+}
+
+float MeanVarianceEstimator::std_deviation() const {
+ RTC_DCHECK_GE(variance_, 0.f);
+ return sqrtf(variance_);
+}
+
+float MeanVarianceEstimator::mean() const {
+ return mean_;
+}
+
+void MeanVarianceEstimator::Clear() {
+ mean_ = 0.f;
+ variance_ = 0.f;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.h b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.h
new file mode 100644
index 0000000000..7f793df1e8
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MEAN_VARIANCE_ESTIMATOR_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MEAN_VARIANCE_ESTIMATOR_H_
+
+namespace webrtc {
+
+// This class iteratively estimates the mean and variance of a signal.
+class MeanVarianceEstimator {
+ public:
+ void Update(float value);
+ float std_deviation() const;
+ float mean() const;
+ void Clear();
+
+ private:
+ // Estimate of the expected value of the input values.
+ float mean_ = 0.f;
+ // Estimate of the variance of the input values.
+ float variance_ = 0.f;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MEAN_VARIANCE_ESTIMATOR_H_
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator_unittest.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator_unittest.cc
new file mode 100644
index 0000000000..8327d23e8a
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/mean_variance_estimator_unittest.cc
@@ -0,0 +1,65 @@
+
+/*
+ * 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/echo_detector/mean_variance_estimator.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(MeanVarianceEstimatorTests, InsertTwoValues) {
+ MeanVarianceEstimator test_estimator;
+ // Insert two values.
+ test_estimator.Update(3.f);
+ test_estimator.Update(5.f);
+
+ EXPECT_GT(test_estimator.mean(), 0.f);
+ EXPECT_GT(test_estimator.std_deviation(), 0.f);
+ // Test Clear method
+ test_estimator.Clear();
+ EXPECT_EQ(test_estimator.mean(), 0.f);
+ EXPECT_EQ(test_estimator.std_deviation(), 0.f);
+}
+
+TEST(MeanVarianceEstimatorTests, InsertZeroes) {
+ MeanVarianceEstimator test_estimator;
+ // Insert the same value many times.
+ for (size_t i = 0; i < 20000; i++) {
+ test_estimator.Update(0.f);
+ }
+ EXPECT_EQ(test_estimator.mean(), 0.f);
+ EXPECT_EQ(test_estimator.std_deviation(), 0.f);
+}
+
+TEST(MeanVarianceEstimatorTests, ConstantValueTest) {
+ MeanVarianceEstimator test_estimator;
+ for (size_t i = 0; i < 20000; i++) {
+ test_estimator.Update(3.f);
+ }
+ // The mean should be close to three, and the standard deviation should be
+ // close to zero.
+ EXPECT_NEAR(3.0f, test_estimator.mean(), 0.01f);
+ EXPECT_NEAR(0.0f, test_estimator.std_deviation(), 0.01f);
+}
+
+TEST(MeanVarianceEstimatorTests, AlternatingValueTest) {
+ MeanVarianceEstimator test_estimator;
+ for (size_t i = 0; i < 20000; i++) {
+ test_estimator.Update(1.f);
+ test_estimator.Update(-1.f);
+ }
+ // The mean should be close to zero, and the standard deviation should be
+ // close to one.
+ EXPECT_NEAR(0.0f, test_estimator.mean(), 0.01f);
+ EXPECT_NEAR(1.0f, test_estimator.std_deviation(), 0.01f);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.cc
new file mode 100644
index 0000000000..3054e98bd3
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.cc
@@ -0,0 +1,52 @@
+/*
+ * 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 "modules/audio_processing/echo_detector/moving_max.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace {
+
+// Parameter for controlling how fast the estimated maximum decays after the
+// previous maximum is no longer valid. With a value of 0.99, the maximum will
+// decay to 1% of its former value after 460 updates.
+constexpr float kDecayFactor = 0.99f;
+
+} // namespace
+
+MovingMax::MovingMax(size_t window_size) : window_size_(window_size) {
+ RTC_DCHECK_GT(window_size, 0);
+}
+
+MovingMax::~MovingMax() {}
+
+void MovingMax::Update(float value) {
+ if (counter_ >= window_size_ - 1) {
+ max_value_ *= kDecayFactor;
+ } else {
+ ++counter_;
+ }
+ if (value > max_value_) {
+ max_value_ = value;
+ counter_ = 0;
+ }
+}
+
+float MovingMax::max() const {
+ return max_value_;
+}
+
+void MovingMax::Clear() {
+ max_value_ = 0.f;
+ counter_ = 0;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.h b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.h
new file mode 100644
index 0000000000..f7d8ee8137
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MOVING_MAX_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MOVING_MAX_H_
+
+#include <stddef.h>
+
+namespace webrtc {
+
+class MovingMax {
+ public:
+ explicit MovingMax(size_t window_size);
+ ~MovingMax();
+
+ void Update(float value);
+ float max() const;
+ // Reset all of the state in this class.
+ void Clear();
+
+ private:
+ float max_value_ = 0.f;
+ size_t counter_ = 0;
+ size_t window_size_ = 1;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_MOVING_MAX_H_
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max_unittest.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max_unittest.cc
new file mode 100644
index 0000000000..9429127a2b
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/moving_max_unittest.cc
@@ -0,0 +1,68 @@
+/*
+ * 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 "modules/audio_processing/echo_detector/moving_max.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+// Test if the maximum is correctly found.
+TEST(MovingMaxTests, SimpleTest) {
+ MovingMax test_moving_max(5);
+ test_moving_max.Update(1.0f);
+ test_moving_max.Update(1.1f);
+ test_moving_max.Update(1.9f);
+ test_moving_max.Update(1.87f);
+ test_moving_max.Update(1.89f);
+ EXPECT_EQ(1.9f, test_moving_max.max());
+}
+
+// Test if values fall out of the window when expected.
+TEST(MovingMaxTests, SlidingWindowTest) {
+ MovingMax test_moving_max(5);
+ test_moving_max.Update(1.0f);
+ test_moving_max.Update(1.9f);
+ test_moving_max.Update(1.7f);
+ test_moving_max.Update(1.87f);
+ test_moving_max.Update(1.89f);
+ test_moving_max.Update(1.3f);
+ test_moving_max.Update(1.2f);
+ EXPECT_LT(test_moving_max.max(), 1.9f);
+}
+
+// Test if Clear() works as expected.
+TEST(MovingMaxTests, ClearTest) {
+ MovingMax test_moving_max(5);
+ test_moving_max.Update(1.0f);
+ test_moving_max.Update(1.1f);
+ test_moving_max.Update(1.9f);
+ test_moving_max.Update(1.87f);
+ test_moving_max.Update(1.89f);
+ EXPECT_EQ(1.9f, test_moving_max.max());
+ test_moving_max.Clear();
+ EXPECT_EQ(0.f, test_moving_max.max());
+}
+
+// Test the decay of the estimated maximum.
+TEST(MovingMaxTests, DecayTest) {
+ MovingMax test_moving_max(1);
+ test_moving_max.Update(1.0f);
+ float previous_value = 1.0f;
+ for (int i = 0; i < 500; i++) {
+ test_moving_max.Update(0.0f);
+ EXPECT_LT(test_moving_max.max(), previous_value);
+ EXPECT_GT(test_moving_max.max(), 0.0f);
+ previous_value = test_moving_max.max();
+ }
+ EXPECT_LT(test_moving_max.max(), 0.01f);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.cc
new file mode 100644
index 0000000000..8ec9fe9f0b
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.cc
@@ -0,0 +1,43 @@
+/*
+ * 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/echo_detector/normalized_covariance_estimator.h"
+
+#include <math.h>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace {
+
+// Parameter controlling the adaptation speed.
+constexpr float kAlpha = 0.001f;
+
+} // namespace
+
+void NormalizedCovarianceEstimator::Update(float x,
+ float x_mean,
+ float x_sigma,
+ float y,
+ float y_mean,
+ float y_sigma) {
+ covariance_ =
+ (1.f - kAlpha) * covariance_ + kAlpha * (x - x_mean) * (y - y_mean);
+ normalized_cross_correlation_ = covariance_ / (x_sigma * y_sigma + .0001f);
+ RTC_DCHECK(isfinite(covariance_));
+ RTC_DCHECK(isfinite(normalized_cross_correlation_));
+}
+
+void NormalizedCovarianceEstimator::Clear() {
+ covariance_ = 0.f;
+ normalized_cross_correlation_ = 0.f;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.h b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.h
new file mode 100644
index 0000000000..e3c36d88ba
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_NORMALIZED_COVARIANCE_ESTIMATOR_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_NORMALIZED_COVARIANCE_ESTIMATOR_H_
+
+namespace webrtc {
+
+// This class iteratively estimates the normalized covariance between two
+// signals.
+class NormalizedCovarianceEstimator {
+ public:
+ void Update(float x,
+ float x_mean,
+ float x_var,
+ float y,
+ float y_mean,
+ float y_var);
+ // This function returns an estimate of the Pearson product-moment correlation
+ // coefficient of the two signals.
+ float normalized_cross_correlation() const {
+ return normalized_cross_correlation_;
+ }
+ float covariance() const { return covariance_; }
+ // This function resets the estimated values to zero.
+ void Clear();
+
+ private:
+ float normalized_cross_correlation_ = 0.f;
+ // Estimate of the covariance value.
+ float covariance_ = 0.f;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_NORMALIZED_COVARIANCE_ESTIMATOR_H_
diff --git a/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc
new file mode 100644
index 0000000000..89fb9383f6
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc
@@ -0,0 +1,41 @@
+
+/*
+ * 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/echo_detector/normalized_covariance_estimator.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(NormalizedCovarianceEstimatorTests, IdenticalSignalTest) {
+ NormalizedCovarianceEstimator test_estimator;
+ for (size_t i = 0; i < 10000; i++) {
+ test_estimator.Update(1.f, 0.f, 1.f, 1.f, 0.f, 1.f);
+ test_estimator.Update(-1.f, 0.f, 1.f, -1.f, 0.f, 1.f);
+ }
+ // A normalized covariance value close to 1 is expected.
+ EXPECT_NEAR(1.f, test_estimator.normalized_cross_correlation(), 0.01f);
+ test_estimator.Clear();
+ EXPECT_EQ(0.f, test_estimator.normalized_cross_correlation());
+}
+
+TEST(NormalizedCovarianceEstimatorTests, OppositeSignalTest) {
+ NormalizedCovarianceEstimator test_estimator;
+ // Insert the same value many times.
+ for (size_t i = 0; i < 10000; i++) {
+ test_estimator.Update(1.f, 0.f, 1.f, -1.f, 0.f, 1.f);
+ test_estimator.Update(-1.f, 0.f, 1.f, 1.f, 0.f, 1.f);
+ }
+ // A normalized covariance value close to -1 is expected.
+ EXPECT_NEAR(-1.f, test_estimator.normalized_cross_correlation(), 0.01f);
+}
+
+} // namespace webrtc