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:
@ -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);
|
||||
|
||||
@ -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_);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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), "");
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user