Compute ERLE over all frequency bins in AEC3.
Bug: webrtc:8533 Change-Id: I0a373f22ec377b226d3bc7d88d3245a99e18c7a0 Reviewed-on: https://webrtc-review.googlesource.com/23621 Reviewed-by: Per Åhgren <peah@webrtc.org> Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20709}
This commit is contained in:

committed by
Commit Bot

parent
8b64fd8a85
commit
c9b89aaa16
@ -11,6 +11,7 @@
|
||||
#include "modules/audio_processing/aec3/erle_estimator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include "rtc_base/safe_minmax.h"
|
||||
|
||||
@ -24,6 +25,8 @@ ErleEstimator::ErleEstimator(float min_erle,
|
||||
max_erle_hf_(max_erle_hf) {
|
||||
erle_.fill(min_erle_);
|
||||
hold_counters_.fill(0);
|
||||
erle_time_domain_ = min_erle_;
|
||||
hold_counter_time_domain_ = 0;
|
||||
}
|
||||
|
||||
ErleEstimator::~ErleEstimator() = default;
|
||||
@ -64,6 +67,24 @@ void ErleEstimator::Update(
|
||||
|
||||
erle_[0] = erle_[1];
|
||||
erle_[kFftLengthBy2] = erle_[kFftLengthBy2 - 1];
|
||||
|
||||
// Compute ERLE over all frequency bins.
|
||||
const float X2_sum = std::accumulate(X2.begin(), X2.end(), 0.0f);
|
||||
const float E2_sum = std::accumulate(E2.begin(), E2.end(), 0.0f);
|
||||
if (X2_sum > kX2Min * X2.size() && E2_sum > 0.f) {
|
||||
const float Y2_sum = std::accumulate(Y2.begin(), Y2.end(), 0.0f);
|
||||
const float new_erle = Y2_sum / E2_sum;
|
||||
if (new_erle > erle_time_domain_) {
|
||||
hold_counter_time_domain_ = 100;
|
||||
erle_time_domain_ += 0.1f * (new_erle - erle_time_domain_);
|
||||
erle_time_domain_ =
|
||||
rtc::SafeClamp(erle_time_domain_, min_erle_, max_erle_lf_);
|
||||
}
|
||||
}
|
||||
--hold_counter_time_domain_;
|
||||
erle_time_domain_ = (hold_counter_time_domain_ > 0)
|
||||
? erle_time_domain_
|
||||
: std::max(min_erle_, 0.97f * erle_time_domain_);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -31,10 +31,13 @@ class ErleEstimator {
|
||||
|
||||
// Returns the most recent ERLE estimate.
|
||||
const std::array<float, kFftLengthBy2Plus1>& Erle() const { return erle_; }
|
||||
float ErleTimeDomain() { return erle_time_domain_; }
|
||||
|
||||
private:
|
||||
std::array<float, kFftLengthBy2Plus1> erle_;
|
||||
std::array<int, kFftLengthBy2Minus1> hold_counters_;
|
||||
float erle_time_domain_;
|
||||
int hold_counter_time_domain_;
|
||||
const float min_erle_;
|
||||
const float max_erle_lf_;
|
||||
const float max_erle_hf_;
|
||||
|
@ -18,6 +18,7 @@ namespace {
|
||||
constexpr int kLowFrequencyLimit = kFftLengthBy2 / 2;
|
||||
|
||||
void VerifyErle(const std::array<float, kFftLengthBy2Plus1>& erle,
|
||||
float erle_time_domain,
|
||||
float reference_lf,
|
||||
float reference_hf) {
|
||||
std::for_each(
|
||||
@ -26,6 +27,7 @@ void VerifyErle(const std::array<float, kFftLengthBy2Plus1>& erle,
|
||||
std::for_each(
|
||||
erle.begin() + kLowFrequencyLimit, erle.end(),
|
||||
[reference_hf](float a) { EXPECT_NEAR(reference_hf, a, 0.001); });
|
||||
EXPECT_NEAR(reference_lf, erle_time_domain, 0.001);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -45,7 +47,7 @@ TEST(ErleEstimator, Estimates) {
|
||||
for (size_t k = 0; k < 200; ++k) {
|
||||
estimator.Update(X2, Y2, E2);
|
||||
}
|
||||
VerifyErle(estimator.Erle(), 8.f, 1.5f);
|
||||
VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 8.f, 1.5f);
|
||||
|
||||
// Verifies that the ERLE is not immediately decreased when the ERLE in the
|
||||
// data decreases.
|
||||
@ -53,13 +55,13 @@ TEST(ErleEstimator, Estimates) {
|
||||
for (size_t k = 0; k < 98; ++k) {
|
||||
estimator.Update(X2, Y2, E2);
|
||||
}
|
||||
VerifyErle(estimator.Erle(), 8.f, 1.5f);
|
||||
VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 8.f, 1.5f);
|
||||
|
||||
// Verifies that the minimum ERLE is eventually achieved.
|
||||
for (size_t k = 0; k < 1000; ++k) {
|
||||
estimator.Update(X2, Y2, E2);
|
||||
}
|
||||
VerifyErle(estimator.Erle(), 1.f, 1.f);
|
||||
VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 1.f, 1.f);
|
||||
|
||||
// Verifies that the ERLE estimate is is not updated for low-level render
|
||||
// signals.
|
||||
@ -68,6 +70,6 @@ TEST(ErleEstimator, Estimates) {
|
||||
for (size_t k = 0; k < 200; ++k) {
|
||||
estimator.Update(X2, Y2, E2);
|
||||
}
|
||||
VerifyErle(estimator.Erle(), 1.f, 1.f);
|
||||
VerifyErle(estimator.Erle(), estimator.ErleTimeDomain(), 1.f, 1.f);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user