From ff0451117efa8499cc5fa5c510b5729e0cef40da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85hgren?= Date: Fri, 20 Mar 2020 11:20:39 +0100 Subject: [PATCH] AEC3: Rename main filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL renames the main filter in AEC3 to have the more accurate name refined filter. The CL consists of 3 main initial patch sets, designed to simplify the review: 1) Replaces "main" with "refined" and adds a fall-back functionality to support the old filter naming. 2) Renames the files according to the new naming. 3) Performs a "git cl format" Bug: webrtc:8671 Change-Id: Ifd0aab34e291736a2250e0986348404618630b1d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170825 Reviewed-by: Sam Zackrisson Commit-Queue: Per Ã…hgren Cr-Commit-Position: refs/heads/master@{#30843} --- api/audio/echo_canceller3_config.cc | 21 +++ api/audio/echo_canceller3_config.h | 15 +- api/audio/echo_canceller3_config_json.cc | 28 +++- .../echo_canceller3_config_json_unittest.cc | 8 +- modules/audio_processing/aec3/BUILD.gn | 6 +- .../aec3/adaptive_fir_filter_unittest.cc | 16 +-- modules/audio_processing/aec3/aec_state.cc | 6 +- modules/audio_processing/aec3/aec_state.h | 2 +- .../aec3/aec_state_unittest.cc | 48 +++---- .../audio_processing/aec3/echo_canceller3.cc | 5 + modules/audio_processing/aec3/echo_remover.cc | 41 +++--- .../aec3/erle_estimator_unittest.cc | 4 +- .../audio_processing/aec3/filter_analyzer.cc | 2 +- .../audio_processing/aec3/filter_analyzer.h | 2 +- ..._gain.cc => refined_filter_update_gain.cc} | 30 ++-- ...te_gain.h => refined_filter_update_gain.h} | 32 +++-- ...=> refined_filter_update_gain_unittest.cc} | 89 ++++++------ .../aec3/render_delay_buffer.cc | 4 +- .../aec3/render_signal_analyzer.cc | 2 +- .../aec3/residual_echo_estimator_unittest.cc | 14 +- .../aec3/reverb_decay_estimator.cc | 8 +- .../aec3/reverb_model_estimator_unittest.cc | 10 +- .../shadow_filter_update_gain_unittest.cc | 12 +- .../aec3/signal_dependent_erle_estimator.cc | 6 +- ...ignal_dependent_erle_estimator_unittest.cc | 12 +- modules/audio_processing/aec3/subtractor.cc | 134 +++++++++--------- modules/audio_processing/aec3/subtractor.h | 27 ++-- .../aec3/subtractor_output.cc | 27 ++-- .../audio_processing/aec3/subtractor_output.h | 14 +- .../aec3/subtractor_output_analyzer.cc | 11 +- .../aec3/subtractor_unittest.cc | 28 ++-- 31 files changed, 370 insertions(+), 294 deletions(-) rename modules/audio_processing/aec3/{main_filter_update_gain.cc => refined_filter_update_gain.cc} (87%) rename modules/audio_processing/aec3/{main_filter_update_gain.h => refined_filter_update_gain.h} (71%) rename modules/audio_processing/aec3/{main_filter_update_gain_unittest.cc => refined_filter_update_gain_unittest.cc} (84%) diff --git a/api/audio/echo_canceller3_config.cc b/api/audio/echo_canceller3_config.cc index 7fd0744c37..1122d4c6b0 100644 --- a/api/audio/echo_canceller3_config.cc +++ b/api/audio/echo_canceller3_config.cc @@ -137,6 +137,26 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) { res = false; } + res = res & FloorLimit(&c->filter.refined.length_blocks, 1); + res = res & Limit(&c->filter.refined.leakage_converged, 0.f, 1000.f); + res = res & Limit(&c->filter.refined.leakage_diverged, 0.f, 1000.f); + res = res & Limit(&c->filter.refined.error_floor, 0.f, 1000.f); + res = res & Limit(&c->filter.refined.error_ceil, 0.f, 100000000.f); + res = res & Limit(&c->filter.refined.noise_gate, 0.f, 100000000.f); + + res = res & FloorLimit(&c->filter.refined_initial.length_blocks, 1); + res = res & Limit(&c->filter.refined_initial.leakage_converged, 0.f, 1000.f); + res = res & Limit(&c->filter.refined_initial.leakage_diverged, 0.f, 1000.f); + res = res & Limit(&c->filter.refined_initial.error_floor, 0.f, 1000.f); + res = res & Limit(&c->filter.refined_initial.error_ceil, 0.f, 100000000.f); + res = res & Limit(&c->filter.refined_initial.noise_gate, 0.f, 100000000.f); + + if (c->filter.refined.length_blocks < + c->filter.refined_initial.length_blocks) { + c->filter.refined_initial.length_blocks = c->filter.refined.length_blocks; + res = false; + } + res = res & FloorLimit(&c->filter.shadow.length_blocks, 1); res = res & Limit(&c->filter.shadow.rate, 0.f, 1.f); res = res & Limit(&c->filter.shadow.noise_gate, 0.f, 100000000.f); @@ -161,6 +181,7 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) { res = false; } res = res & Limit(&c->erle.num_sections, 1, c->filter.main.length_blocks); + res = res & Limit(&c->erle.num_sections, 1, c->filter.refined.length_blocks); res = res & Limit(&c->ep_strength.default_gain, 0.f, 1000000.f); res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f); diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h index a63318f1da..66989db706 100644 --- a/api/audio/echo_canceller3_config.h +++ b/api/audio/echo_canceller3_config.h @@ -61,7 +61,7 @@ struct RTC_EXPORT EchoCanceller3Config { } delay; struct Filter { - struct MainConfiguration { + struct RefinedConfiguration { size_t length_blocks; float leakage_converged; float leakage_diverged; @@ -76,12 +76,16 @@ struct RTC_EXPORT EchoCanceller3Config { float noise_gate; }; - MainConfiguration main = {13, 0.00005f, 0.05f, 0.001f, 2.f, 20075344.f}; + RefinedConfiguration main = {13, 0.00005f, 0.05f, 0.001f, 2.f, 20075344.f}; ShadowConfiguration shadow = {13, 0.7f, 20075344.f}; + RefinedConfiguration refined = {13, 0.00005f, 0.05f, + 0.001f, 2.f, 20075344.f}; - MainConfiguration main_initial = {12, 0.005f, 0.5f, - 0.001f, 2.f, 20075344.f}; + RefinedConfiguration main_initial = {12, 0.005f, 0.5f, + 0.001f, 2.f, 20075344.f}; ShadowConfiguration shadow_initial = {12, 0.9f, 20075344.f}; + RefinedConfiguration refined_initial = {12, 0.005f, 0.5f, + 0.001f, 2.f, 20075344.f}; size_t config_change_duration_blocks = 250; float initial_state_seconds = 2.5f; @@ -89,6 +93,9 @@ struct RTC_EXPORT EchoCanceller3Config { bool enable_shadow_filter_output_usage = true; bool use_linear_filter = true; bool export_linear_aec_output = false; + // Uses the filter configurations named main rather than those named + // refined. + bool use_legacy_filter_naming = true; } filter; struct Erle { diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc index 1364cb7c0a..fd06fa9b8a 100644 --- a/api/audio/echo_canceller3_config_json.cc +++ b/api/audio/echo_canceller3_config_json.cc @@ -55,7 +55,7 @@ void ReadParam(const Json::Value& root, std::string param_name, float* param) { void ReadParam(const Json::Value& root, std::string param_name, - EchoCanceller3Config::Filter::MainConfiguration* param) { + EchoCanceller3Config::Filter::RefinedConfiguration* param) { RTC_DCHECK(param); Json::Value json_array; if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) { @@ -216,8 +216,10 @@ void Aec3ConfigFromJsonString(absl::string_view json_string, if (rtc::GetValueFromJsonObject(aec3_root, "filter", §ion)) { ReadParam(section, "main", &cfg.filter.main); + ReadParam(section, "refined", &cfg.filter.refined); ReadParam(section, "shadow", &cfg.filter.shadow); ReadParam(section, "main_initial", &cfg.filter.main_initial); + ReadParam(section, "refined_initial", &cfg.filter.refined_initial); ReadParam(section, "shadow_initial", &cfg.filter.shadow_initial); ReadParam(section, "config_change_duration_blocks", &cfg.filter.config_change_duration_blocks); @@ -230,6 +232,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string, ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter); ReadParam(section, "export_linear_aec_output", &cfg.filter.export_linear_aec_output); + ReadParam(section, "use_legacy_filter_naming", + &cfg.filter.use_legacy_filter_naming); } if (rtc::GetValueFromJsonObject(aec3_root, "erle", §ion)) { @@ -468,6 +472,15 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << config.filter.main.noise_gate; ost << "],"; + ost << "\"refined\": ["; + ost << config.filter.refined.length_blocks << ","; + ost << config.filter.refined.leakage_converged << ","; + ost << config.filter.refined.leakage_diverged << ","; + ost << config.filter.refined.error_floor << ","; + ost << config.filter.refined.error_ceil << ","; + ost << config.filter.refined.noise_gate; + ost << "],"; + ost << "\"shadow\": ["; ost << config.filter.shadow.length_blocks << ","; ost << config.filter.shadow.rate << ","; @@ -483,6 +496,15 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << config.filter.main_initial.noise_gate; ost << "],"; + ost << "\"refined_initial\": ["; + ost << config.filter.refined_initial.length_blocks << ","; + ost << config.filter.refined_initial.leakage_converged << ","; + ost << config.filter.refined_initial.leakage_diverged << ","; + ost << config.filter.refined_initial.error_floor << ","; + ost << config.filter.refined_initial.error_ceil << ","; + ost << config.filter.refined_initial.noise_gate; + ost << "],"; + ost << "\"shadow_initial\": ["; ost << config.filter.shadow_initial.length_blocks << ","; ost << config.filter.shadow_initial.rate << ","; @@ -501,7 +523,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << "\"use_linear_filter\": " << (config.filter.use_linear_filter ? "true" : "false") << ","; ost << "\"export_linear_aec_output\": " - << (config.filter.export_linear_aec_output ? "true" : "false"); + << (config.filter.export_linear_aec_output ? "true" : "false") << ","; + ost << "\"use_legacy_filter_naming\": " + << (config.filter.use_legacy_filter_naming ? "true" : "false"); ost << "},"; diff --git a/api/audio/test/echo_canceller3_config_json_unittest.cc b/api/audio/test/echo_canceller3_config_json_unittest.cc index acb21c3c45..2cc34635af 100644 --- a/api/audio/test/echo_canceller3_config_json_unittest.cc +++ b/api/audio/test/echo_canceller3_config_json_unittest.cc @@ -19,6 +19,8 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) { EchoCanceller3Config cfg; cfg.delay.down_sampling_factor = 1u; cfg.delay.log_warning_on_delay_changes = true; + cfg.filter.main.error_floor = 1.f; + cfg.filter.refined.error_floor = 2.f; cfg.filter.shadow_initial.length_blocks = 7u; cfg.suppressor.normal_tuning.mask_hf.enr_suppress = .5f; cfg.suppressor.subband_nearend_detection.nearend_average_blocks = 3; @@ -30,8 +32,6 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) { EchoCanceller3Config cfg_transformed = Aec3ConfigFromJsonString(json_string); // Expect unchanged values to remain default. - EXPECT_EQ(cfg.filter.main.error_floor, - cfg_transformed.filter.main.error_floor); EXPECT_EQ(cfg.ep_strength.default_len, cfg_transformed.ep_strength.default_len); EXPECT_EQ(cfg.suppressor.normal_tuning.mask_lf.enr_suppress, @@ -42,6 +42,10 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) { cfg_transformed.delay.down_sampling_factor); EXPECT_EQ(cfg.delay.log_warning_on_delay_changes, cfg_transformed.delay.log_warning_on_delay_changes); + EXPECT_EQ(cfg.filter.main.error_floor, + cfg_transformed.filter.main.error_floor); + EXPECT_EQ(cfg.filter.refined.error_floor, + cfg_transformed.filter.refined.error_floor); EXPECT_EQ(cfg.filter.shadow_initial.length_blocks, cfg_transformed.filter.shadow_initial.length_blocks); EXPECT_EQ(cfg.suppressor.normal_tuning.mask_hf.enr_suppress, diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn index 909d49e508..e67c80299c 100644 --- a/modules/audio_processing/aec3/BUILD.gn +++ b/modules/audio_processing/aec3/BUILD.gn @@ -72,8 +72,6 @@ rtc_library("aec3") { "frame_blocker.h", "fullband_erle_estimator.cc", "fullband_erle_estimator.h", - "main_filter_update_gain.cc", - "main_filter_update_gain.h", "matched_filter.cc", "matched_filter.h", "matched_filter_lag_aggregator.cc", @@ -81,6 +79,8 @@ rtc_library("aec3") { "moving_average.cc", "moving_average.h", "nearend_detector.h", + "refined_filter_update_gain.cc", + "refined_filter_update_gain.h", "render_buffer.cc", "render_buffer.h", "render_delay_buffer.cc", @@ -215,10 +215,10 @@ if (rtc_include_tests) { "fft_data_unittest.cc", "filter_analyzer_unittest.cc", "frame_blocker_unittest.cc", - "main_filter_update_gain_unittest.cc", "matched_filter_lag_aggregator_unittest.cc", "matched_filter_unittest.cc", "moving_average_unittest.cc", + "refined_filter_update_gain_unittest.cc", "render_buffer_unittest.cc", "render_delay_buffer_unittest.cc", "render_delay_controller_metrics_unittest.cc", diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc index 9d9c79ec7a..7e0591d0d1 100644 --- a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc +++ b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc @@ -353,14 +353,14 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) { EchoCanceller3Config config; if (num_render_channels == 33) { - config.filter.main = {13, 0.00005f, 0.0005f, 0.0001f, 2.f, 20075344.f}; + config.filter.refined = {13, 0.00005f, 0.0005f, 0.0001f, 2.f, 20075344.f}; config.filter.shadow = {13, 0.1f, 20075344.f}; - config.filter.main_initial = {12, 0.005f, 0.5f, 0.001f, 2.f, 20075344.f}; + config.filter.refined_initial = {12, 0.005f, 0.5f, 0.001f, 2.f, 20075344.f}; config.filter.shadow_initial = {12, 0.7f, 20075344.f}; } AdaptiveFirFilter filter( - config.filter.main.length_blocks, config.filter.main.length_blocks, + config.filter.refined.length_blocks, config.filter.refined.length_blocks, config.filter.config_change_duration_blocks, num_render_channels, DetectOptimization(), &data_dumper); std::vector>> H2( @@ -393,7 +393,7 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) { FftData G; FftData E; std::vector> Y2(num_capture_channels); - std::vector> E2_main( + std::vector> E2_refined( num_capture_channels); std::array E2_shadow; // [B,A] = butter(2,100/8000,'high') @@ -403,8 +403,8 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) { for (auto& Y2_ch : Y2) { Y2_ch.fill(0.f); } - for (auto& E2_main_ch : E2_main) { - E2_main_ch.fill(0.f); + for (auto& E2_refined_ch : E2_refined) { + E2_refined_ch.fill(0.f); } E2_shadow.fill(0.f); for (auto& subtractor_output : output) { @@ -469,7 +469,7 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) { fft.ZeroPaddedFft(e, Aec3Fft::Window::kRectangular, &E); for (auto& o : output) { for (size_t k = 0; k < kBlockSize; ++k) { - o.s_main[k] = kScale * s_scratch[k + kFftLengthBy2]; + o.s_refined[k] = kScale * s_scratch[k + kFftLengthBy2]; } } @@ -482,7 +482,7 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) { false, EchoPathVariability::DelayAdjustment::kNone, false)); filter.ComputeFrequencyResponse(&H2[0]); - aec_state.Update(delay_estimate, H2, h, *render_buffer, E2_main, Y2, + aec_state.Update(delay_estimate, H2, h, *render_buffer, E2_refined, Y2, output); } // Verify that the filter is able to perform well. diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc index 365ec9e5c7..b4b1411daa 100644 --- a/modules/audio_processing/aec3/aec_state.cc +++ b/modules/audio_processing/aec3/aec_state.cc @@ -161,7 +161,7 @@ void AecState::Update( adaptive_filter_frequency_responses, rtc::ArrayView> adaptive_filter_impulse_responses, const RenderBuffer& render_buffer, - rtc::ArrayView> E2_main, + rtc::ArrayView> E2_refined, rtc::ArrayView> Y2, rtc::ArrayView subtractor_output) { RTC_DCHECK_EQ(num_capture_channels_, Y2.size()); @@ -227,7 +227,7 @@ void AecState::Update( } erle_estimator_.Update(render_buffer, adaptive_filter_frequency_responses, - avg_render_spectrum_with_reverb, Y2, E2_main, + avg_render_spectrum_with_reverb, Y2, E2_refined, subtractor_output_analyzer_.ConvergedFilters()); erl_estimator_.Update( @@ -511,7 +511,7 @@ void AecState::SaturationDetector::Update( for (size_t ch = 0; ch < subtractor_output.size(); ++ch) { saturated_echo_ = saturated_echo_ || - (subtractor_output[ch].s_main_max_abs > kSaturationThreshold || + (subtractor_output[ch].s_refined_max_abs > kSaturationThreshold || subtractor_output[ch].s_shadow_max_abs > kSaturationThreshold); } } else { diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h index 250091e5dd..aadfde9b04 100644 --- a/modules/audio_processing/aec3/aec_state.h +++ b/modules/audio_processing/aec3/aec_state.h @@ -135,7 +135,7 @@ class AecState { rtc::ArrayView> adaptive_filter_impulse_responses, const RenderBuffer& render_buffer, - rtc::ArrayView> E2_main, + rtc::ArrayView> E2_refined, rtc::ArrayView> Y2, rtc::ArrayView subtractor_output); diff --git a/modules/audio_processing/aec3/aec_state_unittest.cc b/modules/audio_processing/aec3/aec_state_unittest.cc index 3ca8220471..67ed5840c6 100644 --- a/modules/audio_processing/aec3/aec_state_unittest.cc +++ b/modules/audio_processing/aec3/aec_state_unittest.cc @@ -32,7 +32,7 @@ void RunNormalUsageTest(size_t num_render_channels, DelayEstimate(DelayEstimate::Quality::kRefined, 10); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels)); - std::vector> E2_main( + std::vector> E2_refined( num_capture_channels); std::vector> Y2(num_capture_channels); std::vector>> x( @@ -44,10 +44,10 @@ void RunNormalUsageTest(size_t num_render_channels, std::vector subtractor_output(num_capture_channels); for (size_t ch = 0; ch < num_capture_channels; ++ch) { subtractor_output[ch].Reset(); - subtractor_output[ch].s_main.fill(100.f); - subtractor_output[ch].e_main.fill(100.f); + subtractor_output[ch].s_refined.fill(100.f); + subtractor_output[ch].e_refined.fill(100.f); y[ch].fill(1000.f); - E2_main[ch].fill(0.f); + E2_refined[ch].fill(0.f); Y2[ch].fill(0.f); } Aec3Fft fft; @@ -66,8 +66,8 @@ void RunNormalUsageTest(size_t num_render_channels, converged_filter_frequency_response[0][2][0] = 1.f; std::vector> impulse_response( num_capture_channels, - std::vector(GetTimeDomainLength(config.filter.main.length_blocks), - 0.f)); + std::vector( + GetTimeDomainLength(config.filter.refined.length_blocks), 0.f)); // Verify that linear AEC usability is true when the filter is converged for (size_t band = 0; band < kNumBands; ++band) { @@ -82,7 +82,7 @@ void RunNormalUsageTest(size_t num_render_channels, } state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); } EXPECT_TRUE(state.UsableLinearEstimate()); @@ -95,7 +95,7 @@ void RunNormalUsageTest(size_t num_render_channels, false, EchoPathVariability::DelayAdjustment::kBufferReadjustment, false)); state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); EXPECT_FALSE(state.UsableLinearEstimate()); // Verify that the active render detection works as intended. @@ -110,7 +110,7 @@ void RunNormalUsageTest(size_t num_render_channels, true, EchoPathVariability::DelayAdjustment::kNewDetectedDelay, false)); state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); EXPECT_FALSE(state.ActiveRender()); for (int k = 0; k < 1000; ++k) { @@ -120,7 +120,7 @@ void RunNormalUsageTest(size_t num_render_channels, } state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); } EXPECT_TRUE(state.ActiveRender()); @@ -152,7 +152,7 @@ void RunNormalUsageTest(size_t num_render_channels, } state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); } ASSERT_TRUE(state.UsableLinearEstimate()); @@ -164,11 +164,11 @@ void RunNormalUsageTest(size_t num_render_channels, EXPECT_EQ(erl[erl.size() - 2], erl[erl.size() - 1]); // Verify that the ERLE is properly estimated - for (auto& E2_main_ch : E2_main) { - E2_main_ch.fill(1.f * 10000.f * 10000.f); + for (auto& E2_refined_ch : E2_refined) { + E2_refined_ch.fill(1.f * 10000.f * 10000.f); } for (auto& Y2_ch : Y2) { - Y2_ch.fill(10.f * E2_main[0][0]); + Y2_ch.fill(10.f * E2_refined[0][0]); } for (size_t k = 0; k < 1000; ++k) { for (size_t ch = 0; ch < num_capture_channels; ++ch) { @@ -176,7 +176,7 @@ void RunNormalUsageTest(size_t num_render_channels, } state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); } ASSERT_TRUE(state.UsableLinearEstimate()); { @@ -193,11 +193,11 @@ void RunNormalUsageTest(size_t num_render_channels, } EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]); } - for (auto& E2_main_ch : E2_main) { - E2_main_ch.fill(1.f * 10000.f * 10000.f); + for (auto& E2_refined_ch : E2_refined) { + E2_refined_ch.fill(1.f * 10000.f * 10000.f); } for (auto& Y2_ch : Y2) { - Y2_ch.fill(5.f * E2_main[0][0]); + Y2_ch.fill(5.f * E2_refined[0][0]); } for (size_t k = 0; k < 1000; ++k) { for (size_t ch = 0; ch < num_capture_channels; ++ch) { @@ -205,7 +205,7 @@ void RunNormalUsageTest(size_t num_render_channels, } state.Update(delay_estimate, converged_filter_frequency_response, impulse_response, *render_delay_buffer->GetRenderBuffer(), - E2_main, Y2, subtractor_output); + E2_refined, Y2, subtractor_output); } ASSERT_TRUE(state.UsableLinearEstimate()); @@ -250,7 +250,7 @@ TEST(AecState, ConvergedFilterDelay) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(config, 48000, 1)); absl::optional delay_estimate; - std::vector> E2_main( + std::vector> E2_refined( kNumCaptureChannels); std::vector> Y2(kNumCaptureChannels); std::array x; @@ -259,7 +259,7 @@ TEST(AecState, ConvergedFilterDelay) { std::vector subtractor_output(kNumCaptureChannels); for (auto& output : subtractor_output) { output.Reset(); - output.s_main.fill(100.f); + output.s_refined.fill(100.f); } std::array y; x.fill(0.f); @@ -277,8 +277,8 @@ TEST(AecState, ConvergedFilterDelay) { std::vector> impulse_response( kNumCaptureChannels, - std::vector(GetTimeDomainLength(config.filter.main.length_blocks), - 0.f)); + std::vector( + GetTimeDomainLength(config.filter.refined.length_blocks), 0.f)); // Verify that the filter delay for a converged filter is properly // identified. @@ -291,7 +291,7 @@ TEST(AecState, ConvergedFilterDelay) { state.HandleEchoPathChange(echo_path_variability); subtractor_output[0].ComputeMetrics(y); state.Update(delay_estimate, frequency_response, impulse_response, - *render_delay_buffer->GetRenderBuffer(), E2_main, Y2, + *render_delay_buffer->GetRenderBuffer(), E2_refined, Y2, subtractor_output); } } diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc index 0a4c61e392..30ae80b2b3 100644 --- a/modules/audio_processing/aec3/echo_canceller3.cc +++ b/modules/audio_processing/aec3/echo_canceller3.cc @@ -38,6 +38,11 @@ bool DetectSaturation(rtc::ArrayView y) { EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { EchoCanceller3Config adjusted_cfg = config; + if (adjusted_cfg.filter.use_legacy_filter_naming) { + adjusted_cfg.filter.refined = adjusted_cfg.filter.main; + adjusted_cfg.filter.refined_initial = adjusted_cfg.filter.main_initial; + } + if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) { // Two blocks headroom. adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2; diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc index b37e871cb0..55cfe4b54b 100644 --- a/modules/audio_processing/aec3/echo_remover.cc +++ b/modules/audio_processing/aec3/echo_remover.cc @@ -133,7 +133,7 @@ class EchoRemoverImpl final : public EchoRemover { } private: - // Selects which of the shadow and main linear filter outputs that is most + // Selects which of the shadow and refined linear filter outputs that is most // appropriate to pass to the suppressor and forms the linear filter output by // smoothly transition between those. void FormLinearFilterOutput(const SubtractorOutput& subtractor_output, @@ -161,7 +161,7 @@ class EchoRemoverImpl final : public EchoRemover { std::vector> y_old_; size_t block_counter_ = 0; int gain_change_hangover_ = 0; - bool main_filter_output_last_selected_ = true; + bool refined_filter_output_last_selected_ = true; std::vector> e_heap_; std::vector> Y2_heap_; @@ -429,7 +429,7 @@ void EchoRemoverImpl::ProcessCapture( // Debug outputs for the purpose of development and analysis. data_dumper_->DumpWav("aec3_echo_estimate", kBlockSize, - &subtractor_output[0].s_main[0], 16000, 1); + &subtractor_output[0].s_refined[0], 16000, 1); data_dumper_->DumpRaw("aec3_output", (*y)[0][0]); data_dumper_->DumpRaw("aec3_narrow_render", render_signal_analyzer_.NarrowPeakBand() ? 1 : 0); @@ -456,34 +456,35 @@ void EchoRemoverImpl::ProcessCapture( void EchoRemoverImpl::FormLinearFilterOutput( const SubtractorOutput& subtractor_output, rtc::ArrayView output) { - RTC_DCHECK_EQ(subtractor_output.e_main.size(), output.size()); + RTC_DCHECK_EQ(subtractor_output.e_refined.size(), output.size()); RTC_DCHECK_EQ(subtractor_output.e_shadow.size(), output.size()); - bool use_main_output = true; + bool use_refined_output = true; if (use_shadow_filter_output_) { - // As the output of the main adaptive filter generally should be better + // As the output of the refined adaptive filter generally should be better // than the shadow filter output, add a margin and threshold for when // choosing the shadow filter output. - if (subtractor_output.e2_shadow < 0.9f * subtractor_output.e2_main && + if (subtractor_output.e2_shadow < 0.9f * subtractor_output.e2_refined && subtractor_output.y2 > 30.f * 30.f * kBlockSize && - (subtractor_output.s2_main > 60.f * 60.f * kBlockSize || + (subtractor_output.s2_refined > 60.f * 60.f * kBlockSize || subtractor_output.s2_shadow > 60.f * 60.f * kBlockSize)) { - use_main_output = false; + use_refined_output = false; } else { - // If the main filter is diverged, choose the filter output that has the - // lowest power. - if (subtractor_output.e2_shadow < subtractor_output.e2_main && - subtractor_output.y2 < subtractor_output.e2_main) { - use_main_output = false; + // If the refined filter is diverged, choose the filter output that has + // the lowest power. + if (subtractor_output.e2_shadow < subtractor_output.e2_refined && + subtractor_output.y2 < subtractor_output.e2_refined) { + use_refined_output = false; } } } - SignalTransition( - main_filter_output_last_selected_ ? subtractor_output.e_main - : subtractor_output.e_shadow, - use_main_output ? subtractor_output.e_main : subtractor_output.e_shadow, - output); - main_filter_output_last_selected_ = use_main_output; + SignalTransition(refined_filter_output_last_selected_ + ? subtractor_output.e_refined + : subtractor_output.e_shadow, + use_refined_output ? subtractor_output.e_refined + : subtractor_output.e_shadow, + output); + refined_filter_output_last_selected_ = use_refined_output; } } // namespace diff --git a/modules/audio_processing/aec3/erle_estimator_unittest.cc b/modules/audio_processing/aec3/erle_estimator_unittest.cc index 20df34d312..7fbad90065 100644 --- a/modules/audio_processing/aec3/erle_estimator_unittest.cc +++ b/modules/audio_processing/aec3/erle_estimator_unittest.cc @@ -157,7 +157,7 @@ TEST_P(ErleEstimatorMultiChannel, VerifyErleIncreaseAndHold) { num_render_channels, std::vector(kBlockSize, 0.f))); std::vector>> filter_frequency_response( - config.filter.main.length_blocks, + config.filter.refined.length_blocks, std::vector>(num_capture_channels)); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels)); @@ -211,7 +211,7 @@ TEST_P(ErleEstimatorMultiChannel, VerifyErleTrackingOnOnsets) { num_render_channels, std::vector(kBlockSize, 0.f))); std::vector>> filter_frequency_response( - config.filter.main.length_blocks, + config.filter.refined.length_blocks, std::vector>(num_capture_channels)); std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels)); diff --git a/modules/audio_processing/aec3/filter_analyzer.cc b/modules/audio_processing/aec3/filter_analyzer.cc index f5920f0b27..e467862ba6 100644 --- a/modules/audio_processing/aec3/filter_analyzer.cc +++ b/modules/audio_processing/aec3/filter_analyzer.cc @@ -55,7 +55,7 @@ FilterAnalyzer::FilterAnalyzer(const EchoCanceller3Config& config, default_gain_(config.ep_strength.default_gain), h_highpass_(num_capture_channels, std::vector( - GetTimeDomainLength(config.filter.main.length_blocks), + GetTimeDomainLength(config.filter.refined.length_blocks), 0.f)), filter_analysis_states_(num_capture_channels, FilterAnalysisState(config)), diff --git a/modules/audio_processing/aec3/filter_analyzer.h b/modules/audio_processing/aec3/filter_analyzer.h index a7375778c6..0be2a7bc30 100644 --- a/modules/audio_processing/aec3/filter_analyzer.h +++ b/modules/audio_processing/aec3/filter_analyzer.h @@ -111,7 +111,7 @@ class FilterAnalyzer { struct FilterAnalysisState { explicit FilterAnalysisState(const EchoCanceller3Config& config) - : filter_length_blocks(config.filter.main_initial.length_blocks), + : filter_length_blocks(config.filter.refined_initial.length_blocks), consistent_filter_detector(config) {} float gain; size_t peak_index; diff --git a/modules/audio_processing/aec3/main_filter_update_gain.cc b/modules/audio_processing/aec3/refined_filter_update_gain.cc similarity index 87% rename from modules/audio_processing/aec3/main_filter_update_gain.cc rename to modules/audio_processing/aec3/refined_filter_update_gain.cc index 43f37b0cf4..bd79f870e8 100644 --- a/modules/audio_processing/aec3/main_filter_update_gain.cc +++ b/modules/audio_processing/aec3/refined_filter_update_gain.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/main_filter_update_gain.h" +#include "modules/audio_processing/aec3/refined_filter_update_gain.h" #include #include @@ -31,10 +31,10 @@ constexpr int kPoorExcitationCounterInitial = 1000; } // namespace -int MainFilterUpdateGain::instance_count_ = 0; +int RefinedFilterUpdateGain::instance_count_ = 0; -MainFilterUpdateGain::MainFilterUpdateGain( - const EchoCanceller3Config::Filter::MainConfiguration& config, +RefinedFilterUpdateGain::RefinedFilterUpdateGain( + const EchoCanceller3Config::Filter::RefinedConfiguration& config, size_t config_change_duration_blocks) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), @@ -47,9 +47,9 @@ MainFilterUpdateGain::MainFilterUpdateGain( one_by_config_change_duration_blocks_ = 1.f / config_change_duration_blocks_; } -MainFilterUpdateGain::~MainFilterUpdateGain() {} +RefinedFilterUpdateGain::~RefinedFilterUpdateGain() {} -void MainFilterUpdateGain::HandleEchoPathChange( +void RefinedFilterUpdateGain::HandleEchoPathChange( const EchoPathVariability& echo_path_variability) { if (echo_path_variability.gain_change) { // TODO(bugs.webrtc.org/9526) Handle gain changes. @@ -66,7 +66,7 @@ void MainFilterUpdateGain::HandleEchoPathChange( } } -void MainFilterUpdateGain::Compute( +void RefinedFilterUpdateGain::Compute( const std::array& render_power, const RenderSignalAnalyzer& render_signal_analyzer, const SubtractorOutput& subtractor_output, @@ -76,8 +76,8 @@ void MainFilterUpdateGain::Compute( FftData* gain_fft) { RTC_DCHECK(gain_fft); // Introducing shorter notation to improve readability. - const FftData& E_main = subtractor_output.E_main; - const auto& E2_main = subtractor_output.E2_main; + const FftData& E_refined = subtractor_output.E_refined; + const auto& E2_refined = subtractor_output.E2_refined; const auto& E2_shadow = subtractor_output.E2_shadow; FftData* G = gain_fft; const auto& X2 = render_power; @@ -102,7 +102,7 @@ void MainFilterUpdateGain::Compute( for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) { if (X2[k] >= current_config_.noise_gate) { mu[k] = H_error_[k] / - (0.5f * H_error_[k] * X2[k] + size_partitions * E2_main[k]); + (0.5f * H_error_[k] * X2[k] + size_partitions * E2_refined[k]); } else { mu[k] = 0.f; } @@ -118,14 +118,14 @@ void MainFilterUpdateGain::Compute( // G = mu * E. for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) { - G->re[k] = mu[k] * E_main.re[k]; - G->im[k] = mu[k] * E_main.im[k]; + G->re[k] = mu[k] * E_refined.re[k]; + G->im[k] = mu[k] * E_refined.im[k]; } } // H_error = H_error + factor * erl. for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) { - if (E2_shadow[k] >= E2_main[k]) { + if (E2_shadow[k] >= E2_refined[k]) { H_error_[k] += current_config_.leakage_converged * erl[k]; } else { H_error_[k] += current_config_.leakage_diverged * erl[k]; @@ -135,10 +135,10 @@ void MainFilterUpdateGain::Compute( H_error_[k] = std::min(H_error_[k], current_config_.error_ceil); } - data_dumper_->DumpRaw("aec3_main_gain_H_error", H_error_); + data_dumper_->DumpRaw("aec3_refined_gain_H_error", H_error_); } -void MainFilterUpdateGain::UpdateCurrentConfig() { +void RefinedFilterUpdateGain::UpdateCurrentConfig() { RTC_DCHECK_GE(config_change_duration_blocks_, config_change_counter_); if (config_change_counter_ > 0) { if (--config_change_counter_ > 0) { diff --git a/modules/audio_processing/aec3/main_filter_update_gain.h b/modules/audio_processing/aec3/refined_filter_update_gain.h similarity index 71% rename from modules/audio_processing/aec3/main_filter_update_gain.h rename to modules/audio_processing/aec3/refined_filter_update_gain.h index 1955d2a402..5730979567 100644 --- a/modules/audio_processing/aec3/main_filter_update_gain.h +++ b/modules/audio_processing/aec3/refined_filter_update_gain.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_AEC3_MAIN_FILTER_UPDATE_GAIN_H_ -#define MODULES_AUDIO_PROCESSING_AEC3_MAIN_FILTER_UPDATE_GAIN_H_ +#ifndef MODULES_AUDIO_PROCESSING_AEC3_REFINED_FILTER_UPDATE_GAIN_H_ +#define MODULES_AUDIO_PROCESSING_AEC3_REFINED_FILTER_UPDATE_GAIN_H_ #include @@ -29,16 +29,17 @@ struct FftData; class RenderSignalAnalyzer; struct SubtractorOutput; -// Provides functionality for computing the adaptive gain for the main filter. -class MainFilterUpdateGain { +// Provides functionality for computing the adaptive gain for the refined +// filter. +class RefinedFilterUpdateGain { public: - MainFilterUpdateGain( - const EchoCanceller3Config::Filter::MainConfiguration& config, + RefinedFilterUpdateGain( + const EchoCanceller3Config::Filter::RefinedConfiguration& config, size_t config_change_duration_blocks); - ~MainFilterUpdateGain(); + ~RefinedFilterUpdateGain(); - MainFilterUpdateGain(const MainFilterUpdateGain&) = delete; - MainFilterUpdateGain& operator=(const MainFilterUpdateGain&) = delete; + RefinedFilterUpdateGain(const RefinedFilterUpdateGain&) = delete; + RefinedFilterUpdateGain& operator=(const RefinedFilterUpdateGain&) = delete; // Takes action in the case of a known echo path change. void HandleEchoPathChange(const EchoPathVariability& echo_path_variability); @@ -53,8 +54,9 @@ class MainFilterUpdateGain { FftData* gain_fft); // Sets a new config. - void SetConfig(const EchoCanceller3Config::Filter::MainConfiguration& config, - bool immediate_effect) { + void SetConfig( + const EchoCanceller3Config::Filter::RefinedConfiguration& config, + bool immediate_effect) { if (immediate_effect) { old_target_config_ = current_config_ = target_config_ = config; config_change_counter_ = 0; @@ -70,9 +72,9 @@ class MainFilterUpdateGain { std::unique_ptr data_dumper_; const int config_change_duration_blocks_; float one_by_config_change_duration_blocks_; - EchoCanceller3Config::Filter::MainConfiguration current_config_; - EchoCanceller3Config::Filter::MainConfiguration target_config_; - EchoCanceller3Config::Filter::MainConfiguration old_target_config_; + EchoCanceller3Config::Filter::RefinedConfiguration current_config_; + EchoCanceller3Config::Filter::RefinedConfiguration target_config_; + EchoCanceller3Config::Filter::RefinedConfiguration old_target_config_; std::array H_error_; size_t poor_excitation_counter_; size_t call_counter_ = 0; @@ -84,4 +86,4 @@ class MainFilterUpdateGain { } // namespace webrtc -#endif // MODULES_AUDIO_PROCESSING_AEC3_MAIN_FILTER_UPDATE_GAIN_H_ +#endif // MODULES_AUDIO_PROCESSING_AEC3_REFINED_FILTER_UPDATE_GAIN_H_ diff --git a/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc b/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc similarity index 84% rename from modules/audio_processing/aec3/main_filter_update_gain_unittest.cc rename to modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc index f79b2d6e84..6ee880ad14 100644 --- a/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc +++ b/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc @@ -8,11 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/main_filter_update_gain.h" +#include "modules/audio_processing/aec3/refined_filter_update_gain.h" #include #include #include +#include #include "modules/audio_processing/aec3/adaptive_fir_filter.h" #include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h" @@ -31,8 +32,8 @@ namespace webrtc { namespace { -// Method for performing the simulations needed to test the main filter update -// gain functionality. +// Method for performing the simulations needed to test the refined filter +// update gain functionality. void RunFilterUpdateTest(int num_blocks_to_process, size_t delay_samples, int filter_length_blocks, @@ -50,19 +51,19 @@ void RunFilterUpdateTest(int num_blocks_to_process, constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz); EchoCanceller3Config config; - config.filter.main.length_blocks = filter_length_blocks; + config.filter.refined.length_blocks = filter_length_blocks; config.filter.shadow.length_blocks = filter_length_blocks; - AdaptiveFirFilter main_filter(config.filter.main.length_blocks, - config.filter.main.length_blocks, - config.filter.config_change_duration_blocks, - kNumRenderChannels, optimization, &data_dumper); + AdaptiveFirFilter refined_filter( + config.filter.refined.length_blocks, config.filter.refined.length_blocks, + config.filter.config_change_duration_blocks, kNumRenderChannels, + optimization, &data_dumper); AdaptiveFirFilter shadow_filter( config.filter.shadow.length_blocks, config.filter.shadow.length_blocks, config.filter.config_change_duration_blocks, kNumRenderChannels, optimization, &data_dumper); std::vector>> H2( kNumCaptureChannels, std::vector>( - main_filter.max_filter_size_partitions(), + refined_filter.max_filter_size_partitions(), std::array())); for (auto& H2_ch : H2) { for (auto& H2_k : H2_ch) { @@ -72,15 +73,16 @@ void RunFilterUpdateTest(int num_blocks_to_process, std::vector> h( kNumCaptureChannels, std::vector( - GetTimeDomainLength(main_filter.max_filter_size_partitions()), 0.f)); + GetTimeDomainLength(refined_filter.max_filter_size_partitions()), + 0.f)); Aec3Fft fft; std::array x_old; x_old.fill(0.f); ShadowFilterUpdateGain shadow_gain( config.filter.shadow, config.filter.config_change_duration_blocks); - MainFilterUpdateGain main_gain(config.filter.main, - config.filter.config_change_duration_blocks); + RefinedFilterUpdateGain refined_gain( + config.filter.refined, config.filter.config_change_duration_blocks); Random random_generator(42U); std::vector>> x( kNumBands, std::vector>( @@ -100,12 +102,12 @@ void RunFilterUpdateTest(int num_blocks_to_process, for (auto& subtractor_output : output) { subtractor_output.Reset(); } - FftData& E_main = output[0].E_main; + FftData& E_refined = output[0].E_refined; FftData E_shadow; std::vector> Y2(kNumCaptureChannels); - std::vector> E2_main( + std::vector> E2_refined( kNumCaptureChannels); - std::array& e_main = output[0].e_main; + std::array& e_refined = output[0].e_refined; std::array& e_shadow = output[0].e_shadow; for (auto& Y2_ch : Y2) { Y2_ch.fill(0.f); @@ -119,7 +121,7 @@ void RunFilterUpdateTest(int num_blocks_to_process, if (std::find(blocks_with_echo_path_changes.begin(), blocks_with_echo_path_changes.end(), k) != blocks_with_echo_path_changes.end()) { - main_filter.HandleEchoPathChange(); + refined_filter.HandleEchoPathChange(); } // Handle saturation. @@ -152,15 +154,15 @@ void RunFilterUpdateTest(int num_blocks_to_process, render_signal_analyzer.Update(*render_delay_buffer->GetRenderBuffer(), aec_state.MinDirectPathFilterDelay()); - // Apply the main filter. - main_filter.Filter(*render_delay_buffer->GetRenderBuffer(), &S); + // Apply the refined filter. + refined_filter.Filter(*render_delay_buffer->GetRenderBuffer(), &S); fft.Ifft(S, &s_scratch); std::transform(y.begin(), y.end(), s_scratch.begin() + kFftLengthBy2, - e_main.begin(), + e_refined.begin(), [&](float a, float b) { return a - b * kScale; }); - std::for_each(e_main.begin(), e_main.end(), + std::for_each(e_refined.begin(), e_refined.end(), [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); }); - fft.ZeroPaddedFft(e_main, Aec3Fft::Window::kRectangular, &E_main); + fft.ZeroPaddedFft(e_refined, Aec3Fft::Window::kRectangular, &E_refined); for (size_t k = 0; k < kBlockSize; ++k) { s[k] = kScale * s_scratch[k + kFftLengthBy2]; } @@ -176,7 +178,7 @@ void RunFilterUpdateTest(int num_blocks_to_process, fft.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kRectangular, &E_shadow); // Compute spectra for future use. - E_main.Spectrum(Aec3Optimization::kNone, output[0].E2_main); + E_refined.Spectrum(Aec3Optimization::kNone, output[0].E2_refined); E_shadow.Spectrum(Aec3Optimization::kNone, output[0].E2_shadow); // Adapt the shadow filter. @@ -187,28 +189,28 @@ void RunFilterUpdateTest(int num_blocks_to_process, shadow_filter.SizePartitions(), saturation, &G); shadow_filter.Adapt(*render_delay_buffer->GetRenderBuffer(), G); - // Adapt the main filter + // Adapt the refined filter render_delay_buffer->GetRenderBuffer()->SpectralSum( - main_filter.SizePartitions(), &render_power); + refined_filter.SizePartitions(), &render_power); std::array erl; ComputeErl(optimization, H2[0], erl); - main_gain.Compute(render_power, render_signal_analyzer, output[0], erl, - main_filter.SizePartitions(), saturation, &G); - main_filter.Adapt(*render_delay_buffer->GetRenderBuffer(), G, &h[0]); + refined_gain.Compute(render_power, render_signal_analyzer, output[0], erl, + refined_filter.SizePartitions(), saturation, &G); + refined_filter.Adapt(*render_delay_buffer->GetRenderBuffer(), G, &h[0]); // Update the delay. aec_state.HandleEchoPathChange(EchoPathVariability( false, EchoPathVariability::DelayAdjustment::kNone, false)); - main_filter.ComputeFrequencyResponse(&H2[0]); - std::copy(output[0].E2_main.begin(), output[0].E2_main.end(), - E2_main[0].begin()); + refined_filter.ComputeFrequencyResponse(&H2[0]); + std::copy(output[0].E2_refined.begin(), output[0].E2_refined.end(), + E2_refined[0].begin()); aec_state.Update(delay_estimate, H2, h, - *render_delay_buffer->GetRenderBuffer(), E2_main, Y2, + *render_delay_buffer->GetRenderBuffer(), E2_refined, Y2, output); } - std::copy(e_main.begin(), e_main.end(), e_last_block->begin()); + std::copy(e_refined.begin(), e_refined.end(), e_last_block->begin()); std::copy(y.begin(), y.end(), y_last_block->begin()); std::copy(G.re.begin(), G.re.end(), G_last_block->re.begin()); std::copy(G.im.begin(), G.im.end(), G_last_block->im.begin()); @@ -232,26 +234,27 @@ std::string ProduceDebugText(size_t delay, int filter_length_blocks) { #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) // Verifies that the check for non-null output gain parameter works. -TEST(MainFilterUpdateGain, NullDataOutputGain) { +TEST(RefinedFilterUpdateGain, NullDataOutputGain) { ApmDataDumper data_dumper(42); EchoCanceller3Config config; RenderSignalAnalyzer analyzer(config); SubtractorOutput output; - MainFilterUpdateGain gain(config.filter.main, - config.filter.config_change_duration_blocks); + RefinedFilterUpdateGain gain(config.filter.refined, + config.filter.config_change_duration_blocks); std::array render_power; render_power.fill(0.f); std::array erl; erl.fill(0.f); - EXPECT_DEATH(gain.Compute(render_power, analyzer, output, erl, - config.filter.main.length_blocks, false, nullptr), - ""); + EXPECT_DEATH( + gain.Compute(render_power, analyzer, output, erl, + config.filter.refined.length_blocks, false, nullptr), + ""); } #endif // Verifies that the gain formed causes the filter using it to converge. -TEST(MainFilterUpdateGain, GainCausesFilterToConverge) { +TEST(RefinedFilterUpdateGain, GainCausesFilterToConverge) { std::vector blocks_with_echo_path_changes; std::vector blocks_with_saturation; for (size_t filter_length_blocks : {12, 20, 30}) { @@ -266,7 +269,7 @@ TEST(MainFilterUpdateGain, GainCausesFilterToConverge) { blocks_with_echo_path_changes, blocks_with_saturation, false, &e, &y, &G); - // Verify that the main filter is able to perform well. + // Verify that the refined filter is able to perform well. // Use different criteria to take overmodelling into account. if (filter_length_blocks == 12) { EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f), @@ -281,7 +284,7 @@ TEST(MainFilterUpdateGain, GainCausesFilterToConverge) { // Verifies that the magnitude of the gain on average decreases for a // persistently exciting signal. -TEST(MainFilterUpdateGain, DecreasingGain) { +TEST(RefinedFilterUpdateGain, DecreasingGain) { std::vector blocks_with_echo_path_changes; std::vector blocks_with_saturation; @@ -314,7 +317,7 @@ TEST(MainFilterUpdateGain, DecreasingGain) { // Verifies that the gain is zero when there is saturation and that the internal // error estimates cause the gain to increase after a period of saturation. -TEST(MainFilterUpdateGain, SaturationBehavior) { +TEST(RefinedFilterUpdateGain, SaturationBehavior) { std::vector blocks_with_echo_path_changes; std::vector blocks_with_saturation; for (int k = 99; k < 200; ++k) { @@ -358,7 +361,7 @@ TEST(MainFilterUpdateGain, SaturationBehavior) { // Verifies that the gain increases after an echo path change. // TODO(peah): Correct and reactivate this test. -TEST(MainFilterUpdateGain, DISABLED_EchoPathChangeBehavior) { +TEST(RefinedFilterUpdateGain, DISABLED_EchoPathChangeBehavior) { for (size_t filter_length_blocks : {12, 20, 30}) { SCOPED_TRACE(ProduceDebugText(filter_length_blocks)); std::vector blocks_with_echo_path_changes; diff --git a/modules/audio_processing/aec3/render_delay_buffer.cc b/modules/audio_processing/aec3/render_delay_buffer.cc index bc6ba15ecb..10e81d8ec9 100644 --- a/modules/audio_processing/aec3/render_delay_buffer.cc +++ b/modules/audio_processing/aec3/render_delay_buffer.cc @@ -133,7 +133,7 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(const EchoCanceller3Config& config, : kBlockSize)), blocks_(GetRenderDelayBufferSize(down_sampling_factor_, config.delay.num_filters, - config.filter.main.length_blocks), + config.filter.refined.length_blocks), NumBandsForRate(sample_rate_hz), num_render_channels, kBlockSize), @@ -147,7 +147,7 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(const EchoCanceller3Config& config, render_decimator_(down_sampling_factor_), fft_(), render_ds_(sub_block_size_, 0.f), - buffer_headroom_(config.filter.main.length_blocks) { + buffer_headroom_(config.filter.refined.length_blocks) { RTC_DCHECK_EQ(blocks_.buffer.size(), ffts_.buffer.size()); RTC_DCHECK_EQ(spectra_.buffer.size(), ffts_.buffer.size()); for (size_t i = 0; i < blocks_.buffer.size(); ++i) { diff --git a/modules/audio_processing/aec3/render_signal_analyzer.cc b/modules/audio_processing/aec3/render_signal_analyzer.cc index e64610ed10..f570aac3a0 100644 --- a/modules/audio_processing/aec3/render_signal_analyzer.cc +++ b/modules/audio_processing/aec3/render_signal_analyzer.cc @@ -118,7 +118,7 @@ void IdentifyStrongNarrowBandComponent(const RenderBuffer& render_buffer, } // namespace RenderSignalAnalyzer::RenderSignalAnalyzer(const EchoCanceller3Config& config) - : strong_peak_freeze_duration_(config.filter.main.length_blocks) { + : strong_peak_freeze_duration_(config.filter.refined.length_blocks) { narrow_band_counters_.fill(0); } RenderSignalAnalyzer::~RenderSignalAnalyzer() = default; diff --git a/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc b/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc index 7c00bbdb2b..f184eb8e6d 100644 --- a/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc +++ b/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc @@ -42,7 +42,7 @@ TEST_P(ResidualEchoEstimatorMultiChannel, BasicTest) { std::unique_ptr render_delay_buffer( RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels)); - std::vector> E2_main( + std::vector> E2_refined( num_capture_channels); std::vector> S2_linear( num_capture_channels); @@ -69,18 +69,18 @@ TEST_P(ResidualEchoEstimatorMultiChannel, BasicTest) { std::vector> h( num_capture_channels, - std::vector(GetTimeDomainLength(config.filter.main.length_blocks), - 0.f)); + std::vector( + GetTimeDomainLength(config.filter.refined.length_blocks), 0.f)); for (auto& subtractor_output : output) { subtractor_output.Reset(); - subtractor_output.s_main.fill(100.f); + subtractor_output.s_refined.fill(100.f); } y.fill(0.f); constexpr float kLevel = 10.f; - for (auto& E2_main_ch : E2_main) { - E2_main_ch.fill(kLevel); + for (auto& E2_refined_ch : E2_refined) { + E2_refined_ch.fill(kLevel); } S2_linear[0].fill(kLevel); for (auto& Y2_ch : Y2) { @@ -96,7 +96,7 @@ TEST_P(ResidualEchoEstimatorMultiChannel, BasicTest) { render_delay_buffer->PrepareCaptureProcessing(); aec_state.Update(delay_estimate, H2, h, - *render_delay_buffer->GetRenderBuffer(), E2_main, Y2, + *render_delay_buffer->GetRenderBuffer(), E2_refined, Y2, output); estimator.Estimate(aec_state, *render_delay_buffer->GetRenderBuffer(), diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.cc b/modules/audio_processing/aec3/reverb_decay_estimator.cc index b9f6120181..f160b835f0 100644 --- a/modules/audio_processing/aec3/reverb_decay_estimator.cc +++ b/modules/audio_processing/aec3/reverb_decay_estimator.cc @@ -85,16 +85,16 @@ float BlockEnergyAverage(rtc::ArrayView h, int block_index) { } // namespace ReverbDecayEstimator::ReverbDecayEstimator(const EchoCanceller3Config& config) - : filter_length_blocks_(config.filter.main.length_blocks), + : filter_length_blocks_(config.filter.refined.length_blocks), filter_length_coefficients_(GetTimeDomainLength(filter_length_blocks_)), use_adaptive_echo_decay_(config.ep_strength.default_len < 0.f), - early_reverb_estimator_(config.filter.main.length_blocks - + early_reverb_estimator_(config.filter.refined.length_blocks - kEarlyReverbMinSizeBlocks), late_reverb_start_(kEarlyReverbMinSizeBlocks), late_reverb_end_(kEarlyReverbMinSizeBlocks), - previous_gains_(config.filter.main.length_blocks, 0.f), + previous_gains_(config.filter.refined.length_blocks, 0.f), decay_(std::fabs(config.ep_strength.default_len)) { - RTC_DCHECK_GT(config.filter.main.length_blocks, + RTC_DCHECK_GT(config.filter.refined.length_blocks, static_cast(kEarlyReverbMinSizeBlocks)); } diff --git a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc index 50a4dc0256..f360a6fcbb 100644 --- a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc +++ b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc @@ -32,7 +32,7 @@ namespace { EchoCanceller3Config CreateConfigForTest(float default_decay) { EchoCanceller3Config cfg; cfg.ep_strength.default_len = default_decay; - cfg.filter.main.length_blocks = 40; + cfg.filter.refined.length_blocks = 40; return cfg; } @@ -47,11 +47,11 @@ class ReverbModelEstimatorTest { estimated_decay_(default_decay), h_(num_capture_channels, std::vector( - aec3_config_.filter.main.length_blocks * kBlockSize, + aec3_config_.filter.refined.length_blocks * kBlockSize, 0.f)), H2_(num_capture_channels, std::vector>( - aec3_config_.filter.main.length_blocks)), + aec3_config_.filter.refined.length_blocks)), quality_linear_(num_capture_channels, 1.0f) { CreateImpulseResponseWithDecay(); } @@ -78,10 +78,10 @@ void ReverbModelEstimatorTest::CreateImpulseResponseWithDecay() { const Aec3Fft fft; for (const auto& h_k : h_) { RTC_DCHECK_EQ(h_k.size(), - aec3_config_.filter.main.length_blocks * kBlockSize); + aec3_config_.filter.refined.length_blocks * kBlockSize); } for (const auto& H2_k : H2_) { - RTC_DCHECK_EQ(H2_k.size(), aec3_config_.filter.main.length_blocks); + RTC_DCHECK_EQ(H2_k.size(), aec3_config_.filter.refined.length_blocks); } RTC_DCHECK_EQ(kFilterDelayBlocks, 2); diff --git a/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc b/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc index 79bc7acfd4..ccac9b3193 100644 --- a/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc +++ b/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc @@ -27,8 +27,8 @@ namespace webrtc { namespace { -// Method for performing the simulations needed to test the main filter update -// gain functionality. +// Method for performing the simulations needed to test the refined filter +// update gain functionality. void RunFilterUpdateTest(int num_blocks_to_process, size_t delay_samples, size_t num_render_channels, @@ -39,9 +39,9 @@ void RunFilterUpdateTest(int num_blocks_to_process, FftData* G_last_block) { ApmDataDumper data_dumper(42); EchoCanceller3Config config; - config.filter.main.length_blocks = filter_length_blocks; - AdaptiveFirFilter main_filter( - config.filter.main.length_blocks, config.filter.main.length_blocks, + config.filter.refined.length_blocks = filter_length_blocks; + AdaptiveFirFilter refined_filter( + config.filter.refined.length_blocks, config.filter.refined.length_blocks, config.filter.config_change_duration_blocks, num_render_channels, DetectOptimization(), &data_dumper); AdaptiveFirFilter shadow_filter( @@ -179,7 +179,7 @@ TEST_P(ShadowFilterUpdateGainOneTwoEightRenderChannels, filter_length_blocks, blocks_with_saturation, &e, &y, &G); - // Verify that the main filter is able to perform well. + // Verify that the refined filter is able to perform well. // Use different criteria to take overmodelling into account. if (filter_length_blocks == 12) { EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f), diff --git a/modules/audio_processing/aec3/signal_dependent_erle_estimator.cc b/modules/audio_processing/aec3/signal_dependent_erle_estimator.cc index d99b7f3e25..5a3ba6c842 100644 --- a/modules/audio_processing/aec3/signal_dependent_erle_estimator.cc +++ b/modules/audio_processing/aec3/signal_dependent_erle_estimator.cc @@ -122,7 +122,7 @@ SignalDependentErleEstimator::SignalDependentErleEstimator( size_t num_capture_channels) : min_erle_(config.erle.min), num_sections_(config.erle.num_sections), - num_blocks_(config.filter.main.length_blocks), + num_blocks_(config.filter.refined.length_blocks), delay_headroom_blocks_(config.delay.delay_headroom_samples / kBlockSize), band_to_subband_(FormSubbandMap()), max_erle_(SetMaxErleSubbands(config.erle.max_l, @@ -261,9 +261,9 @@ void SignalDependentErleEstimator::UpdateCorrectionFactors( for (size_t subband = 0; subband < kSubbands; ++subband) { // When aggregating the number of active sections in the filter for // different bands we choose to take the minimum of all of them. As an - // example, if for one of the bands it is the direct path its main + // example, if for one of the bands it is the direct path its refined // contributor to the final echo estimate, we consider the direct path - // is as well the main contributor for the subband that contains that + // is as well the refined contributor for the subband that contains that // particular band. That aggregate number of sections will be later used // as the identifier of the erle estimator that needs to be updated. RTC_DCHECK_LE(kBandBoundaries[subband + 1], diff --git a/modules/audio_processing/aec3/signal_dependent_erle_estimator_unittest.cc b/modules/audio_processing/aec3/signal_dependent_erle_estimator_unittest.cc index 5c69105b4d..f8a4aece89 100644 --- a/modules/audio_processing/aec3/signal_dependent_erle_estimator_unittest.cc +++ b/modules/audio_processing/aec3/signal_dependent_erle_estimator_unittest.cc @@ -87,7 +87,7 @@ TestInputs::TestInputs(const EchoCanceller3Config& cfg, E2_(num_capture_channels), H2_(num_capture_channels, std::vector>( - cfg.filter.main.length_blocks)), + cfg.filter.refined.length_blocks)), x_(1, std::vector>(num_render_channels, std::vector(kBlockSize, 0.f))), @@ -156,9 +156,9 @@ TEST_P(SignalDependentErleEstimatorMultiChannel, SweepSettings) { for (size_t delay_headroom = 0; delay_headroom < 5; ++delay_headroom) { for (size_t num_sections = 2; num_sections < max_length_blocks; ++num_sections) { - cfg.filter.main.length_blocks = blocks; - cfg.filter.main_initial.length_blocks = - std::min(cfg.filter.main_initial.length_blocks, blocks); + cfg.filter.refined.length_blocks = blocks; + cfg.filter.refined_initial.length_blocks = + std::min(cfg.filter.refined_initial.length_blocks, blocks); cfg.delay.delay_headroom_samples = delay_headroom * kBlockSize; cfg.erle.num_sections = num_sections; if (EchoCanceller3Config::Validate(&cfg)) { @@ -185,8 +185,8 @@ TEST_P(SignalDependentErleEstimatorMultiChannel, LongerRun) { const size_t num_render_channels = std::get<0>(GetParam()); const size_t num_capture_channels = std::get<1>(GetParam()); EchoCanceller3Config cfg; - cfg.filter.main.length_blocks = 2; - cfg.filter.main_initial.length_blocks = 1; + cfg.filter.refined.length_blocks = 2; + cfg.filter.refined_initial.length_blocks = 1; cfg.delay.delay_headroom_samples = 0; cfg.delay.hysteresis_limit_blocks = 0; cfg.erle.num_sections = 2; diff --git a/modules/audio_processing/aec3/subtractor.cc b/modules/audio_processing/aec3/subtractor.cc index 27cc424e07..da6fda1894 100644 --- a/modules/audio_processing/aec3/subtractor.cc +++ b/modules/audio_processing/aec3/subtractor.cc @@ -66,28 +66,28 @@ Subtractor::Subtractor(const EchoCanceller3Config& config, optimization_(optimization), config_(config), num_capture_channels_(num_capture_channels), - main_filters_(num_capture_channels_), + refined_filters_(num_capture_channels_), shadow_filter_(num_capture_channels_), - main_gains_(num_capture_channels_), + refined_gains_(num_capture_channels_), shadow_gains_(num_capture_channels_), filter_misadjustment_estimators_(num_capture_channels_), poor_shadow_filter_counters_(num_capture_channels_, 0), - main_frequency_responses_( + refined_frequency_responses_( num_capture_channels_, std::vector>( - std::max(config_.filter.main_initial.length_blocks, - config_.filter.main.length_blocks), + std::max(config_.filter.refined_initial.length_blocks, + config_.filter.refined.length_blocks), std::array())), - main_impulse_responses_( + refined_impulse_responses_( num_capture_channels_, std::vector(GetTimeDomainLength(std::max( - config_.filter.main_initial.length_blocks, - config_.filter.main.length_blocks)), + config_.filter.refined_initial.length_blocks, + config_.filter.refined.length_blocks)), 0.f)) { for (size_t ch = 0; ch < num_capture_channels_; ++ch) { - main_filters_[ch] = std::make_unique( - config_.filter.main.length_blocks, - config_.filter.main_initial.length_blocks, + refined_filters_[ch] = std::make_unique( + config_.filter.refined.length_blocks, + config_.filter.refined_initial.length_blocks, config.filter.config_change_duration_blocks, num_render_channels, optimization, data_dumper_); @@ -96,8 +96,8 @@ Subtractor::Subtractor(const EchoCanceller3Config& config, config_.filter.shadow_initial.length_blocks, config.filter.config_change_duration_blocks, num_render_channels, optimization, data_dumper_); - main_gains_[ch] = std::make_unique( - config_.filter.main_initial, + refined_gains_[ch] = std::make_unique( + config_.filter.refined_initial, config_.filter.config_change_duration_blocks); shadow_gains_[ch] = std::make_unique( config_.filter.shadow_initial, @@ -106,7 +106,7 @@ Subtractor::Subtractor(const EchoCanceller3Config& config, RTC_DCHECK(data_dumper_); for (size_t ch = 0; ch < num_capture_channels_; ++ch) { - for (auto& H2_k : main_frequency_responses_[ch]) { + for (auto& H2_k : refined_frequency_responses_[ch]) { H2_k.fill(0.f); } } @@ -118,14 +118,14 @@ void Subtractor::HandleEchoPathChange( const EchoPathVariability& echo_path_variability) { const auto full_reset = [&]() { for (size_t ch = 0; ch < num_capture_channels_; ++ch) { - main_filters_[ch]->HandleEchoPathChange(); + refined_filters_[ch]->HandleEchoPathChange(); shadow_filter_[ch]->HandleEchoPathChange(); - main_gains_[ch]->HandleEchoPathChange(echo_path_variability); + refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); shadow_gains_[ch]->HandleEchoPathChange(); - main_gains_[ch]->SetConfig(config_.filter.main_initial, true); + refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true); shadow_gains_[ch]->SetConfig(config_.filter.shadow_initial, true); - main_filters_[ch]->SetSizePartitions( - config_.filter.main_initial.length_blocks, true); + refined_filters_[ch]->SetSizePartitions( + config_.filter.refined_initial.length_blocks, true); shadow_filter_[ch]->SetSizePartitions( config_.filter.shadow_initial.length_blocks, true); } @@ -138,17 +138,17 @@ void Subtractor::HandleEchoPathChange( if (echo_path_variability.gain_change) { for (size_t ch = 0; ch < num_capture_channels_; ++ch) { - main_gains_[ch]->HandleEchoPathChange(echo_path_variability); + refined_gains_[ch]->HandleEchoPathChange(echo_path_variability); } } } void Subtractor::ExitInitialState() { for (size_t ch = 0; ch < num_capture_channels_; ++ch) { - main_gains_[ch]->SetConfig(config_.filter.main, false); + refined_gains_[ch]->SetConfig(config_.filter.refined, false); shadow_gains_[ch]->SetConfig(config_.filter.shadow, false); - main_filters_[ch]->SetSizePartitions(config_.filter.main.length_blocks, - false); + refined_filters_[ch]->SetSizePartitions( + config_.filter.refined.length_blocks, false); shadow_filter_[ch]->SetSizePartitions(config_.filter.shadow.length_blocks, false); } @@ -162,21 +162,22 @@ void Subtractor::Process(const RenderBuffer& render_buffer, RTC_DCHECK_EQ(num_capture_channels_, capture.size()); // Compute the render powers. - const bool same_filter_sizes = - main_filters_[0]->SizePartitions() == shadow_filter_[0]->SizePartitions(); - std::array X2_main; + const bool same_filter_sizes = refined_filters_[0]->SizePartitions() == + shadow_filter_[0]->SizePartitions(); + std::array X2_refined; std::array X2_shadow_data; - auto& X2_shadow = same_filter_sizes ? X2_main : X2_shadow_data; + auto& X2_shadow = same_filter_sizes ? X2_refined : X2_shadow_data; if (same_filter_sizes) { - render_buffer.SpectralSum(main_filters_[0]->SizePartitions(), &X2_main); - } else if (main_filters_[0]->SizePartitions() > + render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(), + &X2_refined); + } else if (refined_filters_[0]->SizePartitions() > shadow_filter_[0]->SizePartitions()) { render_buffer.SpectralSums(shadow_filter_[0]->SizePartitions(), - main_filters_[0]->SizePartitions(), &X2_shadow, - &X2_main); + refined_filters_[0]->SizePartitions(), + &X2_shadow, &X2_refined); } else { - render_buffer.SpectralSums(main_filters_[0]->SizePartitions(), - shadow_filter_[0]->SizePartitions(), &X2_main, + render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(), + shadow_filter_[0]->SizePartitions(), &X2_refined, &X2_shadow); } @@ -185,17 +186,17 @@ void Subtractor::Process(const RenderBuffer& render_buffer, RTC_DCHECK_EQ(kBlockSize, capture[ch].size()); SubtractorOutput& output = outputs[ch]; rtc::ArrayView y = capture[ch]; - FftData& E_main = output.E_main; + FftData& E_refined = output.E_refined; FftData E_shadow; - std::array& e_main = output.e_main; + std::array& e_refined = output.e_refined; std::array& e_shadow = output.e_shadow; FftData S; FftData& G = S; - // Form the outputs of the main and shadow filters. - main_filters_[ch]->Filter(render_buffer, &S); - PredictionError(fft_, S, y, &e_main, &output.s_main); + // Form the outputs of the refined and shadow filters. + refined_filters_[ch]->Filter(render_buffer, &S); + PredictionError(fft_, S, y, &e_refined, &output.s_refined); shadow_filter_[ch]->Filter(render_buffer, &S); PredictionError(fft_, S, y, &e_shadow, &output.s_shadow); @@ -204,59 +205,62 @@ void Subtractor::Process(const RenderBuffer& render_buffer, output.ComputeMetrics(y); // Adjust the filter if needed. - bool main_filters_adjusted = false; + bool refined_filters_adjusted = false; filter_misadjustment_estimators_[ch].Update(output); if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) { float scale = filter_misadjustment_estimators_[ch].GetMisadjustment(); - main_filters_[ch]->ScaleFilter(scale); - for (auto& h_k : main_impulse_responses_[ch]) { + refined_filters_[ch]->ScaleFilter(scale); + for (auto& h_k : refined_impulse_responses_[ch]) { h_k *= scale; } - ScaleFilterOutput(y, scale, e_main, output.s_main); + ScaleFilterOutput(y, scale, e_refined, output.s_refined); filter_misadjustment_estimators_[ch].Reset(); - main_filters_adjusted = true; + refined_filters_adjusted = true; } - // Compute the FFts of the main and shadow filter outputs. - fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kHanning, &E_main); + // Compute the FFts of the refined and shadow filter outputs. + fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined); fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kHanning, &E_shadow); // Compute spectra for future use. E_shadow.Spectrum(optimization_, output.E2_shadow); - E_main.Spectrum(optimization_, output.E2_main); + E_refined.Spectrum(optimization_, output.E2_refined); - // Update the main filter. - if (!main_filters_adjusted) { + // Update the refined filter. + if (!refined_filters_adjusted) { std::array erl; - ComputeErl(optimization_, main_frequency_responses_[ch], erl); - main_gains_[ch]->Compute(X2_main, render_signal_analyzer, output, erl, - main_filters_[ch]->SizePartitions(), - aec_state.SaturatedCapture(), &G); + ComputeErl(optimization_, refined_frequency_responses_[ch], erl); + refined_gains_[ch]->Compute(X2_refined, render_signal_analyzer, output, + erl, refined_filters_[ch]->SizePartitions(), + aec_state.SaturatedCapture(), &G); } else { G.re.fill(0.f); G.im.fill(0.f); } - main_filters_[ch]->Adapt(render_buffer, G, &main_impulse_responses_[ch]); - main_filters_[ch]->ComputeFrequencyResponse(&main_frequency_responses_[ch]); + refined_filters_[ch]->Adapt(render_buffer, G, + &refined_impulse_responses_[ch]); + refined_filters_[ch]->ComputeFrequencyResponse( + &refined_frequency_responses_[ch]); if (ch == 0) { - data_dumper_->DumpRaw("aec3_subtractor_G_main", G.re); - data_dumper_->DumpRaw("aec3_subtractor_G_main", G.im); + data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re); + data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im); } // Update the shadow filter. poor_shadow_filter_counters_[ch] = - output.e2_main < output.e2_shadow ? poor_shadow_filter_counters_[ch] + 1 - : 0; + output.e2_refined < output.e2_shadow + ? poor_shadow_filter_counters_[ch] + 1 + : 0; if (poor_shadow_filter_counters_[ch] < 5) { shadow_gains_[ch]->Compute(X2_shadow, render_signal_analyzer, E_shadow, shadow_filter_[ch]->SizePartitions(), aec_state.SaturatedCapture(), &G); } else { poor_shadow_filter_counters_[ch] = 0; - shadow_filter_[ch]->SetFilter(main_filters_[ch]->SizePartitions(), - main_filters_[ch]->GetFilter()); - shadow_gains_[ch]->Compute(X2_shadow, render_signal_analyzer, E_main, + shadow_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(), + refined_filters_[ch]->GetFilter()); + shadow_gains_[ch]->Compute(X2_shadow, render_signal_analyzer, E_refined, shadow_filter_[ch]->SizePartitions(), aec_state.SaturatedCapture(), &G); } @@ -269,12 +273,12 @@ void Subtractor::Process(const RenderBuffer& render_buffer, DumpFilters(); } - std::for_each(e_main.begin(), e_main.end(), + std::for_each(e_refined.begin(), e_refined.end(), [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); }); if (ch == 0) { - data_dumper_->DumpWav("aec3_main_filters_output", kBlockSize, &e_main[0], - 16000, 1); + data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize, + &e_refined[0], 16000, 1); data_dumper_->DumpWav("aec3_shadow_filter_output", kBlockSize, &e_shadow[0], 16000, 1); } @@ -283,7 +287,7 @@ void Subtractor::Process(const RenderBuffer& render_buffer, void Subtractor::FilterMisadjustmentEstimator::Update( const SubtractorOutput& output) { - e2_acum_ += output.e2_main; + e2_acum_ += output.e2_refined; y2_acum_ += output.y2; if (++n_blocks_acum_ == n_blocks_) { if (y2_acum_ > n_blocks_ * 200.f * 200.f * kBlockSize) { diff --git a/modules/audio_processing/aec3/subtractor.h b/modules/audio_processing/aec3/subtractor.h index 32c42cccc1..7b3e6ac15a 100644 --- a/modules/audio_processing/aec3/subtractor.h +++ b/modules/audio_processing/aec3/subtractor.h @@ -24,7 +24,7 @@ #include "modules/audio_processing/aec3/aec3_fft.h" #include "modules/audio_processing/aec3/aec_state.h" #include "modules/audio_processing/aec3/echo_path_variability.h" -#include "modules/audio_processing/aec3/main_filter_update_gain.h" +#include "modules/audio_processing/aec3/refined_filter_update_gain.h" #include "modules/audio_processing/aec3/render_buffer.h" #include "modules/audio_processing/aec3/render_signal_analyzer.h" #include "modules/audio_processing/aec3/shadow_filter_update_gain.h" @@ -58,27 +58,28 @@ class Subtractor { // Exits the initial state. void ExitInitialState(); - // Returns the block-wise frequency responses for the main adaptive filters. + // Returns the block-wise frequency responses for the refined adaptive + // filters. const std::vector>>& FilterFrequencyResponses() const { - return main_frequency_responses_; + return refined_frequency_responses_; } - // Returns the estimates of the impulse responses for the main adaptive + // Returns the estimates of the impulse responses for the refined adaptive // filters. const std::vector>& FilterImpulseResponses() const { - return main_impulse_responses_; + return refined_impulse_responses_; } void DumpFilters() { data_dumper_->DumpRaw( - "aec3_subtractor_h_main", + "aec3_subtractor_h_refined", rtc::ArrayView( - main_impulse_responses_[0].data(), + refined_impulse_responses_[0].data(), GetTimeDomainLength( - main_filters_[0]->max_filter_size_partitions()))); + refined_filters_[0]->max_filter_size_partitions()))); - main_filters_[0]->DumpFilter("aec3_subtractor_H_main"); + refined_filters_[0]->DumpFilter("aec3_subtractor_H_refined"); shadow_filter_[0]->DumpFilter("aec3_subtractor_H_shadow"); } @@ -120,15 +121,15 @@ class Subtractor { const EchoCanceller3Config config_; const size_t num_capture_channels_; - std::vector> main_filters_; + std::vector> refined_filters_; std::vector> shadow_filter_; - std::vector> main_gains_; + std::vector> refined_gains_; std::vector> shadow_gains_; std::vector filter_misadjustment_estimators_; std::vector poor_shadow_filter_counters_; std::vector>> - main_frequency_responses_; - std::vector> main_impulse_responses_; + refined_frequency_responses_; + std::vector> refined_impulse_responses_; }; } // namespace webrtc diff --git a/modules/audio_processing/aec3/subtractor_output.cc b/modules/audio_processing/aec3/subtractor_output.cc index 922cc3d1b3..11c8174540 100644 --- a/modules/audio_processing/aec3/subtractor_output.cc +++ b/modules/audio_processing/aec3/subtractor_output.cc @@ -18,17 +18,17 @@ SubtractorOutput::SubtractorOutput() = default; SubtractorOutput::~SubtractorOutput() = default; void SubtractorOutput::Reset() { - s_main.fill(0.f); + s_refined.fill(0.f); s_shadow.fill(0.f); - e_main.fill(0.f); + e_refined.fill(0.f); e_shadow.fill(0.f); - E_main.re.fill(0.f); - E_main.im.fill(0.f); - E2_main.fill(0.f); + E_refined.re.fill(0.f); + E_refined.im.fill(0.f); + E2_refined.fill(0.f); E2_shadow.fill(0.f); - e2_main = 0.f; + e2_refined = 0.f; e2_shadow = 0.f; - s2_main = 0.f; + s2_refined = 0.f; s2_shadow = 0.f; y2 = 0.f; } @@ -36,16 +36,19 @@ void SubtractorOutput::Reset() { void SubtractorOutput::ComputeMetrics(rtc::ArrayView y) { const auto sum_of_squares = [](float a, float b) { return a + b * b; }; y2 = std::accumulate(y.begin(), y.end(), 0.f, sum_of_squares); - e2_main = std::accumulate(e_main.begin(), e_main.end(), 0.f, sum_of_squares); + e2_refined = + std::accumulate(e_refined.begin(), e_refined.end(), 0.f, sum_of_squares); e2_shadow = std::accumulate(e_shadow.begin(), e_shadow.end(), 0.f, sum_of_squares); - s2_main = std::accumulate(s_main.begin(), s_main.end(), 0.f, sum_of_squares); + s2_refined = + std::accumulate(s_refined.begin(), s_refined.end(), 0.f, sum_of_squares); s2_shadow = std::accumulate(s_shadow.begin(), s_shadow.end(), 0.f, sum_of_squares); - s_main_max_abs = *std::max_element(s_main.begin(), s_main.end()); - s_main_max_abs = std::max(s_main_max_abs, - -(*std::min_element(s_main.begin(), s_main.end()))); + s_refined_max_abs = *std::max_element(s_refined.begin(), s_refined.end()); + s_refined_max_abs = + std::max(s_refined_max_abs, + -(*std::min_element(s_refined.begin(), s_refined.end()))); s_shadow_max_abs = *std::max_element(s_shadow.begin(), s_shadow.end()); s_shadow_max_abs = std::max( diff --git a/modules/audio_processing/aec3/subtractor_output.h b/modules/audio_processing/aec3/subtractor_output.h index 2822b08b68..3f856d966e 100644 --- a/modules/audio_processing/aec3/subtractor_output.h +++ b/modules/audio_processing/aec3/subtractor_output.h @@ -25,19 +25,19 @@ struct SubtractorOutput { SubtractorOutput(); ~SubtractorOutput(); - std::array s_main; + std::array s_refined; std::array s_shadow; - std::array e_main; + std::array e_refined; std::array e_shadow; - FftData E_main; - std::array E2_main; + FftData E_refined; + std::array E2_refined; std::array E2_shadow; - float s2_main = 0.f; + float s2_refined = 0.f; float s2_shadow = 0.f; - float e2_main = 0.f; + float e2_refined = 0.f; float e2_shadow = 0.f; float y2 = 0.f; - float s_main_max_abs = 0.f; + float s_refined_max_abs = 0.f; float s_shadow_max_abs = 0.f; // Reset the struct content. diff --git a/modules/audio_processing/aec3/subtractor_output_analyzer.cc b/modules/audio_processing/aec3/subtractor_output_analyzer.cc index cf16001153..ac29199dad 100644 --- a/modules/audio_processing/aec3/subtractor_output_analyzer.cc +++ b/modules/audio_processing/aec3/subtractor_output_analyzer.cc @@ -32,17 +32,18 @@ void SubtractorOutputAnalyzer::Update( for (size_t ch = 0; ch < subtractor_output.size(); ++ch) { const float y2 = subtractor_output[ch].y2; - const float e2_main = subtractor_output[ch].e2_main; + const float e2_refined = subtractor_output[ch].e2_refined; const float e2_shadow = subtractor_output[ch].e2_shadow; constexpr float kConvergenceThreshold = 50 * 50 * kBlockSize; - bool main_filter_converged = - e2_main < 0.5f * y2 && y2 > kConvergenceThreshold; + bool refined_filter_converged = + e2_refined < 0.5f * y2 && y2 > kConvergenceThreshold; bool shadow_filter_converged = e2_shadow < 0.05f * y2 && y2 > kConvergenceThreshold; - float min_e2 = std::min(e2_main, e2_shadow); + float min_e2 = std::min(e2_refined, e2_shadow); bool filter_diverged = min_e2 > 1.5f * y2 && y2 > 30.f * 30.f * kBlockSize; - filters_converged_[ch] = main_filter_converged || shadow_filter_converged; + filters_converged_[ch] = + refined_filter_converged || shadow_filter_converged; *any_filter_converged = *any_filter_converged || filters_converged_[ch]; *all_filters_diverged = *all_filters_diverged && filter_diverged; diff --git a/modules/audio_processing/aec3/subtractor_unittest.cc b/modules/audio_processing/aec3/subtractor_unittest.cc index a1ce41dcb1..56b0e938ec 100644 --- a/modules/audio_processing/aec3/subtractor_unittest.cc +++ b/modules/audio_processing/aec3/subtractor_unittest.cc @@ -31,7 +31,7 @@ std::vector RunSubtractorTest( size_t num_capture_channels, int num_blocks_to_process, int delay_samples, - int main_filter_length_blocks, + int refined_filter_length_blocks, int shadow_filter_length_blocks, bool uncorrelated_inputs, const std::vector& blocks_with_echo_path_changes) { @@ -39,7 +39,7 @@ std::vector RunSubtractorTest( constexpr int kSampleRateHz = 48000; constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz); EchoCanceller3Config config; - config.filter.main.length_blocks = main_filter_length_blocks; + config.filter.refined.length_blocks = refined_filter_length_blocks; config.filter.shadow.length_blocks = shadow_filter_length_blocks; Subtractor subtractor(config, num_render_channels, num_capture_channels, @@ -59,7 +59,7 @@ std::vector RunSubtractorTest( Random random_generator(42U); Aec3Fft fft; std::vector> Y2(num_capture_channels); - std::vector> E2_main( + std::vector> E2_refined( num_capture_channels); std::array E2_shadow; AecState aec_state(config, num_capture_channels); @@ -67,8 +67,8 @@ std::vector RunSubtractorTest( for (auto& Y2_ch : Y2) { Y2_ch.fill(0.f); } - for (auto& E2_main_ch : E2_main) { - E2_main_ch.fill(0.f); + for (auto& E2_refined_ch : E2_refined) { + E2_refined_ch.fill(0.f); } E2_shadow.fill(0.f); @@ -152,15 +152,15 @@ std::vector RunSubtractorTest( false, EchoPathVariability::DelayAdjustment::kNone, false)); aec_state.Update(delay_estimate, subtractor.FilterFrequencyResponses(), subtractor.FilterImpulseResponses(), - *render_delay_buffer->GetRenderBuffer(), E2_main, Y2, + *render_delay_buffer->GetRenderBuffer(), E2_refined, Y2, output); } std::vector results(num_capture_channels); for (size_t ch = 0; ch < num_capture_channels; ++ch) { - const float output_power = - std::inner_product(output[ch].e_main.begin(), output[ch].e_main.end(), - output[ch].e_main.begin(), 0.f); + const float output_power = std::inner_product( + output[ch].e_refined.begin(), output[ch].e_refined.end(), + output[ch].e_refined.begin(), 0.f); const float y_power = std::inner_product(y[ch].begin(), y[ch].end(), y[ch].begin(), 0.f); if (y_power == 0.f) { @@ -231,9 +231,9 @@ TEST(Subtractor, Convergence) { } } -// Verifies that the subtractor is able to handle the case when the main filter -// is longer than the shadow filter. -TEST(Subtractor, MainFilterLongerThanShadowFilter) { +// Verifies that the subtractor is able to handle the case when the refined +// filter is longer than the shadow filter. +TEST(Subtractor, RefinedFilterLongerThanShadowFilter) { std::vector blocks_with_echo_path_changes; std::vector echo_to_nearend_powers = RunSubtractorTest( 1, 1, 400, 64, 20, 15, false, blocks_with_echo_path_changes); @@ -243,8 +243,8 @@ TEST(Subtractor, MainFilterLongerThanShadowFilter) { } // Verifies that the subtractor is able to handle the case when the shadow -// filter is longer than the main filter. -TEST(Subtractor, ShadowFilterLongerThanMainFilter) { +// filter is longer than the refined filter. +TEST(Subtractor, ShadowFilterLongerThanRefinedFilter) { std::vector blocks_with_echo_path_changes; std::vector echo_to_nearend_powers = RunSubtractorTest( 1, 1, 400, 64, 15, 20, false, blocks_with_echo_path_changes);