| Index: webrtc/modules/audio_processing/aec3/echo_remover.cc
|
| diff --git a/webrtc/modules/audio_processing/aec3/echo_remover.cc b/webrtc/modules/audio_processing/aec3/echo_remover.cc
|
| index 41e954652a7ec9581cdc8115dee526575961af55..2b28a217510f36de3bc6968d2943b9ff4b605516 100644
|
| --- a/webrtc/modules/audio_processing/aec3/echo_remover.cc
|
| +++ b/webrtc/modules/audio_processing/aec3/echo_remover.cc
|
| @@ -9,6 +9,7 @@
|
| */
|
| #include "webrtc/modules/audio_processing/aec3/echo_remover.h"
|
|
|
| +#include <math.h>
|
| #include <algorithm>
|
| #include <memory>
|
| #include <numeric>
|
| @@ -24,7 +25,6 @@
|
| #include "webrtc/modules/audio_processing/aec3/echo_remover_metrics.h"
|
| #include "webrtc/modules/audio_processing/aec3/fft_data.h"
|
| #include "webrtc/modules/audio_processing/aec3/output_selector.h"
|
| -#include "webrtc/modules/audio_processing/aec3/power_echo_model.h"
|
| #include "webrtc/modules/audio_processing/aec3/render_buffer.h"
|
| #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h"
|
| #include "webrtc/modules/audio_processing/aec3/residual_echo_estimator.h"
|
| @@ -46,11 +46,6 @@ void LinearEchoPower(const FftData& E,
|
| }
|
| }
|
|
|
| -float BlockPower(const std::array<float, kBlockSize> x) {
|
| - return std::accumulate(x.begin(), x.end(), 0.f,
|
| - [](float a, float b) -> float { return a + b * b; });
|
| -}
|
| -
|
| // Class for removing the echo from the capture signal.
|
| class EchoRemoverImpl final : public EchoRemover {
|
| public:
|
| @@ -83,8 +78,6 @@ class EchoRemoverImpl final : public EchoRemover {
|
| SuppressionGain suppression_gain_;
|
| ComfortNoiseGenerator cng_;
|
| SuppressionFilter suppression_filter_;
|
| - PowerEchoModel power_echo_model_;
|
| - RenderBuffer X_buffer_;
|
| RenderSignalAnalyzer render_signal_analyzer_;
|
| OutputSelector output_selector_;
|
| ResidualEchoEstimator residual_echo_estimator_;
|
| @@ -106,12 +99,7 @@ EchoRemoverImpl::EchoRemoverImpl(int sample_rate_hz)
|
| subtractor_(data_dumper_.get(), optimization_),
|
| suppression_gain_(optimization_),
|
| cng_(optimization_),
|
| - suppression_filter_(sample_rate_hz_),
|
| - X_buffer_(optimization_,
|
| - NumBandsForRate(sample_rate_hz_),
|
| - std::max(subtractor_.MinFarendBufferLength(),
|
| - power_echo_model_.MinFarendBufferLength()),
|
| - subtractor_.NumBlocksInRenderSums()) {
|
| + suppression_filter_(sample_rate_hz_) {
|
| RTC_DCHECK(ValidFullBandRate(sample_rate_hz));
|
| }
|
|
|
| @@ -134,23 +122,23 @@ void EchoRemoverImpl::ProcessCapture(
|
| const std::vector<float>& x0 = x[0];
|
| std::vector<float>& y0 = (*y)[0];
|
|
|
| - data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize, &y0[0],
|
| + data_dumper_->DumpWav("aec3_echo_remover_capture_input", kBlockSize, &y0[0],
|
| LowestBandRate(sample_rate_hz_), 1);
|
| - data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize, &x0[0],
|
| + data_dumper_->DumpWav("aec3_echo_remover_render_input", kBlockSize, &x0[0],
|
| LowestBandRate(sample_rate_hz_), 1);
|
|
|
| aec_state_.UpdateCaptureSaturation(capture_signal_saturation);
|
|
|
| if (echo_path_variability.AudioPathChanged()) {
|
| subtractor_.HandleEchoPathChange(echo_path_variability);
|
| - residual_echo_estimator_.HandleEchoPathChange(echo_path_variability);
|
| + aec_state_.HandleEchoPathChange(echo_path_variability);
|
| }
|
|
|
| std::array<float, kFftLengthBy2Plus1> Y2;
|
| - std::array<float, kFftLengthBy2Plus1> S2_power;
|
| std::array<float, kFftLengthBy2Plus1> R2;
|
| std::array<float, kFftLengthBy2Plus1> S2_linear;
|
| std::array<float, kFftLengthBy2Plus1> G;
|
| + float high_bands_gain;
|
| FftData Y;
|
| FftData comfort_noise;
|
| FftData high_band_comfort_noise;
|
| @@ -159,14 +147,13 @@ void EchoRemoverImpl::ProcessCapture(
|
| auto& E2_main = subtractor_output.E2_main;
|
| auto& E2_shadow = subtractor_output.E2_shadow;
|
| auto& e_main = subtractor_output.e_main;
|
| - auto& e_shadow = subtractor_output.e_shadow;
|
|
|
| // Analyze the render signal.
|
| render_signal_analyzer_.Update(render_buffer, aec_state_.FilterDelay());
|
|
|
| // Perform linear echo cancellation.
|
| - subtractor_.Process(render_buffer, y0, render_signal_analyzer_,
|
| - aec_state_.SaturatedCapture(), &subtractor_output);
|
| + subtractor_.Process(render_buffer, y0, render_signal_analyzer_, aec_state_,
|
| + &subtractor_output);
|
|
|
| // Compute spectra.
|
| fft_.ZeroPaddedFft(y0, &Y);
|
| @@ -175,35 +162,29 @@ void EchoRemoverImpl::ProcessCapture(
|
|
|
| // Update the AEC state information.
|
| aec_state_.Update(subtractor_.FilterFrequencyResponse(),
|
| - echo_path_delay_samples, render_buffer, E2_main, E2_shadow,
|
| - Y2, x0, echo_path_variability, echo_leakage_detected_);
|
| -
|
| - // Use the power model to estimate the echo.
|
| - // TODO(peah): Remove in upcoming CL.
|
| - // power_echo_model_.EstimateEcho(render_buffer, Y2, aec_state_, &S2_power);
|
| + echo_path_delay_samples, render_buffer, E2_main, Y2, x0,
|
| + echo_leakage_detected_);
|
|
|
| // Choose the linear output.
|
| - output_selector_.FormLinearOutput(e_main, y0);
|
| + output_selector_.FormLinearOutput(!aec_state_.HeadsetDetected(), e_main, y0);
|
| data_dumper_->DumpWav("aec3_output_linear", kBlockSize, &y0[0],
|
| LowestBandRate(sample_rate_hz_), 1);
|
| const auto& E2 = output_selector_.UseSubtractorOutput() ? E2_main : Y2;
|
|
|
| // Estimate the residual echo power.
|
| - residual_echo_estimator_.Estimate(
|
| - output_selector_.UseSubtractorOutput(), aec_state_, render_buffer,
|
| - subtractor_.FilterFrequencyResponse(), E2_main, E2_shadow, S2_linear,
|
| - S2_power, Y2, &R2);
|
| + residual_echo_estimator_.Estimate(output_selector_.UseSubtractorOutput(),
|
| + aec_state_, render_buffer, S2_linear, Y2,
|
| + &R2);
|
|
|
| // Estimate the comfort noise.
|
| cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise);
|
|
|
| - // Detect basic doubletalk.
|
| - const bool doubletalk = BlockPower(e_shadow) < BlockPower(e_main);
|
| -
|
| // A choose and apply echo suppression gain.
|
| suppression_gain_.GetGain(E2, R2, cng_.NoiseSpectrum(),
|
| - doubletalk ? 0.001f : 0.0001f, &G);
|
| - suppression_filter_.ApplyGain(comfort_noise, high_band_comfort_noise, G, y);
|
| + aec_state_.SaturatedEcho(), x, y->size(),
|
| + &high_bands_gain, &G);
|
| + suppression_filter_.ApplyGain(comfort_noise, high_band_comfort_noise, G,
|
| + high_bands_gain, y);
|
|
|
| // Update the metrics.
|
| metrics_.Update(aec_state_, cng_.NoiseSpectrum(), G);
|
| @@ -216,21 +197,16 @@ void EchoRemoverImpl::ProcessCapture(
|
| LowestBandRate(sample_rate_hz_), 1);
|
| data_dumper_->DumpRaw("aec3_using_subtractor_output",
|
| output_selector_.UseSubtractorOutput() ? 1 : 0);
|
| - data_dumper_->DumpRaw("aec3_doubletalk", doubletalk ? 1 : 0);
|
| data_dumper_->DumpRaw("aec3_E2", E2);
|
| data_dumper_->DumpRaw("aec3_E2_main", E2_main);
|
| data_dumper_->DumpRaw("aec3_E2_shadow", E2_shadow);
|
| data_dumper_->DumpRaw("aec3_S2_linear", S2_linear);
|
| - data_dumper_->DumpRaw("aec3_S2_power", S2_power);
|
| data_dumper_->DumpRaw("aec3_Y2", Y2);
|
| + data_dumper_->DumpRaw("aec3_X2", render_buffer.Spectrum(0));
|
| data_dumper_->DumpRaw("aec3_R2", R2);
|
| data_dumper_->DumpRaw("aec3_erle", aec_state_.Erle());
|
| data_dumper_->DumpRaw("aec3_erl", aec_state_.Erl());
|
| - data_dumper_->DumpRaw("aec3_reliable_filter_bands",
|
| - aec_state_.BandsWithReliableFilter());
|
| data_dumper_->DumpRaw("aec3_active_render", aec_state_.ActiveRender());
|
| - data_dumper_->DumpRaw("aec3_model_based_aec_feasible",
|
| - aec_state_.ModelBasedAecFeasible());
|
| data_dumper_->DumpRaw("aec3_usable_linear_estimate",
|
| aec_state_.UsableLinearEstimate());
|
| data_dumper_->DumpRaw(
|
|
|