Added the ability to adjust the filter adaptation speed in AEC3
Bug: webrtc:8609 Change-Id: I90eac3948ad0b7b1b5df2585ace3783e950c05d5 Reviewed-on: https://webrtc-review.googlesource.com/31485 Commit-Queue: Per Åhgren <peah@webrtc.org> Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21217}
This commit is contained in:
parent
09a718accd
commit
477f289779
@ -316,7 +316,8 @@ TEST(AdaptiveFirFilter, FilterAndAdapt) {
|
||||
config.delay.default_delay = 1;
|
||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||
RenderDelayBuffer::Create(config, 3));
|
||||
ShadowFilterUpdateGain gain;
|
||||
ShadowFilterUpdateGain gain(config.filter.shadow_rate,
|
||||
config.filter.shadow_noise_gate);
|
||||
Random random_generator(42U);
|
||||
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
|
||||
std::vector<float> n(kBlockSize, 0.f);
|
||||
|
||||
@ -28,9 +28,14 @@ constexpr int kPoorExcitationCounterInitial = 1000;
|
||||
|
||||
int MainFilterUpdateGain::instance_count_ = 0;
|
||||
|
||||
MainFilterUpdateGain::MainFilterUpdateGain()
|
||||
MainFilterUpdateGain::MainFilterUpdateGain(float leakage_converged,
|
||||
float leakage_diverged,
|
||||
float noise_gate_power)
|
||||
: data_dumper_(
|
||||
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
|
||||
leakage_converged_(leakage_converged),
|
||||
leakage_diverged_(leakage_diverged),
|
||||
noise_gate_power_(noise_gate_power),
|
||||
poor_excitation_counter_(kPoorExcitationCounterInitial) {
|
||||
H_error_.fill(kHErrorInitial);
|
||||
}
|
||||
@ -75,11 +80,10 @@ void MainFilterUpdateGain::Compute(
|
||||
G->im.fill(0.f);
|
||||
} else {
|
||||
// Corresponds to WGN of power -39 dBFS.
|
||||
constexpr float kNoiseGatePower = 220075344.f;
|
||||
std::array<float, kFftLengthBy2Plus1> mu;
|
||||
// mu = H_error / (0.5* H_error* X2 + n * E2).
|
||||
for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) {
|
||||
mu[k] = X2[k] > kNoiseGatePower
|
||||
mu[k] = X2[k] > noise_gate_power_
|
||||
? H_error_[k] / (0.5f * H_error_[k] * X2[k] +
|
||||
size_partitions * E2_main[k])
|
||||
: 0.f;
|
||||
@ -102,11 +106,9 @@ void MainFilterUpdateGain::Compute(
|
||||
|
||||
// H_error = H_error + factor * erl.
|
||||
std::array<float, kFftLengthBy2Plus1> H_error_increase;
|
||||
constexpr float kErlScaleAccurate = 1.f / 100.0f;
|
||||
constexpr float kErlScaleInaccurate = 1.f / 60.0f;
|
||||
std::transform(E2_shadow.begin(), E2_shadow.end(), E2_main.begin(),
|
||||
H_error_increase.begin(), [&](float a, float b) {
|
||||
return a >= b ? kErlScaleAccurate : kErlScaleInaccurate;
|
||||
return a >= b ? leakage_converged_ : leakage_diverged_;
|
||||
});
|
||||
std::transform(erl.begin(), erl.end(), H_error_increase.begin(),
|
||||
H_error_increase.begin(), std::multiplies<float>());
|
||||
|
||||
@ -28,7 +28,9 @@ class ApmDataDumper;
|
||||
// Provides functionality for computing the adaptive gain for the main filter.
|
||||
class MainFilterUpdateGain {
|
||||
public:
|
||||
MainFilterUpdateGain();
|
||||
MainFilterUpdateGain(float leakage_converged,
|
||||
float leakage_diverged,
|
||||
float noise_gate_power);
|
||||
~MainFilterUpdateGain();
|
||||
|
||||
// Takes action in the case of a known echo path change.
|
||||
@ -45,6 +47,9 @@ class MainFilterUpdateGain {
|
||||
private:
|
||||
static int instance_count_;
|
||||
std::unique_ptr<ApmDataDumper> data_dumper_;
|
||||
const float leakage_converged_;
|
||||
const float leakage_diverged_;
|
||||
const float noise_gate_power_;
|
||||
std::array<float, kFftLengthBy2Plus1> H_error_;
|
||||
size_t poor_excitation_counter_;
|
||||
size_t call_counter_ = 0;
|
||||
|
||||
@ -50,8 +50,11 @@ void RunFilterUpdateTest(int num_blocks_to_process,
|
||||
Aec3Fft fft;
|
||||
std::array<float, kBlockSize> x_old;
|
||||
x_old.fill(0.f);
|
||||
ShadowFilterUpdateGain shadow_gain;
|
||||
MainFilterUpdateGain main_gain;
|
||||
ShadowFilterUpdateGain shadow_gain(config.filter.shadow_rate,
|
||||
config.filter.shadow_noise_gate);
|
||||
MainFilterUpdateGain main_gain(config.filter.leakage_converged,
|
||||
config.filter.leakage_diverged,
|
||||
config.filter.main_noise_gate);
|
||||
Random random_generator(42U);
|
||||
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
|
||||
std::vector<float> y(kBlockSize, 0.f);
|
||||
@ -190,7 +193,9 @@ TEST(MainFilterUpdateGain, NullDataOutputGain) {
|
||||
RenderDelayBuffer::Create(config, 3));
|
||||
RenderSignalAnalyzer analyzer;
|
||||
SubtractorOutput output;
|
||||
MainFilterUpdateGain gain;
|
||||
MainFilterUpdateGain gain(config.filter.leakage_converged,
|
||||
config.filter.leakage_diverged,
|
||||
config.filter.main_noise_gate);
|
||||
EXPECT_DEATH(gain.Compute(*render_delay_buffer->GetRenderBuffer(), analyzer,
|
||||
output, filter, false, nullptr),
|
||||
"");
|
||||
|
||||
@ -17,6 +17,10 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ShadowFilterUpdateGain::ShadowFilterUpdateGain(float rate,
|
||||
float noise_gate_power)
|
||||
: rate_(rate), noise_gate_power_(noise_gate_power) {}
|
||||
|
||||
void ShadowFilterUpdateGain::HandleEchoPathChange() {
|
||||
// TODO(peah): Check whether this counter should instead be initialized to a
|
||||
// large value.
|
||||
@ -47,13 +51,10 @@ void ShadowFilterUpdateGain::Compute(
|
||||
}
|
||||
|
||||
// Compute mu.
|
||||
// Corresponds to WGN of power -39 dBFS.
|
||||
constexpr float kNoiseGatePower = 220075344.f;
|
||||
constexpr float kMuFixed = .5f;
|
||||
std::array<float, kFftLengthBy2Plus1> mu;
|
||||
auto X2 = render_buffer.SpectralSum(size_partitions);
|
||||
std::transform(X2.begin(), X2.end(), mu.begin(), [&](float a) {
|
||||
return a > kNoiseGatePower ? kMuFixed / a : 0.f;
|
||||
return a > noise_gate_power_ ? rate_ / a : 0.f;
|
||||
});
|
||||
|
||||
// Avoid updating the filter close to narrow bands in the render signals.
|
||||
|
||||
@ -21,6 +21,8 @@ namespace webrtc {
|
||||
// Provides functionality for computing the fixed gain for the shadow filter.
|
||||
class ShadowFilterUpdateGain {
|
||||
public:
|
||||
ShadowFilterUpdateGain(float rate, float noise_gate_power);
|
||||
|
||||
// Takes action in the case of a known echo path change.
|
||||
void HandleEchoPathChange();
|
||||
|
||||
@ -33,6 +35,8 @@ class ShadowFilterUpdateGain {
|
||||
FftData* G);
|
||||
|
||||
private:
|
||||
const float rate_;
|
||||
const float noise_gate_power_;
|
||||
// TODO(peah): Check whether this counter should instead be initialized to a
|
||||
// large value.
|
||||
size_t poor_signal_excitation_counter_ = 0;
|
||||
|
||||
@ -52,7 +52,8 @@ void RunFilterUpdateTest(int num_blocks_to_process,
|
||||
|
||||
std::array<float, kBlockSize> x_old;
|
||||
x_old.fill(0.f);
|
||||
ShadowFilterUpdateGain shadow_gain;
|
||||
ShadowFilterUpdateGain shadow_gain(config.filter.shadow_rate,
|
||||
config.filter.shadow_noise_gate);
|
||||
Random random_generator(42U);
|
||||
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
|
||||
std::vector<float> y(kBlockSize, 0.f);
|
||||
@ -134,7 +135,7 @@ TEST(ShadowFilterUpdateGain, NullDataOutputGain) {
|
||||
RenderBuffer render_buffer(1, &block_buffer, &spectrum_buffer, &fft_buffer);
|
||||
RenderSignalAnalyzer analyzer;
|
||||
FftData E;
|
||||
ShadowFilterUpdateGain gain;
|
||||
ShadowFilterUpdateGain gain(0.5f, 220075344.f);
|
||||
EXPECT_DEATH(gain.Compute(render_buffer, analyzer, E, 1, false, nullptr), "");
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,11 @@ Subtractor::Subtractor(const EchoCanceller3Config& config,
|
||||
data_dumper_(data_dumper),
|
||||
optimization_(optimization),
|
||||
main_filter_(config.filter.length_blocks, optimization, data_dumper_),
|
||||
shadow_filter_(config.filter.length_blocks, optimization, data_dumper_) {
|
||||
shadow_filter_(config.filter.length_blocks, optimization, data_dumper_),
|
||||
G_main_(config.filter.leakage_converged,
|
||||
config.filter.leakage_diverged,
|
||||
config.filter.main_noise_gate),
|
||||
G_shadow_(config.filter.shadow_rate, config.filter.shadow_noise_gate) {
|
||||
RTC_DCHECK(data_dumper_);
|
||||
}
|
||||
|
||||
|
||||
@ -1160,6 +1160,11 @@ struct EchoCanceller3Config {
|
||||
|
||||
struct Filter {
|
||||
size_t length_blocks = 12;
|
||||
float shadow_rate = 0.5f;
|
||||
float leakage_converged = 0.01f;
|
||||
float leakage_diverged = 1.f / 60.f;
|
||||
float main_noise_gate = 220075344.f;
|
||||
float shadow_noise_gate = 220075344.f;
|
||||
} filter;
|
||||
|
||||
struct Erle {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user