Compute ERL over all frequency bins in AEC3.

Bug: webrtc:8533
Change-Id: I7160361b3468bb24cef9e6d390f10b23b988edd3
Reviewed-on: https://webrtc-review.googlesource.com/23242
Reviewed-by: Per Åhgren <peah@webrtc.org>
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20713}
This commit is contained in:
Gustaf Ullberg
2017-11-16 09:31:27 +01:00
committed by Commit Bot
parent 8d9c5406c7
commit fe4d673393
3 changed files with 32 additions and 6 deletions

View File

@ -11,6 +11,7 @@
#include "modules/audio_processing/aec3/erl_estimator.h"
#include <algorithm>
#include <numeric>
namespace webrtc {
@ -24,6 +25,8 @@ constexpr float kMaxErl = 1000.f;
ErlEstimator::ErlEstimator() {
erl_.fill(kMaxErl);
hold_counters_.fill(0);
erl_time_domain_ = kMaxErl;
hold_counter_time_domain_ = 0;
}
ErlEstimator::~ErlEstimator() = default;
@ -43,7 +46,7 @@ void ErlEstimator::Update(
const float new_erl = Y2[k] / X2[k];
if (new_erl < erl_[k]) {
hold_counters_[k - 1] = 1000;
erl_[k] += 0.1 * (new_erl - erl_[k]);
erl_[k] += 0.1f * (new_erl - erl_[k]);
erl_[k] = std::max(erl_[k], kMinErl);
}
}
@ -58,6 +61,24 @@ void ErlEstimator::Update(
erl_[0] = erl_[1];
erl_[kFftLengthBy2] = erl_[kFftLengthBy2 - 1];
// Compute ERL over all frequency bins.
const float X2_sum = std::accumulate(X2.begin(), X2.end(), 0.0f);
if (X2_sum > kX2Min * X2.size()) {
const float Y2_sum = std::accumulate(Y2.begin(), Y2.end(), 0.0f);
const float new_erl = Y2_sum / X2_sum;
if (new_erl < erl_time_domain_) {
hold_counter_time_domain_ = 1000;
erl_time_domain_ += 0.1f * (new_erl - erl_time_domain_);
erl_time_domain_ = std::max(erl_time_domain_, kMinErl);
}
}
--hold_counter_time_domain_;
erl_time_domain_ = (hold_counter_time_domain_ > 0)
? erl_time_domain_
: std::min(kMaxErl, 2.f * erl_time_domain_);
}
} // namespace webrtc

View File

@ -30,10 +30,13 @@ class ErlEstimator {
// Returns the most recent ERL estimate.
const std::array<float, kFftLengthBy2Plus1>& Erl() const { return erl_; }
float ErlTimeDomain() const { return erl_time_domain_; }
private:
std::array<float, kFftLengthBy2Plus1> erl_;
std::array<int, kFftLengthBy2Minus1> hold_counters_;
float erl_time_domain_;
int hold_counter_time_domain_;
RTC_DISALLOW_COPY_AND_ASSIGN(ErlEstimator);
};

View File

@ -17,9 +17,11 @@ namespace webrtc {
namespace {
void VerifyErl(const std::array<float, kFftLengthBy2Plus1>& erl,
float erl_time_domain,
float reference) {
std::for_each(erl.begin(), erl.end(),
[reference](float a) { EXPECT_NEAR(reference, a, 0.001); });
EXPECT_NEAR(reference, erl_time_domain, 0.001);
}
} // namespace
@ -37,7 +39,7 @@ TEST(ErlEstimator, Estimates) {
for (size_t k = 0; k < 200; ++k) {
estimator.Update(X2, Y2);
}
VerifyErl(estimator.Erl(), 10.f);
VerifyErl(estimator.Erl(), estimator.ErlTimeDomain(), 10.f);
// Verifies that the ERL is not immediately increased when the ERL in the data
// increases.
@ -45,18 +47,18 @@ TEST(ErlEstimator, Estimates) {
for (size_t k = 0; k < 998; ++k) {
estimator.Update(X2, Y2);
}
VerifyErl(estimator.Erl(), 10.f);
VerifyErl(estimator.Erl(), estimator.ErlTimeDomain(), 10.f);
// Verifies that the rate of increase is 3 dB.
estimator.Update(X2, Y2);
VerifyErl(estimator.Erl(), 20.f);
VerifyErl(estimator.Erl(), estimator.ErlTimeDomain(), 20.f);
// Verifies that the maximum ERL is achieved when there are no low RLE
// estimates.
for (size_t k = 0; k < 1000; ++k) {
estimator.Update(X2, Y2);
}
VerifyErl(estimator.Erl(), 1000.f);
VerifyErl(estimator.Erl(), estimator.ErlTimeDomain(), 1000.f);
// Verifies that the ERL estimate is is not updated for low-level signals
X2.fill(1000.f * 1000.f);
@ -64,7 +66,7 @@ TEST(ErlEstimator, Estimates) {
for (size_t k = 0; k < 200; ++k) {
estimator.Update(X2, Y2);
}
VerifyErl(estimator.Erl(), 1000.f);
VerifyErl(estimator.Erl(), estimator.ErlTimeDomain(), 1000.f);
}
} // namespace webrtc