Simplified the gain methods for the shadow and main filters in AEC3

Bug: webrtc:8671
Change-Id: I21ef41e7e0f3714bfcdacbebae9c713dc2431f55
Reviewed-on: https://webrtc-review.googlesource.com/39504
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Commit-Queue: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21618}
This commit is contained in:
Per Åhgren
2018-01-15 09:11:29 +01:00
committed by Commit Bot
parent 08ea5898ff
commit afd1d6c709
8 changed files with 29 additions and 44 deletions

View File

@ -314,8 +314,7 @@ TEST(AdaptiveFirFilter, FilterAndAdapt) {
config.delay.default_delay = 1;
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
RenderDelayBuffer::Create(config, 3));
ShadowFilterUpdateGain gain(config.filter.shadow.rate,
config.filter.shadow.noise_gate);
ShadowFilterUpdateGain gain(config.filter.shadow);
Random random_generator(42U);
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> n(kBlockSize, 0.f);

View File

@ -28,16 +28,11 @@ constexpr int kPoorExcitationCounterInitial = 1000;
int MainFilterUpdateGain::instance_count_ = 0;
MainFilterUpdateGain::MainFilterUpdateGain(float leakage_converged,
float leakage_diverged,
float noise_gate_power,
float error_floor)
MainFilterUpdateGain::MainFilterUpdateGain(
const EchoCanceller3Config::Filter::MainConfiguration& config)
: data_dumper_(
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
leakage_converged_(leakage_converged),
leakage_diverged_(leakage_diverged),
noise_gate_power_(noise_gate_power),
error_floor_(error_floor),
config_(config),
poor_excitation_counter_(kPoorExcitationCounterInitial) {
H_error_.fill(kHErrorInitial);
}
@ -85,7 +80,7 @@ void MainFilterUpdateGain::Compute(
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] > noise_gate_power_
mu[k] = X2[k] > config_.noise_gate
? H_error_[k] / (0.5f * H_error_[k] * X2[k] +
size_partitions * E2_main[k])
: 0.f;
@ -110,13 +105,14 @@ void MainFilterUpdateGain::Compute(
std::array<float, kFftLengthBy2Plus1> H_error_increase;
std::transform(E2_shadow.begin(), E2_shadow.end(), E2_main.begin(),
H_error_increase.begin(), [&](float a, float b) {
return a >= b ? leakage_converged_ : leakage_diverged_;
return a >= b ? config_.leakage_converged
: config_.leakage_diverged;
});
std::transform(erl.begin(), erl.end(), H_error_increase.begin(),
H_error_increase.begin(), std::multiplies<float>());
std::transform(H_error_.begin(), H_error_.end(), H_error_increase.begin(),
H_error_.begin(), [&](float a, float b) {
return std::max(a + b, error_floor_);
return std::max(a + b, config_.error_floor);
});
data_dumper_->DumpRaw("aec3_main_gain_H_error", H_error_);

View File

@ -19,6 +19,7 @@ spect *
#include "modules/audio_processing/aec3/echo_path_variability.h"
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
#include "modules/audio_processing/aec3/subtractor_output.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructormagic.h"
namespace webrtc {
@ -28,10 +29,8 @@ class ApmDataDumper;
// Provides functionality for computing the adaptive gain for the main filter.
class MainFilterUpdateGain {
public:
MainFilterUpdateGain(float leakage_converged,
float leakage_diverged,
float noise_gate_power,
float error_floor);
explicit MainFilterUpdateGain(
const EchoCanceller3Config::Filter::MainConfiguration& config);
~MainFilterUpdateGain();
// Takes action in the case of a known echo path change.
@ -48,10 +47,7 @@ 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_;
const float error_floor_;
const EchoCanceller3Config::Filter::MainConfiguration config_;
std::array<float, kFftLengthBy2Plus1> H_error_;
size_t poor_excitation_counter_;
size_t call_counter_ = 0;

View File

@ -51,11 +51,8 @@ void RunFilterUpdateTest(int num_blocks_to_process,
Aec3Fft fft;
std::array<float, kBlockSize> x_old;
x_old.fill(0.f);
ShadowFilterUpdateGain shadow_gain(config.filter.shadow.rate,
config.filter.shadow.noise_gate);
MainFilterUpdateGain main_gain(
config.filter.main.leakage_converged, config.filter.main.leakage_diverged,
config.filter.main.noise_gate, config.filter.main.error_floor);
ShadowFilterUpdateGain shadow_gain(config.filter.shadow);
MainFilterUpdateGain main_gain(config.filter.main);
Random random_generator(42U);
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> y(kBlockSize, 0.f);
@ -194,9 +191,7 @@ TEST(MainFilterUpdateGain, NullDataOutputGain) {
DetectOptimization(), &data_dumper);
RenderSignalAnalyzer analyzer;
SubtractorOutput output;
MainFilterUpdateGain gain(
config.filter.main.leakage_converged, config.filter.main.leakage_diverged,
config.filter.main.noise_gate, config.filter.main.error_floor);
MainFilterUpdateGain gain(config.filter.main);
std::array<float, kFftLengthBy2Plus1> render_power;
render_power.fill(0.f);
EXPECT_DEATH(

View File

@ -17,9 +17,9 @@
namespace webrtc {
ShadowFilterUpdateGain::ShadowFilterUpdateGain(float rate,
float noise_gate_power)
: rate_(rate), noise_gate_power_(noise_gate_power) {}
ShadowFilterUpdateGain::ShadowFilterUpdateGain(
const EchoCanceller3Config::Filter::ShadowConfiguration& config)
: config_(config) {}
void ShadowFilterUpdateGain::HandleEchoPathChange() {
// TODO(peah): Check whether this counter should instead be initialized to a
@ -54,7 +54,7 @@ void ShadowFilterUpdateGain::Compute(
std::array<float, kFftLengthBy2Plus1> mu;
auto X2 = render_power;
std::transform(X2.begin(), X2.end(), mu.begin(), [&](float a) {
return a > noise_gate_power_ ? rate_ / a : 0.f;
return a > config_.noise_gate ? config_.rate / a : 0.f;
});
// Avoid updating the filter close to narrow bands in the render signals.

View File

@ -14,6 +14,7 @@
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/render_buffer.h"
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructormagic.h"
namespace webrtc {
@ -21,7 +22,8 @@ namespace webrtc {
// Provides functionality for computing the fixed gain for the shadow filter.
class ShadowFilterUpdateGain {
public:
ShadowFilterUpdateGain(float rate, float noise_gate_power);
explicit ShadowFilterUpdateGain(
const EchoCanceller3Config::Filter::ShadowConfiguration& config);
// Takes action in the case of a known echo path change.
void HandleEchoPathChange();
@ -35,8 +37,7 @@ class ShadowFilterUpdateGain {
FftData* G);
private:
const float rate_;
const float noise_gate_power_;
const EchoCanceller3Config::Filter::ShadowConfiguration config_;
// TODO(peah): Check whether this counter should instead be initialized to a
// large value.
size_t poor_signal_excitation_counter_ = 0;

View File

@ -52,8 +52,7 @@ void RunFilterUpdateTest(int num_blocks_to_process,
std::array<float, kBlockSize> x_old;
x_old.fill(0.f);
ShadowFilterUpdateGain shadow_gain(config.filter.shadow.rate,
config.filter.shadow.noise_gate);
ShadowFilterUpdateGain shadow_gain(config.filter.shadow);
Random random_generator(42U);
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
std::vector<float> y(kBlockSize, 0.f);
@ -133,7 +132,9 @@ TEST(ShadowFilterUpdateGain, NullDataOutputGain) {
FftBuffer fft_buffer(1);
RenderSignalAnalyzer analyzer;
FftData E;
ShadowFilterUpdateGain gain(0.5f, 220075344.f);
const EchoCanceller3Config::Filter::ShadowConfiguration& config = {
12, 0.5f, 220075344.f};
ShadowFilterUpdateGain gain(config);
std::array<float, kFftLengthBy2Plus1> render_power;
render_power.fill(0.f);
EXPECT_DEATH(gain.Compute(render_power, analyzer, E, 1, false, nullptr), "");

View File

@ -57,11 +57,8 @@ Subtractor::Subtractor(const EchoCanceller3Config& config,
shadow_filter_(config.filter.shadow.length_blocks,
optimization,
data_dumper_),
G_main_(config.filter.main.leakage_converged,
config.filter.main.leakage_diverged,
config.filter.main.noise_gate,
config.filter.main.error_floor),
G_shadow_(config.filter.shadow.rate, config.filter.shadow.noise_gate) {
G_main_(config.filter.main),
G_shadow_(config.filter.shadow) {
RTC_DCHECK(data_dumper_);
// Currently, the rest of AEC3 requires the main and shadow filter lengths to
// be identical.