| Index: webrtc/modules/audio_processing/echo_detector/echo_detector.cc
|
| diff --git a/webrtc/modules/audio_processing/echo_detector/echo_detector.cc b/webrtc/modules/audio_processing/echo_detector/echo_detector.cc
|
| index 842be9e2db3a5a999de4dd07c02c40ec41c879db..e0f5dab97c4dc007d30bdf17760b4a6843c0a002 100644
|
| --- a/webrtc/modules/audio_processing/echo_detector/echo_detector.cc
|
| +++ b/webrtc/modules/audio_processing/echo_detector/echo_detector.cc
|
| @@ -10,21 +10,85 @@
|
|
|
| #include "webrtc/modules/audio_processing/echo_detector/echo_detector.h"
|
|
|
| +#include <algorithm>
|
| +#include <numeric>
|
| +
|
| +#include "webrtc/base/logging.h"
|
| +
|
| +namespace {
|
| +
|
| +float Power(rtc::ArrayView<const float> input) {
|
| + return std::inner_product(input.begin(), input.end(), input.begin(), 0.f);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| namespace webrtc {
|
|
|
| -void EchoDetector::BufferFarend(const rtc::ArrayView<const float>& /*farend*/) {
|
| - // TODO(ivoc): Add implementation.
|
| - RTC_NOTREACHED();
|
| +EchoDetector::EchoDetector() = default;
|
| +
|
| +EchoDetector::~EchoDetector() = default;
|
| +
|
| +constexpr size_t EchoDetector::kLookbackFrames;
|
| +constexpr size_t EchoDetector::kRenderBufferSize;
|
| +
|
| +void EchoDetector::BufferRender(rtc::ArrayView<const float> render) {
|
| + float power = Power(render);
|
| + render_buffer_.Push(power);
|
| }
|
|
|
| -void EchoDetector::Process(const rtc::ArrayView<const float>& /*nearend*/) {
|
| - // TODO(ivoc): Add implementation.
|
| - RTC_NOTREACHED();
|
| +void EchoDetector::Process(rtc::ArrayView<const float> nearend) {
|
| + const float capture_power = Power(nearend);
|
| + const float capture_mean = capture_variance_.mean();
|
| + const float capture_std_deviation = capture_variance_.std_deviation();
|
| +
|
| + const rtc::Optional<float> buffered_render_power = render_buffer_.Pop();
|
| + if (!buffered_render_power) {
|
| + // This should only happen in case of clock drift. For now we will just
|
| + // ignore the "extra" capture value.
|
| + LOG(LS_ERROR) << "Clockdrift detected in residual echo detector. Ignoring "
|
| + "capture frame.";
|
| + return;
|
| + }
|
| + const float latest_render_power = *buffered_render_power;
|
| + capture_variance_.UpdateEstimate(capture_power);
|
| + render_variance_.UpdateEstimate(latest_render_power);
|
| + RTC_DCHECK_LT(next_insertion_index_, kLookbackFrames);
|
| + render_power_[next_insertion_index_] = latest_render_power;
|
| + render_power_mean_[next_insertion_index_] = render_variance_.mean();
|
| + render_power_std_dev_[next_insertion_index_] =
|
| + render_variance_.std_deviation();
|
| + echo_likelihood_ = 0.f;
|
| + for (size_t delay = 0; delay < covariance_.size(); ++delay) {
|
| + const size_t read_index =
|
| + (kLookbackFrames + next_insertion_index_ - delay) % kLookbackFrames;
|
| + RTC_DCHECK_LT(read_index, render_power_.size());
|
| + const float render_power = render_power_[read_index];
|
| + const float render_mean = render_power_mean_[read_index];
|
| + const float render_std_dev = render_power_std_dev_[read_index];
|
| + covariance_[delay].UpdateCovarianceEstimate(
|
| + capture_power, capture_mean, capture_std_deviation, render_power,
|
| + render_mean, render_std_dev);
|
| + echo_likelihood_ = std::max(
|
| + echo_likelihood_, covariance_[delay].normalized_cross_correlation());
|
| + }
|
| + // Update the next insertion index.
|
| + ++next_insertion_index_;
|
| + next_insertion_index_ %= kLookbackFrames;
|
| }
|
|
|
| -void EchoDetector::Initialize(int /*sample_rate_hz*/) {
|
| - // TODO(ivoc): Add implementation.
|
| - RTC_NOTREACHED();
|
| +void EchoDetector::Initialize() {
|
| + render_buffer_.Clear();
|
| + std::fill(render_power_.begin(), render_power_.end(), 0.f);
|
| + std::fill(render_power_mean_.begin(), render_power_mean_.end(), 0.f);
|
| + std::fill(render_power_std_dev_.begin(), render_power_std_dev_.end(), 0.f);
|
| + render_variance_.Clear();
|
| + capture_variance_.Clear();
|
| + for (auto& cov : covariance_) {
|
| + cov.Clear();
|
| + }
|
| + echo_likelihood_ = 0.f;
|
| + next_insertion_index_ = 0;
|
| }
|
|
|
| } // namespace webrtc
|
|
|