Utilizing the AEC3 config struct for constants.
This CL replaces inline constants with config struct
constants.
BUG=webrtc:5298
Review-Url: https://codereview.webrtc.org/3003733002
Cr-Commit-Position: refs/heads/master@{#19507}
diff --git a/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
index ddc7896..c861d46 100644
--- a/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
@@ -305,7 +305,7 @@
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> n(kBlockSize, 0.f);
std::vector<float> y(kBlockSize, 0.f);
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
RenderSignalAnalyzer render_signal_analyzer;
std::vector<float> e(kBlockSize, 0.f);
std::array<float, kFftLength> s_scratch;
diff --git a/webrtc/modules/audio_processing/aec3/aec_state.cc b/webrtc/modules/audio_processing/aec3/aec_state.cc
index cc344ab..6908270 100644
--- a/webrtc/modules/audio_processing/aec3/aec_state.cc
+++ b/webrtc/modules/audio_processing/aec3/aec_state.cc
@@ -75,11 +75,15 @@
int AecState::instance_count_ = 0;
-AecState::AecState(float reverb_decay)
+AecState::AecState(const AudioProcessing::Config::EchoCanceller3& config)
: data_dumper_(
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
+ erle_estimator_(config.param.erle.min,
+ config.param.erle.max_l,
+ config.param.erle.max_h),
echo_path_change_counter_(kEchoPathChangeCounterInitial),
- reverb_decay_(reverb_decay) {}
+ config_(config),
+ reverb_decay_(config_.param.ep_strength.default_len) {}
AecState::~AecState() = default;
@@ -252,7 +256,8 @@
// Limit the estimated reverb_decay_ to the maximum one needed in practice
// to minimize the impact of incorrect estimates.
- reverb_decay_ = std::min(0.8f, reverb_decay_);
+ reverb_decay_ =
+ std::min(config_.param.ep_strength.default_len, reverb_decay_);
}
reverb_decay_to_test_ = 0.9f;
reverb_decay_candidate_residual_ = -1.f;
@@ -260,7 +265,7 @@
// For noisy impulse responses, assume a fixed tail length.
if (tail_power > 0.0005f) {
- reverb_decay_ = 0.7f;
+ reverb_decay_ = config_.param.ep_strength.default_len;
}
data_dumper_->DumpRaw("aec3_reverb_decay", reverb_decay_);
data_dumper_->DumpRaw("aec3_tail_power", tail_power);
diff --git a/webrtc/modules/audio_processing/aec3/aec_state.h b/webrtc/modules/audio_processing/aec3/aec_state.h
index 5192a92..44a1767 100644
--- a/webrtc/modules/audio_processing/aec3/aec_state.h
+++ b/webrtc/modules/audio_processing/aec3/aec_state.h
@@ -20,6 +20,7 @@
#include "webrtc/modules/audio_processing/aec3/erl_estimator.h"
#include "webrtc/modules/audio_processing/aec3/erle_estimator.h"
#include "webrtc/modules/audio_processing/aec3/render_buffer.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/rtc_base/array_view.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/optional.h"
@@ -31,7 +32,7 @@
// Handles the state and the conditions for the echo removal functionality.
class AecState {
public:
- explicit AecState(float reverb_decay);
+ explicit AecState(const AudioProcessing::Config::EchoCanceller3& config);
~AecState();
// Returns whether the linear filter estimate is usable.
@@ -140,13 +141,14 @@
rtc::Optional<size_t> filter_delay_;
rtc::Optional<size_t> external_delay_;
size_t blocks_since_last_saturation_ = 1000;
- float reverb_decay_;
float reverb_decay_to_test_ = 0.9f;
float reverb_decay_candidate_ = 0.f;
float reverb_decay_candidate_residual_ = -1.f;
EchoAudibility echo_audibility_;
+ const AudioProcessing::Config::EchoCanceller3 config_;
+ float reverb_decay_;
- RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AecState);
+ RTC_DISALLOW_COPY_AND_ASSIGN(AecState);
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/aec3/aec_state_unittest.cc b/webrtc/modules/audio_processing/aec3/aec_state_unittest.cc
index 7062d24..05530ca 100644
--- a/webrtc/modules/audio_processing/aec3/aec_state_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/aec_state_unittest.cc
@@ -18,7 +18,7 @@
// Verify the general functionality of AecState
TEST(AecState, NormalUsage) {
ApmDataDumper data_dumper(42);
- AecState state(0.f);
+ AecState state(AudioProcessing::Config::EchoCanceller3{});
RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
std::vector<size_t>(1, 30));
std::array<float, kFftLengthBy2Plus1> E2_main = {};
@@ -163,7 +163,7 @@
// Verifies the a non-significant delay is correctly identified.
TEST(AecState, NonSignificantDelay) {
- AecState state(0.f);
+ AecState state(AudioProcessing::Config::EchoCanceller3{});
RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
std::vector<size_t>(1, 30));
std::array<float, kFftLengthBy2Plus1> E2_main;
@@ -192,7 +192,7 @@
// Verifies the delay for a converged filter is correctly identified.
TEST(AecState, ConvergedFilterDelay) {
constexpr int kFilterLength = 10;
- AecState state(0.f);
+ AecState state(AudioProcessing::Config::EchoCanceller3{});
RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
std::vector<size_t>(1, 30));
std::array<float, kFftLengthBy2Plus1> E2_main;
@@ -228,7 +228,7 @@
// Verify that the externally reported delay is properly reported and converted.
TEST(AecState, ExternalDelay) {
- AecState state(0.f);
+ AecState state(AudioProcessing::Config::EchoCanceller3{});
std::array<float, kFftLengthBy2Plus1> E2_main;
std::array<float, kFftLengthBy2Plus1> E2_shadow;
std::array<float, kFftLengthBy2Plus1> Y2;
diff --git a/webrtc/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc b/webrtc/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
index 9e10ee8..7cb0aa1 100644
--- a/webrtc/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
@@ -36,7 +36,8 @@
std::array<float, kFftLengthBy2Plus1> N2;
FftData noise;
EXPECT_DEATH(ComfortNoiseGenerator(DetectOptimization())
- .Compute(AecState(0.f), N2, nullptr, &noise),
+ .Compute(AecState(AudioProcessing::Config::EchoCanceller3{}),
+ N2, nullptr, &noise),
"");
}
@@ -44,7 +45,8 @@
std::array<float, kFftLengthBy2Plus1> N2;
FftData noise;
EXPECT_DEATH(ComfortNoiseGenerator(DetectOptimization())
- .Compute(AecState(0.f), N2, &noise, nullptr),
+ .Compute(AecState(AudioProcessing::Config::EchoCanceller3{}),
+ N2, &noise, nullptr),
"");
}
@@ -91,7 +93,7 @@
TEST(ComfortNoiseGenerator, CorrectLevel) {
ComfortNoiseGenerator cng(DetectOptimization());
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
std::array<float, kFftLengthBy2Plus1> N2;
N2.fill(1000.f * 1000.f);
diff --git a/webrtc/modules/audio_processing/aec3/echo_remover.cc b/webrtc/modules/audio_processing/aec3/echo_remover.cc
index a67a04e..32ecc73 100644
--- a/webrtc/modules/audio_processing/aec3/echo_remover.cc
+++ b/webrtc/modules/audio_processing/aec3/echo_remover.cc
@@ -72,6 +72,7 @@
private:
static int instance_count_;
+ const AudioProcessing::Config::EchoCanceller3 config_;
const Aec3Fft fft_;
std::unique_ptr<ApmDataDumper> data_dumper_;
const Aec3Optimization optimization_;
@@ -95,16 +96,18 @@
EchoRemoverImpl::EchoRemoverImpl(
const AudioProcessing::Config::EchoCanceller3& config,
int sample_rate_hz)
- : fft_(),
+ : config_(config),
+ fft_(),
data_dumper_(
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
optimization_(DetectOptimization()),
sample_rate_hz_(sample_rate_hz),
subtractor_(data_dumper_.get(), optimization_),
- suppression_gain_(optimization_),
+ suppression_gain_(config_, optimization_),
cng_(optimization_),
suppression_filter_(sample_rate_hz_),
- aec_state_(0.8f) {
+ residual_echo_estimator_(config_),
+ aec_state_(config_) {
RTC_DCHECK(ValidFullBandRate(sample_rate_hz));
}
diff --git a/webrtc/modules/audio_processing/aec3/echo_remover_metrics_unittest.cc b/webrtc/modules/audio_processing/aec3/echo_remover_metrics_unittest.cc
index 21a5af2..094508e 100644
--- a/webrtc/modules/audio_processing/aec3/echo_remover_metrics_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/echo_remover_metrics_unittest.cc
@@ -126,7 +126,7 @@
// Verify the general functionality of EchoRemoverMetrics.
TEST(EchoRemoverMetrics, NormalUsage) {
EchoRemoverMetrics metrics;
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
std::array<float, kFftLengthBy2Plus1> comfort_noise_spectrum;
std::array<float, kFftLengthBy2Plus1> suppressor_gain;
comfort_noise_spectrum.fill(10.f);
diff --git a/webrtc/modules/audio_processing/aec3/erle_estimator.cc b/webrtc/modules/audio_processing/aec3/erle_estimator.cc
index 8cdaee5..da0e421 100644
--- a/webrtc/modules/audio_processing/aec3/erle_estimator.cc
+++ b/webrtc/modules/audio_processing/aec3/erle_estimator.cc
@@ -16,16 +16,13 @@
namespace webrtc {
-namespace {
-
-constexpr float kMinErle = 1.f;
-constexpr float kMaxLfErle = 8.f;
-constexpr float kMaxHfErle = 1.5f;
-
-} // namespace
-
-ErleEstimator::ErleEstimator() {
- erle_.fill(kMinErle);
+ErleEstimator::ErleEstimator(float min_erle,
+ float max_erle_lf,
+ float max_erle_hf)
+ : min_erle_(min_erle),
+ max_erle_lf_(max_erle_lf),
+ max_erle_hf_(max_erle_hf) {
+ erle_.fill(min_erle_);
hold_counters_.fill(0);
}
@@ -50,19 +47,19 @@
if (new_erle > erle_[k]) {
hold_counters_[k - 1] = 100;
erle_[k] += 0.1f * (new_erle - erle_[k]);
- erle_[k] = rtc::SafeClamp(erle_[k], kMinErle, max_erle);
+ erle_[k] = rtc::SafeClamp(erle_[k], min_erle_, max_erle);
}
}
}
};
- erle_update(1, kFftLengthBy2 / 2, kMaxLfErle);
- erle_update(kFftLengthBy2 / 2, kFftLengthBy2, kMaxHfErle);
+ erle_update(1, kFftLengthBy2 / 2, max_erle_lf_);
+ erle_update(kFftLengthBy2 / 2, kFftLengthBy2, max_erle_hf_);
std::for_each(hold_counters_.begin(), hold_counters_.end(),
[](int& a) { --a; });
std::transform(hold_counters_.begin(), hold_counters_.end(),
- erle_.begin() + 1, erle_.begin() + 1, [](int a, float b) {
- return a > 0 ? b : std::max(kMinErle, 0.97f * b);
+ erle_.begin() + 1, erle_.begin() + 1, [&](int a, float b) {
+ return a > 0 ? b : std::max(min_erle_, 0.97f * b);
});
erle_[0] = erle_[1];
diff --git a/webrtc/modules/audio_processing/aec3/erle_estimator.h b/webrtc/modules/audio_processing/aec3/erle_estimator.h
index 48bb75a..91a8c6c 100644
--- a/webrtc/modules/audio_processing/aec3/erle_estimator.h
+++ b/webrtc/modules/audio_processing/aec3/erle_estimator.h
@@ -21,7 +21,7 @@
// Estimates the echo return loss enhancement based on the signal spectra.
class ErleEstimator {
public:
- ErleEstimator();
+ ErleEstimator(float min_erle, float max_erle_lf, float max_erle_hf);
~ErleEstimator();
// Updates the ERLE estimate.
@@ -35,6 +35,9 @@
private:
std::array<float, kFftLengthBy2Plus1> erle_;
std::array<int, kFftLengthBy2Minus1> hold_counters_;
+ const float min_erle_;
+ const float max_erle_lf_;
+ const float max_erle_hf_;
RTC_DISALLOW_COPY_AND_ASSIGN(ErleEstimator);
};
diff --git a/webrtc/modules/audio_processing/aec3/erle_estimator_unittest.cc b/webrtc/modules/audio_processing/aec3/erle_estimator_unittest.cc
index dc95eee..be435c0 100644
--- a/webrtc/modules/audio_processing/aec3/erle_estimator_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/erle_estimator_unittest.cc
@@ -36,7 +36,7 @@
std::array<float, kFftLengthBy2Plus1> E2;
std::array<float, kFftLengthBy2Plus1> Y2;
- ErleEstimator estimator;
+ ErleEstimator estimator(1.f, 8.f, 1.5f);
// Verifies that the ERLE estimate is properley increased to higher values.
X2.fill(500 * 1000.f * 1000.f);
diff --git a/webrtc/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc b/webrtc/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
index 6e8a80b..cbd62b5 100644
--- a/webrtc/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
@@ -53,7 +53,7 @@
Random random_generator(42U);
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> y(kBlockSize, 0.f);
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
RenderSignalAnalyzer render_signal_analyzer;
std::array<float, kFftLength> s_scratch;
std::array<float, kBlockSize> s;
diff --git a/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
index c708664..0dfec66 100644
--- a/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
+++ b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc
@@ -79,7 +79,9 @@
} // namespace
-ResidualEchoEstimator::ResidualEchoEstimator() {
+ResidualEchoEstimator::ResidualEchoEstimator(
+ const AudioProcessing::Config::EchoCanceller3& config)
+ : config_(config) {
Reset();
}
@@ -188,11 +190,12 @@
const std::array<float, kFftLengthBy2Plus1>& Y2,
std::array<float, kFftLengthBy2Plus1>* R2) {
// Choose gains.
- const float echo_path_gain_lf = headset_detected ? kHeadsetEchoPathGain : 100;
+ const float echo_path_gain_lf =
+ headset_detected ? kHeadsetEchoPathGain : config_.param.ep_strength.lf;
const float echo_path_gain_mf =
- headset_detected ? kHeadsetEchoPathGain : 1000;
+ headset_detected ? kHeadsetEchoPathGain : config_.param.ep_strength.mf;
const float echo_path_gain_hf =
- headset_detected ? kHeadsetEchoPathGain : 5000;
+ headset_detected ? kHeadsetEchoPathGain : config_.param.ep_strength.hf;
// Compute preliminary residual echo.
std::transform(
diff --git a/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h
index e9370ba..5d2835d 100644
--- a/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h
+++ b/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h
@@ -18,6 +18,7 @@
#include "webrtc/modules/audio_processing/aec3/aec3_common.h"
#include "webrtc/modules/audio_processing/aec3/aec_state.h"
#include "webrtc/modules/audio_processing/aec3/render_buffer.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/rtc_base/array_view.h"
#include "webrtc/rtc_base/constructormagic.h"
@@ -25,7 +26,8 @@
class ResidualEchoEstimator {
public:
- ResidualEchoEstimator();
+ explicit ResidualEchoEstimator(
+ const AudioProcessing::Config::EchoCanceller3& config);
~ResidualEchoEstimator();
void Estimate(bool using_subtractor_output,
@@ -69,8 +71,9 @@
S2_old_;
std::array<float, kFftLengthBy2Plus1> X2_noise_floor_;
std::array<int, kFftLengthBy2Plus1> X2_noise_floor_counter_;
+ const AudioProcessing::Config::EchoCanceller3 config_;
- RTC_DISALLOW_COPY_AND_ASSIGN(ResidualEchoEstimator);
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ResidualEchoEstimator);
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc b/webrtc/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
index b448c4d..6abb155 100644
--- a/webrtc/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
@@ -12,6 +12,7 @@
#include "webrtc/modules/audio_processing/aec3/aec3_fft.h"
#include "webrtc/modules/audio_processing/aec3/aec_state.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/audio_processing/test/echo_canceller_test_tools.h"
#include "webrtc/rtc_base/random.h"
#include "webrtc/test/gtest.h"
@@ -22,22 +23,25 @@
// Verifies that the check for non-null output residual echo power works.
TEST(ResidualEchoEstimator, NullResidualEchoPowerOutput) {
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 10,
std::vector<size_t>(1, 10));
std::vector<std::array<float, kFftLengthBy2Plus1>> H2;
std::array<float, kFftLengthBy2Plus1> S2_linear;
std::array<float, kFftLengthBy2Plus1> Y2;
- EXPECT_DEATH(ResidualEchoEstimator().Estimate(true, aec_state, render_buffer,
- S2_linear, Y2, nullptr),
- "");
+ EXPECT_DEATH(
+ ResidualEchoEstimator(AudioProcessing::Config::EchoCanceller3{})
+ .Estimate(true, aec_state, render_buffer, S2_linear, Y2, nullptr),
+ "");
}
#endif
TEST(ResidualEchoEstimator, BasicTest) {
- ResidualEchoEstimator estimator;
- AecState aec_state(0.f);
+ ResidualEchoEstimator estimator(AudioProcessing::Config::EchoCanceller3{});
+ AudioProcessing::Config::EchoCanceller3 config;
+ config.param.ep_strength.default_len = 0.f;
+ AecState aec_state(config);
RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 10,
std::vector<size_t>(1, 10));
std::array<float, kFftLengthBy2Plus1> E2_main;
diff --git a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
index 1ceb634..99e3f25 100644
--- a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
@@ -47,7 +47,7 @@
Random random_generator(42U);
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> y(kBlockSize, 0.f);
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
RenderSignalAnalyzer render_signal_analyzer;
std::array<float, kFftLength> s;
FftData S;
diff --git a/webrtc/modules/audio_processing/aec3/subtractor_unittest.cc b/webrtc/modules/audio_processing/aec3/subtractor_unittest.cc
index 32fc054..07b1213 100644
--- a/webrtc/modules/audio_processing/aec3/subtractor_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/subtractor_unittest.cc
@@ -40,7 +40,7 @@
std::array<float, kFftLengthBy2Plus1> Y2;
std::array<float, kFftLengthBy2Plus1> E2_main;
std::array<float, kFftLengthBy2Plus1> E2_shadow;
- AecState aec_state(0.f);
+ AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
x_old.fill(0.f);
Y2.fill(0.f);
E2_main.fill(0.f);
@@ -109,9 +109,11 @@
RenderSignalAnalyzer render_signal_analyzer;
std::vector<float> y(kBlockSize, 0.f);
- EXPECT_DEATH(subtractor.Process(render_buffer, y, render_signal_analyzer,
- AecState(0.f), nullptr),
- "");
+ EXPECT_DEATH(
+ subtractor.Process(render_buffer, y, render_signal_analyzer,
+ AecState(AudioProcessing::Config::EchoCanceller3{}),
+ nullptr),
+ "");
}
// Verifies the check for the capture signal size.
@@ -124,9 +126,11 @@
std::vector<float> y(kBlockSize - 1, 0.f);
SubtractorOutput output;
- EXPECT_DEATH(subtractor.Process(render_buffer, y, render_signal_analyzer,
- AecState(0.f), &output),
- "");
+ EXPECT_DEATH(
+ subtractor.Process(render_buffer, y, render_signal_analyzer,
+ AecState(AudioProcessing::Config::EchoCanceller3{}),
+ &output),
+ "");
}
#endif
diff --git a/webrtc/modules/audio_processing/aec3/suppression_gain.cc b/webrtc/modules/audio_processing/aec3/suppression_gain.cc
index a25f748..8e78967 100644
--- a/webrtc/modules/audio_processing/aec3/suppression_gain.cc
+++ b/webrtc/modules/audio_processing/aec3/suppression_gain.cc
@@ -109,6 +109,7 @@
// Limits the gain increase.
void UpdateMaxGainIncrease(
+ const AudioProcessing::Config::EchoCanceller3& config,
size_t no_saturation_counter,
bool low_noise_render,
const std::array<float, kFftLengthBy2Plus1>& last_echo,
@@ -123,27 +124,28 @@
float min_increasing;
float min_decreasing;
+ auto& param = config.param.gain_updates;
if (low_noise_render) {
- max_increasing = 8.f;
- max_decreasing = 8.f;
- rate_increasing = 2.f;
- rate_decreasing = 2.f;
- min_increasing = 4.f;
- min_decreasing = 4.f;
+ max_increasing = param.low_noise.max_inc;
+ max_decreasing = param.low_noise.max_dec;
+ rate_increasing = param.low_noise.rate_inc;
+ rate_decreasing = param.low_noise.rate_dec;
+ min_increasing = param.low_noise.min_inc;
+ min_decreasing = param.low_noise.min_dec;
} else if (no_saturation_counter > 10) {
- max_increasing = 4.f;
- max_decreasing = 4.f;
- rate_increasing = 2.f;
- rate_decreasing = 2.f;
- min_increasing = 1.2f;
- min_decreasing = 2.f;
+ max_increasing = param.normal.max_inc;
+ max_decreasing = param.normal.max_dec;
+ rate_increasing = param.normal.rate_inc;
+ rate_decreasing = param.normal.rate_dec;
+ min_increasing = param.normal.min_inc;
+ min_decreasing = param.normal.min_dec;
} else {
- max_increasing = 1.2f;
- max_decreasing = 1.2f;
- rate_increasing = 1.5f;
- rate_decreasing = 1.5f;
- min_increasing = 1.f;
- min_decreasing = 1.f;
+ max_increasing = param.saturation.max_inc;
+ max_decreasing = param.saturation.max_dec;
+ rate_increasing = param.saturation.rate_inc;
+ rate_decreasing = param.saturation.rate_dec;
+ min_increasing = param.saturation.min_inc;
+ min_decreasing = param.saturation.min_dec;
}
for (size_t k = 0; k < new_gain.size(); ++k) {
@@ -163,6 +165,7 @@
// Computes the gain to reduce the echo to a non audible level.
void GainToNoAudibleEcho(
+ const AudioProcessing::Config::EchoCanceller3& config,
bool low_noise_render,
bool saturated_echo,
const std::array<float, kFftLengthBy2Plus1>& nearend,
@@ -172,16 +175,17 @@
const std::array<float, kFftLengthBy2Plus1>& max_gain,
const std::array<float, kFftLengthBy2Plus1>& one_by_echo,
std::array<float, kFftLengthBy2Plus1>* gain) {
- constexpr float kEchoMaskingMargin = 1.f / 100.f;
const float nearend_masking_margin =
- low_noise_render ? 0.1f : (saturated_echo ? 0.001f : 0.01f);
+ low_noise_render ? 0.1f
+ : (saturated_echo ? config.param.gain_mask.m2
+ : config.param.gain_mask.m3);
for (size_t k = 0; k < gain->size(); ++k) {
RTC_DCHECK_LE(0.f, nearend_masking_margin * nearend[k]);
if (echo[k] <= nearend_masking_margin * nearend[k]) {
(*gain)[k] = 1.f;
} else {
- (*gain)[k] = kEchoMaskingMargin * masker[k] * one_by_echo[k];
+ (*gain)[k] = config.param.gain_mask.m1 * masker[k] * one_by_echo[k];
}
(*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]);
@@ -189,7 +193,8 @@
}
// Computes the signal output power that masks the echo signal.
-void MaskingPower(const std::array<float, kFftLengthBy2Plus1>& nearend,
+void MaskingPower(const AudioProcessing::Config::EchoCanceller3& config,
+ const std::array<float, kFftLengthBy2Plus1>& nearend,
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
const std::array<float, kFftLengthBy2Plus1>& last_masker,
const std::array<float, kFftLengthBy2Plus1>& gain,
@@ -197,7 +202,8 @@
std::array<float, kFftLengthBy2Plus1> side_band_masker;
for (size_t k = 0; k < gain.size(); ++k) {
side_band_masker[k] = nearend[k] * gain[k] + comfort_noise[k];
- (*masker)[k] = comfort_noise[k] + 0.1f * last_masker[k];
+ (*masker)[k] =
+ comfort_noise[k] + config.param.gain_mask.m4 * last_masker[k];
}
for (size_t k = 1; k < gain.size() - 1; ++k) {
(*masker)[k] += 0.1f * (side_band_masker[k - 1] + side_band_masker[k + 1]);
@@ -227,7 +233,9 @@
// Compute the minimum gain as the attenuating gain to put the signal just
// above the zero sample values.
std::array<float, kFftLengthBy2Plus1> min_gain;
- const float min_echo_power = low_noise_render ? 192.f : 64.f;
+ const float min_echo_power =
+ low_noise_render ? config_.param.echo_audibility.low_render_limit
+ : config_.param.echo_audibility.normal_render_limit;
if (no_saturation_counter_ > 10) {
for (size_t k = 0; k < nearend.size(); ++k) {
const float denom = std::min(nearend[k], echo[k]);
@@ -243,7 +251,9 @@
std::array<float, kFftLengthBy2Plus1> max_gain;
for (size_t k = 0; k < gain->size(); ++k) {
max_gain[k] =
- std::min(std::max(last_gain_[k] * gain_increase_[k], 0.001f), 1.f);
+ std::min(std::max(last_gain_[k] * gain_increase_[k],
+ config_.param.gain_updates.floor_first_increase),
+ 1.f);
}
// Iteratively compute the gain required to attenuate the echo to a non
@@ -251,9 +261,9 @@
gain->fill(0.f);
for (int k = 0; k < 2; ++k) {
std::array<float, kFftLengthBy2Plus1> masker;
- MaskingPower(nearend, comfort_noise, last_masker_, *gain, &masker);
- GainToNoAudibleEcho(low_noise_render, saturated_echo, nearend, echo, masker,
- min_gain, max_gain, one_by_echo, gain);
+ MaskingPower(config_, nearend, comfort_noise, last_masker_, *gain, &masker);
+ GainToNoAudibleEcho(config_, low_noise_render, saturated_echo, nearend,
+ echo, masker, min_gain, max_gain, one_by_echo, gain);
AdjustForExternalFilters(gain);
if (narrow_peak_band) {
NarrowBandAttenuation(*narrow_peak_band, gain);
@@ -261,18 +271,21 @@
}
// Update the allowed maximum gain increase.
- UpdateMaxGainIncrease(no_saturation_counter_, low_noise_render, last_echo_,
- echo, last_gain_, *gain, &gain_increase_);
+ UpdateMaxGainIncrease(config_, no_saturation_counter_, low_noise_render,
+ last_echo_, echo, last_gain_, *gain, &gain_increase_);
// Store data required for the gain computation of the next block.
std::copy(echo.begin(), echo.end(), last_echo_.begin());
std::copy(gain->begin(), gain->end(), last_gain_.begin());
- MaskingPower(nearend, comfort_noise, last_masker_, *gain, &last_masker_);
+ MaskingPower(config_, nearend, comfort_noise, last_masker_, *gain,
+ &last_masker_);
aec3::VectorMath(optimization_).Sqrt(*gain);
}
-SuppressionGain::SuppressionGain(Aec3Optimization optimization)
- : optimization_(optimization) {
+SuppressionGain::SuppressionGain(
+ const AudioProcessing::Config::EchoCanceller3& config,
+ Aec3Optimization optimization)
+ : optimization_(optimization), config_(config) {
last_gain_.fill(1.f);
last_masker_.fill(0.f);
gain_increase_.fill(1.f);
diff --git a/webrtc/modules/audio_processing/aec3/suppression_gain.h b/webrtc/modules/audio_processing/aec3/suppression_gain.h
index d22eb8a..2d618c3 100644
--- a/webrtc/modules/audio_processing/aec3/suppression_gain.h
+++ b/webrtc/modules/audio_processing/aec3/suppression_gain.h
@@ -16,13 +16,15 @@
#include "webrtc/modules/audio_processing/aec3/aec3_common.h"
#include "webrtc/modules/audio_processing/aec3/render_signal_analyzer.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/rtc_base/constructormagic.h"
namespace webrtc {
class SuppressionGain {
public:
- explicit SuppressionGain(Aec3Optimization optimization);
+ SuppressionGain(const AudioProcessing::Config::EchoCanceller3& config,
+ Aec3Optimization optimization);
void GetGain(const std::array<float, kFftLengthBy2Plus1>& nearend,
const std::array<float, kFftLengthBy2Plus1>& echo,
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
@@ -58,7 +60,8 @@
LowNoiseRenderDetector low_render_detector_;
size_t no_saturation_counter_ = 0;
- RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SuppressionGain);
+ const AudioProcessing::Config::EchoCanceller3 config_;
+ RTC_DISALLOW_COPY_AND_ASSIGN(SuppressionGain);
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/aec3/suppression_gain_unittest.cc b/webrtc/modules/audio_processing/aec3/suppression_gain_unittest.cc
index 61238d9..cde3c94 100644
--- a/webrtc/modules/audio_processing/aec3/suppression_gain_unittest.cc
+++ b/webrtc/modules/audio_processing/aec3/suppression_gain_unittest.cc
@@ -29,7 +29,8 @@
R2.fill(0.f);
N2.fill(0.f);
float high_bands_gain;
- EXPECT_DEATH(SuppressionGain(DetectOptimization())
+ EXPECT_DEATH(SuppressionGain(AudioProcessing::Config::EchoCanceller3{},
+ DetectOptimization())
.GetGain(E2, R2, N2, RenderSignalAnalyzer(), false,
std::vector<std::vector<float>>(
3, std::vector<float>(kBlockSize, 0.f)),
@@ -41,7 +42,8 @@
// Does a sanity check that the gains are correctly computed.
TEST(SuppressionGain, BasicGainComputation) {
- SuppressionGain suppression_gain(DetectOptimization());
+ SuppressionGain suppression_gain(AudioProcessing::Config::EchoCanceller3(),
+ DetectOptimization());
RenderSignalAnalyzer analyzer;
float high_bands_gain;
std::array<float, kFftLengthBy2Plus1> E2;
diff --git a/webrtc/modules/audio_processing/include/audio_processing.h b/webrtc/modules/audio_processing/include/audio_processing.h
index 0a09517..de77bac 100644
--- a/webrtc/modules/audio_processing/include/audio_processing.h
+++ b/webrtc/modules/audio_processing/include/audio_processing.h
@@ -17,6 +17,7 @@
#include <math.h>
#include <stddef.h> // size_t
#include <stdio.h> // FILE
+#include <string.h>
#include <vector>
#include "webrtc/modules/audio_processing/beamformer/array_util.h"
@@ -267,6 +268,49 @@
// The functionality is not yet activated in the code and turning this on
// does not yet have the desired behavior.
struct EchoCanceller3 {
+ struct Param {
+ struct Erle {
+ float min = 1.f;
+ float max_l = 8.f;
+ float max_h = 1.5f;
+ } erle;
+
+ struct EpStrength {
+ float lf = 100.f;
+ float mf = 1000.f;
+ float hf = 5000.f;
+ float default_len = 0.7f;
+ } ep_strength;
+
+ struct Mask {
+ float m1 = 0.01f;
+ float m2 = 0.001f;
+ float m3 = 0.01f;
+ float m4 = 0.1f;
+ } gain_mask;
+
+ struct EchoAudibility {
+ float low_render_limit = 192.f;
+ float normal_render_limit = 64.f;
+ } echo_audibility;
+
+ struct GainUpdates {
+ struct GainChanges {
+ float max_inc;
+ float max_dec;
+ float rate_inc;
+ float rate_dec;
+ float min_inc;
+ float min_dec;
+ };
+
+ GainChanges low_noise = {8.f, 8.f, 2.f, 2.f, 4.f, 4.f};
+ GainChanges normal = {4.f, 4.f, 2.f, 2.f, 1.2f, 2.f};
+ GainChanges saturation = {1.2f, 1.2f, 1.5f, 1.5f, 1.f, 1.f};
+
+ float floor_first_increase = 0.001f;
+ } gain_updates;
+ } param;
bool enabled = false;
} echo_canceller3;
@@ -277,6 +321,17 @@
struct GainController2 {
bool enabled = false;
} gain_controller2;
+
+ // Explicit copy assignment implementation to avoid issues with memory
+ // sanitizer complaints in case of self-assignment.
+ // TODO(peah): Add buildflag to ensure that this is only included for memory
+ // sanitizer builds.
+ Config& operator=(const Config& config) {
+ if (this != &config) {
+ memcpy(this, &config, sizeof(*this));
+ }
+ return *this;
+ }
};
// TODO(mgraczyk): Remove once all methods that use ChannelLayout are gone.