From 0eef9c0c61fef66bceb6767ad2db83cd8c60b409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85hgren?= Date: Mon, 22 Jan 2018 20:24:06 +0100 Subject: [PATCH] Increasing the speed of the initial alignment in AEC3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL increases the speech of the initial alignment in AEC3 by loosening the requirements on the accuracy of the initial estimates. Bug: webrtc:8784, chromium:804270 Change-Id: I86e2d97830843524090a1cf877965739f66dc058 Reviewed-on: https://webrtc-review.googlesource.com/40660 Commit-Queue: Per Ã…hgren Reviewed-by: Gustaf Ullberg Cr-Commit-Position: refs/heads/master@{#21728} --- modules/audio_processing/aec3/aec_state.cc | 4 +- .../echo_path_delay_estimator_unittest.cc | 43 ------------------- .../aec3/matched_filter_lag_aggregator.cc | 4 ++ .../aec3/matched_filter_lag_aggregator.h | 1 + .../matched_filter_lag_aggregator_unittest.cc | 18 +++++++- .../aec3/render_delay_controller.cc | 5 --- 6 files changed, 23 insertions(+), 52 deletions(-) diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc index c1d7cc5883..7b37550e68 100644 --- a/modules/audio_processing/aec3/aec_state.cc +++ b/modules/audio_processing/aec3/aec_state.cc @@ -154,7 +154,7 @@ void AecState::Update( // TODO(peah): Move? filter_has_had_time_to_converge_ = - blocks_with_proper_filter_adaptation_ >= 2.5 * kNumBlocksPerSecond; + blocks_with_proper_filter_adaptation_ >= 0.5f * kNumBlocksPerSecond; initial_state_ = blocks_with_proper_filter_adaptation_ < 5 * kNumBlocksPerSecond; @@ -163,7 +163,7 @@ void AecState::Update( usable_linear_estimate_ = !echo_saturation_ && (converged_filter && filter_has_had_time_to_converge_) && - capture_block_counter_ >= 2 * kNumBlocksPerSecond && !TransparentMode(); + capture_block_counter_ >= 1.f * kNumBlocksPerSecond && !TransparentMode(); // After an amount of active render samples for which an echo should have been // detected in the capture signal if the ERL was not infinite, flag that a diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc b/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc index 8cc69ea17d..8d6488df1a 100644 --- a/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc +++ b/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc @@ -102,28 +102,6 @@ TEST(EchoPathDelayEstimator, DelayEstimation) { } } -// Verifies that the delay estimator does not produce delay estimates too -// quickly. -TEST(EchoPathDelayEstimator, NoInitialDelayestimates) { - Random random_generator(42U); - EchoCanceller3Config config; - std::vector> render(3, std::vector(kBlockSize)); - std::vector capture(kBlockSize); - ApmDataDumper data_dumper(0); - std::unique_ptr render_delay_buffer( - RenderDelayBuffer::Create(config, 3)); - - EchoPathDelayEstimator estimator(&data_dumper, config); - for (size_t k = 0; k < 19; ++k) { - RandomizeSampleVector(&random_generator, render[0]); - std::copy(render[0].begin(), render[0].end(), capture.begin()); - render_delay_buffer->Insert(render); - render_delay_buffer->PrepareCaptureProcessing(); - EXPECT_FALSE(estimator.EstimateDelay( - render_delay_buffer->GetDownsampledRenderBuffer(), capture)); - } -} - // Verifies that the delay estimator does not produce delay estimates for render // signals of low level. TEST(EchoPathDelayEstimator, NoDelayEstimatesForLowLevelRenderSignals) { @@ -148,27 +126,6 @@ TEST(EchoPathDelayEstimator, NoDelayEstimatesForLowLevelRenderSignals) { } } -// Verifies that the delay estimator does not produce delay estimates for -// uncorrelated signals. -TEST(EchoPathDelayEstimator, NoDelayEstimatesForUncorrelatedSignals) { - Random random_generator(42U); - EchoCanceller3Config config; - std::vector> render(3, std::vector(kBlockSize)); - std::vector capture(kBlockSize); - ApmDataDumper data_dumper(0); - EchoPathDelayEstimator estimator(&data_dumper, config); - std::unique_ptr render_delay_buffer( - RenderDelayBuffer::Create(config, 3)); - for (size_t k = 0; k < 100; ++k) { - RandomizeSampleVector(&random_generator, render[0]); - RandomizeSampleVector(&random_generator, capture); - render_delay_buffer->Insert(render); - render_delay_buffer->PrepareCaptureProcessing(); - EXPECT_FALSE(estimator.EstimateDelay( - render_delay_buffer->GetDownsampledRenderBuffer(), capture)); - } -} - #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) // Verifies the check for the render blocksize. diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc index 92cb4f7736..0a8d27cb5b 100644 --- a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc +++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc @@ -27,6 +27,7 @@ void MatchedFilterLagAggregator::Reset() { std::fill(histogram_.begin(), histogram_.end(), 0); histogram_data_.fill(0); histogram_data_index_ = 0; + significant_candidate_found_ = false; } rtc::Optional MatchedFilterLagAggregator::Aggregate( @@ -67,6 +68,9 @@ rtc::Optional MatchedFilterLagAggregator::Aggregate( std::max_element(histogram_.begin(), histogram_.end())); if (histogram_[candidate] > 25) { + significant_candidate_found_ = true; + return candidate; + } else if (!significant_candidate_found_) { return candidate; } } diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator.h b/modules/audio_processing/aec3/matched_filter_lag_aggregator.h index c5dd24700e..4d72150d63 100644 --- a/modules/audio_processing/aec3/matched_filter_lag_aggregator.h +++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator.h @@ -40,6 +40,7 @@ class MatchedFilterLagAggregator { std::vector histogram_; std::array histogram_data_; int histogram_data_index_ = 0; + bool significant_candidate_found_ = false; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MatchedFilterLagAggregator); }; diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc b/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc index 985ed43427..ce08f1cb05 100644 --- a/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc +++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc @@ -37,7 +37,7 @@ TEST(MatchedFilterLagAggregator, MostAccurateLagChosen) { lag_estimates[1] = MatchedFilter::LagEstimate(0.5f, true, kLag2, true); for (size_t k = 0; k < kNumLagsBeforeDetection; ++k) { - EXPECT_FALSE(aggregator.Aggregate(lag_estimates)); + EXPECT_TRUE(aggregator.Aggregate(lag_estimates)); } rtc::Optional aggregated_lag = aggregator.Aggregate(lag_estimates); @@ -66,9 +66,23 @@ TEST(MatchedFilterLagAggregator, ApmDataDumper data_dumper(0); std::vector lag_estimates(1); MatchedFilterLagAggregator aggregator(&data_dumper, 100); + + rtc::Optional aggregated_lag; + for (size_t k = 0; k < kNumLagsBeforeDetection; ++k) { + lag_estimates[0] = MatchedFilter::LagEstimate(1.f, true, 10, true); + aggregated_lag = aggregator.Aggregate(lag_estimates); + } + EXPECT_TRUE(aggregated_lag); + for (size_t k = 0; k < kNumLagsBeforeDetection * 100; ++k) { lag_estimates[0] = MatchedFilter::LagEstimate(1.f, true, k % 100, true); - rtc::Optional aggregated_lag = aggregator.Aggregate(lag_estimates); + aggregated_lag = aggregator.Aggregate(lag_estimates); + } + EXPECT_FALSE(aggregated_lag); + + for (size_t k = 0; k < kNumLagsBeforeDetection * 100; ++k) { + lag_estimates[0] = MatchedFilter::LagEstimate(1.f, true, k % 100, true); + aggregated_lag = aggregator.Aggregate(lag_estimates); EXPECT_FALSE(aggregated_lag); } } diff --git a/modules/audio_processing/aec3/render_delay_controller.cc b/modules/audio_processing/aec3/render_delay_controller.cc index 16a447730d..799ea6b29b 100644 --- a/modules/audio_processing/aec3/render_delay_controller.cc +++ b/modules/audio_processing/aec3/render_delay_controller.cc @@ -44,7 +44,6 @@ class RenderDelayControllerImpl final : public RenderDelayController { const int hysteresis_limit_2_blocks_; rtc::Optional delay_; EchoPathDelayEstimator delay_estimator_; - size_t align_call_counter_ = 0; std::vector delay_buf_; int delay_buf_index_ = 0; RenderDelayControllerMetrics metrics_; @@ -106,7 +105,6 @@ RenderDelayControllerImpl::~RenderDelayControllerImpl() = default; void RenderDelayControllerImpl::Reset() { delay_ = rtc::nullopt; - align_call_counter_ = 0; std::fill(delay_buf_.begin(), delay_buf_.end(), 0.f); delay_estimator_.Reset(); } @@ -124,7 +122,6 @@ rtc::Optional RenderDelayControllerImpl::GetDelay( const DownsampledRenderBuffer& render_buffer, rtc::ArrayView capture) { RTC_DCHECK_EQ(kBlockSize, capture.size()); - ++align_call_counter_; // Estimate the delay with a delayed capture. RTC_DCHECK_LT(delay_buf_index_ + kBlockSize - 1, delay_buf_.size()); @@ -139,11 +136,9 @@ rtc::Optional RenderDelayControllerImpl::GetDelay( if (delay_samples) { // Compute and set new render delay buffer delay. - if (align_call_counter_ > kNumBlocksPerSecond) { delay_ = ComputeNewBufferDelay( delay_, delay_headroom_blocks_, hysteresis_limit_1_blocks_, hysteresis_limit_2_blocks_, static_cast(*delay_samples)); - } metrics_.Update(static_cast(*delay_samples), delay_ ? *delay_ : 0); } else {