mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-17 15:47:53 +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.
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -1 +1 @@
|
|||
169276fe22bbeb1c06e0ed1a9df8149c5dbf8f80
|
||||
bc19d9e9fd9503cad02f3b0c21cbd63ed3c5f22c
|
Loading…
Reference in a new issue