Propagate field trials to aec3 sub components
Bug: webrtc:369904700 Change-Id: I17264de11346838b70ab2c47d6f6dc768e74b41a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/374361 Reviewed-by: Sam Zackrisson <saza@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43746}
This commit is contained in:
parent
1ba220a816
commit
23b95d4fe4
@ -182,7 +182,6 @@ rtc_library("audio_processing") {
|
|||||||
"../../rtc_base/system:rtc_export",
|
"../../rtc_base/system:rtc_export",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:denormal_disabler",
|
"../../system_wrappers:denormal_disabler",
|
||||||
"../../system_wrappers:field_trial",
|
|
||||||
"../../system_wrappers:metrics",
|
"../../system_wrappers:metrics",
|
||||||
"aec3",
|
"aec3",
|
||||||
"aec_dump",
|
"aec_dump",
|
||||||
|
|||||||
@ -155,7 +155,6 @@ rtc_library("aec3") {
|
|||||||
"../../../rtc_base/experiments:field_trial_parser",
|
"../../../rtc_base/experiments:field_trial_parser",
|
||||||
"../../../rtc_base/system:arch",
|
"../../../rtc_base/system:arch",
|
||||||
"../../../system_wrappers",
|
"../../../system_wrappers",
|
||||||
"../../../system_wrappers:field_trial",
|
|
||||||
"../../../system_wrappers:metrics",
|
"../../../system_wrappers:metrics",
|
||||||
"../utility:cascaded_biquad_filter",
|
"../utility:cascaded_biquad_filter",
|
||||||
"//third_party/abseil-cpp/absl/strings:string_view",
|
"//third_party/abseil-cpp/absl/strings:string_view",
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
@ -482,7 +483,8 @@ TEST_P(AdaptiveFirFilterMultiChannel, FilterAndAdapt) {
|
|||||||
Block x(kNumBands, num_render_channels);
|
Block x(kNumBands, num_render_channels);
|
||||||
std::vector<float> n(kBlockSize, 0.f);
|
std::vector<float> n(kBlockSize, 0.f);
|
||||||
std::vector<float> y(kBlockSize, 0.f);
|
std::vector<float> y(kBlockSize, 0.f);
|
||||||
AecState aec_state(EchoCanceller3Config{}, num_capture_channels);
|
AecState aec_state(CreateEnvironment(), EchoCanceller3Config{},
|
||||||
|
num_capture_channels);
|
||||||
RenderSignalAnalyzer render_signal_analyzer(config);
|
RenderSignalAnalyzer render_signal_analyzer(config);
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
std::vector<float> e(kBlockSize, 0.f);
|
std::vector<float> e(kBlockSize, 0.f);
|
||||||
|
|||||||
@ -18,25 +18,28 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/field_trials_view.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool DeactivateInitialStateResetAtEchoPathChange() {
|
bool DeactivateInitialStateResetAtEchoPathChange(
|
||||||
return field_trial::IsEnabled(
|
const FieldTrialsView& field_trials) {
|
||||||
|
return field_trials.IsEnabled(
|
||||||
"WebRTC-Aec3DeactivateInitialStateResetKillSwitch");
|
"WebRTC-Aec3DeactivateInitialStateResetKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FullResetAtEchoPathChange() {
|
bool FullResetAtEchoPathChange(const FieldTrialsView& field_trials) {
|
||||||
return !field_trial::IsEnabled("WebRTC-Aec3AecStateFullResetKillSwitch");
|
return !field_trials.IsEnabled("WebRTC-Aec3AecStateFullResetKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubtractorAnalyzerResetAtEchoPathChange() {
|
bool SubtractorAnalyzerResetAtEchoPathChange(
|
||||||
return !field_trial::IsEnabled(
|
const FieldTrialsView& field_trials) {
|
||||||
|
return !field_trials.IsEnabled(
|
||||||
"WebRTC-Aec3AecStateSubtractorAnalyzerResetKillSwitch");
|
"WebRTC-Aec3AecStateSubtractorAnalyzerResetKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,22 +115,27 @@ void AecState::GetResidualEchoScaling(
|
|||||||
residual_scaling);
|
residual_scaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
AecState::AecState(const EchoCanceller3Config& config,
|
AecState::AecState(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels)
|
size_t num_capture_channels)
|
||||||
: data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
|
: data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
|
||||||
config_(config),
|
config_(config),
|
||||||
num_capture_channels_(num_capture_channels),
|
num_capture_channels_(num_capture_channels),
|
||||||
deactivate_initial_state_reset_at_echo_path_change_(
|
deactivate_initial_state_reset_at_echo_path_change_(
|
||||||
DeactivateInitialStateResetAtEchoPathChange()),
|
DeactivateInitialStateResetAtEchoPathChange(env.field_trials())),
|
||||||
full_reset_at_echo_path_change_(FullResetAtEchoPathChange()),
|
full_reset_at_echo_path_change_(
|
||||||
|
FullResetAtEchoPathChange(env.field_trials())),
|
||||||
subtractor_analyzer_reset_at_echo_path_change_(
|
subtractor_analyzer_reset_at_echo_path_change_(
|
||||||
SubtractorAnalyzerResetAtEchoPathChange()),
|
SubtractorAnalyzerResetAtEchoPathChange(env.field_trials())),
|
||||||
initial_state_(config_),
|
initial_state_(config_),
|
||||||
delay_state_(config_, num_capture_channels_),
|
delay_state_(config_, num_capture_channels_),
|
||||||
transparent_state_(TransparentMode::Create(config_)),
|
transparent_state_(TransparentMode::Create(env, config_)),
|
||||||
filter_quality_state_(config_, num_capture_channels_),
|
filter_quality_state_(config_, num_capture_channels_),
|
||||||
erl_estimator_(2 * kNumBlocksPerSecond),
|
erl_estimator_(2 * kNumBlocksPerSecond),
|
||||||
erle_estimator_(2 * kNumBlocksPerSecond, config_, num_capture_channels_),
|
erle_estimator_(env,
|
||||||
|
2 * kNumBlocksPerSecond,
|
||||||
|
config_,
|
||||||
|
num_capture_channels_),
|
||||||
filter_analyzer_(config_, num_capture_channels_),
|
filter_analyzer_(config_, num_capture_channels_),
|
||||||
echo_audibility_(
|
echo_audibility_(
|
||||||
config_.echo_audibility.use_stationarity_properties_at_init),
|
config_.echo_audibility.use_stationarity_properties_at_init),
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/delay_estimate.h"
|
#include "modules/audio_processing/aec3/delay_estimate.h"
|
||||||
#include "modules/audio_processing/aec3/echo_audibility.h"
|
#include "modules/audio_processing/aec3/echo_audibility.h"
|
||||||
@ -41,7 +42,9 @@ class ApmDataDumper;
|
|||||||
// Handles the state and the conditions for the echo removal functionality.
|
// Handles the state and the conditions for the echo removal functionality.
|
||||||
class AecState {
|
class AecState {
|
||||||
public:
|
public:
|
||||||
AecState(const EchoCanceller3Config& config, size_t num_capture_channels);
|
AecState(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
|
size_t num_capture_channels);
|
||||||
~AecState();
|
~AecState();
|
||||||
|
|
||||||
// Returns whether the echo subtractor can be used to determine the residual
|
// Returns whether the echo subtractor can be used to determine the residual
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
@ -27,7 +29,7 @@ void RunNormalUsageTest(size_t num_render_channels,
|
|||||||
constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);
|
constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);
|
||||||
ApmDataDumper data_dumper(42);
|
ApmDataDumper data_dumper(42);
|
||||||
EchoCanceller3Config config;
|
EchoCanceller3Config config;
|
||||||
AecState state(config, num_capture_channels);
|
AecState state(CreateEnvironment(), config, num_capture_channels);
|
||||||
std::optional<DelayEstimate> delay_estimate =
|
std::optional<DelayEstimate> delay_estimate =
|
||||||
DelayEstimate(DelayEstimate::Quality::kRefined, 10);
|
DelayEstimate(DelayEstimate::Quality::kRefined, 10);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||||
@ -244,7 +246,7 @@ TEST(AecState, ConvergedFilterDelay) {
|
|||||||
constexpr int kFilterLengthBlocks = 10;
|
constexpr int kFilterLengthBlocks = 10;
|
||||||
constexpr size_t kNumCaptureChannels = 1;
|
constexpr size_t kNumCaptureChannels = 1;
|
||||||
EchoCanceller3Config config;
|
EchoCanceller3Config config;
|
||||||
AecState state(config, kNumCaptureChannels);
|
AecState state(CreateEnvironment(), config, kNumCaptureChannels);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||||
RenderDelayBuffer::Create(config, 48000, 1));
|
RenderDelayBuffer::Create(config, 48000, 1));
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
|
|||||||
@ -237,10 +237,12 @@ void BlockProcessorImpl::SetCaptureOutputUsage(bool capture_output_used) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
|
std::unique_ptr<BlockProcessor> BlockProcessor::Create(
|
||||||
int sample_rate_hz,
|
const Environment& env,
|
||||||
size_t num_render_channels,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels) {
|
int sample_rate_hz,
|
||||||
|
size_t num_render_channels,
|
||||||
|
size_t num_capture_channels) {
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
||||||
RenderDelayBuffer::Create(config, sample_rate_hz, num_render_channels));
|
RenderDelayBuffer::Create(config, sample_rate_hz, num_render_channels));
|
||||||
std::unique_ptr<RenderDelayController> delay_controller;
|
std::unique_ptr<RenderDelayController> delay_controller;
|
||||||
@ -248,14 +250,15 @@ BlockProcessor* BlockProcessor::Create(const EchoCanceller3Config& config,
|
|||||||
delay_controller.reset(RenderDelayController::Create(config, sample_rate_hz,
|
delay_controller.reset(RenderDelayController::Create(config, sample_rate_hz,
|
||||||
num_capture_channels));
|
num_capture_channels));
|
||||||
}
|
}
|
||||||
std::unique_ptr<EchoRemover> echo_remover(EchoRemover::Create(
|
std::unique_ptr<EchoRemover> echo_remover = EchoRemover::Create(
|
||||||
config, sample_rate_hz, num_render_channels, num_capture_channels));
|
env, config, sample_rate_hz, num_render_channels, num_capture_channels);
|
||||||
return Create(config, sample_rate_hz, num_render_channels,
|
return Create(config, sample_rate_hz, num_render_channels,
|
||||||
num_capture_channels, std::move(render_buffer),
|
num_capture_channels, std::move(render_buffer),
|
||||||
std::move(delay_controller), std::move(echo_remover));
|
std::move(delay_controller), std::move(echo_remover));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockProcessor* BlockProcessor::Create(
|
std::unique_ptr<BlockProcessor> BlockProcessor::Create(
|
||||||
|
const Environment& env,
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
@ -266,14 +269,14 @@ BlockProcessor* BlockProcessor::Create(
|
|||||||
delay_controller.reset(RenderDelayController::Create(config, sample_rate_hz,
|
delay_controller.reset(RenderDelayController::Create(config, sample_rate_hz,
|
||||||
num_capture_channels));
|
num_capture_channels));
|
||||||
}
|
}
|
||||||
std::unique_ptr<EchoRemover> echo_remover(EchoRemover::Create(
|
std::unique_ptr<EchoRemover> echo_remover = EchoRemover::Create(
|
||||||
config, sample_rate_hz, num_render_channels, num_capture_channels));
|
env, config, sample_rate_hz, num_render_channels, num_capture_channels);
|
||||||
return Create(config, sample_rate_hz, num_render_channels,
|
return Create(config, sample_rate_hz, num_render_channels,
|
||||||
num_capture_channels, std::move(render_buffer),
|
num_capture_channels, std::move(render_buffer),
|
||||||
std::move(delay_controller), std::move(echo_remover));
|
std::move(delay_controller), std::move(echo_remover));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockProcessor* BlockProcessor::Create(
|
std::unique_ptr<BlockProcessor> BlockProcessor::Create(
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
@ -281,10 +284,10 @@ BlockProcessor* BlockProcessor::Create(
|
|||||||
std::unique_ptr<RenderDelayBuffer> render_buffer,
|
std::unique_ptr<RenderDelayBuffer> render_buffer,
|
||||||
std::unique_ptr<RenderDelayController> delay_controller,
|
std::unique_ptr<RenderDelayController> delay_controller,
|
||||||
std::unique_ptr<EchoRemover> echo_remover) {
|
std::unique_ptr<EchoRemover> echo_remover) {
|
||||||
return new BlockProcessorImpl(config, sample_rate_hz, num_render_channels,
|
return std::make_unique<BlockProcessorImpl>(
|
||||||
num_capture_channels, std::move(render_buffer),
|
config, sample_rate_hz, num_render_channels, num_capture_channels,
|
||||||
std::move(delay_controller),
|
std::move(render_buffer), std::move(delay_controller),
|
||||||
std::move(echo_remover));
|
std::move(echo_remover));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
#include "api/audio/echo_control.h"
|
#include "api/audio/echo_control.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/block.h"
|
#include "modules/audio_processing/aec3/block.h"
|
||||||
#include "modules/audio_processing/aec3/echo_remover.h"
|
#include "modules/audio_processing/aec3/echo_remover.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
@ -28,18 +29,21 @@ namespace webrtc {
|
|||||||
// Class for performing echo cancellation on 64 sample blocks of audio data.
|
// Class for performing echo cancellation on 64 sample blocks of audio data.
|
||||||
class BlockProcessor {
|
class BlockProcessor {
|
||||||
public:
|
public:
|
||||||
static BlockProcessor* Create(const EchoCanceller3Config& config,
|
static std::unique_ptr<BlockProcessor> Create(
|
||||||
int sample_rate_hz,
|
const Environment& env,
|
||||||
size_t num_render_channels,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels);
|
int sample_rate_hz,
|
||||||
|
size_t num_render_channels,
|
||||||
|
size_t num_capture_channels);
|
||||||
// Only used for testing purposes.
|
// Only used for testing purposes.
|
||||||
static BlockProcessor* Create(
|
static std::unique_ptr<BlockProcessor> Create(
|
||||||
|
const Environment& env,
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels,
|
size_t num_capture_channels,
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer);
|
std::unique_ptr<RenderDelayBuffer> render_buffer);
|
||||||
static BlockProcessor* Create(
|
static std::unique_ptr<BlockProcessor> Create(
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
|
#include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
|
||||||
#include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
|
||||||
@ -36,13 +38,15 @@ using ::testing::StrictMock;
|
|||||||
|
|
||||||
// Verifies that the basic BlockProcessor functionality works and that the API
|
// Verifies that the basic BlockProcessor functionality works and that the API
|
||||||
// methods are callable.
|
// methods are callable.
|
||||||
void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
|
void RunBasicSetupAndApiCallTest(const Environment& env,
|
||||||
|
int sample_rate_hz,
|
||||||
|
int num_iterations) {
|
||||||
constexpr size_t kNumRenderChannels = 1;
|
constexpr size_t kNumRenderChannels = 1;
|
||||||
constexpr size_t kNumCaptureChannels = 1;
|
constexpr size_t kNumCaptureChannels = 1;
|
||||||
|
|
||||||
std::unique_ptr<BlockProcessor> block_processor(
|
std::unique_ptr<BlockProcessor> block_processor =
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
|
BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
|
||||||
kNumRenderChannels, kNumCaptureChannels));
|
kNumRenderChannels, kNumCaptureChannels);
|
||||||
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels, 1000.f);
|
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels, 1000.f);
|
||||||
for (int k = 0; k < num_iterations; ++k) {
|
for (int k = 0; k < num_iterations; ++k) {
|
||||||
block_processor->BufferRender(block);
|
block_processor->BufferRender(block);
|
||||||
@ -52,43 +56,46 @@ void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||||
void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
|
void RunRenderBlockSizeVerificationTest(const Environment& env,
|
||||||
|
int sample_rate_hz) {
|
||||||
constexpr size_t kNumRenderChannels = 1;
|
constexpr size_t kNumRenderChannels = 1;
|
||||||
constexpr size_t kNumCaptureChannels = 1;
|
constexpr size_t kNumCaptureChannels = 1;
|
||||||
|
|
||||||
std::unique_ptr<BlockProcessor> block_processor(
|
std::unique_ptr<BlockProcessor> block_processor =
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
|
BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
|
||||||
kNumRenderChannels, kNumCaptureChannels));
|
kNumRenderChannels, kNumCaptureChannels);
|
||||||
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels);
|
Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels);
|
||||||
|
|
||||||
EXPECT_DEATH(block_processor->BufferRender(block), "");
|
EXPECT_DEATH(block_processor->BufferRender(block), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
|
void RunRenderNumBandsVerificationTest(const Environment& env,
|
||||||
|
int sample_rate_hz) {
|
||||||
constexpr size_t kNumRenderChannels = 1;
|
constexpr size_t kNumRenderChannels = 1;
|
||||||
constexpr size_t kNumCaptureChannels = 1;
|
constexpr size_t kNumCaptureChannels = 1;
|
||||||
|
|
||||||
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
|
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
|
||||||
? NumBandsForRate(sample_rate_hz) + 1
|
? NumBandsForRate(sample_rate_hz) + 1
|
||||||
: 1;
|
: 1;
|
||||||
std::unique_ptr<BlockProcessor> block_processor(
|
std::unique_ptr<BlockProcessor> block_processor =
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
|
BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
|
||||||
kNumRenderChannels, kNumCaptureChannels));
|
kNumRenderChannels, kNumCaptureChannels);
|
||||||
Block block(wrong_num_bands, kNumRenderChannels);
|
Block block(wrong_num_bands, kNumRenderChannels);
|
||||||
|
|
||||||
EXPECT_DEATH(block_processor->BufferRender(block), "");
|
EXPECT_DEATH(block_processor->BufferRender(block), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
|
void RunCaptureNumBandsVerificationTest(const Environment& env,
|
||||||
|
int sample_rate_hz) {
|
||||||
constexpr size_t kNumRenderChannels = 1;
|
constexpr size_t kNumRenderChannels = 1;
|
||||||
constexpr size_t kNumCaptureChannels = 1;
|
constexpr size_t kNumCaptureChannels = 1;
|
||||||
|
|
||||||
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
|
const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
|
||||||
? NumBandsForRate(sample_rate_hz) + 1
|
? NumBandsForRate(sample_rate_hz) + 1
|
||||||
: 1;
|
: 1;
|
||||||
std::unique_ptr<BlockProcessor> block_processor(
|
std::unique_ptr<BlockProcessor> block_processor =
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz,
|
BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
|
||||||
kNumRenderChannels, kNumCaptureChannels));
|
kNumRenderChannels, kNumCaptureChannels);
|
||||||
Block block(wrong_num_bands, kNumRenderChannels);
|
Block block(wrong_num_bands, kNumRenderChannels);
|
||||||
|
|
||||||
EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
|
EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
|
||||||
@ -123,6 +130,7 @@ TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
|
|||||||
constexpr size_t kDelayHeadroom = 1;
|
constexpr size_t kDelayHeadroom = 1;
|
||||||
constexpr size_t kDelayInBlocks =
|
constexpr size_t kDelayInBlocks =
|
||||||
kDelayInSamples / kBlockSize - kDelayHeadroom;
|
kDelayInSamples / kBlockSize - kDelayHeadroom;
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
Random random_generator(42U);
|
Random random_generator(42U);
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
@ -138,9 +146,9 @@ TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
|
|||||||
EXPECT_CALL(*render_delay_buffer_mock, Delay())
|
EXPECT_CALL(*render_delay_buffer_mock, Delay())
|
||||||
.Times(kNumBlocks + 1)
|
.Times(kNumBlocks + 1)
|
||||||
.WillRepeatedly(Return(0));
|
.WillRepeatedly(Return(0));
|
||||||
std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
|
std::unique_ptr<BlockProcessor> block_processor = BlockProcessor::Create(
|
||||||
EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
|
env, EchoCanceller3Config(), rate, kNumRenderChannels,
|
||||||
std::move(render_delay_buffer_mock)));
|
kNumCaptureChannels, std::move(render_delay_buffer_mock));
|
||||||
|
|
||||||
Block render_block(NumBandsForRate(rate), kNumRenderChannels);
|
Block render_block(NumBandsForRate(rate), kNumRenderChannels);
|
||||||
Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
|
Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
|
||||||
@ -212,46 +220,51 @@ TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(BlockProcessor, BasicSetupAndApiCalls) {
|
TEST(BlockProcessor, BasicSetupAndApiCalls) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
RunBasicSetupAndApiCallTest(rate, 1);
|
RunBasicSetupAndApiCallTest(env, rate, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BlockProcessor, TestLongerCall) {
|
TEST(BlockProcessor, TestLongerCall) {
|
||||||
RunBasicSetupAndApiCallTest(16000, 20 * kNumBlocksPerSecond);
|
RunBasicSetupAndApiCallTest(CreateEnvironment(), 16000,
|
||||||
|
20 * kNumBlocksPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||||
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
|
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
|
||||||
// DEATH tests on test bots has been fixed.
|
// DEATH tests on test bots has been fixed.
|
||||||
TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
|
TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
RunRenderBlockSizeVerificationTest(rate);
|
RunRenderBlockSizeVerificationTest(env, rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
|
TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
RunRenderNumBandsVerificationTest(rate);
|
RunRenderNumBandsVerificationTest(env, rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(peah): Verify the check for correct number of bands in the capture
|
// TODO(peah): Verify the check for correct number of bands in the capture
|
||||||
// signal.
|
// signal.
|
||||||
TEST(BlockProcessorDeathTest, VerifyCaptureNumBandsCheck) {
|
TEST(BlockProcessorDeathTest, VerifyCaptureNumBandsCheck) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
RunCaptureNumBandsVerificationTest(rate);
|
RunCaptureNumBandsVerificationTest(env, rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifiers that the verification for null ProcessCapture input works.
|
// Verifiers that the verification for null ProcessCapture input works.
|
||||||
TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
|
TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
|
||||||
EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
|
EXPECT_DEATH(BlockProcessor::Create(CreateEnvironment(),
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), 16000, 1, 1))
|
EchoCanceller3Config(), 16000, 1, 1)
|
||||||
->ProcessCapture(false, false, nullptr, nullptr),
|
->ProcessCapture(false, false, nullptr, nullptr),
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
@ -260,8 +273,8 @@ TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
|
|||||||
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
||||||
// tests on test bots has been fixed.
|
// tests on test bots has been fixed.
|
||||||
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
|
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
|
||||||
EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
|
EXPECT_DEATH(BlockProcessor::Create(CreateEnvironment(),
|
||||||
BlockProcessor::Create(EchoCanceller3Config(), 8001, 1, 1)),
|
EchoCanceller3Config(), 8001, 1, 1),
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "rtc_base/random.h"
|
#include "rtc_base/random.h"
|
||||||
#include "rtc_base/system/arch.h"
|
#include "rtc_base/system/arch.h"
|
||||||
@ -36,7 +37,7 @@ TEST(ComfortNoiseGenerator, CorrectLevel) {
|
|||||||
constexpr size_t kNumChannels = 5;
|
constexpr size_t kNumChannels = 5;
|
||||||
EchoCanceller3Config config;
|
EchoCanceller3Config config;
|
||||||
ComfortNoiseGenerator cng(config, DetectOptimization(), kNumChannels);
|
ComfortNoiseGenerator cng(config, DetectOptimization(), kNumChannels);
|
||||||
AecState aec_state(config, kNumChannels);
|
AecState aec_state(CreateEnvironment(), config, kNumChannels);
|
||||||
|
|
||||||
std::vector<std::array<float, kFftLengthBy2Plus1>> N2(kNumChannels);
|
std::vector<std::array<float, kFftLengthBy2Plus1>> N2(kNumChannels);
|
||||||
std::vector<FftData> n_lower(kNumChannels);
|
std::vector<FftData> n_lower(kNumChannels);
|
||||||
|
|||||||
@ -735,7 +735,8 @@ EchoCanceller3::EchoCanceller3(
|
|||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels)
|
size_t num_capture_channels)
|
||||||
: data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
|
: env_(env),
|
||||||
|
data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
|
||||||
config_(AdjustConfig(config, env.field_trials())),
|
config_(AdjustConfig(config, env.field_trials())),
|
||||||
sample_rate_hz_(sample_rate_hz),
|
sample_rate_hz_(sample_rate_hz),
|
||||||
num_bands_(NumBandsForRate(sample_rate_hz_)),
|
num_bands_(NumBandsForRate(sample_rate_hz_)),
|
||||||
@ -825,9 +826,9 @@ void EchoCanceller3::Initialize() {
|
|||||||
render_blocker_.reset(
|
render_blocker_.reset(
|
||||||
new FrameBlocker(num_bands_, num_render_channels_to_aec_));
|
new FrameBlocker(num_bands_, num_render_channels_to_aec_));
|
||||||
|
|
||||||
block_processor_.reset(BlockProcessor::Create(
|
block_processor_ = BlockProcessor::Create(
|
||||||
config_selector_.active_config(), sample_rate_hz_,
|
env_, config_selector_.active_config(), sample_rate_hz_,
|
||||||
num_render_channels_to_aec_, num_capture_channels_));
|
num_render_channels_to_aec_, num_capture_channels_);
|
||||||
|
|
||||||
render_sub_frame_view_ = std::vector<std::vector<rtc::ArrayView<float>>>(
|
render_sub_frame_view_ = std::vector<std::vector<rtc::ArrayView<float>>>(
|
||||||
num_bands_,
|
num_bands_,
|
||||||
|
|||||||
@ -181,6 +181,7 @@ class EchoCanceller3 : public EchoControl {
|
|||||||
// Analyzes the full-band domain capture signal to detect signal saturation.
|
// Analyzes the full-band domain capture signal to detect signal saturation.
|
||||||
void AnalyzeCapture(const AudioBuffer& capture);
|
void AnalyzeCapture(const AudioBuffer& capture);
|
||||||
|
|
||||||
|
const Environment env_;
|
||||||
rtc::RaceChecker capture_race_checker_;
|
rtc::RaceChecker capture_race_checker_;
|
||||||
rtc::RaceChecker render_race_checker_;
|
rtc::RaceChecker render_race_checker_;
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
@ -105,7 +106,8 @@ void WindowedPaddedFft(const Aec3Fft& fft,
|
|||||||
// Class for removing the echo from the capture signal.
|
// Class for removing the echo from the capture signal.
|
||||||
class EchoRemoverImpl final : public EchoRemover {
|
class EchoRemoverImpl final : public EchoRemover {
|
||||||
public:
|
public:
|
||||||
EchoRemoverImpl(const EchoCanceller3Config& config,
|
EchoRemoverImpl(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels);
|
size_t num_capture_channels);
|
||||||
@ -182,7 +184,8 @@ class EchoRemoverImpl final : public EchoRemover {
|
|||||||
|
|
||||||
std::atomic<int> EchoRemoverImpl::instance_count_(0);
|
std::atomic<int> EchoRemoverImpl::instance_count_(0);
|
||||||
|
|
||||||
EchoRemoverImpl::EchoRemoverImpl(const EchoCanceller3Config& config,
|
EchoRemoverImpl::EchoRemoverImpl(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels)
|
size_t num_capture_channels)
|
||||||
@ -195,7 +198,8 @@ EchoRemoverImpl::EchoRemoverImpl(const EchoCanceller3Config& config,
|
|||||||
num_capture_channels_(num_capture_channels),
|
num_capture_channels_(num_capture_channels),
|
||||||
use_coarse_filter_output_(
|
use_coarse_filter_output_(
|
||||||
config_.filter.enable_coarse_filter_output_usage),
|
config_.filter.enable_coarse_filter_output_usage),
|
||||||
subtractor_(config,
|
subtractor_(env,
|
||||||
|
config,
|
||||||
num_render_channels_,
|
num_render_channels_,
|
||||||
num_capture_channels_,
|
num_capture_channels_,
|
||||||
data_dumper_.get(),
|
data_dumper_.get(),
|
||||||
@ -209,8 +213,8 @@ EchoRemoverImpl::EchoRemoverImpl(const EchoCanceller3Config& config,
|
|||||||
sample_rate_hz_,
|
sample_rate_hz_,
|
||||||
num_capture_channels_),
|
num_capture_channels_),
|
||||||
render_signal_analyzer_(config_),
|
render_signal_analyzer_(config_),
|
||||||
residual_echo_estimator_(config_, num_render_channels),
|
residual_echo_estimator_(env, config_, num_render_channels),
|
||||||
aec_state_(config_, num_capture_channels_),
|
aec_state_(env, config_, num_capture_channels_),
|
||||||
e_old_(num_capture_channels_, {0.f}),
|
e_old_(num_capture_channels_, {0.f}),
|
||||||
y_old_(num_capture_channels_, {0.f}),
|
y_old_(num_capture_channels_, {0.f}),
|
||||||
e_heap_(NumChannelsOnHeap(num_capture_channels_), {0.f}),
|
e_heap_(NumChannelsOnHeap(num_capture_channels_), {0.f}),
|
||||||
@ -510,12 +514,14 @@ void EchoRemoverImpl::FormLinearFilterOutput(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EchoRemover* EchoRemover::Create(const EchoCanceller3Config& config,
|
std::unique_ptr<EchoRemover> EchoRemover::Create(
|
||||||
int sample_rate_hz,
|
const Environment& env,
|
||||||
size_t num_render_channels,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels) {
|
int sample_rate_hz,
|
||||||
return new EchoRemoverImpl(config, sample_rate_hz, num_render_channels,
|
size_t num_render_channels,
|
||||||
num_capture_channels);
|
size_t num_capture_channels) {
|
||||||
|
return std::make_unique<EchoRemoverImpl>(
|
||||||
|
env, config, sample_rate_hz, num_render_channels, num_capture_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -11,11 +11,13 @@
|
|||||||
#ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
|
#ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
|
||||||
#define MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
|
#define MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
#include "api/audio/echo_control.h"
|
#include "api/audio/echo_control.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/block.h"
|
#include "modules/audio_processing/aec3/block.h"
|
||||||
#include "modules/audio_processing/aec3/delay_estimate.h"
|
#include "modules/audio_processing/aec3/delay_estimate.h"
|
||||||
#include "modules/audio_processing/aec3/echo_path_variability.h"
|
#include "modules/audio_processing/aec3/echo_path_variability.h"
|
||||||
@ -26,10 +28,11 @@ namespace webrtc {
|
|||||||
// Class for removing the echo from the capture signal.
|
// Class for removing the echo from the capture signal.
|
||||||
class EchoRemover {
|
class EchoRemover {
|
||||||
public:
|
public:
|
||||||
static EchoRemover* Create(const EchoCanceller3Config& config,
|
static std::unique_ptr<EchoRemover> Create(const Environment& env,
|
||||||
int sample_rate_hz,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_render_channels,
|
int sample_rate_hz,
|
||||||
size_t num_capture_channels);
|
size_t num_render_channels,
|
||||||
|
size_t num_capture_channels);
|
||||||
virtual ~EchoRemover() = default;
|
virtual ~EchoRemover() = default;
|
||||||
|
|
||||||
// Get current metrics.
|
// Get current metrics.
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
@ -138,7 +139,7 @@ TEST(DbMetric, Constructor) {
|
|||||||
// Verify the general functionality of EchoRemoverMetrics.
|
// Verify the general functionality of EchoRemoverMetrics.
|
||||||
TEST(EchoRemoverMetrics, NormalUsage) {
|
TEST(EchoRemoverMetrics, NormalUsage) {
|
||||||
EchoRemoverMetrics metrics;
|
EchoRemoverMetrics metrics;
|
||||||
AecState aec_state(EchoCanceller3Config{}, 1);
|
AecState aec_state(CreateEnvironment(), EchoCanceller3Config{}, 1);
|
||||||
std::array<float, kFftLengthBy2Plus1> comfort_noise_spectrum;
|
std::array<float, kFftLengthBy2Plus1> comfort_noise_spectrum;
|
||||||
std::array<float, kFftLengthBy2Plus1> suppressor_gain;
|
std::array<float, kFftLengthBy2Plus1> suppressor_gain;
|
||||||
comfort_noise_spectrum.fill(10.f);
|
comfort_noise_spectrum.fill(10.f);
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/render_buffer.h"
|
#include "modules/audio_processing/aec3/render_buffer.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
@ -53,12 +55,13 @@ INSTANTIATE_TEST_SUITE_P(MultiChannel,
|
|||||||
TEST_P(EchoRemoverMultiChannel, BasicApiCalls) {
|
TEST_P(EchoRemoverMultiChannel, BasicApiCalls) {
|
||||||
const size_t num_render_channels = std::get<0>(GetParam());
|
const size_t num_render_channels = std::get<0>(GetParam());
|
||||||
const size_t num_capture_channels = std::get<1>(GetParam());
|
const size_t num_capture_channels = std::get<1>(GetParam());
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
std::unique_ptr<EchoRemover> remover(
|
std::unique_ptr<EchoRemover> remover =
|
||||||
EchoRemover::Create(EchoCanceller3Config(), rate, num_render_channels,
|
EchoRemover::Create(env, EchoCanceller3Config(), rate,
|
||||||
num_capture_channels));
|
num_render_channels, num_capture_channels);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer(RenderDelayBuffer::Create(
|
std::unique_ptr<RenderDelayBuffer> render_buffer(RenderDelayBuffer::Create(
|
||||||
EchoCanceller3Config(), rate, num_render_channels));
|
EchoCanceller3Config(), rate, num_render_channels));
|
||||||
|
|
||||||
@ -86,8 +89,8 @@ TEST_P(EchoRemoverMultiChannel, BasicApiCalls) {
|
|||||||
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
||||||
// tests on test bots has been fixed.
|
// tests on test bots has been fixed.
|
||||||
TEST(EchoRemoverDeathTest, DISABLED_WrongSampleRate) {
|
TEST(EchoRemoverDeathTest, DISABLED_WrongSampleRate) {
|
||||||
EXPECT_DEATH(std::unique_ptr<EchoRemover>(
|
EXPECT_DEATH(EchoRemover::Create(CreateEnvironment(), EchoCanceller3Config(),
|
||||||
EchoRemover::Create(EchoCanceller3Config(), 8001, 1, 1)),
|
8001, 1, 1),
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,11 +98,12 @@ TEST(EchoRemoverDeathTest, DISABLED_WrongSampleRate) {
|
|||||||
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
|
||||||
// tests on test bots has been fixed.c
|
// tests on test bots has been fixed.c
|
||||||
TEST(EchoRemoverDeathTest, DISABLED_WrongCaptureNumBands) {
|
TEST(EchoRemoverDeathTest, DISABLED_WrongCaptureNumBands) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
for (auto rate : {16000, 32000, 48000}) {
|
for (auto rate : {16000, 32000, 48000}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate));
|
SCOPED_TRACE(ProduceDebugText(rate));
|
||||||
std::unique_ptr<EchoRemover> remover(
|
std::unique_ptr<EchoRemover> remover =
|
||||||
EchoRemover::Create(EchoCanceller3Config(), rate, 1, 1));
|
EchoRemover::Create(env, EchoCanceller3Config(), rate, 1, 1);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
||||||
RenderDelayBuffer::Create(EchoCanceller3Config(), rate, 1));
|
RenderDelayBuffer::Create(EchoCanceller3Config(), rate, 1));
|
||||||
Block capture(NumBandsForRate(rate == 48000 ? 16000 : rate + 16000), 1);
|
Block capture(NumBandsForRate(rate == 48000 ? 16000 : rate + 16000), 1);
|
||||||
@ -115,8 +119,8 @@ TEST(EchoRemoverDeathTest, DISABLED_WrongCaptureNumBands) {
|
|||||||
// Verifies the check for non-null capture block.
|
// Verifies the check for non-null capture block.
|
||||||
TEST(EchoRemoverDeathTest, NullCapture) {
|
TEST(EchoRemoverDeathTest, NullCapture) {
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
std::unique_ptr<EchoRemover> remover(
|
std::unique_ptr<EchoRemover> remover = EchoRemover::Create(
|
||||||
EchoRemover::Create(EchoCanceller3Config(), 16000, 1, 1));
|
CreateEnvironment(), EchoCanceller3Config(), 16000, 1, 1);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
||||||
RenderDelayBuffer::Create(EchoCanceller3Config(), 16000, 1));
|
RenderDelayBuffer::Create(EchoCanceller3Config(), 16000, 1));
|
||||||
EchoPathVariability echo_path_variability(
|
EchoPathVariability echo_path_variability(
|
||||||
@ -133,6 +137,7 @@ TEST(EchoRemoverDeathTest, NullCapture) {
|
|||||||
// remove echoes.
|
// remove echoes.
|
||||||
TEST(EchoRemover, BasicEchoRemoval) {
|
TEST(EchoRemover, BasicEchoRemoval) {
|
||||||
constexpr int kNumBlocksToProcess = 500;
|
constexpr int kNumBlocksToProcess = 500;
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
Random random_generator(42U);
|
Random random_generator(42U);
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
for (size_t num_channels : {1, 2, 4}) {
|
for (size_t num_channels : {1, 2, 4}) {
|
||||||
@ -144,8 +149,8 @@ TEST(EchoRemover, BasicEchoRemoval) {
|
|||||||
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(rate, delay_samples));
|
SCOPED_TRACE(ProduceDebugText(rate, delay_samples));
|
||||||
EchoCanceller3Config config;
|
EchoCanceller3Config config;
|
||||||
std::unique_ptr<EchoRemover> remover(
|
std::unique_ptr<EchoRemover> remover =
|
||||||
EchoRemover::Create(config, rate, num_channels, num_channels));
|
EchoRemover::Create(env, config, rate, num_channels, num_channels);
|
||||||
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_buffer(
|
||||||
RenderDelayBuffer::Create(config, rate, num_channels));
|
RenderDelayBuffer::Create(config, rate, num_channels));
|
||||||
render_buffer->AlignFromDelay(delay_samples / kBlockSize);
|
render_buffer->AlignFromDelay(delay_samples / kBlockSize);
|
||||||
|
|||||||
@ -15,12 +15,13 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
ErleEstimator::ErleEstimator(size_t startup_phase_length_blocks,
|
ErleEstimator::ErleEstimator(const Environment& env,
|
||||||
|
size_t startup_phase_length_blocks,
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels)
|
size_t num_capture_channels)
|
||||||
: startup_phase_length_blocks_(startup_phase_length_blocks),
|
: startup_phase_length_blocks_(startup_phase_length_blocks),
|
||||||
fullband_erle_estimator_(config.erle, num_capture_channels),
|
fullband_erle_estimator_(config.erle, num_capture_channels),
|
||||||
subband_erle_estimator_(config, num_capture_channels) {
|
subband_erle_estimator_(env, config, num_capture_channels) {
|
||||||
if (config.erle.num_sections > 1) {
|
if (config.erle.num_sections > 1) {
|
||||||
signal_dependent_erle_estimator_ =
|
signal_dependent_erle_estimator_ =
|
||||||
std::make_unique<SignalDependentErleEstimator>(config,
|
std::make_unique<SignalDependentErleEstimator>(config,
|
||||||
|
|||||||
@ -33,7 +33,8 @@ namespace webrtc {
|
|||||||
// and another one is done using the aggreation of energy over all the subbands.
|
// and another one is done using the aggreation of energy over all the subbands.
|
||||||
class ErleEstimator {
|
class ErleEstimator {
|
||||||
public:
|
public:
|
||||||
ErleEstimator(size_t startup_phase_length_blocks,
|
ErleEstimator(const Environment& env,
|
||||||
|
size_t startup_phase_length_blocks,
|
||||||
const EchoCanceller3Config& config,
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels);
|
size_t num_capture_channels);
|
||||||
~ErleEstimator();
|
~ErleEstimator();
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
#include "modules/audio_processing/aec3/spectrum_buffer.h"
|
#include "modules/audio_processing/aec3/spectrum_buffer.h"
|
||||||
#include "rtc_base/random.h"
|
#include "rtc_base/random.h"
|
||||||
@ -173,7 +174,7 @@ TEST_P(ErleEstimatorMultiChannel, VerifyErleIncreaseAndHold) {
|
|||||||
|
|
||||||
GetFilterFreq(config.delay.delay_headroom_samples, filter_frequency_response);
|
GetFilterFreq(config.delay.delay_headroom_samples, filter_frequency_response);
|
||||||
|
|
||||||
ErleEstimator estimator(0, config, num_capture_channels);
|
ErleEstimator estimator(CreateEnvironment(), 0, config, num_capture_channels);
|
||||||
|
|
||||||
FormFarendTimeFrame(&x);
|
FormFarendTimeFrame(&x);
|
||||||
render_delay_buffer->Insert(x);
|
render_delay_buffer->Insert(x);
|
||||||
@ -236,7 +237,8 @@ TEST_P(ErleEstimatorMultiChannel, VerifyErleTrackingOnOnsets) {
|
|||||||
|
|
||||||
GetFilterFreq(config.delay.delay_headroom_samples, filter_frequency_response);
|
GetFilterFreq(config.delay.delay_headroom_samples, filter_frequency_response);
|
||||||
|
|
||||||
ErleEstimator estimator(/*startup_phase_length_blocks=*/0, config,
|
ErleEstimator estimator(CreateEnvironment(),
|
||||||
|
/*startup_phase_length_blocks=*/0, config,
|
||||||
num_capture_channels);
|
num_capture_channels);
|
||||||
|
|
||||||
FormFarendTimeFrame(&x);
|
FormFarendTimeFrame(&x);
|
||||||
|
|||||||
@ -29,9 +29,7 @@
|
|||||||
#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
|
#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
|
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
|
||||||
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
@ -34,7 +36,8 @@ namespace {
|
|||||||
|
|
||||||
// Method for performing the simulations needed to test the refined filter
|
// Method for performing the simulations needed to test the refined filter
|
||||||
// update gain functionality.
|
// update gain functionality.
|
||||||
void RunFilterUpdateTest(int num_blocks_to_process,
|
void RunFilterUpdateTest(const Environment& env,
|
||||||
|
int num_blocks_to_process,
|
||||||
size_t delay_samples,
|
size_t delay_samples,
|
||||||
int filter_length_blocks,
|
int filter_length_blocks,
|
||||||
const std::vector<int>& blocks_with_echo_path_changes,
|
const std::vector<int>& blocks_with_echo_path_changes,
|
||||||
@ -89,7 +92,7 @@ void RunFilterUpdateTest(int num_blocks_to_process,
|
|||||||
config.delay.default_delay = 1;
|
config.delay.default_delay = 1;
|
||||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||||
RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
|
RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
|
||||||
AecState aec_state(config, kNumCaptureChannels);
|
AecState aec_state(env, config, kNumCaptureChannels);
|
||||||
RenderSignalAnalyzer render_signal_analyzer(config);
|
RenderSignalAnalyzer render_signal_analyzer(config);
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
std::array<float, kFftLength> s_scratch;
|
std::array<float, kFftLength> s_scratch;
|
||||||
@ -254,6 +257,7 @@ TEST(RefinedFilterUpdateGainDeathTest, NullDataOutputGain) {
|
|||||||
|
|
||||||
// Verifies that the gain formed causes the filter using it to converge.
|
// Verifies that the gain formed causes the filter using it to converge.
|
||||||
TEST(RefinedFilterUpdateGain, GainCausesFilterToConverge) {
|
TEST(RefinedFilterUpdateGain, GainCausesFilterToConverge) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
std::vector<int> blocks_with_saturation;
|
std::vector<int> blocks_with_saturation;
|
||||||
for (size_t filter_length_blocks : {12, 20, 30}) {
|
for (size_t filter_length_blocks : {12, 20, 30}) {
|
||||||
@ -264,7 +268,7 @@ TEST(RefinedFilterUpdateGain, GainCausesFilterToConverge) {
|
|||||||
std::array<float, kBlockSize> y;
|
std::array<float, kBlockSize> y;
|
||||||
FftData G;
|
FftData G;
|
||||||
|
|
||||||
RunFilterUpdateTest(600, delay_samples, filter_length_blocks,
|
RunFilterUpdateTest(env, 600, delay_samples, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G);
|
false, &e, &y, &G);
|
||||||
|
|
||||||
@ -284,6 +288,7 @@ TEST(RefinedFilterUpdateGain, GainCausesFilterToConverge) {
|
|||||||
// Verifies that the magnitude of the gain on average decreases for a
|
// Verifies that the magnitude of the gain on average decreases for a
|
||||||
// persistently exciting signal.
|
// persistently exciting signal.
|
||||||
TEST(RefinedFilterUpdateGain, DecreasingGain) {
|
TEST(RefinedFilterUpdateGain, DecreasingGain) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
std::vector<int> blocks_with_saturation;
|
std::vector<int> blocks_with_saturation;
|
||||||
|
|
||||||
@ -296,11 +301,11 @@ TEST(RefinedFilterUpdateGain, DecreasingGain) {
|
|||||||
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
||||||
std::array<float, kFftLengthBy2Plus1> G_c_power;
|
std::array<float, kFftLengthBy2Plus1> G_c_power;
|
||||||
|
|
||||||
RunFilterUpdateTest(250, 65, 12, blocks_with_echo_path_changes,
|
RunFilterUpdateTest(env, 250, 65, 12, blocks_with_echo_path_changes,
|
||||||
blocks_with_saturation, false, &e, &y, &G_a);
|
blocks_with_saturation, false, &e, &y, &G_a);
|
||||||
RunFilterUpdateTest(500, 65, 12, blocks_with_echo_path_changes,
|
RunFilterUpdateTest(env, 500, 65, 12, blocks_with_echo_path_changes,
|
||||||
blocks_with_saturation, false, &e, &y, &G_b);
|
blocks_with_saturation, false, &e, &y, &G_b);
|
||||||
RunFilterUpdateTest(750, 65, 12, blocks_with_echo_path_changes,
|
RunFilterUpdateTest(env, 750, 65, 12, blocks_with_echo_path_changes,
|
||||||
blocks_with_saturation, false, &e, &y, &G_c);
|
blocks_with_saturation, false, &e, &y, &G_c);
|
||||||
|
|
||||||
G_a.Spectrum(Aec3Optimization::kNone, G_a_power);
|
G_a.Spectrum(Aec3Optimization::kNone, G_a_power);
|
||||||
@ -317,6 +322,7 @@ TEST(RefinedFilterUpdateGain, DecreasingGain) {
|
|||||||
// Verifies that the gain is zero when there is saturation and that the internal
|
// Verifies that the gain is zero when there is saturation and that the internal
|
||||||
// error estimates cause the gain to increase after a period of saturation.
|
// error estimates cause the gain to increase after a period of saturation.
|
||||||
TEST(RefinedFilterUpdateGain, SaturationBehavior) {
|
TEST(RefinedFilterUpdateGain, SaturationBehavior) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
std::vector<int> blocks_with_saturation;
|
std::vector<int> blocks_with_saturation;
|
||||||
for (int k = 99; k < 200; ++k) {
|
for (int k = 99; k < 200; ++k) {
|
||||||
@ -336,17 +342,17 @@ TEST(RefinedFilterUpdateGain, SaturationBehavior) {
|
|||||||
std::array<float, kFftLengthBy2Plus1> G_a_power;
|
std::array<float, kFftLengthBy2Plus1> G_a_power;
|
||||||
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
||||||
|
|
||||||
RunFilterUpdateTest(100, 65, filter_length_blocks,
|
RunFilterUpdateTest(env, 100, 65, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G_a);
|
false, &e, &y, &G_a);
|
||||||
|
|
||||||
EXPECT_EQ(G_a_ref.re, G_a.re);
|
EXPECT_EQ(G_a_ref.re, G_a.re);
|
||||||
EXPECT_EQ(G_a_ref.im, G_a.im);
|
EXPECT_EQ(G_a_ref.im, G_a.im);
|
||||||
|
|
||||||
RunFilterUpdateTest(99, 65, filter_length_blocks,
|
RunFilterUpdateTest(env, 99, 65, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G_a);
|
false, &e, &y, &G_a);
|
||||||
RunFilterUpdateTest(201, 65, filter_length_blocks,
|
RunFilterUpdateTest(env, 201, 65, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G_b);
|
false, &e, &y, &G_b);
|
||||||
|
|
||||||
@ -361,6 +367,7 @@ TEST(RefinedFilterUpdateGain, SaturationBehavior) {
|
|||||||
// Verifies that the gain increases after an echo path change.
|
// Verifies that the gain increases after an echo path change.
|
||||||
// TODO(peah): Correct and reactivate this test.
|
// TODO(peah): Correct and reactivate this test.
|
||||||
TEST(RefinedFilterUpdateGain, DISABLED_EchoPathChangeBehavior) {
|
TEST(RefinedFilterUpdateGain, DISABLED_EchoPathChangeBehavior) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
for (size_t filter_length_blocks : {12, 20, 30}) {
|
for (size_t filter_length_blocks : {12, 20, 30}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(filter_length_blocks));
|
SCOPED_TRACE(ProduceDebugText(filter_length_blocks));
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
@ -374,10 +381,10 @@ TEST(RefinedFilterUpdateGain, DISABLED_EchoPathChangeBehavior) {
|
|||||||
std::array<float, kFftLengthBy2Plus1> G_a_power;
|
std::array<float, kFftLengthBy2Plus1> G_a_power;
|
||||||
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
std::array<float, kFftLengthBy2Plus1> G_b_power;
|
||||||
|
|
||||||
RunFilterUpdateTest(100, 65, filter_length_blocks,
|
RunFilterUpdateTest(env, 100, 65, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G_a);
|
false, &e, &y, &G_a);
|
||||||
RunFilterUpdateTest(101, 65, filter_length_blocks,
|
RunFilterUpdateTest(env, 101, 65, filter_length_blocks,
|
||||||
blocks_with_echo_path_changes, blocks_with_saturation,
|
blocks_with_echo_path_changes, blocks_with_saturation,
|
||||||
false, &e, &y, &G_b);
|
false, &e, &y, &G_b);
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,6 @@
|
|||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|||||||
@ -16,9 +16,10 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/field_trials_view.h"
|
||||||
#include "modules/audio_processing/aec3/reverb_model.h"
|
#include "modules/audio_processing/aec3/reverb_model.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -30,25 +31,28 @@ float GetTransparentModeGain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float GetEarlyReflectionsDefaultModeGain(
|
float GetEarlyReflectionsDefaultModeGain(
|
||||||
|
const FieldTrialsView& field_trials,
|
||||||
const EchoCanceller3Config::EpStrength& config) {
|
const EchoCanceller3Config::EpStrength& config) {
|
||||||
if (field_trial::IsEnabled("WebRTC-Aec3UseLowEarlyReflectionsDefaultGain")) {
|
if (field_trials.IsEnabled("WebRTC-Aec3UseLowEarlyReflectionsDefaultGain")) {
|
||||||
return 0.1f;
|
return 0.1f;
|
||||||
}
|
}
|
||||||
return config.default_gain;
|
return config.default_gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetLateReflectionsDefaultModeGain(
|
float GetLateReflectionsDefaultModeGain(
|
||||||
|
const FieldTrialsView& field_trials,
|
||||||
const EchoCanceller3Config::EpStrength& config) {
|
const EchoCanceller3Config::EpStrength& config) {
|
||||||
if (field_trial::IsEnabled("WebRTC-Aec3UseLowLateReflectionsDefaultGain")) {
|
if (field_trials.IsEnabled("WebRTC-Aec3UseLowLateReflectionsDefaultGain")) {
|
||||||
return 0.1f;
|
return 0.1f;
|
||||||
}
|
}
|
||||||
return config.default_gain;
|
return config.default_gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UseErleOnsetCompensationInDominantNearend(
|
bool UseErleOnsetCompensationInDominantNearend(
|
||||||
|
const FieldTrialsView& field_trials,
|
||||||
const EchoCanceller3Config::EpStrength& config) {
|
const EchoCanceller3Config::EpStrength& config) {
|
||||||
return config.erle_onset_compensation_in_dominant_nearend ||
|
return config.erle_onset_compensation_in_dominant_nearend ||
|
||||||
field_trial::IsEnabled(
|
field_trials.IsEnabled(
|
||||||
"WebRTC-Aec3UseErleOnsetCompensationInDominantNearend");
|
"WebRTC-Aec3UseErleOnsetCompensationInDominantNearend");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,18 +158,22 @@ void EchoGeneratingPower(size_t num_render_channels,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ResidualEchoEstimator::ResidualEchoEstimator(const EchoCanceller3Config& config,
|
ResidualEchoEstimator::ResidualEchoEstimator(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_render_channels)
|
size_t num_render_channels)
|
||||||
: config_(config),
|
: config_(config),
|
||||||
num_render_channels_(num_render_channels),
|
num_render_channels_(num_render_channels),
|
||||||
early_reflections_transparent_mode_gain_(GetTransparentModeGain()),
|
early_reflections_transparent_mode_gain_(GetTransparentModeGain()),
|
||||||
late_reflections_transparent_mode_gain_(GetTransparentModeGain()),
|
late_reflections_transparent_mode_gain_(GetTransparentModeGain()),
|
||||||
early_reflections_general_gain_(
|
early_reflections_general_gain_(
|
||||||
GetEarlyReflectionsDefaultModeGain(config_.ep_strength)),
|
GetEarlyReflectionsDefaultModeGain(env.field_trials(),
|
||||||
|
config_.ep_strength)),
|
||||||
late_reflections_general_gain_(
|
late_reflections_general_gain_(
|
||||||
GetLateReflectionsDefaultModeGain(config_.ep_strength)),
|
GetLateReflectionsDefaultModeGain(env.field_trials(),
|
||||||
|
config_.ep_strength)),
|
||||||
erle_onset_compensation_in_dominant_nearend_(
|
erle_onset_compensation_in_dominant_nearend_(
|
||||||
UseErleOnsetCompensationInDominantNearend(config_.ep_strength)) {
|
UseErleOnsetCompensationInDominantNearend(env.field_trials(),
|
||||||
|
config_.ep_strength)) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "modules/audio_processing/aec3/render_buffer.h"
|
#include "modules/audio_processing/aec3/render_buffer.h"
|
||||||
@ -27,7 +28,8 @@ namespace webrtc {
|
|||||||
|
|
||||||
class ResidualEchoEstimator {
|
class ResidualEchoEstimator {
|
||||||
public:
|
public:
|
||||||
ResidualEchoEstimator(const EchoCanceller3Config& config,
|
ResidualEchoEstimator(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_render_channels);
|
size_t num_render_channels);
|
||||||
~ResidualEchoEstimator();
|
~ResidualEchoEstimator();
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,8 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
@ -37,8 +39,8 @@ class ResidualEchoEstimatorTest {
|
|||||||
: num_render_channels_(num_render_channels),
|
: num_render_channels_(num_render_channels),
|
||||||
num_capture_channels_(num_capture_channels),
|
num_capture_channels_(num_capture_channels),
|
||||||
config_(config),
|
config_(config),
|
||||||
estimator_(config_, num_render_channels_),
|
estimator_(env_, config_, num_render_channels_),
|
||||||
aec_state_(config_, num_capture_channels_),
|
aec_state_(env_, config_, num_capture_channels_),
|
||||||
render_delay_buffer_(RenderDelayBuffer::Create(config_,
|
render_delay_buffer_(RenderDelayBuffer::Create(config_,
|
||||||
kSampleRateHz,
|
kSampleRateHz,
|
||||||
num_render_channels_)),
|
num_render_channels_)),
|
||||||
@ -105,6 +107,7 @@ class ResidualEchoEstimatorTest {
|
|||||||
private:
|
private:
|
||||||
const size_t num_render_channels_;
|
const size_t num_render_channels_;
|
||||||
const size_t num_capture_channels_;
|
const size_t num_capture_channels_;
|
||||||
|
const Environment env_ = CreateEnvironment();
|
||||||
const EchoCanceller3Config& config_;
|
const EchoCanceller3Config& config_;
|
||||||
ResidualEchoEstimator estimator_;
|
ResidualEchoEstimator estimator_;
|
||||||
AecState aec_state_;
|
AecState aec_state_;
|
||||||
|
|||||||
@ -13,9 +13,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/field_trials_view.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/numerics/safe_minmax.h"
|
#include "rtc_base/numerics/safe_minmax.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -34,18 +35,20 @@ std::array<float, kFftLengthBy2Plus1> SetMaxErleBands(float max_erle_l,
|
|||||||
return max_erle;
|
return max_erle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnableMinErleDuringOnsets() {
|
bool EnableMinErleDuringOnsets(const FieldTrialsView& field_trials) {
|
||||||
return !field_trial::IsEnabled("WebRTC-Aec3MinErleDuringOnsetsKillSwitch");
|
return !field_trials.IsEnabled("WebRTC-Aec3MinErleDuringOnsetsKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
SubbandErleEstimator::SubbandErleEstimator(const EchoCanceller3Config& config,
|
SubbandErleEstimator::SubbandErleEstimator(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels)
|
size_t num_capture_channels)
|
||||||
: use_onset_detection_(config.erle.onset_detection),
|
: use_onset_detection_(config.erle.onset_detection),
|
||||||
min_erle_(config.erle.min),
|
min_erle_(config.erle.min),
|
||||||
max_erle_(SetMaxErleBands(config.erle.max_l, config.erle.max_h)),
|
max_erle_(SetMaxErleBands(config.erle.max_l, config.erle.max_h)),
|
||||||
use_min_erle_during_onsets_(EnableMinErleDuringOnsets()),
|
use_min_erle_during_onsets_(
|
||||||
|
EnableMinErleDuringOnsets(env.field_trials())),
|
||||||
accum_spectra_(num_capture_channels),
|
accum_spectra_(num_capture_channels),
|
||||||
erle_(num_capture_channels),
|
erle_(num_capture_channels),
|
||||||
erle_onset_compensated_(num_capture_channels),
|
erle_onset_compensated_(num_capture_channels),
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
|
|
||||||
@ -27,7 +28,8 @@ namespace webrtc {
|
|||||||
// Estimates the echo return loss enhancement for each frequency subband.
|
// Estimates the echo return loss enhancement for each frequency subband.
|
||||||
class SubbandErleEstimator {
|
class SubbandErleEstimator {
|
||||||
public:
|
public:
|
||||||
SubbandErleEstimator(const EchoCanceller3Config& config,
|
SubbandErleEstimator(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_capture_channels);
|
size_t num_capture_channels);
|
||||||
~SubbandErleEstimator();
|
~SubbandErleEstimator();
|
||||||
|
|
||||||
|
|||||||
@ -14,19 +14,20 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/field_trials_view.h"
|
||||||
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
|
||||||
#include "modules/audio_processing/aec3/fft_data.h"
|
#include "modules/audio_processing/aec3/fft_data.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/numerics/safe_minmax.h"
|
#include "rtc_base/numerics/safe_minmax.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool UseCoarseFilterResetHangover() {
|
bool UseCoarseFilterResetHangover(const FieldTrialsView& field_trials) {
|
||||||
return !field_trial::IsEnabled(
|
return !field_trials.IsEnabled(
|
||||||
"WebRTC-Aec3CoarseFilterResetHangoverKillSwitch");
|
"WebRTC-Aec3CoarseFilterResetHangoverKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ void ScaleFilterOutput(rtc::ArrayView<const float> y,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Subtractor::Subtractor(const EchoCanceller3Config& config,
|
Subtractor::Subtractor(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels,
|
size_t num_capture_channels,
|
||||||
ApmDataDumper* data_dumper,
|
ApmDataDumper* data_dumper,
|
||||||
@ -72,7 +74,8 @@ Subtractor::Subtractor(const EchoCanceller3Config& config,
|
|||||||
optimization_(optimization),
|
optimization_(optimization),
|
||||||
config_(config),
|
config_(config),
|
||||||
num_capture_channels_(num_capture_channels),
|
num_capture_channels_(num_capture_channels),
|
||||||
use_coarse_filter_reset_hangover_(UseCoarseFilterResetHangover()),
|
use_coarse_filter_reset_hangover_(
|
||||||
|
UseCoarseFilterResetHangover(env.field_trials())),
|
||||||
refined_filters_(num_capture_channels_),
|
refined_filters_(num_capture_channels_),
|
||||||
coarse_filter_(num_capture_channels_),
|
coarse_filter_(num_capture_channels_),
|
||||||
refined_gains_(num_capture_channels_),
|
refined_gains_(num_capture_channels_),
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
|
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_fft.h"
|
#include "modules/audio_processing/aec3/aec3_fft.h"
|
||||||
@ -38,7 +39,8 @@ namespace webrtc {
|
|||||||
// Proves linear echo cancellation functionality
|
// Proves linear echo cancellation functionality
|
||||||
class Subtractor {
|
class Subtractor {
|
||||||
public:
|
public:
|
||||||
Subtractor(const EchoCanceller3Config& config,
|
Subtractor(const Environment& env,
|
||||||
|
const EchoCanceller3Config& config,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels,
|
size_t num_capture_channels,
|
||||||
ApmDataDumper* data_dumper,
|
ApmDataDumper* data_dumper,
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
|
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
|
||||||
@ -27,6 +29,7 @@ namespace webrtc {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::vector<float> RunSubtractorTest(
|
std::vector<float> RunSubtractorTest(
|
||||||
|
const Environment& env,
|
||||||
size_t num_render_channels,
|
size_t num_render_channels,
|
||||||
size_t num_capture_channels,
|
size_t num_capture_channels,
|
||||||
int num_blocks_to_process,
|
int num_blocks_to_process,
|
||||||
@ -42,7 +45,7 @@ std::vector<float> RunSubtractorTest(
|
|||||||
config.filter.refined.length_blocks = refined_filter_length_blocks;
|
config.filter.refined.length_blocks = refined_filter_length_blocks;
|
||||||
config.filter.coarse.length_blocks = coarse_filter_length_blocks;
|
config.filter.coarse.length_blocks = coarse_filter_length_blocks;
|
||||||
|
|
||||||
Subtractor subtractor(config, num_render_channels, num_capture_channels,
|
Subtractor subtractor(env, config, num_render_channels, num_capture_channels,
|
||||||
&data_dumper, DetectOptimization());
|
&data_dumper, DetectOptimization());
|
||||||
std::optional<DelayEstimate> delay_estimate;
|
std::optional<DelayEstimate> delay_estimate;
|
||||||
Block x(kNumBands, num_render_channels);
|
Block x(kNumBands, num_render_channels);
|
||||||
@ -59,7 +62,7 @@ std::vector<float> RunSubtractorTest(
|
|||||||
std::vector<std::array<float, kFftLengthBy2Plus1>> E2_refined(
|
std::vector<std::array<float, kFftLengthBy2Plus1>> E2_refined(
|
||||||
num_capture_channels);
|
num_capture_channels);
|
||||||
std::array<float, kFftLengthBy2Plus1> E2_coarse;
|
std::array<float, kFftLengthBy2Plus1> E2_coarse;
|
||||||
AecState aec_state(config, num_capture_channels);
|
AecState aec_state(env, config, num_capture_channels);
|
||||||
x_old.fill(0.f);
|
x_old.fill(0.f);
|
||||||
for (auto& Y2_ch : Y2) {
|
for (auto& Y2_ch : Y2) {
|
||||||
Y2_ch.fill(0.f);
|
Y2_ch.fill(0.f);
|
||||||
@ -190,22 +193,23 @@ std::string ProduceDebugText(size_t num_render_channels,
|
|||||||
|
|
||||||
// Verifies that the check for non data dumper works.
|
// Verifies that the check for non data dumper works.
|
||||||
TEST(SubtractorDeathTest, NullDataDumper) {
|
TEST(SubtractorDeathTest, NullDataDumper) {
|
||||||
EXPECT_DEATH(
|
EXPECT_DEATH(Subtractor(CreateEnvironment(), EchoCanceller3Config(), 1, 1,
|
||||||
Subtractor(EchoCanceller3Config(), 1, 1, nullptr, DetectOptimization()),
|
nullptr, DetectOptimization()),
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Verifies that the subtractor is able to converge on correlated data.
|
// Verifies that the subtractor is able to converge on correlated data.
|
||||||
TEST(Subtractor, Convergence) {
|
TEST(Subtractor, Convergence) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
for (size_t filter_length_blocks : {12, 20, 30}) {
|
for (size_t filter_length_blocks : {12, 20, 30}) {
|
||||||
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(1, 1, delay_samples, filter_length_blocks));
|
SCOPED_TRACE(ProduceDebugText(1, 1, delay_samples, filter_length_blocks));
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
1, 1, 2500, delay_samples, filter_length_blocks, filter_length_blocks,
|
env, 1, 1, 2500, delay_samples, filter_length_blocks,
|
||||||
false, blocks_with_echo_path_changes);
|
filter_length_blocks, false, blocks_with_echo_path_changes);
|
||||||
|
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_GT(0.1f, echo_to_nearend_power);
|
EXPECT_GT(0.1f, echo_to_nearend_power);
|
||||||
@ -217,9 +221,10 @@ TEST(Subtractor, Convergence) {
|
|||||||
// Verifies that the subtractor is able to handle the case when the refined
|
// Verifies that the subtractor is able to handle the case when the refined
|
||||||
// filter is longer than the coarse filter.
|
// filter is longer than the coarse filter.
|
||||||
TEST(Subtractor, RefinedFilterLongerThanCoarseFilter) {
|
TEST(Subtractor, RefinedFilterLongerThanCoarseFilter) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
1, 1, 400, 64, 20, 15, false, blocks_with_echo_path_changes);
|
env, 1, 1, 400, 64, 20, 15, false, blocks_with_echo_path_changes);
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_GT(0.5f, echo_to_nearend_power);
|
EXPECT_GT(0.5f, echo_to_nearend_power);
|
||||||
}
|
}
|
||||||
@ -228,9 +233,10 @@ TEST(Subtractor, RefinedFilterLongerThanCoarseFilter) {
|
|||||||
// Verifies that the subtractor is able to handle the case when the coarse
|
// Verifies that the subtractor is able to handle the case when the coarse
|
||||||
// filter is longer than the refined filter.
|
// filter is longer than the refined filter.
|
||||||
TEST(Subtractor, CoarseFilterLongerThanRefinedFilter) {
|
TEST(Subtractor, CoarseFilterLongerThanRefinedFilter) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
1, 1, 400, 64, 15, 20, false, blocks_with_echo_path_changes);
|
env, 1, 1, 400, 64, 15, 20, false, blocks_with_echo_path_changes);
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_GT(0.5f, echo_to_nearend_power);
|
EXPECT_GT(0.5f, echo_to_nearend_power);
|
||||||
}
|
}
|
||||||
@ -238,14 +244,15 @@ TEST(Subtractor, CoarseFilterLongerThanRefinedFilter) {
|
|||||||
|
|
||||||
// Verifies that the subtractor does not converge on uncorrelated signals.
|
// Verifies that the subtractor does not converge on uncorrelated signals.
|
||||||
TEST(Subtractor, NonConvergenceOnUncorrelatedSignals) {
|
TEST(Subtractor, NonConvergenceOnUncorrelatedSignals) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
for (size_t filter_length_blocks : {12, 20, 30}) {
|
for (size_t filter_length_blocks : {12, 20, 30}) {
|
||||||
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
|
||||||
SCOPED_TRACE(ProduceDebugText(1, 1, delay_samples, filter_length_blocks));
|
SCOPED_TRACE(ProduceDebugText(1, 1, delay_samples, filter_length_blocks));
|
||||||
|
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
1, 1, 3000, delay_samples, filter_length_blocks, filter_length_blocks,
|
env, 1, 1, 3000, delay_samples, filter_length_blocks,
|
||||||
true, blocks_with_echo_path_changes);
|
filter_length_blocks, true, blocks_with_echo_path_changes);
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.1);
|
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.1);
|
||||||
}
|
}
|
||||||
@ -273,12 +280,13 @@ INSTANTIATE_TEST_SUITE_P(DebugMultiChannel,
|
|||||||
TEST_P(SubtractorMultiChannelUpToEightRender, Convergence) {
|
TEST_P(SubtractorMultiChannelUpToEightRender, Convergence) {
|
||||||
const size_t num_render_channels = std::get<0>(GetParam());
|
const size_t num_render_channels = std::get<0>(GetParam());
|
||||||
const size_t num_capture_channels = std::get<1>(GetParam());
|
const size_t num_capture_channels = std::get<1>(GetParam());
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
|
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
size_t num_blocks_to_process = 2500 * num_render_channels;
|
size_t num_blocks_to_process = 2500 * num_render_channels;
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
num_render_channels, num_capture_channels, num_blocks_to_process, 64, 20,
|
env, num_render_channels, num_capture_channels, num_blocks_to_process, 64,
|
||||||
20, false, blocks_with_echo_path_changes);
|
20, 20, false, blocks_with_echo_path_changes);
|
||||||
|
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_GT(0.1f, echo_to_nearend_power);
|
EXPECT_GT(0.1f, echo_to_nearend_power);
|
||||||
@ -306,12 +314,13 @@ TEST_P(SubtractorMultiChannelUpToFourRender,
|
|||||||
NonConvergenceOnUncorrelatedSignals) {
|
NonConvergenceOnUncorrelatedSignals) {
|
||||||
const size_t num_render_channels = std::get<0>(GetParam());
|
const size_t num_render_channels = std::get<0>(GetParam());
|
||||||
const size_t num_capture_channels = std::get<1>(GetParam());
|
const size_t num_capture_channels = std::get<1>(GetParam());
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
|
|
||||||
std::vector<int> blocks_with_echo_path_changes;
|
std::vector<int> blocks_with_echo_path_changes;
|
||||||
size_t num_blocks_to_process = 5000 * num_render_channels;
|
size_t num_blocks_to_process = 5000 * num_render_channels;
|
||||||
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
std::vector<float> echo_to_nearend_powers = RunSubtractorTest(
|
||||||
num_render_channels, num_capture_channels, num_blocks_to_process, 64, 20,
|
env, num_render_channels, num_capture_channels, num_blocks_to_process, 64,
|
||||||
20, true, blocks_with_echo_path_changes);
|
20, 20, true, blocks_with_echo_path_changes);
|
||||||
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
for (float echo_to_nearend_power : echo_to_nearend_powers) {
|
||||||
EXPECT_LT(.8f, echo_to_nearend_power);
|
EXPECT_LT(.8f, echo_to_nearend_power);
|
||||||
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.25f);
|
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.25f);
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include "modules/audio_processing/aec3/vector_math.h"
|
#include "modules/audio_processing/aec3/vector_math.h"
|
||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "modules/audio_processing/aec3/suppression_gain.h"
|
#include "modules/audio_processing/aec3/suppression_gain.h"
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/environment/environment_factory.h"
|
||||||
#include "modules/audio_processing/aec3/aec_state.h"
|
#include "modules/audio_processing/aec3/aec_state.h"
|
||||||
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
#include "modules/audio_processing/aec3/render_delay_buffer.h"
|
||||||
#include "modules/audio_processing/aec3/subtractor.h"
|
#include "modules/audio_processing/aec3/subtractor.h"
|
||||||
@ -42,7 +44,7 @@ TEST(SuppressionGainDeathTest, NullOutputGains) {
|
|||||||
Y.im.fill(0.0f);
|
Y.im.fill(0.0f);
|
||||||
|
|
||||||
float high_bands_gain;
|
float high_bands_gain;
|
||||||
AecState aec_state(EchoCanceller3Config{}, 1);
|
AecState aec_state(CreateEnvironment(), EchoCanceller3Config{}, 1);
|
||||||
EXPECT_DEATH(
|
EXPECT_DEATH(
|
||||||
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000, 1)
|
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000, 1)
|
||||||
.GetGain(E2, S2, R2, R2_unbounded, N2,
|
.GetGain(E2, S2, R2, R2_unbounded, N2,
|
||||||
@ -74,10 +76,11 @@ TEST(SuppressionGain, BasicGainComputation) {
|
|||||||
std::array<float, kFftLengthBy2Plus1> g;
|
std::array<float, kFftLengthBy2Plus1> g;
|
||||||
std::vector<SubtractorOutput> output(kNumCaptureChannels);
|
std::vector<SubtractorOutput> output(kNumCaptureChannels);
|
||||||
Block x(kNumBands, kNumRenderChannels);
|
Block x(kNumBands, kNumRenderChannels);
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
EchoCanceller3Config config;
|
EchoCanceller3Config config;
|
||||||
AecState aec_state(config, kNumCaptureChannels);
|
AecState aec_state(env, config, kNumCaptureChannels);
|
||||||
ApmDataDumper data_dumper(42);
|
ApmDataDumper data_dumper(42);
|
||||||
Subtractor subtractor(config, kNumRenderChannels, kNumCaptureChannels,
|
Subtractor subtractor(env, config, kNumRenderChannels, kNumCaptureChannels,
|
||||||
&data_dumper, DetectOptimization());
|
&data_dumper, DetectOptimization());
|
||||||
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
|
||||||
RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
|
RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
|
||||||
|
|||||||
@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
#include "modules/audio_processing/aec3/transparent_mode.h"
|
#include "modules/audio_processing/aec3/transparent_mode.h"
|
||||||
|
|
||||||
|
#include "api/environment/environment.h"
|
||||||
|
#include "api/field_trials_view.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -21,12 +22,12 @@ constexpr size_t kBlocksSinceConvergencedFilterInit = 10000;
|
|||||||
constexpr size_t kBlocksSinceConsistentEstimateInit = 10000;
|
constexpr size_t kBlocksSinceConsistentEstimateInit = 10000;
|
||||||
constexpr float kInitialTransparentStateProbability = 0.2f;
|
constexpr float kInitialTransparentStateProbability = 0.2f;
|
||||||
|
|
||||||
bool DeactivateTransparentMode() {
|
bool DeactivateTransparentMode(const FieldTrialsView& field_trials) {
|
||||||
return field_trial::IsEnabled("WebRTC-Aec3TransparentModeKillSwitch");
|
return field_trials.IsEnabled("WebRTC-Aec3TransparentModeKillSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActivateTransparentModeHmm() {
|
bool ActivateTransparentModeHmm(const FieldTrialsView& field_trials) {
|
||||||
return field_trial::IsEnabled("WebRTC-Aec3TransparentModeHmm");
|
return field_trials.IsEnabled("WebRTC-Aec3TransparentModeHmm");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -228,12 +229,14 @@ class LegacyTransparentModeImpl : public TransparentMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<TransparentMode> TransparentMode::Create(
|
std::unique_ptr<TransparentMode> TransparentMode::Create(
|
||||||
|
const Environment& env,
|
||||||
const EchoCanceller3Config& config) {
|
const EchoCanceller3Config& config) {
|
||||||
if (config.ep_strength.bounded_erl || DeactivateTransparentMode()) {
|
if (config.ep_strength.bounded_erl ||
|
||||||
|
DeactivateTransparentMode(env.field_trials())) {
|
||||||
RTC_LOG(LS_INFO) << "AEC3 Transparent Mode: Disabled";
|
RTC_LOG(LS_INFO) << "AEC3 Transparent Mode: Disabled";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (ActivateTransparentModeHmm()) {
|
if (ActivateTransparentModeHmm(env.field_trials())) {
|
||||||
RTC_LOG(LS_INFO) << "AEC3 Transparent Mode: HMM";
|
RTC_LOG(LS_INFO) << "AEC3 Transparent Mode: HMM";
|
||||||
return std::make_unique<TransparentModeImpl>();
|
return std::make_unique<TransparentModeImpl>();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "api/audio/echo_canceller3_config.h"
|
#include "api/audio/echo_canceller3_config.h"
|
||||||
|
#include "api/environment/environment.h"
|
||||||
#include "modules/audio_processing/aec3/aec3_common.h"
|
#include "modules/audio_processing/aec3/aec3_common.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -23,6 +24,7 @@ namespace webrtc {
|
|||||||
class TransparentMode {
|
class TransparentMode {
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TransparentMode> Create(
|
static std::unique_ptr<TransparentMode> Create(
|
||||||
|
const Environment& env,
|
||||||
const EchoCanceller3Config& config);
|
const EchoCanceller3Config& config);
|
||||||
|
|
||||||
virtual ~TransparentMode() {}
|
virtual ~TransparentMode() {}
|
||||||
|
|||||||
@ -19,7 +19,6 @@
|
|||||||
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user