AEC3: Removing the coherence computation
This CL removes the unused coherence computation from AEC3. This CL only removes unused code, the output of AEC3 does not change. Bug: webrtc:8671 Change-Id: Ie127c5ec64e29414f1e1570511d57a4d09fc9145 Reviewed-on: https://webrtc-review.googlesource.com/95650 Reviewed-by: Per Åhgren <peah@webrtc.org> Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24403}
This commit is contained in:
committed by
Commit Bot
parent
bc25899363
commit
a73c3b0e07
@ -161,7 +161,6 @@ struct EchoCanceller3Config {
|
||||
} echo_model;
|
||||
|
||||
struct Suppressor {
|
||||
size_t bands_with_reliable_coherence = 5;
|
||||
size_t nearend_average_blocks = 4;
|
||||
|
||||
struct MaskingThresholds {
|
||||
|
||||
@ -30,8 +30,6 @@ rtc_static_library("aec3") {
|
||||
"block_processor_metrics.h",
|
||||
"cascaded_biquad_filter.cc",
|
||||
"cascaded_biquad_filter.h",
|
||||
"coherence_gain.cc",
|
||||
"coherence_gain.h",
|
||||
"comfort_noise_generator.cc",
|
||||
"comfort_noise_generator.h",
|
||||
"decimator.cc",
|
||||
|
||||
@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/aec3/coherence_gain.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Matlab code to produce table:
|
||||
// overDriveCurve = [sqrt(linspace(0,1,65))' + 1];
|
||||
// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', overDriveCurve);
|
||||
const float kOverDriveCurve[kFftLengthBy2Plus1] = {
|
||||
1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, 1.3062f, 1.3307f,
|
||||
1.3536f, 1.3750f, 1.3953f, 1.4146f, 1.4330f, 1.4507f, 1.4677f, 1.4841f,
|
||||
1.5000f, 1.5154f, 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f,
|
||||
1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, 1.6847f, 1.6960f,
|
||||
1.7071f, 1.7181f, 1.7289f, 1.7395f, 1.7500f, 1.7603f, 1.7706f, 1.7806f,
|
||||
1.7906f, 1.8004f, 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f,
|
||||
1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, 1.9186f, 1.9270f,
|
||||
1.9354f, 1.9437f, 1.9520f, 1.9601f, 1.9682f, 1.9763f, 1.9843f, 1.9922f,
|
||||
2.0000f};
|
||||
|
||||
// Matlab code to produce table:
|
||||
// weightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1];
|
||||
// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', weightCurve);
|
||||
const float kWeightCurve[kFftLengthBy2Plus1] = {
|
||||
0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, 0.1845f, 0.1926f,
|
||||
0.2000f, 0.2069f, 0.2134f, 0.2195f, 0.2254f, 0.2309f, 0.2363f, 0.2414f,
|
||||
0.2464f, 0.2512f, 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f,
|
||||
0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, 0.3035f, 0.3070f,
|
||||
0.3104f, 0.3138f, 0.3171f, 0.3204f, 0.3236f, 0.3268f, 0.3299f, 0.3330f,
|
||||
0.3360f, 0.3390f, 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f,
|
||||
0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, 0.3752f, 0.3777f,
|
||||
0.3803f, 0.3828f, 0.3854f, 0.3878f, 0.3903f, 0.3928f, 0.3952f, 0.3976f,
|
||||
0.4000f};
|
||||
|
||||
int CmpFloat(const void* a, const void* b) {
|
||||
const float* da = static_cast<const float*>(a);
|
||||
const float* db = static_cast<const float*>(b);
|
||||
return (*da > *db) - (*da < *db);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CoherenceGain::CoherenceGain(int sample_rate_hz, size_t num_bands_to_compute)
|
||||
: num_bands_to_compute_(num_bands_to_compute),
|
||||
sample_rate_scaler_(sample_rate_hz >= 16000 ? 2 : 1) {
|
||||
spectra_.Cye.Clear();
|
||||
spectra_.Cxy.Clear();
|
||||
spectra_.Pe.fill(0.f);
|
||||
// Initialize to 1 in order to prevent numerical instability in the first
|
||||
// block.
|
||||
spectra_.Py.fill(1.f);
|
||||
spectra_.Px.fill(1.f);
|
||||
}
|
||||
|
||||
CoherenceGain::~CoherenceGain() = default;
|
||||
|
||||
void CoherenceGain::ComputeGain(const FftData& E,
|
||||
const FftData& X,
|
||||
const FftData& Y,
|
||||
rtc::ArrayView<float> gain) {
|
||||
std::array<float, kFftLengthBy2Plus1> coherence_ye;
|
||||
std::array<float, kFftLengthBy2Plus1> coherence_xy;
|
||||
|
||||
UpdateCoherenceSpectra(E, X, Y);
|
||||
ComputeCoherence(coherence_ye, coherence_xy);
|
||||
FormSuppressionGain(coherence_ye, coherence_xy, gain);
|
||||
}
|
||||
|
||||
// Updates the following smoothed Power Spectral Densities (PSD):
|
||||
// - sd : near-end
|
||||
// - se : residual echo
|
||||
// - sx : far-end
|
||||
// - sde : cross-PSD of near-end and residual echo
|
||||
// - sxd : cross-PSD of near-end and far-end
|
||||
//
|
||||
void CoherenceGain::UpdateCoherenceSpectra(const FftData& E,
|
||||
const FftData& X,
|
||||
const FftData& Y) {
|
||||
const float s = sample_rate_scaler_ == 1 ? 0.9f : 0.92f;
|
||||
const float one_minus_s = 1.f - s;
|
||||
auto& c = spectra_;
|
||||
|
||||
for (size_t i = 0; i < c.Py.size(); i++) {
|
||||
c.Py[i] =
|
||||
s * c.Py[i] + one_minus_s * (Y.re[i] * Y.re[i] + Y.im[i] * Y.im[i]);
|
||||
c.Pe[i] =
|
||||
s * c.Pe[i] + one_minus_s * (E.re[i] * E.re[i] + E.im[i] * E.im[i]);
|
||||
// We threshold here to protect against the ill-effects of a zero farend.
|
||||
// The threshold is not arbitrarily chosen, but balances protection and
|
||||
// adverse interaction with the algorithm's tuning.
|
||||
|
||||
// Threshold to protect against the ill-effects of a zero far-end.
|
||||
c.Px[i] =
|
||||
s * c.Px[i] +
|
||||
one_minus_s * std::max(X.re[i] * X.re[i] + X.im[i] * X.im[i], 15.f);
|
||||
|
||||
c.Cye.re[i] =
|
||||
s * c.Cye.re[i] + one_minus_s * (Y.re[i] * E.re[i] + Y.im[i] * E.im[i]);
|
||||
c.Cye.im[i] =
|
||||
s * c.Cye.im[i] + one_minus_s * (Y.re[i] * E.im[i] - Y.im[i] * E.re[i]);
|
||||
|
||||
c.Cxy.re[i] =
|
||||
s * c.Cxy.re[i] + one_minus_s * (Y.re[i] * X.re[i] + Y.im[i] * X.im[i]);
|
||||
c.Cxy.im[i] =
|
||||
s * c.Cxy.im[i] + one_minus_s * (Y.re[i] * X.im[i] - Y.im[i] * X.re[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CoherenceGain::FormSuppressionGain(
|
||||
rtc::ArrayView<const float> coherence_ye,
|
||||
rtc::ArrayView<const float> coherence_xy,
|
||||
rtc::ArrayView<float> gain) {
|
||||
RTC_DCHECK_EQ(kFftLengthBy2Plus1, coherence_ye.size());
|
||||
RTC_DCHECK_EQ(kFftLengthBy2Plus1, coherence_xy.size());
|
||||
RTC_DCHECK_EQ(kFftLengthBy2Plus1, gain.size());
|
||||
constexpr int kPrefBandSize = 24;
|
||||
auto& gs = gain_state_;
|
||||
std::array<float, kPrefBandSize> h_nl_pref;
|
||||
float h_nl_fb = 0;
|
||||
float h_nl_fb_low = 0;
|
||||
const int pref_band_size = kPrefBandSize / sample_rate_scaler_;
|
||||
const int min_pref_band = 4 / sample_rate_scaler_;
|
||||
|
||||
float h_nl_de_avg = 0.f;
|
||||
float h_nl_xd_avg = 0.f;
|
||||
for (int i = min_pref_band; i < pref_band_size + min_pref_band; ++i) {
|
||||
h_nl_xd_avg += coherence_xy[i];
|
||||
h_nl_de_avg += coherence_ye[i];
|
||||
}
|
||||
h_nl_xd_avg /= pref_band_size;
|
||||
h_nl_xd_avg = 1 - h_nl_xd_avg;
|
||||
h_nl_de_avg /= pref_band_size;
|
||||
|
||||
if (h_nl_xd_avg < 0.75f && h_nl_xd_avg < gs.h_nl_xd_avg_min) {
|
||||
gs.h_nl_xd_avg_min = h_nl_xd_avg;
|
||||
}
|
||||
|
||||
if (h_nl_de_avg > 0.98f && h_nl_xd_avg > 0.9f) {
|
||||
gs.near_state = true;
|
||||
} else if (h_nl_de_avg < 0.95f || h_nl_xd_avg < 0.8f) {
|
||||
gs.near_state = false;
|
||||
}
|
||||
|
||||
std::array<float, kFftLengthBy2Plus1> h_nl;
|
||||
if (gs.h_nl_xd_avg_min == 1) {
|
||||
gs.overdrive = 15.f;
|
||||
|
||||
if (gs.near_state) {
|
||||
std::copy(coherence_ye.begin(), coherence_ye.end(), h_nl.begin());
|
||||
h_nl_fb = h_nl_de_avg;
|
||||
h_nl_fb_low = h_nl_de_avg;
|
||||
} else {
|
||||
for (size_t i = 0; i < h_nl.size(); ++i) {
|
||||
h_nl[i] = 1 - coherence_xy[i];
|
||||
h_nl[i] = std::max(h_nl[i], 0.f);
|
||||
}
|
||||
h_nl_fb = h_nl_xd_avg;
|
||||
h_nl_fb_low = h_nl_xd_avg;
|
||||
}
|
||||
} else {
|
||||
if (gs.near_state) {
|
||||
std::copy(coherence_ye.begin(), coherence_ye.end(), h_nl.begin());
|
||||
h_nl_fb = h_nl_de_avg;
|
||||
h_nl_fb_low = h_nl_de_avg;
|
||||
} else {
|
||||
for (size_t i = 0; i < h_nl.size(); ++i) {
|
||||
h_nl[i] = std::min(coherence_ye[i], 1 - coherence_xy[i]);
|
||||
h_nl[i] = std::max(h_nl[i], 0.f);
|
||||
}
|
||||
|
||||
// Select an order statistic from the preferred bands.
|
||||
// TODO(peah): Using quicksort now, but a selection algorithm may be
|
||||
// preferred.
|
||||
std::copy(h_nl.begin() + min_pref_band,
|
||||
h_nl.begin() + min_pref_band + pref_band_size,
|
||||
h_nl_pref.begin());
|
||||
std::qsort(h_nl_pref.data(), pref_band_size, sizeof(float), CmpFloat);
|
||||
|
||||
constexpr float kPrefBandQuant = 0.75f;
|
||||
h_nl_fb = h_nl_pref[static_cast<int>(
|
||||
floor(kPrefBandQuant * (pref_band_size - 1)))];
|
||||
constexpr float kPrefBandQuantLow = 0.5f;
|
||||
h_nl_fb_low = h_nl_pref[static_cast<int>(
|
||||
floor(kPrefBandQuantLow * (pref_band_size - 1)))];
|
||||
}
|
||||
}
|
||||
|
||||
// Track the local filter minimum to determine suppression overdrive.
|
||||
if (h_nl_fb_low < 0.6f && h_nl_fb_low < gs.h_nl_fb_local_min) {
|
||||
gs.h_nl_fb_local_min = h_nl_fb_low;
|
||||
gs.h_nl_fb_min = h_nl_fb_low;
|
||||
gs.h_nl_new_min = 1;
|
||||
gs.h_nl_min_ctr = 0;
|
||||
}
|
||||
gs.h_nl_fb_local_min =
|
||||
std::min(gs.h_nl_fb_local_min + 0.0008f / sample_rate_scaler_, 1.f);
|
||||
gs.h_nl_xd_avg_min =
|
||||
std::min(gs.h_nl_xd_avg_min + 0.0006f / sample_rate_scaler_, 1.f);
|
||||
|
||||
if (gs.h_nl_new_min == 1) {
|
||||
++gs.h_nl_min_ctr;
|
||||
}
|
||||
if (gs.h_nl_min_ctr == 2) {
|
||||
gs.h_nl_new_min = 0;
|
||||
gs.h_nl_min_ctr = 0;
|
||||
constexpr float epsilon = 1e-10f;
|
||||
gs.overdrive = std::max(
|
||||
-18.4f / static_cast<float>(log(gs.h_nl_fb_min + epsilon) + epsilon),
|
||||
15.f);
|
||||
}
|
||||
|
||||
// Smooth the overdrive.
|
||||
if (gs.overdrive < gs.overdrive_scaling) {
|
||||
gs.overdrive_scaling = 0.99f * gs.overdrive_scaling + 0.01f * gs.overdrive;
|
||||
} else {
|
||||
gs.overdrive_scaling = 0.9f * gs.overdrive_scaling + 0.1f * gs.overdrive;
|
||||
}
|
||||
|
||||
// Apply the overdrive.
|
||||
RTC_DCHECK_LE(num_bands_to_compute_, gain.size());
|
||||
for (size_t i = 0; i < num_bands_to_compute_; ++i) {
|
||||
if (h_nl[i] > h_nl_fb) {
|
||||
h_nl[i] = kWeightCurve[i] * h_nl_fb + (1 - kWeightCurve[i]) * h_nl[i];
|
||||
}
|
||||
gain[i] = powf(h_nl[i], gs.overdrive_scaling * kOverDriveCurve[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CoherenceGain::ComputeCoherence(rtc::ArrayView<float> coherence_ye,
|
||||
rtc::ArrayView<float> coherence_xy) const {
|
||||
const auto& c = spectra_;
|
||||
constexpr float epsilon = 1e-10f;
|
||||
for (size_t i = 0; i < coherence_ye.size(); ++i) {
|
||||
coherence_ye[i] = (c.Cye.re[i] * c.Cye.re[i] + c.Cye.im[i] * c.Cye.im[i]) /
|
||||
(c.Py[i] * c.Pe[i] + epsilon);
|
||||
coherence_xy[i] = (c.Cxy.re[i] * c.Cxy.re[i] + c.Cxy.im[i] * c.Cxy.im[i]) /
|
||||
(c.Px[i] * c.Py[i] + epsilon);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
|
||||
#define MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class for computing an echo suppression gain based on the coherence measure.
|
||||
class CoherenceGain {
|
||||
public:
|
||||
CoherenceGain(int sample_rate_hz, size_t num_bands_to_compute);
|
||||
~CoherenceGain();
|
||||
|
||||
// Computes the gain based on the FFTs of the filter error output signal, the
|
||||
// render signal and the capture signal.
|
||||
void ComputeGain(const FftData& E,
|
||||
const FftData& X,
|
||||
const FftData& Y,
|
||||
rtc::ArrayView<float> gain);
|
||||
|
||||
private:
|
||||
struct {
|
||||
FftData Cye;
|
||||
FftData Cxy;
|
||||
std::array<float, kFftLengthBy2Plus1> Px;
|
||||
std::array<float, kFftLengthBy2Plus1> Py;
|
||||
std::array<float, kFftLengthBy2Plus1> Pe;
|
||||
} spectra_;
|
||||
|
||||
struct {
|
||||
float h_nl_fb_min = 1;
|
||||
float h_nl_fb_local_min = 1;
|
||||
float h_nl_xd_avg_min = 1.f;
|
||||
int h_nl_new_min = 0;
|
||||
float h_nl_min_ctr = 0;
|
||||
float overdrive = 2;
|
||||
float overdrive_scaling = 2;
|
||||
bool near_state = false;
|
||||
} gain_state_;
|
||||
|
||||
const Aec3Fft fft_;
|
||||
const size_t num_bands_to_compute_;
|
||||
const int sample_rate_scaler_;
|
||||
|
||||
// Updates the spectral estimates used for the coherence computation.
|
||||
void UpdateCoherenceSpectra(const FftData& E,
|
||||
const FftData& X,
|
||||
const FftData& Y);
|
||||
|
||||
// Compute the suppression gain based on the coherence.
|
||||
void FormSuppressionGain(rtc::ArrayView<const float> coherence_ye,
|
||||
rtc::ArrayView<const float> coherence_xy,
|
||||
rtc::ArrayView<float> h_nl);
|
||||
|
||||
// Compute the coherence.
|
||||
void ComputeCoherence(rtc::ArrayView<float> coherence_ye,
|
||||
rtc::ArrayView<float> coherence_xy) const;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CoherenceGain);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
|
||||
@ -281,17 +281,6 @@ void EchoRemoverImpl::ProcessCapture(
|
||||
subtractor_.FilterImpulseResponse(), *render_buffer, E2, Y2,
|
||||
subtractor_output, y0);
|
||||
|
||||
// Compute spectra.
|
||||
const bool suppression_gain_uses_ffts =
|
||||
config_.suppressor.bands_with_reliable_coherence > 0;
|
||||
FftData X;
|
||||
if (suppression_gain_uses_ffts) {
|
||||
auto& x_aligned = render_buffer->Block(-aec_state_.FilterDelayBlocks())[0];
|
||||
WindowedPaddedFft(fft_, x_aligned, x_old_, &X);
|
||||
} else {
|
||||
X.Clear();
|
||||
}
|
||||
|
||||
// Choose the linear output.
|
||||
data_dumper_->DumpWav("aec3_output_linear2", kBlockSize, &e[0],
|
||||
LowestBandRate(sample_rate_hz_), 1);
|
||||
@ -321,7 +310,7 @@ void EchoRemoverImpl::ProcessCapture(
|
||||
cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise);
|
||||
|
||||
// Compute and apply the suppression gain.
|
||||
suppression_gain_.GetGain(E2, R2, cng_.NoiseSpectrum(), E, X, Y,
|
||||
suppression_gain_.GetGain(E2, R2, cng_.NoiseSpectrum(), E, Y,
|
||||
render_signal_analyzer_, aec_state_, x,
|
||||
&high_bands_gain, &G);
|
||||
|
||||
|
||||
@ -417,8 +417,6 @@ SuppressionGain::SuppressionGain(const EchoCanceller3Config& config,
|
||||
config_(config),
|
||||
state_change_duration_blocks_(
|
||||
static_cast<int>(config_.filter.config_change_duration_blocks)),
|
||||
coherence_gain_(sample_rate_hz,
|
||||
config_.suppressor.bands_with_reliable_coherence),
|
||||
enable_transparency_improvements_(EnableTransparencyImprovements()),
|
||||
enable_new_suppression_(EnableNewSuppression()),
|
||||
moving_average_(kFftLengthBy2Plus1,
|
||||
@ -461,7 +459,6 @@ void SuppressionGain::GetGain(
|
||||
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
||||
const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
|
||||
const FftData& linear_aec_fft,
|
||||
const FftData& render_fft,
|
||||
const FftData& capture_fft,
|
||||
const RenderSignalAnalyzer& render_signal_analyzer,
|
||||
const AecState& aec_state,
|
||||
@ -488,17 +485,6 @@ void SuppressionGain::GetGain(
|
||||
LowerBandGain(low_noise_render, aec_state, nearend_average, echo_spectrum,
|
||||
comfort_noise_spectrum, low_band_gain);
|
||||
|
||||
// Adjust the gain for bands where the coherence indicates not echo.
|
||||
if (cfg.bands_with_reliable_coherence > 0 &&
|
||||
!enable_transparency_improvements_) {
|
||||
std::array<float, kFftLengthBy2Plus1> G_coherence;
|
||||
coherence_gain_.ComputeGain(linear_aec_fft, render_fft, capture_fft,
|
||||
G_coherence);
|
||||
for (size_t k = 0; k < cfg.bands_with_reliable_coherence; ++k) {
|
||||
(*low_band_gain)[k] = std::max((*low_band_gain)[k], G_coherence[k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the gain of the lower bands during start up and after resets.
|
||||
const float gain_upper_bound = aec_state.SuppressionGainLimit();
|
||||
if (gain_upper_bound < 1.f) {
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#include "api/audio/echo_canceller3_config.h"
|
||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||
#include "modules/audio_processing/aec3/aec_state.h"
|
||||
#include "modules/audio_processing/aec3/coherence_gain.h"
|
||||
#include "modules/audio_processing/aec3/moving_average.h"
|
||||
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
@ -35,7 +34,6 @@ class SuppressionGain {
|
||||
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
|
||||
const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
|
||||
const FftData& linear_aec_fft,
|
||||
const FftData& render_fft,
|
||||
const FftData& capture_fft,
|
||||
const RenderSignalAnalyzer& render_signal_analyzer,
|
||||
const AecState& aec_state,
|
||||
@ -95,7 +93,6 @@ class SuppressionGain {
|
||||
LowNoiseRenderDetector low_render_detector_;
|
||||
bool initial_state_ = true;
|
||||
int initial_state_change_counter_ = 0;
|
||||
CoherenceGain coherence_gain_;
|
||||
const bool enable_transparency_improvements_;
|
||||
const bool enable_new_suppression_;
|
||||
aec3::MovingAverage moving_average_;
|
||||
|
||||
@ -30,15 +30,12 @@ TEST(SuppressionGain, NullOutputGains) {
|
||||
std::array<float, kFftLengthBy2Plus1> R2;
|
||||
std::array<float, kFftLengthBy2Plus1> N2;
|
||||
FftData E;
|
||||
FftData X;
|
||||
FftData Y;
|
||||
E2.fill(0.f);
|
||||
R2.fill(0.f);
|
||||
N2.fill(0.f);
|
||||
E.re.fill(0.f);
|
||||
E.im.fill(0.f);
|
||||
X.re.fill(0.f);
|
||||
X.im.fill(0.f);
|
||||
Y.re.fill(0.f);
|
||||
Y.im.fill(0.f);
|
||||
|
||||
@ -46,7 +43,7 @@ TEST(SuppressionGain, NullOutputGains) {
|
||||
AecState aec_state(EchoCanceller3Config{});
|
||||
EXPECT_DEATH(
|
||||
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
|
||||
.GetGain(E2, R2, N2, E, X, Y,
|
||||
.GetGain(E2, R2, N2, E, Y,
|
||||
RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
|
||||
std::vector<std::vector<float>>(
|
||||
3, std::vector<float>(kBlockSize, 0.f)),
|
||||
@ -70,7 +67,6 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
SubtractorOutput output;
|
||||
std::array<float, kBlockSize> y;
|
||||
FftData E;
|
||||
FftData X;
|
||||
FftData Y;
|
||||
std::vector<std::vector<float>> x(1, std::vector<float>(kBlockSize, 0.f));
|
||||
EchoCanceller3Config config;
|
||||
@ -90,8 +86,6 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
y.fill(0.f);
|
||||
E.re.fill(sqrtf(E2[0]));
|
||||
E.im.fill(0.f);
|
||||
X.re.fill(sqrtf(R2[0]));
|
||||
X.im.fill(0.f);
|
||||
Y.re.fill(sqrtf(Y2[0]));
|
||||
Y.im.fill(0.f);
|
||||
|
||||
@ -108,7 +102,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
subtractor.FilterImpulseResponse(),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
||||
y);
|
||||
suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
|
||||
suppression_gain.GetGain(E2, R2, N2, E, Y, analyzer, aec_state, x,
|
||||
&high_bands_gain, &g);
|
||||
}
|
||||
std::for_each(g.begin(), g.end(),
|
||||
@ -120,7 +114,6 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
R2.fill(0.1f);
|
||||
N2.fill(0.f);
|
||||
E.re.fill(sqrtf(E2[0]));
|
||||
X.re.fill(sqrtf(R2[0]));
|
||||
Y.re.fill(sqrtf(Y2[0]));
|
||||
|
||||
for (int k = 0; k < 100; ++k) {
|
||||
@ -128,7 +121,7 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
subtractor.FilterImpulseResponse(),
|
||||
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
|
||||
y);
|
||||
suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
|
||||
suppression_gain.GetGain(E2, R2, N2, E, Y, analyzer, aec_state, x,
|
||||
&high_bands_gain, &g);
|
||||
}
|
||||
std::for_each(g.begin(), g.end(),
|
||||
@ -138,10 +131,9 @@ TEST(SuppressionGain, BasicGainComputation) {
|
||||
E2.fill(1000000000.f);
|
||||
R2.fill(10000000000000.f);
|
||||
E.re.fill(sqrtf(E2[0]));
|
||||
X.re.fill(sqrtf(R2[0]));
|
||||
|
||||
for (int k = 0; k < 10; ++k) {
|
||||
suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
|
||||
suppression_gain.GetGain(E2, R2, N2, E, Y, analyzer, aec_state, x,
|
||||
&high_bands_gain, &g);
|
||||
}
|
||||
std::for_each(g.begin(), g.end(),
|
||||
|
||||
@ -327,8 +327,6 @@ EchoCanceller3Config ParseAec3Parameters(const std::string& filename) {
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(root, "suppressor", §ion)) {
|
||||
ReadParam(section, "bands_with_reliable_coherence",
|
||||
&cfg.suppressor.bands_with_reliable_coherence);
|
||||
ReadParam(section, "nearend_average_blocks",
|
||||
&cfg.suppressor.nearend_average_blocks);
|
||||
ReadParam(section, "mask_lf", &cfg.suppressor.mask_lf);
|
||||
|
||||
Reference in New Issue
Block a user