AEC3: Avoid using filter output in suppression gain computation in non-linear mode

As non-linear mode uses a suppressed version of y (not e) as output, this change
uses Y2, rather than E2, as nearend spectrum when computing the suppression gains.
E2 is still used in linear mode.

This change also affects how the minimum suppression gains are calculated. The
minimum gain is now min_echo_power / weighted_residual_echo.

Bug: webrtc:10550
Change-Id: I2904c5a09dd64b06bf25eb5a37c18dab50297794
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133023
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Reviewed-by: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27629}
This commit is contained in:
Gustaf Ullberg 2019-04-15 17:15:37 +02:00 committed by Commit Bot
parent 01738c63aa
commit 2bab5ad3b1
5 changed files with 26 additions and 24 deletions

View file

@ -290,15 +290,22 @@ void EchoRemoverImpl::ProcessCapture(
// Estimate the comfort noise.
cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise);
// Compute and apply the suppression gain.
// Suppressor echo estimate.
const auto& echo_spectrum =
aec_state_.UsableLinearEstimate() ? S2_linear : R2;
std::array<float, kFftLengthBy2Plus1> E2_bounded;
std::transform(E2.begin(), E2.end(), Y2.begin(), E2_bounded.begin(),
[](float a, float b) { return std::min(a, b); });
// Suppressor nearend estimate.
std::array<float, kFftLengthBy2Plus1> nearend_spectrum_bounded;
if (aec_state_.UsableLinearEstimate()) {
std::transform(E2.begin(), E2.end(), Y2.begin(),
nearend_spectrum_bounded.begin(),
[](float a, float b) { return std::min(a, b); });
}
auto& nearend_spectrum =
aec_state_.UsableLinearEstimate() ? nearend_spectrum_bounded : Y2;
suppression_gain_.GetGain(E2, E2_bounded, echo_spectrum, R2,
// Compute and apply the suppression gain.
suppression_gain_.GetGain(nearend_spectrum, echo_spectrum, R2,
cng_.NoiseSpectrum(), render_signal_analyzer_,
aec_state_, x, &high_bands_gain, &G);

View file

@ -197,7 +197,6 @@ void SuppressionGain::GainToNoAudibleEcho(
// Compute the minimum gain as the attenuating gain to put the signal just
// above the zero sample values.
void SuppressionGain::GetMinGain(
rtc::ArrayView<const float> suppressor_input,
rtc::ArrayView<const float> weighted_residual_echo,
bool low_noise_render,
bool saturated_echo,
@ -207,10 +206,10 @@ void SuppressionGain::GetMinGain(
low_noise_render ? config_.echo_audibility.low_render_limit
: config_.echo_audibility.normal_render_limit;
for (size_t k = 0; k < suppressor_input.size(); ++k) {
const float denom =
std::min(suppressor_input[k], weighted_residual_echo[k]);
min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
for (size_t k = 0; k < min_gain.size(); ++k) {
min_gain[k] = weighted_residual_echo[k] > 0.f
? min_echo_power / weighted_residual_echo[k]
: 1.f;
min_gain[k] = std::min(min_gain[k], 1.f);
}
for (size_t k = 0; k < 6; ++k) {
@ -259,8 +258,8 @@ void SuppressionGain::LowerBandGain(
WeightEchoForAudibility(config_, residual_echo, weighted_residual_echo);
std::array<float, kFftLengthBy2Plus1> min_gain;
GetMinGain(suppressor_input, weighted_residual_echo, low_noise_render,
saturated_echo, min_gain);
GetMinGain(weighted_residual_echo, low_noise_render, saturated_echo,
min_gain);
std::array<float, kFftLengthBy2Plus1> max_gain;
GetMaxGain(max_gain);
@ -311,7 +310,6 @@ SuppressionGain::SuppressionGain(const EchoCanceller3Config& config,
SuppressionGain::~SuppressionGain() = default;
void SuppressionGain::GetGain(
const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
@ -340,9 +338,8 @@ void SuppressionGain::GetGain(
// Compute gain for the lower band.
bool low_noise_render = low_render_detector_.Detect(render);
LowerBandGain(low_noise_render, aec_state, suppressor_input_spectrum,
nearend_average, residual_echo_spectrum, comfort_noise_spectrum,
low_band_gain);
LowerBandGain(low_noise_render, aec_state, nearend_spectrum, nearend_average,
residual_echo_spectrum, comfort_noise_spectrum, low_band_gain);
// Compute the gain for the upper bands.
const absl::optional<int> narrow_peak_band =

View file

@ -35,7 +35,6 @@ class SuppressionGain {
int sample_rate_hz);
~SuppressionGain();
void GetGain(
const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
@ -76,8 +75,7 @@ class SuppressionGain {
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
std::array<float, kFftLengthBy2Plus1>* gain);
void GetMinGain(rtc::ArrayView<const float> suppressor_input,
rtc::ArrayView<const float> weighted_residual_echo,
void GetMinGain(rtc::ArrayView<const float> weighted_residual_echo,
bool low_noise_render,
bool saturated_echo,
rtc::ArrayView<float> min_gain) const;

View file

@ -45,7 +45,7 @@ TEST(SuppressionGain, NullOutputGains) {
AecState aec_state(EchoCanceller3Config{});
EXPECT_DEATH(
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
.GetGain(E2, E2, S2, R2, N2,
.GetGain(E2, S2, R2, N2,
RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
std::vector<std::vector<float>>(
3, std::vector<float>(kBlockSize, 0.f)),
@ -100,7 +100,7 @@ TEST(SuppressionGain, BasicGainComputation) {
subtractor.FilterImpulseResponse(),
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
y);
suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),
@ -118,7 +118,7 @@ TEST(SuppressionGain, BasicGainComputation) {
subtractor.FilterImpulseResponse(),
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
y);
suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),
@ -129,7 +129,7 @@ TEST(SuppressionGain, BasicGainComputation) {
R2.fill(10000000000000.f);
for (int k = 0; k < 10; ++k) {
suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),

View file

@ -1 +1 @@
169276fe22bbeb1c06e0ed1a9df8149c5dbf8f80
bc19d9e9fd9503cad02f3b0c21cbd63ed3c5f22c