AEC3: Corrected the filter adjustment during analog gain changes
This CL corrects the way that the echo subtractor output is adjusted during the adjustment of the adaptive filter when the analog AGC gain changes. The CL also ensures that the main adaptive filter is not updated when this occurs. Bug: webrtc:9561,chromium:867373 Change-Id: I636f936128f7d9f0d82ca4140b59f148eb35d6a4 Reviewed-on: https://webrtc-review.googlesource.com/90401 Commit-Queue: Per Åhgren <peah@webrtc.org> Reviewed-by: Sam Zackrisson <saza@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24101}
This commit is contained in:
@ -71,6 +71,18 @@ void PredictionError(const Aec3Fft& fft,
|
||||
}
|
||||
}
|
||||
|
||||
void ScaleFilterOutput(rtc::ArrayView<const float> y,
|
||||
float factor,
|
||||
rtc::ArrayView<float> e,
|
||||
rtc::ArrayView<float> s) {
|
||||
RTC_DCHECK_EQ(y.size(), e.size());
|
||||
RTC_DCHECK_EQ(y.size(), s.size());
|
||||
for (size_t k = 0; k < y.size(); ++k) {
|
||||
s[k] *= factor;
|
||||
e[k] = y[k] - s[k];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Subtractor::Subtractor(const EchoCanceller3Config& config,
|
||||
@ -157,29 +169,34 @@ void Subtractor::Process(const RenderBuffer& render_buffer,
|
||||
FftData S;
|
||||
FftData& G = S;
|
||||
|
||||
// Form the output of the main filter.
|
||||
// Form the outputs of the main and shadow filters.
|
||||
main_filter_.Filter(render_buffer, &S);
|
||||
bool main_saturation = false;
|
||||
PredictionError(fft_, S, y, &e_main, &output->s_main,
|
||||
adaptation_during_saturation_, &main_saturation);
|
||||
fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kHanning, &E_main);
|
||||
|
||||
// Form the output of the shadow filter.
|
||||
shadow_filter_.Filter(render_buffer, &S);
|
||||
bool shadow_saturation = false;
|
||||
PredictionError(fft_, S, y, &e_shadow, nullptr, adaptation_during_saturation_,
|
||||
&shadow_saturation);
|
||||
fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kHanning, &E_shadow);
|
||||
|
||||
// Adjust the filter if needed.
|
||||
bool main_filter_adjusted = false;
|
||||
if (enable_misadjustment_estimator_) {
|
||||
filter_misadjustment_estimator_.Update(e_main, y);
|
||||
if (filter_misadjustment_estimator_.IsAdjustmentNeeded()) {
|
||||
float scale = filter_misadjustment_estimator_.GetMisadjustment();
|
||||
main_filter_.ScaleFilter(scale);
|
||||
output->ScaleOutputMainFilter(scale);
|
||||
ScaleFilterOutput(y, scale, e_main, output->s_main);
|
||||
filter_misadjustment_estimator_.Reset();
|
||||
main_filter_adjusted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the FFts of the main and shadow filter outputs.
|
||||
fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kHanning, &E_main);
|
||||
fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kHanning, &E_shadow);
|
||||
|
||||
// Compute spectra for future use.
|
||||
E_shadow.Spectrum(optimization_, output->E2_shadow);
|
||||
E_main.Spectrum(optimization_, output->E2_main);
|
||||
@ -187,8 +204,13 @@ void Subtractor::Process(const RenderBuffer& render_buffer,
|
||||
// Update the main filter.
|
||||
std::array<float, kFftLengthBy2Plus1> X2;
|
||||
render_buffer.SpectralSum(main_filter_.SizePartitions(), &X2);
|
||||
G_main_.Compute(X2, render_signal_analyzer, *output, main_filter_,
|
||||
aec_state.SaturatedCapture() || main_saturation, &G);
|
||||
if (!main_filter_adjusted) {
|
||||
G_main_.Compute(X2, render_signal_analyzer, *output, main_filter_,
|
||||
aec_state.SaturatedCapture() || main_saturation, &G);
|
||||
} else {
|
||||
G.re.fill(0.f);
|
||||
G.im.fill(0.f);
|
||||
}
|
||||
main_filter_.Adapt(render_buffer, G);
|
||||
data_dumper_->DumpRaw("aec3_subtractor_G_main", G.re);
|
||||
data_dumper_->DumpRaw("aec3_subtractor_G_main", G.im);
|
||||
|
||||
@ -36,24 +36,6 @@ struct SubtractorOutput {
|
||||
E2_main.fill(0.f);
|
||||
E2_shadow.fill(0.f);
|
||||
}
|
||||
|
||||
void ScaleOutputMainFilter(float factor) {
|
||||
for (auto& s : s_main) {
|
||||
s *= factor;
|
||||
}
|
||||
for (auto& e : e_main) {
|
||||
e *= factor;
|
||||
}
|
||||
for (auto& E2 : E2_main) {
|
||||
E2 *= factor * factor;
|
||||
}
|
||||
for (auto& re : E_main.re) {
|
||||
re *= factor;
|
||||
}
|
||||
for (auto& im : E_main.im) {
|
||||
im *= factor;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Reference in New Issue
Block a user