diff --git a/webrtc/modules/audio_processing/aec3/aec_state.cc b/webrtc/modules/audio_processing/aec3/aec_state.cc index 6908270995..d4a3c76d3e 100644 --- a/webrtc/modules/audio_processing/aec3/aec_state.cc +++ b/webrtc/modules/audio_processing/aec3/aec_state.cc @@ -129,7 +129,11 @@ void AecState::Update(const std::vector>& // Update counters. const float x_energy = std::inner_product(x.begin(), x.end(), x.begin(), 0.f); - const bool active_render_block = x_energy > 10000.f * kFftLengthBy2; + + const bool active_render_block = + x_energy > (config_.param.render_levels.active_render_limit * + config_.param.render_levels.active_render_limit) * + kFftLengthBy2; if (active_render_block) { render_received_ = true; } diff --git a/webrtc/modules/audio_processing/aec3/block_processor.cc b/webrtc/modules/audio_processing/aec3/block_processor.cc index 52bc4ef1a3..536335e8a2 100644 --- a/webrtc/modules/audio_processing/aec3/block_processor.cc +++ b/webrtc/modules/audio_processing/aec3/block_processor.cc @@ -181,7 +181,7 @@ BlockProcessor* BlockProcessor::Create( std::unique_ptr render_buffer( RenderDelayBuffer::Create(NumBandsForRate(sample_rate_hz))); std::unique_ptr delay_controller( - RenderDelayController::Create(sample_rate_hz)); + RenderDelayController::Create(config, sample_rate_hz)); std::unique_ptr echo_remover( EchoRemover::Create(config, sample_rate_hz)); return Create(config, sample_rate_hz, std::move(render_buffer), @@ -193,7 +193,7 @@ BlockProcessor* BlockProcessor::Create( int sample_rate_hz, std::unique_ptr render_buffer) { std::unique_ptr delay_controller( - RenderDelayController::Create(sample_rate_hz)); + RenderDelayController::Create(config, sample_rate_hz)); std::unique_ptr echo_remover( EchoRemover::Create(config, sample_rate_hz)); return Create(config, sample_rate_hz, std::move(render_buffer), diff --git a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.cc b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.cc index 8f84f59609..3c182f3952 100644 --- a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.cc +++ b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.cc @@ -24,13 +24,16 @@ namespace { constexpr int kDownSamplingFactor = 4; } // namespace -EchoPathDelayEstimator::EchoPathDelayEstimator(ApmDataDumper* data_dumper) +EchoPathDelayEstimator::EchoPathDelayEstimator( + ApmDataDumper* data_dumper, + const AudioProcessing::Config::EchoCanceller3& config) : data_dumper_(data_dumper), matched_filter_(data_dumper_, DetectOptimization(), kMatchedFilterWindowSizeSubBlocks, kNumMatchedFilters, - kMatchedFilterAlignmentShiftSizeSubBlocks), + kMatchedFilterAlignmentShiftSizeSubBlocks, + config.param.render_levels.poor_excitation_render_limit), matched_filter_lag_aggregator_(data_dumper_, matched_filter_.NumLagEstimates()) { RTC_DCHECK(data_dumper); diff --git a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.h b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.h index d392044fb5..4b536b99a9 100644 --- a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.h +++ b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.h @@ -17,6 +17,7 @@ #include "webrtc/modules/audio_processing/aec3/downsampled_render_buffer.h" #include "webrtc/modules/audio_processing/aec3/matched_filter.h" #include "webrtc/modules/audio_processing/aec3/matched_filter_lag_aggregator.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" #include "webrtc/rtc_base/constructormagic.h" #include "webrtc/rtc_base/optional.h" @@ -27,7 +28,8 @@ class ApmDataDumper; // Estimates the delay of the echo path. class EchoPathDelayEstimator { public: - explicit EchoPathDelayEstimator(ApmDataDumper* data_dumper); + EchoPathDelayEstimator(ApmDataDumper* data_dumper, + const AudioProcessing::Config::EchoCanceller3& config); ~EchoPathDelayEstimator(); // Resets the estimation. @@ -44,7 +46,7 @@ class EchoPathDelayEstimator { MatchedFilter matched_filter_; MatchedFilterLagAggregator matched_filter_lag_aggregator_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoPathDelayEstimator); + RTC_DISALLOW_COPY_AND_ASSIGN(EchoPathDelayEstimator); }; } // namespace webrtc diff --git a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc index aaaf87d7c2..89b49cae40 100644 --- a/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc +++ b/webrtc/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc @@ -37,7 +37,8 @@ TEST(EchoPathDelayEstimator, BasicApiCalls) { ApmDataDumper data_dumper(0); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); std::vector> render(3, std::vector(kBlockSize)); std::vector capture(kBlockSize); for (size_t k = 0; k < 100; ++k) { @@ -59,7 +60,8 @@ TEST(EchoPathDelayEstimator, DelayEstimation) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); DelayBuffer signal_delay_buffer(delay_samples); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); rtc::Optional estimated_delay_samples; for (size_t k = 0; k < (100 + delay_samples / kBlockSize); ++k) { @@ -91,7 +93,8 @@ TEST(EchoPathDelayEstimator, NoInitialDelayestimates) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); for (size_t k = 0; k < 19; ++k) { RandomizeSampleVector(&random_generator, render[0]); std::copy(render[0].begin(), render[0].end(), capture.begin()); @@ -109,7 +112,8 @@ TEST(EchoPathDelayEstimator, NoDelayEstimatesForLowLevelRenderSignals) { std::vector> render(3, std::vector(kBlockSize)); std::vector capture(kBlockSize); ApmDataDumper data_dumper(0); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); for (size_t k = 0; k < 100; ++k) { @@ -132,7 +136,8 @@ TEST(EchoPathDelayEstimator, NoDelayEstimatesForUncorrelatedSignals) { std::vector> render(3, std::vector(kBlockSize)); std::vector capture(kBlockSize); ApmDataDumper data_dumper(0); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); for (size_t k = 0; k < 100; ++k) { @@ -152,7 +157,8 @@ TEST(EchoPathDelayEstimator, NoDelayEstimatesForUncorrelatedSignals) { // tests on test bots has been fixed. TEST(EchoPathDelayEstimator, DISABLED_WrongRenderBlockSize) { ApmDataDumper data_dumper(0); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); std::vector capture(kBlockSize); @@ -166,7 +172,8 @@ TEST(EchoPathDelayEstimator, DISABLED_WrongRenderBlockSize) { // tests on test bots has been fixed. TEST(EchoPathDelayEstimator, WrongCaptureBlockSize) { ApmDataDumper data_dumper(0); - EchoPathDelayEstimator estimator(&data_dumper); + EchoPathDelayEstimator estimator(&data_dumper, + AudioProcessing::Config::EchoCanceller3()); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); std::vector capture(std::vector(kBlockSize - 1)); @@ -177,7 +184,9 @@ TEST(EchoPathDelayEstimator, WrongCaptureBlockSize) { // Verifies the check for non-null data dumper. TEST(EchoPathDelayEstimator, NullDataDumper) { - EXPECT_DEATH(EchoPathDelayEstimator(nullptr), ""); + EXPECT_DEATH(EchoPathDelayEstimator( + nullptr, AudioProcessing::Config::EchoCanceller3()), + ""); } #endif diff --git a/webrtc/modules/audio_processing/aec3/matched_filter.cc b/webrtc/modules/audio_processing/aec3/matched_filter.cc index 4c6e0d7052..5414cfcb31 100644 --- a/webrtc/modules/audio_processing/aec3/matched_filter.cc +++ b/webrtc/modules/audio_processing/aec3/matched_filter.cc @@ -291,13 +291,15 @@ MatchedFilter::MatchedFilter(ApmDataDumper* data_dumper, Aec3Optimization optimization, size_t window_size_sub_blocks, int num_matched_filters, - size_t alignment_shift_sub_blocks) + size_t alignment_shift_sub_blocks, + float excitation_limit) : data_dumper_(data_dumper), optimization_(optimization), filter_intra_lag_shift_(alignment_shift_sub_blocks * kSubBlockSize), filters_(num_matched_filters, std::vector(window_size_sub_blocks * kSubBlockSize, 0.f)), - lag_estimates_(num_matched_filters) { + lag_estimates_(num_matched_filters), + excitation_limit_(excitation_limit) { RTC_DCHECK(data_dumper); RTC_DCHECK_LT(0, window_size_sub_blocks); } @@ -318,7 +320,8 @@ void MatchedFilter::Update(const DownsampledRenderBuffer& render_buffer, const std::array& capture) { const std::array& y = capture; - const float x2_sum_threshold = filters_[0].size() * 150.f * 150.f; + const float x2_sum_threshold = + filters_[0].size() * excitation_limit_ * excitation_limit_; // Apply all matched filters. size_t alignment_shift = 0; diff --git a/webrtc/modules/audio_processing/aec3/matched_filter.h b/webrtc/modules/audio_processing/aec3/matched_filter.h index fd20625594..0702a124e8 100644 --- a/webrtc/modules/audio_processing/aec3/matched_filter.h +++ b/webrtc/modules/audio_processing/aec3/matched_filter.h @@ -83,7 +83,8 @@ class MatchedFilter { Aec3Optimization optimization, size_t window_size_sub_blocks, int num_matched_filters, - size_t alignment_shift_sub_blocks); + size_t alignment_shift_sub_blocks, + float excitation_limit); ~MatchedFilter(); @@ -108,6 +109,7 @@ class MatchedFilter { const size_t filter_intra_lag_shift_; std::vector> filters_; std::vector lag_estimates_; + const float excitation_limit_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MatchedFilter); }; diff --git a/webrtc/modules/audio_processing/aec3/matched_filter_unittest.cc b/webrtc/modules/audio_processing/aec3/matched_filter_unittest.cc index b2978b6bf4..47ff353be8 100644 --- a/webrtc/modules/audio_processing/aec3/matched_filter_unittest.cc +++ b/webrtc/modules/audio_processing/aec3/matched_filter_unittest.cc @@ -137,7 +137,7 @@ TEST(MatchedFilter, LagEstimation) { DelayBuffer signal_delay_buffer(4 * delay_samples); MatchedFilter filter(&data_dumper, DetectOptimization(), kWindowSizeSubBlocks, kNumMatchedFilters, - kAlignmentShiftSubBlocks); + kAlignmentShiftSubBlocks, 150); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); @@ -206,7 +206,7 @@ TEST(MatchedFilter, LagNotReliableForUncorrelatedRenderAndCapture) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); MatchedFilter filter(&data_dumper, DetectOptimization(), kWindowSizeSubBlocks, - kNumMatchedFilters, kAlignmentShiftSubBlocks); + kNumMatchedFilters, kAlignmentShiftSubBlocks, 150); // Analyze the correlation between render and capture. for (size_t k = 0; k < 100; ++k) { @@ -236,7 +236,7 @@ TEST(MatchedFilter, LagNotUpdatedForLowLevelRender) { capture.fill(0.f); ApmDataDumper data_dumper(0); MatchedFilter filter(&data_dumper, DetectOptimization(), kWindowSizeSubBlocks, - kNumMatchedFilters, kAlignmentShiftSubBlocks); + kNumMatchedFilters, kAlignmentShiftSubBlocks, 150); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(3)); DecimatorBy4 capture_decimator; @@ -273,7 +273,7 @@ TEST(MatchedFilter, NumberOfLagEstimates) { for (size_t num_matched_filters = 0; num_matched_filters < 10; ++num_matched_filters) { MatchedFilter filter(&data_dumper, DetectOptimization(), 32, - num_matched_filters, 1); + num_matched_filters, 1, 150); EXPECT_EQ(num_matched_filters, filter.GetLagEstimates().size()); } } @@ -283,12 +283,13 @@ TEST(MatchedFilter, NumberOfLagEstimates) { // Verifies the check for non-zero windows size. TEST(MatchedFilter, ZeroWindowSize) { ApmDataDumper data_dumper(0); - EXPECT_DEATH(MatchedFilter(&data_dumper, DetectOptimization(), 0, 1, 1), ""); + EXPECT_DEATH(MatchedFilter(&data_dumper, DetectOptimization(), 0, 1, 1, 150), + ""); } // Verifies the check for non-null data dumper. TEST(MatchedFilter, NullDataDumper) { - EXPECT_DEATH(MatchedFilter(nullptr, DetectOptimization(), 1, 1, 1), ""); + EXPECT_DEATH(MatchedFilter(nullptr, DetectOptimization(), 1, 1, 1, 150), ""); } #endif diff --git a/webrtc/modules/audio_processing/aec3/render_delay_controller.cc b/webrtc/modules/audio_processing/aec3/render_delay_controller.cc index a88540e21f..d5d8a14478 100644 --- a/webrtc/modules/audio_processing/aec3/render_delay_controller.cc +++ b/webrtc/modules/audio_processing/aec3/render_delay_controller.cc @@ -17,6 +17,7 @@ #include "webrtc/modules/audio_processing/aec3/aec3_common.h" #include "webrtc/modules/audio_processing/aec3/echo_path_delay_estimator.h" #include "webrtc/modules/audio_processing/aec3/render_delay_controller_metrics.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" #include "webrtc/rtc_base/atomicops.h" #include "webrtc/rtc_base/constructormagic.h" @@ -26,7 +27,9 @@ namespace { class RenderDelayControllerImpl final : public RenderDelayController { public: - RenderDelayControllerImpl(int sample_rate_hz); + RenderDelayControllerImpl( + const AudioProcessing::Config::EchoCanceller3& config, + int sample_rate_hz); ~RenderDelayControllerImpl() override; void Reset() override; void SetDelay(size_t render_delay) override; @@ -68,10 +71,12 @@ size_t ComputeNewBufferDelay(size_t current_delay, int RenderDelayControllerImpl::instance_count_ = 0; -RenderDelayControllerImpl::RenderDelayControllerImpl(int sample_rate_hz) +RenderDelayControllerImpl::RenderDelayControllerImpl( + const AudioProcessing::Config::EchoCanceller3& config, + int sample_rate_hz) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), - delay_estimator_(data_dumper_.get()) { + delay_estimator_(data_dumper_.get(), config) { RTC_DCHECK(ValidFullBandRate(sample_rate_hz)); } @@ -134,8 +139,10 @@ size_t RenderDelayControllerImpl::GetDelay( } // namespace -RenderDelayController* RenderDelayController::Create(int sample_rate_hz) { - return new RenderDelayControllerImpl(sample_rate_hz); +RenderDelayController* RenderDelayController::Create( + const AudioProcessing::Config::EchoCanceller3& config, + int sample_rate_hz) { + return new RenderDelayControllerImpl(config, sample_rate_hz); } } // namespace webrtc diff --git a/webrtc/modules/audio_processing/aec3/render_delay_controller.h b/webrtc/modules/audio_processing/aec3/render_delay_controller.h index e3a8ee3550..ef0aaac731 100644 --- a/webrtc/modules/audio_processing/aec3/render_delay_controller.h +++ b/webrtc/modules/audio_processing/aec3/render_delay_controller.h @@ -13,6 +13,7 @@ #include "webrtc/modules/audio_processing/aec3/downsampled_render_buffer.h" #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" #include "webrtc/rtc_base/array_view.h" #include "webrtc/rtc_base/optional.h" @@ -22,7 +23,9 @@ namespace webrtc { // Class for aligning the render and capture signal using a RenderDelayBuffer. class RenderDelayController { public: - static RenderDelayController* Create(int sample_rate_hz); + static RenderDelayController* Create( + const AudioProcessing::Config::EchoCanceller3& config, + int sample_rate_hz); virtual ~RenderDelayController() = default; // Resets the delay controller. diff --git a/webrtc/modules/audio_processing/aec3/render_delay_controller_unittest.cc b/webrtc/modules/audio_processing/aec3/render_delay_controller_unittest.cc index af0778bc22..ba2f25bc72 100644 --- a/webrtc/modules/audio_processing/aec3/render_delay_controller_unittest.cc +++ b/webrtc/modules/audio_processing/aec3/render_delay_controller_unittest.cc @@ -50,7 +50,8 @@ TEST(RenderDelayController, NoRenderSignal) { std::unique_ptr delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); std::unique_ptr delay_controller( - RenderDelayController::Create(rate)); + RenderDelayController::Create(AudioProcessing::Config::EchoCanceller3(), + rate)); for (size_t k = 0; k < 100; ++k) { EXPECT_EQ(0u, delay_controller->GetDelay( delay_buffer->GetDownsampledRenderBuffer(), block)); @@ -68,7 +69,8 @@ TEST(RenderDelayController, BasicApiCalls) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); std::unique_ptr delay_controller( - RenderDelayController::Create(rate)); + RenderDelayController::Create(AudioProcessing::Config::EchoCanceller3(), + rate)); for (size_t k = 0; k < 10; ++k) { render_delay_buffer->Insert(render_block); render_delay_buffer->UpdateBuffers(); @@ -95,7 +97,8 @@ TEST(RenderDelayController, Alignment) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); std::unique_ptr delay_controller( - RenderDelayController::Create(rate)); + RenderDelayController::Create( + AudioProcessing::Config::EchoCanceller3(), rate)); DelayBuffer signal_delay_buffer(delay_samples); for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) { RandomizeSampleVector(&random_generator, render_block[0]); @@ -139,7 +142,8 @@ TEST(RenderDelayController, AlignmentWithJitter) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); std::unique_ptr delay_controller( - RenderDelayController::Create(rate)); + RenderDelayController::Create( + AudioProcessing::Config::EchoCanceller3(), rate)); DelayBuffer signal_delay_buffer(delay_samples); for (size_t j = 0; j < @@ -188,7 +192,8 @@ TEST(RenderDelayController, InitialHeadroom) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); std::unique_ptr delay_controller( - RenderDelayController::Create(rate)); + RenderDelayController::Create(AudioProcessing::Config::EchoCanceller3(), + rate)); EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples()); } } @@ -204,7 +209,8 @@ TEST(RenderDelayController, WrongCaptureSize) { RenderDelayBuffer::Create(NumBandsForRate(rate))); EXPECT_DEATH( std::unique_ptr( - RenderDelayController::Create(rate)) + RenderDelayController::Create( + AudioProcessing::Config::EchoCanceller3(), rate)) ->GetDelay(render_delay_buffer->GetDownsampledRenderBuffer(), block), ""); @@ -219,9 +225,10 @@ TEST(RenderDelayController, DISABLED_WrongSampleRate) { SCOPED_TRACE(ProduceDebugText(rate)); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(NumBandsForRate(rate))); - EXPECT_DEATH(std::unique_ptr( - RenderDelayController::Create(rate)), - ""); + EXPECT_DEATH( + std::unique_ptr(RenderDelayController::Create( + AudioProcessing::Config::EchoCanceller3(), rate)), + ""); } } diff --git a/webrtc/modules/audio_processing/include/audio_processing.h b/webrtc/modules/audio_processing/include/audio_processing.h index e130b836ce..03bd8c85b0 100644 --- a/webrtc/modules/audio_processing/include/audio_processing.h +++ b/webrtc/modules/audio_processing/include/audio_processing.h @@ -292,8 +292,14 @@ class AudioProcessing : public rtc::RefCountInterface { struct EchoAudibility { float low_render_limit = 192.f; float normal_render_limit = 64.f; + float active_render_limit = 100.f; } echo_audibility; + struct RenderLevels { + float active_render_limit = 100.f; + float poor_excitation_render_limit = 150.f; + } render_levels; + struct GainUpdates { struct GainChanges { float max_inc;