mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-17 23:57:59 +01:00
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:
parent
01738c63aa
commit
2bab5ad3b1
5 changed files with 26 additions and 24 deletions
|
@ -290,15 +290,22 @@ void EchoRemoverImpl::ProcessCapture(
|
||||||
// Estimate the comfort noise.
|
// Estimate the comfort noise.
|
||||||
cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_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 =
|
const auto& echo_spectrum =
|
||||||
aec_state_.UsableLinearEstimate() ? S2_linear : R2;
|
aec_state_.UsableLinearEstimate() ? S2_linear : R2;
|
||||||
|
|
||||||
std::array<float, kFftLengthBy2Plus1> E2_bounded;
|
// Suppressor nearend estimate.
|
||||||
std::transform(E2.begin(), E2.end(), Y2.begin(), E2_bounded.begin(),
|
std::array<float, kFftLengthBy2Plus1> nearend_spectrum_bounded;
|
||||||
[](float a, float b) { return std::min(a, b); });
|
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_,
|
cng_.NoiseSpectrum(), render_signal_analyzer_,
|
||||||
aec_state_, x, &high_bands_gain, &G);
|
aec_state_, x, &high_bands_gain, &G);
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,6 @@ void SuppressionGain::GainToNoAudibleEcho(
|
||||||
// Compute the minimum gain as the attenuating gain to put the signal just
|
// Compute the minimum gain as the attenuating gain to put the signal just
|
||||||
// above the zero sample values.
|
// above the zero sample values.
|
||||||
void SuppressionGain::GetMinGain(
|
void SuppressionGain::GetMinGain(
|
||||||
rtc::ArrayView<const float> suppressor_input,
|
|
||||||
rtc::ArrayView<const float> weighted_residual_echo,
|
rtc::ArrayView<const float> weighted_residual_echo,
|
||||||
bool low_noise_render,
|
bool low_noise_render,
|
||||||
bool saturated_echo,
|
bool saturated_echo,
|
||||||
|
@ -207,10 +206,10 @@ void SuppressionGain::GetMinGain(
|
||||||
low_noise_render ? config_.echo_audibility.low_render_limit
|
low_noise_render ? config_.echo_audibility.low_render_limit
|
||||||
: config_.echo_audibility.normal_render_limit;
|
: config_.echo_audibility.normal_render_limit;
|
||||||
|
|
||||||
for (size_t k = 0; k < suppressor_input.size(); ++k) {
|
for (size_t k = 0; k < min_gain.size(); ++k) {
|
||||||
const float denom =
|
min_gain[k] = weighted_residual_echo[k] > 0.f
|
||||||
std::min(suppressor_input[k], weighted_residual_echo[k]);
|
? min_echo_power / weighted_residual_echo[k]
|
||||||
min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
|
: 1.f;
|
||||||
min_gain[k] = std::min(min_gain[k], 1.f);
|
min_gain[k] = std::min(min_gain[k], 1.f);
|
||||||
}
|
}
|
||||||
for (size_t k = 0; k < 6; ++k) {
|
for (size_t k = 0; k < 6; ++k) {
|
||||||
|
@ -259,8 +258,8 @@ void SuppressionGain::LowerBandGain(
|
||||||
WeightEchoForAudibility(config_, residual_echo, weighted_residual_echo);
|
WeightEchoForAudibility(config_, residual_echo, weighted_residual_echo);
|
||||||
|
|
||||||
std::array<float, kFftLengthBy2Plus1> min_gain;
|
std::array<float, kFftLengthBy2Plus1> min_gain;
|
||||||
GetMinGain(suppressor_input, weighted_residual_echo, low_noise_render,
|
GetMinGain(weighted_residual_echo, low_noise_render, saturated_echo,
|
||||||
saturated_echo, min_gain);
|
min_gain);
|
||||||
|
|
||||||
std::array<float, kFftLengthBy2Plus1> max_gain;
|
std::array<float, kFftLengthBy2Plus1> max_gain;
|
||||||
GetMaxGain(max_gain);
|
GetMaxGain(max_gain);
|
||||||
|
@ -311,7 +310,6 @@ SuppressionGain::SuppressionGain(const EchoCanceller3Config& config,
|
||||||
SuppressionGain::~SuppressionGain() = default;
|
SuppressionGain::~SuppressionGain() = default;
|
||||||
|
|
||||||
void SuppressionGain::GetGain(
|
void SuppressionGain::GetGain(
|
||||||
const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
|
|
||||||
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
|
||||||
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
||||||
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
|
||||||
|
@ -340,9 +338,8 @@ void SuppressionGain::GetGain(
|
||||||
|
|
||||||
// Compute gain for the lower band.
|
// Compute gain for the lower band.
|
||||||
bool low_noise_render = low_render_detector_.Detect(render);
|
bool low_noise_render = low_render_detector_.Detect(render);
|
||||||
LowerBandGain(low_noise_render, aec_state, suppressor_input_spectrum,
|
LowerBandGain(low_noise_render, aec_state, nearend_spectrum, nearend_average,
|
||||||
nearend_average, residual_echo_spectrum, comfort_noise_spectrum,
|
residual_echo_spectrum, comfort_noise_spectrum, low_band_gain);
|
||||||
low_band_gain);
|
|
||||||
|
|
||||||
// Compute the gain for the upper bands.
|
// Compute the gain for the upper bands.
|
||||||
const absl::optional<int> narrow_peak_band =
|
const absl::optional<int> narrow_peak_band =
|
||||||
|
|
|
@ -35,7 +35,6 @@ class SuppressionGain {
|
||||||
int sample_rate_hz);
|
int sample_rate_hz);
|
||||||
~SuppressionGain();
|
~SuppressionGain();
|
||||||
void GetGain(
|
void GetGain(
|
||||||
const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
|
|
||||||
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
|
||||||
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
||||||
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
|
const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
|
||||||
|
@ -76,8 +75,7 @@ class SuppressionGain {
|
||||||
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
|
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
|
||||||
std::array<float, kFftLengthBy2Plus1>* gain);
|
std::array<float, kFftLengthBy2Plus1>* gain);
|
||||||
|
|
||||||
void GetMinGain(rtc::ArrayView<const float> suppressor_input,
|
void GetMinGain(rtc::ArrayView<const float> weighted_residual_echo,
|
||||||
rtc::ArrayView<const float> weighted_residual_echo,
|
|
||||||
bool low_noise_render,
|
bool low_noise_render,
|
||||||
bool saturated_echo,
|
bool saturated_echo,
|
||||||
rtc::ArrayView<float> min_gain) const;
|
rtc::ArrayView<float> min_gain) const;
|
||||||
|
|
|
@ -45,7 +45,7 @@ TEST(SuppressionGain, NullOutputGains) {
|
||||||
AecState aec_state(EchoCanceller3Config{});
|
AecState aec_state(EchoCanceller3Config{});
|
||||||
EXPECT_DEATH(
|
EXPECT_DEATH(
|
||||||
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
|
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
|
||||||
.GetGain(E2, E2, S2, R2, N2,
|
.GetGain(E2, S2, R2, N2,
|
||||||
RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
|
RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
|
||||||
std::vector<std::vector<float>>(
|
std::vector<std::vector<float>>(
|
||||||
3, std::vector<float>(kBlockSize, 0.f)),
|
3, std::vector<float>(kBlockSize, 0.f)),
|
||||||
|
@ -100,7 +100,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||||
subtractor.FilterImpulseResponse(),
|
subtractor.FilterImpulseResponse(),
|
||||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
||||||
y);
|
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);
|
&high_bands_gain, &g);
|
||||||
}
|
}
|
||||||
std::for_each(g.begin(), g.end(),
|
std::for_each(g.begin(), g.end(),
|
||||||
|
@ -118,7 +118,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||||
subtractor.FilterImpulseResponse(),
|
subtractor.FilterImpulseResponse(),
|
||||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
||||||
y);
|
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);
|
&high_bands_gain, &g);
|
||||||
}
|
}
|
||||||
std::for_each(g.begin(), g.end(),
|
std::for_each(g.begin(), g.end(),
|
||||||
|
@ -129,7 +129,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||||
R2.fill(10000000000000.f);
|
R2.fill(10000000000000.f);
|
||||||
|
|
||||||
for (int k = 0; k < 10; ++k) {
|
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);
|
&high_bands_gain, &g);
|
||||||
}
|
}
|
||||||
std::for_each(g.begin(), g.end(),
|
std::for_each(g.begin(), g.end(),
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
169276fe22bbeb1c06e0ed1a9df8149c5dbf8f80
|
bc19d9e9fd9503cad02f3b0c21cbd63ed3c5f22c
|
Loading…
Reference in a new issue