Delete deprecated AEC interfaces

They've been officially deprecated since September 4, 2018.
PSA: https://groups.google.com/forum/#!topic/discuss-webrtc/r_9n-PRUIX4

Bug: webrtc:9535
Change-Id: I294e22ae874b1edd81a0a0347755d82c5ebc61e0
Reviewed-on: https://webrtc-review.googlesource.com/c/103444
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Commit-Queue: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24971}
This commit is contained in:
saza 2018-10-03 17:03:13 +02:00 committed by Commit Bot
parent 4b6c2ec5db
commit be490b2abe
17 changed files with 154 additions and 592 deletions

View File

@ -37,12 +37,8 @@ rtc_static_library("audio_processing") {
"common.h",
"echo_cancellation_impl.cc",
"echo_cancellation_impl.h",
"echo_cancellation_proxy.cc",
"echo_cancellation_proxy.h",
"echo_control_mobile_impl.cc",
"echo_control_mobile_impl.h",
"echo_control_mobile_proxy.cc",
"echo_control_mobile_proxy.h",
"echo_detector/circular_buffer.cc",
"echo_detector/circular_buffer.h",
"echo_detector/mean_variance_estimator.cc",

View File

@ -24,9 +24,7 @@
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/common.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/echo_cancellation_proxy.h"
#include "modules/audio_processing/echo_control_mobile_impl.h"
#include "modules/audio_processing/echo_control_mobile_proxy.h"
#include "modules/audio_processing/gain_control_for_experimental_agc.h"
#include "modules/audio_processing/gain_control_impl.h"
#include "modules/audio_processing/gain_controller2.h"
@ -253,8 +251,6 @@ struct AudioProcessingImpl::ApmPublicSubmodules {
// Accessed externally of APM without any lock acquired.
std::unique_ptr<EchoCancellationImpl> echo_cancellation;
std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
std::unique_ptr<EchoCancellationProxy> echo_cancellation_proxy;
std::unique_ptr<EchoControlMobileProxy> echo_control_mobile_proxy;
std::unique_ptr<GainControlImpl> gain_control;
std::unique_ptr<LevelEstimatorImpl> level_estimator;
std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
@ -398,11 +394,6 @@ AudioProcessingImpl::AudioProcessingImpl(
new EchoCancellationImpl(&crit_render_, &crit_capture_));
public_submodules_->echo_control_mobile.reset(
new EchoControlMobileImpl(&crit_render_, &crit_capture_));
public_submodules_->echo_cancellation_proxy.reset(new EchoCancellationProxy(
this, public_submodules_->echo_cancellation.get()));
public_submodules_->echo_control_mobile_proxy.reset(
new EchoControlMobileProxy(
this, public_submodules_->echo_control_mobile.get()));
public_submodules_->gain_control.reset(
new GainControlImpl(&crit_render_, &crit_capture_));
public_submodules_->level_estimator.reset(
@ -684,8 +675,8 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
public_submodules_->echo_cancellation->set_suppression_level(
config.echo_canceller.legacy_moderate_suppression_level
? EchoCancellation::SuppressionLevel::kModerateSuppression
: EchoCancellation::SuppressionLevel::kHighSuppression);
? EchoCancellationImpl::SuppressionLevel::kModerateSuppression
: EchoCancellationImpl::SuppressionLevel::kHighSuppression);
InitializeLowCutFilter();
@ -1650,7 +1641,7 @@ AudioProcessingStats AudioProcessing::GetStatistics(
AudioProcessing::AudioProcessingStatistics AudioProcessingImpl::GetStatistics()
const {
AudioProcessingStatistics stats;
EchoCancellation::Metrics metrics;
EchoCancellationImpl::Metrics metrics;
if (private_submodules_->echo_controller) {
rtc::CritScope cs_capture(&crit_capture_);
auto ec_metrics = private_submodules_->echo_controller->GetMetrics();
@ -1686,7 +1677,7 @@ AudioProcessingStats AudioProcessingImpl::GetStatistics(
bool has_remote_tracks) const {
AudioProcessingStats stats;
if (has_remote_tracks) {
EchoCancellation::Metrics metrics;
EchoCancellationImpl::Metrics metrics;
if (private_submodules_->echo_controller) {
rtc::CritScope cs_capture(&crit_capture_);
auto ec_metrics = private_submodules_->echo_controller->GetMetrics();
@ -1733,14 +1724,6 @@ AudioProcessingStats AudioProcessingImpl::GetStatistics(
return stats;
}
EchoCancellation* AudioProcessingImpl::echo_cancellation() const {
return public_submodules_->echo_cancellation_proxy.get();
}
EchoControlMobile* AudioProcessingImpl::echo_control_mobile() const {
return public_submodules_->echo_control_mobile_proxy.get();
}
GainControl* AudioProcessingImpl::gain_control() const {
if (constants_.use_experimental_agc) {
return public_submodules_->gain_control_for_experimental_agc.get();

View File

@ -117,8 +117,6 @@ class AudioProcessingImpl : public AudioProcessing {
// would offer no protection (the submodules are
// created only once in a single-treaded manner
// during APM creation).
EchoCancellation* echo_cancellation() const override;
EchoControlMobile* echo_control_mobile() const override;
GainControl* gain_control() const override;
// TODO(peah): Deprecate this API call.
HighPassFilter* high_pass_filter() const override;

View File

@ -22,7 +22,7 @@ namespace {
const int kNumFramesToProcess = 100;
void SetupComponent(int sample_rate_hz,
EchoCancellation::SuppressionLevel suppression_level,
EchoCancellationImpl::SuppressionLevel suppression_level,
bool drift_compensation_enabled,
EchoCancellationImpl* echo_canceller) {
echo_canceller->Initialize(sample_rate_hz, 1, 1, 1);
@ -65,14 +65,15 @@ void ProcessOneFrame(int sample_rate_hz,
}
}
void RunBitexactnessTest(int sample_rate_hz,
size_t num_channels,
int stream_delay_ms,
bool drift_compensation_enabled,
int stream_drift_samples,
EchoCancellation::SuppressionLevel suppression_level,
bool stream_has_echo_reference,
const rtc::ArrayView<const float>& output_reference) {
void RunBitexactnessTest(
int sample_rate_hz,
size_t num_channels,
int stream_delay_ms,
bool drift_compensation_enabled,
int stream_drift_samples,
EchoCancellationImpl::SuppressionLevel suppression_level,
bool stream_has_echo_reference,
const rtc::ArrayView<const float>& output_reference) {
rtc::CriticalSection crit_render;
rtc::CriticalSection crit_capture;
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
@ -147,7 +148,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {-0.000646f, -0.001525f, 0.002688f};
RunBitexactnessTest(8000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -161,7 +162,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -175,7 +176,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {-0.000671f, 0.000061f, -0.000031f};
RunBitexactnessTest(32000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -189,7 +190,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {-0.001403f, -0.001411f, -0.000755f};
RunBitexactnessTest(48000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -207,7 +208,7 @@ TEST(EchoCancellationBitExactnessTest,
const float kOutputReference[] = {-0.000009f, 0.000363f, 0.001094f};
#endif
RunBitexactnessTest(16000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kLowSuppression,
EchoCancellationImpl::SuppressionLevel::kLowSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -220,9 +221,10 @@ TEST(EchoCancellationBitExactnessTest,
DISABLED_Mono16kHz_ModerateLevel_NoDrift_StreamDelay0) {
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 0, false, 0,
EchoCancellation::SuppressionLevel::kModerateSuppression,
kStreamHasEchoReference, kOutputReference);
RunBitexactnessTest(
16000, 1, 0, false, 0,
EchoCancellationImpl::SuppressionLevel::kModerateSuppression,
kStreamHasEchoReference, kOutputReference);
}
#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
@ -235,7 +237,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 10, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -249,7 +251,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 20, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -263,7 +265,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 0, true, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -277,7 +279,7 @@ TEST(EchoCancellationBitExactnessTest,
#endif
const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
RunBitexactnessTest(16000, 1, 0, true, 5,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -297,7 +299,7 @@ TEST(EchoCancellationBitExactnessTest,
-0.000464f, -0.001525f, 0.002933f};
#endif
RunBitexactnessTest(8000, 2, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -312,7 +314,7 @@ TEST(EchoCancellationBitExactnessTest,
const float kOutputReference[] = {0.000166f, 0.000735f, 0.000841f,
0.000166f, 0.000735f, 0.000841f};
RunBitexactnessTest(16000, 2, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -332,7 +334,7 @@ TEST(EchoCancellationBitExactnessTest,
-0.000427f, 0.000183f, 0.000183f};
#endif
RunBitexactnessTest(32000, 2, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}
@ -347,7 +349,7 @@ TEST(EchoCancellationBitExactnessTest,
const float kOutputReference[] = {-0.001101f, -0.001101f, -0.000449f,
-0.001101f, -0.001101f, -0.000449f};
RunBitexactnessTest(48000, 2, 0, false, 0,
EchoCancellation::SuppressionLevel::kHighSuppression,
EchoCancellationImpl::SuppressionLevel::kHighSuppression,
kStreamHasEchoReference, kOutputReference);
}

View File

@ -21,13 +21,13 @@
namespace webrtc {
namespace {
int16_t MapSetting(EchoCancellation::SuppressionLevel level) {
int16_t MapSetting(EchoCancellationImpl::SuppressionLevel level) {
switch (level) {
case EchoCancellation::kLowSuppression:
case EchoCancellationImpl::kLowSuppression:
return kAecNlpConservative;
case EchoCancellation::kModerateSuppression:
case EchoCancellationImpl::kModerateSuppression:
return kAecNlpModerate;
case EchoCancellation::kHighSuppression:
case EchoCancellationImpl::kHighSuppression:
return kAecNlpAggressive;
}
RTC_NOTREACHED();
@ -242,7 +242,7 @@ int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
return Configure();
}
EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level()
EchoCancellationImpl::SuppressionLevel EchoCancellationImpl::suppression_level()
const {
rtc::CritScope cs(crit_capture_);
return suppression_level_;

View File

@ -22,39 +22,106 @@ namespace webrtc {
class AudioBuffer;
class EchoCancellationImpl : EchoCancellation {
// The acoustic echo cancellation (AEC) component provides better performance
// than AECM but also requires more processing power and is dependent on delay
// stability and reporting accuracy. As such it is well-suited and recommended
// for PC and IP phone applications.
class EchoCancellationImpl {
public:
EchoCancellationImpl(rtc::CriticalSection* crit_render,
rtc::CriticalSection* crit_capture);
~EchoCancellationImpl() override;
~EchoCancellationImpl();
void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
// EchoCancellation implementation.
int Enable(bool enable) override;
bool is_enabled() const override;
int enable_drift_compensation(bool enable) override;
bool is_drift_compensation_enabled() const override;
void set_stream_drift_samples(int drift) override;
int stream_drift_samples() const override;
int set_suppression_level(SuppressionLevel level) override;
SuppressionLevel suppression_level() const override;
bool stream_has_echo() const override;
// Enable logging of various AEC statistics.
int enable_metrics(bool enable) override;
bool are_metrics_enabled() const override;
int Enable(bool enable);
bool is_enabled() const;
// Differences in clock speed on the primary and reverse streams can impact
// the AEC performance. On the client-side, this could be seen when different
// render and capture devices are used, particularly with webcams.
//
// This enables a compensation mechanism, and requires that
// set_stream_drift_samples() be called.
int enable_drift_compensation(bool enable);
bool is_drift_compensation_enabled() const;
// Sets the difference between the number of samples rendered and captured by
// the audio devices since the last call to |ProcessStream()|. Must be called
// if drift compensation is enabled, prior to |ProcessStream()|.
void set_stream_drift_samples(int drift);
int stream_drift_samples() const;
enum SuppressionLevel {
kLowSuppression,
kModerateSuppression,
kHighSuppression
};
// Sets the aggressiveness of the suppressor. A higher level trades off
// double-talk performance for increased echo suppression.
int set_suppression_level(SuppressionLevel level);
SuppressionLevel suppression_level() const;
// Returns false if the current frame almost certainly contains no echo
// and true if it _might_ contain echo.
bool stream_has_echo() const;
// Enables the computation of various echo metrics. These are obtained
// through |GetMetrics()|.
int enable_metrics(bool enable);
bool are_metrics_enabled() const;
// Each statistic is reported in dB.
// P_far: Far-end (render) signal power.
// P_echo: Near-end (capture) echo signal power.
// P_out: Signal power at the output of the AEC.
// P_a: Internal signal power at the point before the AEC's non-linear
// processor.
struct Metrics {
// RERL = ERL + ERLE
AudioProcessing::Statistic residual_echo_return_loss;
// ERL = 10log_10(P_far / P_echo)
AudioProcessing::Statistic echo_return_loss;
// ERLE = 10log_10(P_echo / P_out)
AudioProcessing::Statistic echo_return_loss_enhancement;
// (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
AudioProcessing::Statistic a_nlp;
// Fraction of time that the AEC linear filter is divergent, in a 1-second
// non-overlapped aggregation window.
float divergent_filter_fraction;
};
// Provides various statistics about the AEC.
int GetMetrics(Metrics* metrics) override;
// Enable logging of delay metrics.
int enable_delay_logging(bool enable) override;
bool is_delay_logging_enabled() const override;
int GetMetrics(Metrics* metrics);
// Enables computation and logging of delay values. Statistics are obtained
// through |GetDelayMetrics()|.
int enable_delay_logging(bool enable);
bool is_delay_logging_enabled() const;
// Provides delay metrics.
int GetDelayMetrics(int* median, int* std) override;
int GetDelayMetrics(int* median,
int* std,
float* fraction_poor_delays) override;
struct AecCore* aec_core() const override;
// The delay metrics consists of the delay |median| and the delay standard
// deviation |std|. It also consists of the fraction of delay estimates
// |fraction_poor_delays| that can make the echo cancellation perform poorly.
// The values are aggregated until the first call to |GetDelayMetrics()| and
// afterwards aggregated and updated every second.
// Note that if there are several clients pulling metrics from
// |GetDelayMetrics()| during a session the first call from any of them will
// change to one second aggregation window for all.
int GetDelayMetrics(int* median, int* std);
int GetDelayMetrics(int* median, int* std, float* fraction_poor_delays);
// Returns a pointer to the low level AEC component. In case of multiple
// channels, the pointer to the first one is returned. A NULL pointer is
// returned when the AEC component is disabled or has not been initialized
// successfully.
struct AecCore* aec_core() const;
void Initialize(int sample_rate_hz,
size_t num_reverse_channels_,

View File

@ -95,16 +95,17 @@ TEST(EchoCancellationInternalTest, InterfaceConfiguration) {
EXPECT_EQ(0, echo_canceller.enable_drift_compensation(false));
EXPECT_FALSE(echo_canceller.is_drift_compensation_enabled());
EchoCancellation::SuppressionLevel level[] = {
EchoCancellation::kLowSuppression, EchoCancellation::kModerateSuppression,
EchoCancellation::kHighSuppression,
EchoCancellationImpl::SuppressionLevel level[] = {
EchoCancellationImpl::kLowSuppression,
EchoCancellationImpl::kModerateSuppression,
EchoCancellationImpl::kHighSuppression,
};
for (size_t i = 0; i < arraysize(level); i++) {
EXPECT_EQ(0, echo_canceller.set_suppression_level(level[i]));
EXPECT_EQ(level[i], echo_canceller.suppression_level());
}
EchoCancellation::Metrics metrics;
EchoCancellationImpl::Metrics metrics;
EXPECT_EQ(AudioProcessing::kNotEnabledError,
echo_canceller.GetMetrics(&metrics));

View File

@ -1,107 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_processing/echo_cancellation_proxy.h"
#include "rtc_base/logging.h"
namespace webrtc {
EchoCancellationProxy::EchoCancellationProxy(
AudioProcessing* audio_processing,
EchoCancellationImpl* echo_cancellation)
: audio_processing_(audio_processing),
echo_cancellation_(echo_cancellation) {}
EchoCancellationProxy::~EchoCancellationProxy() = default;
int EchoCancellationProxy::Enable(bool enable) {
// Change the config in APM to mirror the applied settings.
AudioProcessing::Config apm_config = audio_processing_->GetConfig();
bool aec2_enabled = apm_config.echo_canceller.enabled &&
!apm_config.echo_canceller.mobile_mode;
if ((aec2_enabled && !enable) || (!aec2_enabled && enable)) {
apm_config.echo_canceller.enabled = enable;
apm_config.echo_canceller.mobile_mode = false;
audio_processing_->ApplyConfig(apm_config);
}
return AudioProcessing::kNoError;
}
bool EchoCancellationProxy::is_enabled() const {
return echo_cancellation_->is_enabled();
}
int EchoCancellationProxy::enable_drift_compensation(bool enable) {
return echo_cancellation_->enable_drift_compensation(enable);
}
bool EchoCancellationProxy::is_drift_compensation_enabled() const {
return echo_cancellation_->is_drift_compensation_enabled();
}
void EchoCancellationProxy::set_stream_drift_samples(int drift) {
echo_cancellation_->set_stream_drift_samples(drift);
}
int EchoCancellationProxy::stream_drift_samples() const {
return echo_cancellation_->stream_drift_samples();
}
int EchoCancellationProxy::set_suppression_level(
EchoCancellation::SuppressionLevel level) {
if (level == EchoCancellation::SuppressionLevel::kLowSuppression) {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 low suppression";
return AudioProcessing::kBadParameterError;
}
AudioProcessing::Config apm_config = audio_processing_->GetConfig();
apm_config.echo_canceller.legacy_moderate_suppression_level =
(level == EchoCancellation::SuppressionLevel::kModerateSuppression);
audio_processing_->ApplyConfig(apm_config);
return AudioProcessing::kNoError;
}
EchoCancellation::SuppressionLevel EchoCancellationProxy::suppression_level()
const {
return echo_cancellation_->suppression_level();
}
bool EchoCancellationProxy::stream_has_echo() const {
return echo_cancellation_->stream_has_echo();
}
int EchoCancellationProxy::enable_metrics(bool enable) {
return echo_cancellation_->enable_metrics(enable);
}
bool EchoCancellationProxy::are_metrics_enabled() const {
return echo_cancellation_->are_metrics_enabled();
}
int EchoCancellationProxy::GetMetrics(Metrics* metrics) {
return echo_cancellation_->GetMetrics(metrics);
}
int EchoCancellationProxy::enable_delay_logging(bool enable) {
return echo_cancellation_->enable_delay_logging(enable);
}
bool EchoCancellationProxy::is_delay_logging_enabled() const {
return echo_cancellation_->is_delay_logging_enabled();
}
int EchoCancellationProxy::GetDelayMetrics(int* median, int* std) {
return echo_cancellation_->GetDelayMetrics(median, std);
}
int EchoCancellationProxy::GetDelayMetrics(int* median,
int* std,
float* fraction_poor_delays) {
return echo_cancellation_->GetDelayMetrics(median, std, fraction_poor_delays);
}
struct AecCore* EchoCancellationProxy::aec_core() const {
return echo_cancellation_->aec_core();
}
} // namespace webrtc

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_
#define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
namespace webrtc {
// Class for temporarily redirecting AEC2 configuration to a new API.
class EchoCancellationProxy : public EchoCancellation {
public:
EchoCancellationProxy(AudioProcessing* audio_processing,
EchoCancellationImpl* echo_cancellation);
~EchoCancellationProxy() override;
int Enable(bool enable) override;
bool is_enabled() const override;
int enable_drift_compensation(bool enable) override;
bool is_drift_compensation_enabled() const override;
void set_stream_drift_samples(int drift) override;
int stream_drift_samples() const override;
int set_suppression_level(SuppressionLevel level) override;
SuppressionLevel suppression_level() const override;
bool stream_has_echo() const override;
int enable_metrics(bool enable) override;
bool are_metrics_enabled() const override;
int GetMetrics(Metrics* metrics) override;
int enable_delay_logging(bool enable) override;
bool is_delay_logging_enabled() const override;
int GetDelayMetrics(int* median, int* std) override;
int GetDelayMetrics(int* median,
int* std,
float* fraction_poor_delays) override;
struct AecCore* aec_core() const override;
private:
AudioProcessing* audio_processing_;
EchoCancellationImpl* echo_cancellation_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationProxy);
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_

View File

@ -24,6 +24,8 @@ namespace webrtc {
class AudioBuffer;
// The acoustic echo control for mobile (AECM) component is a low complexity
// robust option intended for use on mobile devices.
class EchoControlMobileImpl {
public:
EchoControlMobileImpl(rtc::CriticalSection* crit_render,

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_processing/echo_control_mobile_proxy.h"
#include "rtc_base/logging.h"
namespace webrtc {
EchoControlMobileProxy::EchoControlMobileProxy(
AudioProcessing* audio_processing,
EchoControlMobileImpl* echo_control_mobile)
: audio_processing_(audio_processing),
echo_control_mobile_(echo_control_mobile) {}
EchoControlMobileProxy::~EchoControlMobileProxy() = default;
int EchoControlMobileProxy::Enable(bool enable) {
AudioProcessing::Config apm_config = audio_processing_->GetConfig();
bool aecm_enabled = apm_config.echo_canceller.enabled &&
apm_config.echo_canceller.mobile_mode;
if ((aecm_enabled && !enable) || (!aecm_enabled && enable)) {
apm_config.echo_canceller.enabled = enable;
apm_config.echo_canceller.mobile_mode = true;
audio_processing_->ApplyConfig(apm_config);
}
return AudioProcessing::kNoError;
}
bool EchoControlMobileProxy::is_enabled() const {
return echo_control_mobile_->is_enabled();
}
int EchoControlMobileProxy::set_routing_mode(RoutingMode mode) {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AECM routing mode";
return AudioProcessing::kUnsupportedFunctionError;
}
EchoControlMobile::RoutingMode EchoControlMobileProxy::routing_mode() const {
return EchoControlMobile::kSpeakerphone;
}
int EchoControlMobileProxy::enable_comfort_noise(bool enable) {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AECM comfort noise";
return AudioProcessing::kUnsupportedFunctionError;
}
bool EchoControlMobileProxy::is_comfort_noise_enabled() const {
return false;
}
int EchoControlMobileProxy::SetEchoPath(const void* echo_path,
size_t size_bytes) {
return AudioProcessing::kUnsupportedFunctionError;
}
int EchoControlMobileProxy::GetEchoPath(void* echo_path,
size_t size_bytes) const {
return AudioProcessing::kUnsupportedFunctionError;
}
} // namespace webrtc

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_
#define MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_
#include "modules/audio_processing/echo_control_mobile_impl.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
namespace webrtc {
// Class for temporarily redirecting AECM configuration to a new API.
class EchoControlMobileProxy : public EchoControlMobile {
public:
EchoControlMobileProxy(AudioProcessing* audio_processing,
EchoControlMobileImpl* echo_control_mobile);
~EchoControlMobileProxy() override;
bool is_enabled() const override;
RoutingMode routing_mode() const override;
bool is_comfort_noise_enabled() const override;
int Enable(bool enable) override;
int set_routing_mode(RoutingMode mode) override;
int enable_comfort_noise(bool enable) override;
int SetEchoPath(const void* echo_path, size_t size_bytes) override;
int GetEchoPath(void* echo_path, size_t size_bytes) const override;
private:
AudioProcessing* audio_processing_;
EchoControlMobileImpl* echo_control_mobile_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoControlMobileProxy);
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_

View File

@ -47,8 +47,6 @@ class AudioFrame;
class StreamConfig;
class ProcessingConfig;
class EchoCancellation;
class EchoControlMobile;
class EchoDetector;
class GainControl;
class HighPassFilter;
@ -83,9 +81,8 @@ struct ExtendedFilter {
};
// Enables the refined linear filter adaptation in the echo canceller.
// This configuration only applies to EchoCancellation and not
// EchoControlMobile. It can be set in the constructor
// or using AudioProcessing::SetExtraOptions().
// This configuration only applies to non-mobile echo cancellation.
// It can be set in the constructor or using AudioProcessing::SetExtraOptions().
struct RefinedAdaptiveFilter {
RefinedAdaptiveFilter() : enabled(false) {}
explicit RefinedAdaptiveFilter(bool enabled) : enabled(enabled) {}
@ -96,9 +93,9 @@ struct RefinedAdaptiveFilter {
// Enables delay-agnostic echo cancellation. This feature relies on internally
// estimated delays between the process and reverse streams, thus not relying
// on reported system delays. This configuration only applies to
// EchoCancellation and not EchoControlMobile. It can be set in the constructor
// or using AudioProcessing::SetExtraOptions().
// on reported system delays. This configuration only applies to non-mobile echo
// cancellation. It can be set in the constructor or using
// AudioProcessing::SetExtraOptions().
struct DelayAgnostic {
DelayAgnostic() : enabled(false) {}
explicit DelayAgnostic(bool enabled) : enabled(enabled) {}
@ -600,8 +597,6 @@ class AudioProcessing : public rtc::RefCountInterface {
// These provide access to the component interfaces and should never return
// NULL. The pointers will be valid for the lifetime of the APM instance.
// The memory for these objects is entirely managed internally.
virtual EchoCancellation* echo_cancellation() const = 0;
virtual EchoControlMobile* echo_control_mobile() const = 0;
virtual GainControl* gain_control() const = 0;
// TODO(peah): Deprecate this API call.
virtual HighPassFilter* high_pass_filter() const = 0;
@ -794,168 +789,6 @@ class ProcessingConfig {
StreamConfig streams[StreamName::kNumStreamNames];
};
// The acoustic echo cancellation (AEC) component provides better performance
// than AECM but also requires more processing power and is dependent on delay
// stability and reporting accuracy. As such it is well-suited and recommended
// for PC and IP phone applications.
//
// Not recommended to be enabled on the server-side.
class EchoCancellation {
public:
// EchoCancellation and EchoControlMobile may not be enabled simultaneously.
// Enabling one will disable the other.
virtual int Enable(bool enable) = 0;
virtual bool is_enabled() const = 0;
// Differences in clock speed on the primary and reverse streams can impact
// the AEC performance. On the client-side, this could be seen when different
// render and capture devices are used, particularly with webcams.
//
// This enables a compensation mechanism, and requires that
// set_stream_drift_samples() be called.
virtual int enable_drift_compensation(bool enable) = 0;
virtual bool is_drift_compensation_enabled() const = 0;
// Sets the difference between the number of samples rendered and captured by
// the audio devices since the last call to |ProcessStream()|. Must be called
// if drift compensation is enabled, prior to |ProcessStream()|.
virtual void set_stream_drift_samples(int drift) = 0;
virtual int stream_drift_samples() const = 0;
enum SuppressionLevel {
kLowSuppression,
kModerateSuppression,
kHighSuppression
};
// Sets the aggressiveness of the suppressor. A higher level trades off
// double-talk performance for increased echo suppression.
virtual int set_suppression_level(SuppressionLevel level) = 0;
virtual SuppressionLevel suppression_level() const = 0;
// Returns false if the current frame almost certainly contains no echo
// and true if it _might_ contain echo.
virtual bool stream_has_echo() const = 0;
// Enables the computation of various echo metrics. These are obtained
// through |GetMetrics()|.
virtual int enable_metrics(bool enable) = 0;
virtual bool are_metrics_enabled() const = 0;
// Each statistic is reported in dB.
// P_far: Far-end (render) signal power.
// P_echo: Near-end (capture) echo signal power.
// P_out: Signal power at the output of the AEC.
// P_a: Internal signal power at the point before the AEC's non-linear
// processor.
struct Metrics {
// RERL = ERL + ERLE
AudioProcessing::Statistic residual_echo_return_loss;
// ERL = 10log_10(P_far / P_echo)
AudioProcessing::Statistic echo_return_loss;
// ERLE = 10log_10(P_echo / P_out)
AudioProcessing::Statistic echo_return_loss_enhancement;
// (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
AudioProcessing::Statistic a_nlp;
// Fraction of time that the AEC linear filter is divergent, in a 1-second
// non-overlapped aggregation window.
float divergent_filter_fraction;
};
// Deprecated. Use GetStatistics on the AudioProcessing interface instead.
// TODO(ajm): discuss the metrics update period.
virtual int GetMetrics(Metrics* metrics) = 0;
// Enables computation and logging of delay values. Statistics are obtained
// through |GetDelayMetrics()|.
virtual int enable_delay_logging(bool enable) = 0;
virtual bool is_delay_logging_enabled() const = 0;
// The delay metrics consists of the delay |median| and the delay standard
// deviation |std|. It also consists of the fraction of delay estimates
// |fraction_poor_delays| that can make the echo cancellation perform poorly.
// The values are aggregated until the first call to |GetDelayMetrics()| and
// afterwards aggregated and updated every second.
// Note that if there are several clients pulling metrics from
// |GetDelayMetrics()| during a session the first call from any of them will
// change to one second aggregation window for all.
// Deprecated. Use GetStatistics on the AudioProcessing interface instead.
virtual int GetDelayMetrics(int* median, int* std) = 0;
// Deprecated. Use GetStatistics on the AudioProcessing interface instead.
virtual int GetDelayMetrics(int* median,
int* std,
float* fraction_poor_delays) = 0;
// Returns a pointer to the low level AEC component. In case of multiple
// channels, the pointer to the first one is returned. A NULL pointer is
// returned when the AEC component is disabled or has not been initialized
// successfully.
virtual struct AecCore* aec_core() const = 0;
protected:
virtual ~EchoCancellation() {}
};
// The acoustic echo control for mobile (AECM) component is a low complexity
// robust option intended for use on mobile devices.
//
// Not recommended to be enabled on the server-side.
class EchoControlMobile {
public:
// EchoCancellation and EchoControlMobile may not be enabled simultaneously.
// Enabling one will disable the other.
virtual int Enable(bool enable) = 0;
virtual bool is_enabled() const = 0;
// Recommended settings for particular audio routes. In general, the louder
// the echo is expected to be, the higher this value should be set. The
// preferred setting may vary from device to device.
enum RoutingMode {
kQuietEarpieceOrHeadset,
kEarpiece,
kLoudEarpiece,
kSpeakerphone,
kLoudSpeakerphone
};
// Sets echo control appropriate for the audio routing |mode| on the device.
// It can and should be updated during a call if the audio routing changes.
virtual int set_routing_mode(RoutingMode mode) = 0;
virtual RoutingMode routing_mode() const = 0;
// Comfort noise replaces suppressed background noise to maintain a
// consistent signal level.
virtual int enable_comfort_noise(bool enable) = 0;
virtual bool is_comfort_noise_enabled() const = 0;
// A typical use case is to initialize the component with an echo path from a
// previous call. The echo path is retrieved using |GetEchoPath()|, typically
// at the end of a call. The data can then be stored for later use as an
// initializer before the next call, using |SetEchoPath()|.
//
// Controlling the echo path this way requires the data |size_bytes| to match
// the internal echo path size. This size can be acquired using
// |echo_path_size_bytes()|. |SetEchoPath()| causes an entire reset, worth
// noting if it is to be called during an ongoing call.
//
// It is possible that version incompatibilities may result in a stored echo
// path of the incorrect size. In this case, the stored path should be
// discarded.
virtual int SetEchoPath(const void* echo_path, size_t size_bytes) = 0;
virtual int GetEchoPath(void* echo_path, size_t size_bytes) const = 0;
// The returned path size is guaranteed not to change for the lifetime of
// the application.
static size_t echo_path_size_bytes();
protected:
virtual ~EchoControlMobile() {}
};
// TODO(peah): Remove this interface.
// A filtering component which removes DC offset and low-frequency noise.
// Recommended to be enabled on the client-side.

View File

@ -21,43 +21,6 @@
namespace webrtc {
namespace test {
class MockEchoCancellation : public EchoCancellation {
public:
virtual ~MockEchoCancellation() {}
MOCK_METHOD1(Enable, int(bool enable));
MOCK_CONST_METHOD0(is_enabled, bool());
MOCK_METHOD1(enable_drift_compensation, int(bool enable));
MOCK_CONST_METHOD0(is_drift_compensation_enabled, bool());
MOCK_METHOD1(set_stream_drift_samples, void(int drift));
MOCK_CONST_METHOD0(stream_drift_samples, int());
MOCK_METHOD1(set_suppression_level, int(SuppressionLevel level));
MOCK_CONST_METHOD0(suppression_level, SuppressionLevel());
MOCK_CONST_METHOD0(stream_has_echo, bool());
MOCK_METHOD1(enable_metrics, int(bool enable));
MOCK_CONST_METHOD0(are_metrics_enabled, bool());
MOCK_METHOD1(GetMetrics, int(Metrics* metrics));
MOCK_METHOD1(enable_delay_logging, int(bool enable));
MOCK_CONST_METHOD0(is_delay_logging_enabled, bool());
MOCK_METHOD2(GetDelayMetrics, int(int* median, int* std));
MOCK_METHOD3(GetDelayMetrics,
int(int* median, int* std, float* fraction_poor_delays));
MOCK_CONST_METHOD0(aec_core, struct AecCore*());
};
class MockEchoControlMobile : public EchoControlMobile {
public:
virtual ~MockEchoControlMobile() {}
MOCK_METHOD1(Enable, int(bool enable));
MOCK_CONST_METHOD0(is_enabled, bool());
MOCK_METHOD1(set_routing_mode, int(RoutingMode mode));
MOCK_CONST_METHOD0(routing_mode, RoutingMode());
MOCK_METHOD1(enable_comfort_noise, int(bool enable));
MOCK_CONST_METHOD0(is_comfort_noise_enabled, bool());
MOCK_METHOD2(SetEchoPath, int(const void* echo_path, size_t size_bytes));
MOCK_CONST_METHOD2(GetEchoPath, int(void* echo_path, size_t size_bytes));
};
class MockGainControl : public GainControl {
public:
virtual ~MockGainControl() {}
@ -150,9 +113,7 @@ class MockVoiceDetection : public VoiceDetection {
class MockAudioProcessing : public testing::NiceMock<AudioProcessing> {
public:
MockAudioProcessing()
: echo_cancellation_(new testing::NiceMock<MockEchoCancellation>()),
echo_control_mobile_(new testing::NiceMock<MockEchoControlMobile>()),
gain_control_(new testing::NiceMock<MockGainControl>()),
: gain_control_(new testing::NiceMock<MockGainControl>()),
high_pass_filter_(new testing::NiceMock<MockHighPassFilter>()),
level_estimator_(new testing::NiceMock<MockLevelEstimator>()),
noise_suppression_(new testing::NiceMock<MockNoiseSuppression>()),
@ -221,12 +182,6 @@ class MockAudioProcessing : public testing::NiceMock<AudioProcessing> {
MOCK_METHOD0(UpdateHistogramsOnCallEnd, void());
MOCK_CONST_METHOD0(GetStatistics, AudioProcessingStatistics());
MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool));
virtual MockEchoCancellation* echo_cancellation() const {
return echo_cancellation_.get();
}
virtual MockEchoControlMobile* echo_control_mobile() const {
return echo_control_mobile_.get();
}
virtual MockGainControl* gain_control() const { return gain_control_.get(); }
virtual MockHighPassFilter* high_pass_filter() const {
return high_pass_filter_.get();
@ -244,8 +199,6 @@ class MockAudioProcessing : public testing::NiceMock<AudioProcessing> {
MOCK_CONST_METHOD0(GetConfig, AudioProcessing::Config());
private:
std::unique_ptr<MockEchoCancellation> echo_cancellation_;
std::unique_ptr<MockEchoControlMobile> echo_control_mobile_;
std::unique_ptr<MockGainControl> gain_control_;
std::unique_ptr<MockHighPassFilter> high_pass_filter_;
std::unique_ptr<MockLevelEstimator> level_estimator_;

View File

@ -10,6 +10,7 @@
#include <iostream>
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/echo_control_mobile_impl.h"
#include "modules/audio_processing/test/aec_dump_based_simulator.h"
#include "modules/audio_processing/test/protobuf_utils.h"
@ -319,17 +320,17 @@ void AecDumpBasedSimulator::HandleMessage(
}
if (msg.has_aec_suppression_level() || settings_.aec_suppression_level) {
auto level = static_cast<webrtc::EchoCancellation::SuppressionLevel>(
auto level = static_cast<webrtc::EchoCancellationImpl::SuppressionLevel>(
settings_.aec_suppression_level ? *settings_.aec_suppression_level
: msg.aec_suppression_level());
if (level ==
webrtc::EchoCancellation::SuppressionLevel::kLowSuppression) {
webrtc::EchoCancellationImpl::SuppressionLevel::kLowSuppression) {
RTC_LOG(LS_ERROR)
<< "Ignoring deprecated setting: AEC2 low suppression";
} else {
apm_config.echo_canceller.legacy_moderate_suppression_level =
(level ==
webrtc::EchoCancellation::SuppressionLevel::kModerateSuppression);
(level == webrtc::EchoCancellationImpl::SuppressionLevel::
kModerateSuppression);
if (settings_.use_verbose_logging) {
std::cout << " aec_suppression_level: " << level << std::endl;
}

View File

@ -21,6 +21,7 @@
#include "api/audio/echo_canceller3_factory.h"
#include "common_audio/include/audio_util.h"
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/echo_control_mobile_impl.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/test/fake_recording_device.h"
@ -959,14 +960,15 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 drift compensation";
}
if (settings_.aec_suppression_level) {
auto level = static_cast<webrtc::EchoCancellation::SuppressionLevel>(
auto level = static_cast<webrtc::EchoCancellationImpl::SuppressionLevel>(
*settings_.aec_suppression_level);
if (level == webrtc::EchoCancellation::SuppressionLevel::kLowSuppression) {
if (level ==
webrtc::EchoCancellationImpl::SuppressionLevel::kLowSuppression) {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 low suppression";
} else {
apm_config.echo_canceller.legacy_moderate_suppression_level =
(level ==
webrtc::EchoCancellation::SuppressionLevel::kModerateSuppression);
(level == webrtc::EchoCancellationImpl::SuppressionLevel::
kModerateSuppression);
}
}

View File

@ -10,6 +10,7 @@
#include "modules/audio_processing/test/debug_dump_replayer.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/test/protobuf_utils.h"
#include "modules/audio_processing/test/runtime_setting_util.h"
#include "rtc_base/checks.h"
@ -214,9 +215,9 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
RTC_CHECK(msg.has_aec_suppression_level());
apm_config.echo_canceller.legacy_moderate_suppression_level =
static_cast<EchoCancellation::SuppressionLevel>(
static_cast<EchoCancellationImpl::SuppressionLevel>(
msg.aec_suppression_level()) ==
EchoCancellation::SuppressionLevel::kModerateSuppression;
EchoCancellationImpl::SuppressionLevel::kModerateSuppression;
// AGC configs.
RTC_CHECK(msg.has_agc_enabled());