AEC3: Using a more conservative frequency response representation of the tails.
Bug: webrtc:13173
Change-Id: Ic469f6226fe079c306cec6f941eeb70d6d9094f3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231682
Commit-Queue: Jesus de Vicente Pena <devicentepena@webrtc.org>
Reviewed-by: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34966}
diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h
index bc7c6f0..0df6450 100644
--- a/api/audio/echo_canceller3_config.h
+++ b/api/audio/echo_canceller3_config.h
@@ -112,6 +112,7 @@
bool echo_can_saturate = true;
bool bounded_erl = false;
bool erle_onset_compensation_in_dominant_nearend = false;
+ bool use_conservative_tail_frequency_response = false;
} ep_strength;
struct EchoAudibility {
diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc
index eaf95b3..f6ffd57 100644
--- a/api/audio/echo_canceller3_config_json.cc
+++ b/api/audio/echo_canceller3_config_json.cc
@@ -264,6 +264,8 @@
ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
ReadParam(section, "erle_onset_compensation_in_dominant_nearend",
&cfg.ep_strength.erle_onset_compensation_in_dominant_nearend);
+ ReadParam(section, "use_conservative_tail_frequency_response",
+ &cfg.ep_strength.use_conservative_tail_frequency_response);
}
if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", §ion)) {
@@ -569,6 +571,10 @@
ost << "\"erle_onset_compensation_in_dominant_nearend\": "
<< (config.ep_strength.erle_onset_compensation_in_dominant_nearend
? "true"
+ : "false") << ",";
+ ost << "\"use_conservative_tail_frequency_response\": "
+ << (config.ep_strength.use_conservative_tail_frequency_response
+ ? "true"
: "false");
ost << "},";
diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc
index a0432e6..dfa932f 100644
--- a/modules/audio_processing/aec3/echo_canceller3.cc
+++ b/modules/audio_processing/aec3/echo_canceller3.cc
@@ -286,6 +286,10 @@
static_cast<float>(nearend_reverb_nearend_len.Get());
}
+ if (field_trial::IsEnabled("WebRTC-Aec3ConservativeTailFreqResponse")) {
+ adjusted_cfg.ep_strength.use_conservative_tail_frequency_response = true;
+ }
+
if (field_trial::IsEnabled("WebRTC-Aec3ShortHeadroomKillSwitch")) {
// Two blocks headroom.
adjusted_cfg.delay.delay_headroom_samples = kBlockSize * 2;
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.cc b/modules/audio_processing/aec3/reverb_frequency_response.cc
index f4bd91f..6e7282a 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.cc
+++ b/modules/audio_processing/aec3/reverb_frequency_response.cc
@@ -49,9 +49,13 @@
} // namespace
-ReverbFrequencyResponse::ReverbFrequencyResponse() {
- tail_response_.fill(0.f);
+ReverbFrequencyResponse::ReverbFrequencyResponse(
+ bool use_conservative_tail_frequency_response)
+ : use_conservative_tail_frequency_response_(
+ use_conservative_tail_frequency_response) {
+ tail_response_.fill(0.0f);
}
+
ReverbFrequencyResponse::~ReverbFrequencyResponse() = default;
void ReverbFrequencyResponse::Update(
@@ -88,6 +92,12 @@
tail_response_[k] = freq_resp_direct_path[k] * average_decay_;
}
+ if (use_conservative_tail_frequency_response_) {
+ for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) {
+ tail_response_[k] = std::max(freq_resp_tail[k], tail_response_[k]);
+ }
+ }
+
for (size_t k = 1; k < kFftLengthBy2; ++k) {
const float avg_neighbour =
0.5f * (tail_response_[k - 1] + tail_response_[k + 1]);
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.h b/modules/audio_processing/aec3/reverb_frequency_response.h
index b164186..69b16b5 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.h
+++ b/modules/audio_processing/aec3/reverb_frequency_response.h
@@ -23,7 +23,8 @@
// Class for updating the frequency response for the reverb.
class ReverbFrequencyResponse {
public:
- ReverbFrequencyResponse();
+ explicit ReverbFrequencyResponse(
+ bool use_conservative_tail_frequency_response);
~ReverbFrequencyResponse();
// Updates the frequency response estimate of the reverb.
@@ -44,6 +45,7 @@
int filter_delay_blocks,
float linear_filter_quality);
+ const bool use_conservative_tail_frequency_response_;
float average_decay_ = 0.f;
std::array<float, kFftLengthBy2Plus1> tail_response_;
};
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.cc b/modules/audio_processing/aec3/reverb_model_estimator.cc
index 7174311..5cd7a78 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.cc
+++ b/modules/audio_processing/aec3/reverb_model_estimator.cc
@@ -15,7 +15,10 @@
ReverbModelEstimator::ReverbModelEstimator(const EchoCanceller3Config& config,
size_t num_capture_channels)
: reverb_decay_estimators_(num_capture_channels),
- reverb_frequency_responses_(num_capture_channels) {
+ reverb_frequency_responses_(
+ num_capture_channels,
+ ReverbFrequencyResponse(
+ config.ep_strength.use_conservative_tail_frequency_response)) {
for (size_t ch = 0; ch < reverb_decay_estimators_.size(); ++ch) {
reverb_decay_estimators_[ch] =
std::make_unique<ReverbDecayEstimator>(config);