From 53e22113fd7d0f43d6b1c0e97512316cce3c573d Mon Sep 17 00:00:00 2001 From: Gustaf Ullberg Date: Thu, 11 Oct 2018 15:27:26 +0200 Subject: [PATCH] AEC3: Kill kill-switches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." This CL removes the following kill-switches from AEC3 - WebRTC-Aec3DownSamplingFactor8KillSwitch - WebRTC-Aec3NewSuppressionKillSwitch - WebRTC-Aec3ShadowFilterJumpstartKillSwitch - WebRTC-Aec3SlowFilterAdaptationKillSwitch - WebRTC-Aec3SuppressorNearendAveragingKillSwitch It also removes code paths and configuration parameters that are no longer in use. The list of kill-switches in the audio processing fuzzer test is updated. The change has been tested for bit-exactness. Bug: webrtc:8671 Change-Id: Ie0af86a14baf853548bf9c00b2b9b3bbc32c1aaa Reviewed-on: https://webrtc-review.googlesource.com/c/105324 Reviewed-by: Sam Zackrisson Reviewed-by: Per Ã…hgren Commit-Queue: Gustaf Ullberg Cr-Commit-Position: refs/heads/master@{#25120} --- api/audio/echo_canceller3_config.cc | 19 ----- api/audio/echo_canceller3_config.h | 20 ----- api/audio/echo_canceller3_config_json.cc | 40 ---------- .../audio_processing/aec3/echo_canceller3.cc | 37 --------- .../aec3/echo_path_delay_estimator.cc | 13 +--- .../aec3/render_delay_buffer.cc | 10 +-- .../audio_processing/aec3/suppression_gain.cc | 77 ------------------- .../audio_processing/aec3/suppression_gain.h | 1 - .../audio_processing_configs_fuzzer.cc | 48 +++++++----- 9 files changed, 30 insertions(+), 235 deletions(-) diff --git a/api/audio/echo_canceller3_config.cc b/api/audio/echo_canceller3_config.cc index 036ef9c5b2..46c1eda326 100644 --- a/api/audio/echo_canceller3_config.cc +++ b/api/audio/echo_canceller3_config.cc @@ -45,9 +45,6 @@ EchoCanceller3Config::Delay::Delay() = default; EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) = default; -EchoCanceller3Config::Mask::Mask() = default; -EchoCanceller3Config::Mask::Mask(const EchoCanceller3Config::Mask& m) = default; - EchoCanceller3Config::EchoModel::EchoModel() = default; EchoCanceller3Config::EchoModel::EchoModel( const EchoCanceller3Config::EchoModel& e) = default; @@ -158,22 +155,6 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) { res = res && Limit(&c->ep_strength.hf, 0.f, 1000000.f); res = res && Limit(&c->ep_strength.default_len, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m0, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m1, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m2, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m3, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m5, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m6, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m7, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m8, 0.f, 1.f); - res = res && Limit(&c->gain_mask.m9, 0.f, 1.f); - - res = res && Limit(&c->gain_mask.gain_curve_offset, 0.f, 1000.f); - res = res && Limit(&c->gain_mask.gain_curve_slope, 0.f, 1000.f); - res = res && Limit(&c->gain_mask.temporal_masking_lf, 0.f, 1000.f); - res = res && Limit(&c->gain_mask.temporal_masking_hf, 0.f, 1000.f); - res = res && Limit(&c->gain_mask.temporal_masking_lf_bands, 0, 65); - res = res && Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f); res = res && diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h index f180a44f91..e7dc0825e3 100644 --- a/api/audio/echo_canceller3_config.h +++ b/api/audio/echo_canceller3_config.h @@ -92,26 +92,6 @@ struct RTC_EXPORT EchoCanceller3Config { bool bounded_erl = false; } ep_strength; - struct Mask { - Mask(); - Mask(const Mask& m); - float m0 = 0.1f; - float m1 = 0.01f; - float m2 = 0.0001f; - float m3 = 0.01f; - float m5 = 0.01f; - float m6 = 0.0001f; - float m7 = 0.01f; - float m8 = 0.0001f; - float m9 = 0.1f; - - float gain_curve_offset = 1.45f; - float gain_curve_slope = 5.f; - float temporal_masking_lf = 0.9f; - float temporal_masking_hf = 0.6f; - size_t temporal_masking_lf_bands = 3; - } gain_mask; - struct EchoAudibility { float low_render_limit = 4 * 64.f; float normal_render_limit = 64.f; diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc index cbe751364d..fa5815566b 100644 --- a/api/audio/echo_canceller3_config_json.cc +++ b/api/audio/echo_canceller3_config_json.cc @@ -192,26 +192,6 @@ EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) { ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl); } - if (rtc::GetValueFromJsonObject(aec3_root, "gain_mask", §ion)) { - ReadParam(section, "m1", &cfg.gain_mask.m1); - ReadParam(section, "m2", &cfg.gain_mask.m2); - ReadParam(section, "m3", &cfg.gain_mask.m3); - ReadParam(section, "m5", &cfg.gain_mask.m5); - ReadParam(section, "m6", &cfg.gain_mask.m6); - ReadParam(section, "m7", &cfg.gain_mask.m7); - ReadParam(section, "m8", &cfg.gain_mask.m8); - ReadParam(section, "m9", &cfg.gain_mask.m9); - - ReadParam(section, "gain_curve_offset", &cfg.gain_mask.gain_curve_offset); - ReadParam(section, "gain_curve_slope", &cfg.gain_mask.gain_curve_slope); - ReadParam(section, "temporal_masking_lf", - &cfg.gain_mask.temporal_masking_lf); - ReadParam(section, "temporal_masking_hf", - &cfg.gain_mask.temporal_masking_hf); - ReadParam(section, "temporal_masking_lf_bands", - &cfg.gain_mask.temporal_masking_lf_bands); - } - if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", §ion)) { ReadParam(section, "low_render_limit", &cfg.echo_audibility.low_render_limit); @@ -424,26 +404,6 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << "},"; - ost << "\"gain_mask\": {"; - ost << "\"m0\": " << config.gain_mask.m0 << ","; - ost << "\"m1\": " << config.gain_mask.m1 << ","; - ost << "\"m2\": " << config.gain_mask.m2 << ","; - ost << "\"m3\": " << config.gain_mask.m3 << ","; - ost << "\"m5\": " << config.gain_mask.m5 << ","; - ost << "\"m6\": " << config.gain_mask.m6 << ","; - ost << "\"m7\": " << config.gain_mask.m7 << ","; - ost << "\"m8\": " << config.gain_mask.m8 << ","; - ost << "\"m9\": " << config.gain_mask.m9 << ","; - ost << "\"gain_curve_offset\": " << config.gain_mask.gain_curve_offset << ","; - ost << "\"gain_curve_slope\": " << config.gain_mask.gain_curve_slope << ","; - ost << "\"temporal_masking_lf\": " << config.gain_mask.temporal_masking_lf - << ","; - ost << "\"temporal_masking_hf\": " << config.gain_mask.temporal_masking_hf - << ","; - ost << "\"temporal_masking_lf_bands\": " - << config.gain_mask.temporal_masking_lf_bands; - ost << "},"; - ost << "\"echo_audibility\": {"; ost << "\"low_render_limit\": " << config.echo_audibility.low_render_limit << ","; diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc index 71b8c08ba4..b78155e653 100644 --- a/modules/audio_processing/aec3/echo_canceller3.cc +++ b/modules/audio_processing/aec3/echo_canceller3.cc @@ -41,19 +41,6 @@ bool EnableReverbModelling() { return !field_trial::IsEnabled("WebRTC-Aec3ReverbModellingKillSwitch"); } -bool EnableSuppressorNearendAveraging() { - return !field_trial::IsEnabled( - "WebRTC-Aec3SuppressorNearendAveragingKillSwitch"); -} - -bool EnableSlowFilterAdaptation() { - return !field_trial::IsEnabled("WebRTC-Aec3SlowFilterAdaptationKillSwitch"); -} - -bool EnableShadowFilterJumpstart() { - return !field_trial::IsEnabled("WebRTC-Aec3ShadowFilterJumpstartKillSwitch"); -} - bool EnableUnityInitialRampupGain() { return field_trial::IsEnabled("WebRTC-Aec3EnableUnityInitialRampupGain"); } @@ -101,30 +88,6 @@ EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { adjusted_cfg.ep_strength.reverb_based_on_render = false; } - if (!EnableSuppressorNearendAveraging()) { - adjusted_cfg.suppressor.nearend_average_blocks = 1; - } - - if (!EnableSlowFilterAdaptation()) { - if (!EnableShadowFilterJumpstart()) { - adjusted_cfg.filter.main.leakage_converged = 0.005f; - adjusted_cfg.filter.main.leakage_diverged = 0.1f; - } - adjusted_cfg.filter.main_initial.leakage_converged = 0.05f; - adjusted_cfg.filter.main_initial.leakage_diverged = 5.f; - } - - if (!EnableShadowFilterJumpstart()) { - if (EnableSlowFilterAdaptation()) { - adjusted_cfg.filter.main.leakage_converged = 0.0005f; - adjusted_cfg.filter.main.leakage_diverged = 0.01f; - } else { - adjusted_cfg.filter.main.leakage_converged = 0.005f; - adjusted_cfg.filter.main.leakage_diverged = 0.1f; - } - adjusted_cfg.filter.main.error_floor = 0.001f; - } - if (!EnableNewFilterParams()) { adjusted_cfg.filter.main.leakage_diverged = 0.01f; adjusted_cfg.filter.main.error_floor = 0.1f; diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.cc b/modules/audio_processing/aec3/echo_path_delay_estimator.cc index 638ddc4408..022030eadd 100644 --- a/modules/audio_processing/aec3/echo_path_delay_estimator.cc +++ b/modules/audio_processing/aec3/echo_path_delay_estimator.cc @@ -19,21 +19,12 @@ #include "system_wrappers/include/field_trial.h" namespace webrtc { -namespace { -size_t GetDownSamplingFactor(const EchoCanceller3Config& config) { - // Do not use down sampling factor 8 if kill switch is triggered. - return (config.delay.down_sampling_factor == 8 && - field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch")) - ? 4 - : config.delay.down_sampling_factor; -} -} // namespace EchoPathDelayEstimator::EchoPathDelayEstimator( ApmDataDumper* data_dumper, const EchoCanceller3Config& config) : data_dumper_(data_dumper), - down_sampling_factor_(GetDownSamplingFactor(config)), + down_sampling_factor_(config.delay.down_sampling_factor), sub_block_size_(down_sampling_factor_ != 0 ? kBlockSize / down_sampling_factor_ : kBlockSize), @@ -45,7 +36,7 @@ EchoPathDelayEstimator::EchoPathDelayEstimator( kMatchedFilterWindowSizeSubBlocks, config.delay.num_filters, kMatchedFilterAlignmentShiftSizeSubBlocks, - GetDownSamplingFactor(config) == 8 + config.delay.down_sampling_factor == 8 ? config.render_levels.poor_excitation_render_limit_ds8 : config.render_levels.poor_excitation_render_limit, config.delay.delay_estimate_smoothing, diff --git a/modules/audio_processing/aec3/render_delay_buffer.cc b/modules/audio_processing/aec3/render_delay_buffer.cc index 37a2378738..3c5c3ac3e4 100644 --- a/modules/audio_processing/aec3/render_delay_buffer.cc +++ b/modules/audio_processing/aec3/render_delay_buffer.cc @@ -35,14 +35,6 @@ bool EnableZeroExternalDelayHeadroom() { "WebRTC-Aec3ZeroExternalDelayHeadroomKillSwitch"); } -size_t GetDownSamplingFactor(const EchoCanceller3Config& config) { - // Do not use down sampling factor 8 if kill switch is triggered. - return (config.delay.down_sampling_factor == 8 && - field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch")) - ? 4 - : config.delay.down_sampling_factor; -} - class RenderDelayBufferImpl final : public RenderDelayBuffer { public: RenderDelayBufferImpl(const EchoCanceller3Config& config, size_t num_bands); @@ -177,7 +169,7 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(const EchoCanceller3Config& config, new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), optimization_(DetectOptimization()), config_(config), - down_sampling_factor_(GetDownSamplingFactor(config)), + down_sampling_factor_(config.delay.down_sampling_factor), use_zero_external_delay_headroom_(EnableZeroExternalDelayHeadroom()), sub_block_size_(static_cast(down_sampling_factor_ > 0 ? kBlockSize / down_sampling_factor_ diff --git a/modules/audio_processing/aec3/suppression_gain.cc b/modules/audio_processing/aec3/suppression_gain.cc index 6132566730..50ee14c4e8 100644 --- a/modules/audio_processing/aec3/suppression_gain.cc +++ b/modules/audio_processing/aec3/suppression_gain.cc @@ -25,10 +25,6 @@ namespace webrtc { namespace { -bool EnableNewSuppression() { - return !field_trial::IsEnabled("WebRTC-Aec3NewSuppressionKillSwitch"); -} - // Adjust the gains according to the presence of known external filters. void AdjustForExternalFilters(std::array* gain) { // Limit the low frequency gains to avoid the impact of the high-pass filter @@ -83,57 +79,6 @@ void WeightEchoForAudibility(const EchoCanceller3Config& config, weigh(threshold, normalizer, 7, kFftLengthBy2Plus1, echo, weighted_echo); } -// Computes the gain to reduce the echo to a non audible level. -void GainToNoAudibleEchoFallback( - const EchoCanceller3Config& config, - bool low_noise_render, - bool saturated_echo, - bool linear_echo_estimate, - const std::array& nearend, - const std::array& weighted_echo, - const std::array& masker, - const std::array& min_gain, - const std::array& max_gain, - const std::array& one_by_weighted_echo, - std::array* gain) { - float nearend_masking_margin = 0.f; - if (linear_echo_estimate) { - nearend_masking_margin = - low_noise_render - ? config.gain_mask.m9 - : (saturated_echo ? config.gain_mask.m2 : config.gain_mask.m3); - } else { - nearend_masking_margin = config.gain_mask.m7; - } - - RTC_DCHECK_LE(0.f, nearend_masking_margin); - RTC_DCHECK_GT(1.f, nearend_masking_margin); - - const float masker_margin = - linear_echo_estimate ? config.gain_mask.m0 : config.gain_mask.m8; - - for (size_t k = 0; k < gain->size(); ++k) { - // TODO(devicentepena): Experiment by removing the reverberation estimation - // from the nearend signal before computing the gains. - const float unity_gain_masker = std::max(nearend[k], masker[k]); - RTC_DCHECK_LE(0.f, nearend_masking_margin * unity_gain_masker); - if (weighted_echo[k] <= nearend_masking_margin * unity_gain_masker || - unity_gain_masker <= 0.f) { - (*gain)[k] = 1.f; - } else { - RTC_DCHECK_LT(0.f, unity_gain_masker); - (*gain)[k] = - std::max(0.f, (1.f - config.gain_mask.gain_curve_slope * - weighted_echo[k] / unity_gain_masker) * - config.gain_mask.gain_curve_offset); - (*gain)[k] = std::max(masker_margin * masker[k] * one_by_weighted_echo[k], - (*gain)[k]); - } - - (*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]); - } -} - // TODO(peah): Make adaptive to take the actual filter error into account. constexpr size_t kUpperAccurateBandPlus1 = 29; @@ -321,30 +266,9 @@ void SuppressionGain::LowerBandGain( std::array max_gain; GetMaxGain(max_gain); - // Iteratively compute the gain required to attenuate the echo to a non - // noticeable level. - - if (enable_new_suppression_) { GainToNoAudibleEcho(nearend, weighted_residual_echo, comfort_noise, min_gain, max_gain, gain); AdjustForExternalFilters(gain); - } else { - const bool linear_echo_estimate = aec_state.UsableLinearEstimate(); - std::array masker; - std::array one_by_weighted_echo; - std::transform(weighted_residual_echo.begin(), weighted_residual_echo.end(), - one_by_weighted_echo.begin(), - [](float e) { return e > 0.f ? 1.f / e : 1.f; }); - gain->fill(0.f); - for (int k = 0; k < 2; ++k) { - std::copy(comfort_noise.begin(), comfort_noise.end(), masker.begin()); - GainToNoAudibleEchoFallback(config_, low_noise_render, saturated_echo, - linear_echo_estimate, nearend, - weighted_residual_echo, masker, min_gain, - max_gain, one_by_weighted_echo, gain); - AdjustForExternalFilters(gain); - } - } // Adjust the gain for frequencies which have not yet converged. AdjustNonConvergedFrequencies(gain); @@ -372,7 +296,6 @@ SuppressionGain::SuppressionGain(const EchoCanceller3Config& config, config_(config), state_change_duration_blocks_( static_cast(config_.filter.config_change_duration_blocks)), - enable_new_suppression_(EnableNewSuppression()), moving_average_(kFftLengthBy2Plus1, config.suppressor.nearend_average_blocks), nearend_params_(config_.suppressor.nearend_tuning), diff --git a/modules/audio_processing/aec3/suppression_gain.h b/modules/audio_processing/aec3/suppression_gain.h index 4eb8581a86..89a0556b30 100644 --- a/modules/audio_processing/aec3/suppression_gain.h +++ b/modules/audio_processing/aec3/suppression_gain.h @@ -137,7 +137,6 @@ class SuppressionGain { LowNoiseRenderDetector low_render_detector_; bool initial_state_ = true; int initial_state_change_counter_ = 0; - const bool enable_new_suppression_; aec3::MovingAverage moving_average_; const GainParameters nearend_params_; const GainParameters normal_params_; diff --git a/test/fuzzers/audio_processing_configs_fuzzer.cc b/test/fuzzers/audio_processing_configs_fuzzer.cc index 8117c52aaf..8c6cbbcfe2 100644 --- a/test/fuzzers/audio_processing_configs_fuzzer.cc +++ b/test/fuzzers/audio_processing_configs_fuzzer.cc @@ -25,33 +25,39 @@ namespace webrtc { namespace { const std::string kFieldTrialNames[] = { - "WebRTC-Aec3TransparentModeKillSwitch", - "WebRTC-Aec3StationaryRenderImprovementsKillSwitch", - "WebRTC-Aec3EnforceDelayAfterRealignmentKillSwitch", - "WebRTC-Aec3UseShortDelayEstimatorWindow", - "WebRTC-Aec3ReverbBasedOnRenderKillSwitch", - "WebRTC-Aec3ReverbModellingKillSwitch", - "WebRTC-Aec3FilterAnalyzerPreprocessorKillSwitch", - "WebRTC-Aec3TransparencyImprovementsKillSwitch", - "WebRTC-Aec3SoftTransparentModeKillSwitch", - "WebRTC-Aec3OverrideEchoPathGainKillSwitch", - "WebRTC-Aec3ZeroExternalDelayHeadroomKillSwitch", - "WebRTC-Aec3DownSamplingFactor8KillSwitch", + "WebRTC-Aec3AdaptErleOnLowRenderKillSwitch", + "WebRTC-Aec3AgcGainChangeResponseKillSwitch", + "WebRTC-Aec3BoundedNearendKillSwitch", + "WebRTC-Aec3EarlyShadowFilterJumpstartKillSwitch", + "WebRTC-Aec3EnableAdaptiveEchoReverbEstimation", + "WebRTC-Aec3EnableLegacyDominantNearend", + "WebRTC-Aec3EnableUnityInitialRampupGain", + "WebRTC-Aec3EnableUnityNonZeroRampupGain", "WebRTC-Aec3EnforceSkewHysteresis1", "WebRTC-Aec3EnforceSkewHysteresis2", - "WebRTC-Aec3NewSuppressionKillSwitch", - "WebRTC-Aec3LinearModeWithDivergedFilterKillSwitch", + "WebRTC-Aec3FilterAnalyzerPreprocessorKillSwitch", "WebRTC-Aec3MisadjustmentEstimatorKillSwitch", + "WebRTC-Aec3NewFilterParamsKillSwitch", + "WebRTC-Aec3OverrideEchoPathGainKillSwitch", "WebRTC-Aec3RapidAgcGainRecoveryKillSwitch", - "WebRTC-Aec3SlowFilterAdaptationKillSwitch", - "WebRTC-Aec3SmoothUpdatesTailFreqRespKillSwitch", - "WebRTC-Aec3SuppressorNearendAveragingKillSwitch", - "WebRTC-Aec3AgcGainChangeResponseKillSwitch", + "WebRTC-Aec3ResetErleAtGainChangesKillSwitch", + "WebRTC-Aec3ReverbBasedOnRenderKillSwitch", + "WebRTC-Aec3ReverbModellingKillSwitch", + "WebRTC-Aec3ShadowFilterBoostedJumpstartKillSwitch", "WebRTC-Aec3ShadowFilterJumpstartKillSwitch", - "WebRTC-Aec3EarlyLinearFilterUsageKillSwitch", - "WebRTC-Aec3ShortInitialStateKillSwitch", + "WebRTC-Aec3ShortReverbKillSwitch", + "WebRTC-Aec3SmoothSignalTransitionsKillSwitch", + "WebRTC-Aec3SmoothUpdatesTailFreqRespKillSwitch", + "WebRTC-Aec3SoftTransparentModeKillSwitch", "WebRTC-Aec3StandardNonlinearReverbModelKillSwitch", - "WebRTC-Aec3EnableAdaptiveEchoReverbEstimation"}; + "WebRTC-Aec3StrictDivergenceCheckKillSwitch", + "WebRTC-Aec3UseLegacyNormalSuppressorTuning", + "WebRTC-Aec3UseOffsetBlocks", + "WebRTC-Aec3UseShortDelayEstimatorWindow", + "WebRTC-Aec3UseStationarityPropertiesKillSwitch", + "WebRTC-Aec3UtilizeShadowFilterOutputKillSwitch", + "WebRTC-Aec3ZeroExternalDelayHeadroomKillSwitch", +}; std::unique_ptr CreateApm(test::FuzzDataHelper* fuzz_data, std::string* field_trial_string) {