diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h index 63847f2acb..672f2c028d 100644 --- a/api/audio/echo_canceller3_config.h +++ b/api/audio/echo_canceller3_config.h @@ -21,7 +21,7 @@ struct EchoCanceller3Config { EchoCanceller3Config(const EchoCanceller3Config& e); struct Delay { size_t default_delay = 5; - size_t down_sampling_factor = 4; + size_t down_sampling_factor = 8; size_t num_filters = 5; size_t api_call_jitter_blocks = 26; size_t min_echo_path_delay_blocks = 0; diff --git a/modules/audio_processing/aec3/decimator.cc b/modules/audio_processing/aec3/decimator.cc index 75aa33134f..6135db5bc2 100644 --- a/modules/audio_processing/aec3/decimator.cc +++ b/modules/audio_processing/aec3/decimator.cc @@ -28,32 +28,39 @@ const CascadedBiQuadFilter::BiQuadCoefficients kLowPassFilterCoefficients4 = { {-1.5879f, 0.6594f}}; constexpr int kNumFilters4 = 3; -// b, a = signal.butter(2, 800/8000.0, 'lowpass', analog=False) which are the -// same as b, a = signal.butter(2, 400/4000.0, 'lowpass', analog=False). -const CascadedBiQuadFilter::BiQuadCoefficients kLowPassFilterCoefficients8 = { - {0.02008337f, 0.04016673f, 0.02008337f}, - {-1.56101808f, 0.64135154f}}; -constexpr int kNumFilters8 = 4; +// b, a = signal.cheby1(1, 6, [1000/8000, 2000/8000], btype='bandpass', +// analog=False) +const CascadedBiQuadFilter::BiQuadCoefficients kBandPassFilterCoefficients8 = { + {0.10330478f, 0.f, -0.10330478f}, + {-1.520363f, 0.79339043f}}; +constexpr int kNumFilters8 = 5; // b, a = signal.butter(2, 1000/8000.0, 'highpass', analog=False) -const CascadedBiQuadFilter::BiQuadCoefficients kHighPassFilterCoefficients4 = { +const CascadedBiQuadFilter::BiQuadCoefficients kHighPassFilterCoefficients = { {0.75707638f, -1.51415275f, 0.75707638f}, {-1.45424359f, 0.57406192f}}; +constexpr int kNumFiltersHP2 = 1; constexpr int kNumFiltersHP4 = 1; +constexpr int kNumFiltersHP8 = 0; } // namespace Decimator::Decimator(size_t down_sampling_factor) : down_sampling_factor_(down_sampling_factor), - low_pass_filter_( + anti_aliasing_filter_( down_sampling_factor_ == 4 ? kLowPassFilterCoefficients4 - : (down_sampling_factor_ == 8 ? kLowPassFilterCoefficients8 + : (down_sampling_factor_ == 8 ? kBandPassFilterCoefficients8 : kLowPassFilterCoefficients2), down_sampling_factor_ == 4 ? kNumFilters4 : (down_sampling_factor_ == 8 ? kNumFilters8 : kNumFilters2)), - high_pass_filter_(kHighPassFilterCoefficients4, kNumFiltersHP4) { + noise_reduction_filter_( + kHighPassFilterCoefficients, + down_sampling_factor_ == 4 + ? kNumFiltersHP4 + : (down_sampling_factor_ == 8 ? kNumFiltersHP8 + : kNumFiltersHP2)) { RTC_DCHECK(down_sampling_factor_ == 2 || down_sampling_factor_ == 4 || down_sampling_factor_ == 8); } @@ -65,11 +72,10 @@ void Decimator::Decimate(rtc::ArrayView in, std::array x; // Limit the frequency content of the signal to avoid aliasing. - low_pass_filter_.Process(in, x); + anti_aliasing_filter_.Process(in, x); - // High-pass filter to reduce the impact of near-end noise. - if (down_sampling_factor_ == 4) - high_pass_filter_.Process(x, x); + // Reduce the impact of near-end noise. + noise_reduction_filter_.Process(x); // Downsample the signal. for (size_t j = 0, k = 0; j < out.size(); ++j, k += down_sampling_factor_) { diff --git a/modules/audio_processing/aec3/decimator.h b/modules/audio_processing/aec3/decimator.h index e6922e0ffa..2bb60a4d7b 100644 --- a/modules/audio_processing/aec3/decimator.h +++ b/modules/audio_processing/aec3/decimator.h @@ -30,8 +30,8 @@ class Decimator { private: const size_t down_sampling_factor_; - CascadedBiQuadFilter low_pass_filter_; - CascadedBiQuadFilter high_pass_filter_; + CascadedBiQuadFilter anti_aliasing_filter_; + CascadedBiQuadFilter noise_reduction_filter_; RTC_DISALLOW_COPY_AND_ASSIGN(Decimator); }; diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.cc b/modules/audio_processing/aec3/echo_path_delay_estimator.cc index 0026522d53..14cf8daac9 100644 --- a/modules/audio_processing/aec3/echo_path_delay_estimator.cc +++ b/modules/audio_processing/aec3/echo_path_delay_estimator.cc @@ -16,14 +16,24 @@ #include "modules/audio_processing/aec3/aec3_common.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" namespace webrtc { +namespace { +size_t GetDownSamplingFactor(const EchoCanceller3Config& config) { + // Do not use down sampling factor 8 if kill switch is triggered. + return (config.delay.down_sampling_factor == 8 && + field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch")) + ? 4 + : config.delay.down_sampling_factor; +} +} // namespace EchoPathDelayEstimator::EchoPathDelayEstimator( ApmDataDumper* data_dumper, const EchoCanceller3Config& config) : data_dumper_(data_dumper), - down_sampling_factor_(config.delay.down_sampling_factor), + down_sampling_factor_(GetDownSamplingFactor(config)), sub_block_size_(down_sampling_factor_ != 0 ? kBlockSize / down_sampling_factor_ : kBlockSize), diff --git a/modules/audio_processing/aec3/render_delay_buffer.cc b/modules/audio_processing/aec3/render_delay_buffer.cc index 28909a2e33..b01593be0e 100644 --- a/modules/audio_processing/aec3/render_delay_buffer.cc +++ b/modules/audio_processing/aec3/render_delay_buffer.cc @@ -35,6 +35,14 @@ bool EnableZeroExternalDelayHeadroom() { "WebRTC-Aec3ZeroExternalDelayHeadroomKillSwitch"); } +size_t GetDownSamplingFactor(const EchoCanceller3Config& config) { + // Do not use down sampling factor 8 if kill switch is triggered. + return (config.delay.down_sampling_factor == 8 && + field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch")) + ? 4 + : config.delay.down_sampling_factor; +} + class RenderDelayBufferImpl final : public RenderDelayBuffer { public: RenderDelayBufferImpl(const EchoCanceller3Config& config, size_t num_bands); @@ -63,6 +71,7 @@ class RenderDelayBufferImpl final : public RenderDelayBuffer { std::unique_ptr data_dumper_; const Aec3Optimization optimization_; const EchoCanceller3Config config_; + size_t down_sampling_factor_; const bool use_zero_external_delay_headroom_; const int sub_block_size_; MatrixBuffer blocks_; @@ -168,12 +177,12 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(const EchoCanceller3Config& config, new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), optimization_(DetectOptimization()), config_(config), + down_sampling_factor_(GetDownSamplingFactor(config)), use_zero_external_delay_headroom_(EnableZeroExternalDelayHeadroom()), - sub_block_size_( - static_cast(config.delay.down_sampling_factor > 0 - ? kBlockSize / config.delay.down_sampling_factor - : kBlockSize)), - blocks_(GetRenderDelayBufferSize(config.delay.down_sampling_factor, + sub_block_size_(static_cast(down_sampling_factor_ > 0 + ? kBlockSize / down_sampling_factor_ + : kBlockSize)), + blocks_(GetRenderDelayBufferSize(down_sampling_factor_, config.delay.num_filters, config.filter.main.length_blocks), num_bands, @@ -182,9 +191,9 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(const EchoCanceller3Config& config, ffts_(blocks_.buffer.size()), delay_(config_.delay.default_delay), echo_remover_buffer_(&blocks_, &spectra_, &ffts_), - low_rate_(GetDownSampledBufferSize(config.delay.down_sampling_factor, + low_rate_(GetDownSampledBufferSize(down_sampling_factor_, config.delay.num_filters)), - render_decimator_(config.delay.down_sampling_factor), + render_decimator_(down_sampling_factor_), zero_block_(num_bands, std::vector(kBlockSize, 0.f)), fft_(), render_ds_(sub_block_size_, 0.f), @@ -433,7 +442,7 @@ void RenderDelayBufferImpl::InsertBlock( block[0].data(), 16000, 1); render_decimator_.Decimate(block[0], ds); data_dumper_->DumpWav("aec3_render_decimator_output", ds.size(), ds.data(), - 16000 / config_.delay.down_sampling_factor, 1); + 16000 / down_sampling_factor_, 1); std::copy(ds.rbegin(), ds.rend(), lr.buffer.begin() + lr.write); fft_.PaddedFft(block[0], b.buffer[previous_write][0], &f.buffer[f.write]); f.buffer[f.write].Spectrum(optimization_, s.buffer[s.write]);