Revert "Remove APM internal usage of EchoCancellation"

This reverts commit 1a03960e63.

Reason for revert: breaks downstream projects.

Original change's description:
> Remove APM internal usage of EchoCancellation
> 
> This CL:
>  - Changes EchoCancellationImpl to inherit privately from
>    EchoCancellation.
>  - Removes usage of AudioProcessing::echo_cancellation() inside most of
>    the audio processing module and unit tests.
>  - Default-enables metrics collection in AEC2.
> 
> This CL breaks audioproc_f backwards compatibility: It can no longer
> use all recorded settings (drift compensation, suppression level), but
> prints an error message when such settings are encountered.
> 
> Some code in audio_processing_unittest.cc still uses the old interface.
> I'll handle that in a separate change, as it is not as straightforward
> to preserve coverage.
> 
> Bug: webrtc:9535
> Change-Id: Ia4d4b8d117ccbe516e5345c15d37298418590686
> Reviewed-on: https://webrtc-review.googlesource.com/97603
> Commit-Queue: Sam Zackrisson <saza@webrtc.org>
> Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#24724}

TBR=gustaf@webrtc.org,saza@webrtc.org

Change-Id: Ifdc4235f9c5ee8a8a5d32cc8e1dda0853b941693
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:9535
Reviewed-on: https://webrtc-review.googlesource.com/100305
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24729}
This commit is contained in:
Sergey Silkin 2018-09-13 14:55:17 +00:00 committed by Commit Bot
parent cd56486ffd
commit 271812a893
17 changed files with 345 additions and 268 deletions

View file

@ -672,17 +672,13 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
public_submodules_->echo_cancellation->Enable(
config_.echo_canceller.enabled && !config_.echo_canceller.mobile_mode);
static_cast<EchoCancellation*>(public_submodules_->echo_cancellation.get())
->Enable(config_.echo_canceller.enabled &&
!config_.echo_canceller.mobile_mode);
static_cast<EchoControlMobile*>(public_submodules_->echo_control_mobile.get())
->Enable(config_.echo_canceller.enabled &&
config_.echo_canceller.mobile_mode);
public_submodules_->echo_cancellation->set_suppression_level(
config.echo_canceller.legacy_moderate_suppression_level
? EchoCancellation::SuppressionLevel::kModerateSuppression
: EchoCancellation::SuppressionLevel::kHighSuppression);
InitializeLowCutFilter();
RTC_LOG(LS_INFO) << "Highpass filter activated: "
@ -1310,8 +1306,7 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
capture_buffer->num_frames_per_band(), capture_nonlocked_.split_rate);
}
RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(
capture_buffer,
public_submodules_->echo_cancellation->stream_has_echo()));
capture_buffer, echo_cancellation()->stream_has_echo()));
if (submodule_states_.CaptureMultiBandProcessingActive() &&
SampleRateSupportsMultiBand(
@ -1857,15 +1852,15 @@ void AudioProcessingImpl::InitializePreProcessor() {
void AudioProcessingImpl::MaybeUpdateHistograms() {
static const int kMinDiffDelayMs = 60;
if (public_submodules_->echo_cancellation->is_enabled()) {
if (echo_cancellation()->is_enabled()) {
// Activate delay_jumps_ counters if we know echo_cancellation is running.
// If a stream has echo we know that the echo_cancellation is in process.
if (capture_.stream_delay_jumps == -1 &&
public_submodules_->echo_cancellation->stream_has_echo()) {
echo_cancellation()->stream_has_echo()) {
capture_.stream_delay_jumps = 0;
}
if (capture_.aec_system_delay_jumps == -1 &&
public_submodules_->echo_cancellation->stream_has_echo()) {
echo_cancellation()->stream_has_echo()) {
capture_.aec_system_delay_jumps = 0;
}

View file

@ -540,14 +540,21 @@ void AudioProcessingImplLockTest::SetUp() {
ASSERT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
ASSERT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
AudioProcessing::Config apm_config;
apm_config.echo_canceller.enabled =
(test_config_.aec_type != AecType::AecTurnedOff);
apm_config.echo_canceller.mobile_mode =
(test_config_.aec_type == AecType::BasicWebRtcAecSettingsWithAecMobile);
apm_->ApplyConfig(apm_config);
Config config;
if (test_config_.aec_type == AecType::AecTurnedOff) {
ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
} else if (test_config_.aec_type ==
AecType::BasicWebRtcAecSettingsWithAecMobile) {
ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
} else {
ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->enable_metrics(true));
ASSERT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_delay_logging(true));
config.Set<ExtendedFilter>(
new ExtendedFilter(test_config_.aec_type ==
AecType::BasicWebRtcAecSettingsWithExtentedFilter));
@ -558,6 +565,7 @@ void AudioProcessingImplLockTest::SetUp() {
apm_->SetExtraOptions(config);
}
}
void AudioProcessingImplLockTest::TearDown() {
render_call_event_.Set();
@ -577,15 +585,15 @@ StatsProcessor::StatsProcessor(RandomGenerator* rand_gen,
bool StatsProcessor::Process() {
SleepRandomMs(100, rand_gen_);
AudioProcessing::Config apm_config = apm_->GetConfig();
if (test_config_->aec_type != AecType::AecTurnedOff) {
EXPECT_TRUE(apm_config.echo_canceller.enabled);
EXPECT_EQ(apm_config.echo_canceller.mobile_mode,
EXPECT_EQ(apm_->echo_cancellation()->is_enabled(),
((test_config_->aec_type != AecType::AecTurnedOff) &&
(test_config_->aec_type !=
AecType::BasicWebRtcAecSettingsWithAecMobile)));
apm_->echo_cancellation()->stream_drift_samples();
EXPECT_EQ(apm_->echo_control_mobile()->is_enabled(),
(test_config_->aec_type != AecType::AecTurnedOff) &&
(test_config_->aec_type ==
AecType::BasicWebRtcAecSettingsWithAecMobile));
} else {
EXPECT_FALSE(apm_config.echo_canceller.enabled);
}
EXPECT_TRUE(apm_->gain_control()->is_enabled());
EXPECT_TRUE(apm_->noise_suppression()->is_enabled());

View file

@ -452,10 +452,11 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm->ApplyConfig(apm_config);
ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->enable_metrics(true));
ASSERT_EQ(apm->kNoError,
apm->echo_cancellation()->enable_delay_logging(true));
};
// Lambda function for setting the default APM runtime settings for mobile.
@ -467,10 +468,8 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = true;
apm->ApplyConfig(apm_config);
ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false));
};
// Lambda function for turning off all of the APM runtime settings
@ -483,9 +482,11 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(false));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = false;
apm->ApplyConfig(apm_config);
ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->enable_metrics(false));
ASSERT_EQ(apm->kNoError,
apm->echo_cancellation()->enable_delay_logging(false));
};
// Lambda function for adding default desktop APM settings to a config.

View file

@ -188,7 +188,11 @@ void EnableAllAPComponents(AudioProcessing* ap) {
EXPECT_NOERR(ap->gain_control()->Enable(true));
#elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
apm_config.echo_canceller.mobile_mode = false;
apm_config.echo_canceller.legacy_moderate_suppression_level = true;
EXPECT_NOERR(ap->echo_cancellation()->enable_drift_compensation(true));
EXPECT_NOERR(ap->echo_cancellation()->enable_metrics(true));
EXPECT_NOERR(ap->echo_cancellation()->enable_delay_logging(true));
EXPECT_NOERR(ap->echo_cancellation()->set_suppression_level(
EchoCancellation::SuppressionLevel::kModerateSuppression));
EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
EXPECT_NOERR(ap->gain_control()->set_analog_level_limits(0, 255));
@ -594,6 +598,7 @@ void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame) {
void ApmTest::ProcessWithDefaultStreamParameters(AudioFrame* frame) {
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(127));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame));
@ -678,8 +683,13 @@ void ApmTest::ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
delete frame;
if (frame_count == 250) {
int median;
int std;
float poor_fraction;
// Discard the first delay metrics to avoid convergence effects.
static_cast<void>(apm_->GetStatistics(true /* has_remote_tracks */));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->GetDelayMetrics(&median, &std,
&poor_fraction));
}
}
@ -702,10 +712,12 @@ void ApmTest::ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
expected_median - rtc::dchecked_cast<int>(96 / samples_per_ms), delay_min,
delay_max);
// Verify delay metrics.
AudioProcessingStats stats =
apm_->GetStatistics(true /* has_remote_tracks */);
ASSERT_TRUE(stats.delay_median_ms.has_value());
int32_t median = *stats.delay_median_ms;
int median;
int std;
float poor_fraction;
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->GetDelayMetrics(&median, &std,
&poor_fraction));
EXPECT_GE(expected_median_high, median);
EXPECT_LE(expected_median_low, median);
}
@ -727,16 +739,19 @@ void ApmTest::StreamParametersTest(Format format) {
ProcessStreamChooser(format));
// Other stream parameters set correctly.
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(true));
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(false));
// -- Missing delay --
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
@ -749,12 +764,34 @@ void ApmTest::StreamParametersTest(Format format) {
// Other stream parameters set correctly.
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(true));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(127));
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
// -- Missing drift --
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
// Resets after successful ProcessStream().
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
// Other stream parameters set correctly.
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(127));
EXPECT_EQ(apm_->kStreamParameterNotSetError,
ProcessStreamChooser(format));
// -- No stream parameters --
EXPECT_EQ(apm_->kNoError,
AnalyzeReverseStreamChooser(format));
@ -763,6 +800,7 @@ void ApmTest::StreamParametersTest(Format format) {
// -- All there --
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(127));
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
@ -886,13 +924,79 @@ TEST_F(ApmTest, SampleRatesInt) {
}
}
TEST_F(ApmTest, EchoCancellation) {
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(true));
EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(false));
EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
EchoCancellation::SuppressionLevel level[] = {
EchoCancellation::kLowSuppression,
EchoCancellation::kModerateSuppression,
EchoCancellation::kHighSuppression,
};
for (size_t i = 0; i < arraysize(level); i++) {
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->set_suppression_level(level[i]));
EXPECT_EQ(level[i],
apm_->echo_cancellation()->suppression_level());
}
EchoCancellation::Metrics metrics;
EXPECT_EQ(apm_->kNotEnabledError,
apm_->echo_cancellation()->GetMetrics(&metrics));
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_metrics(true));
EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_metrics(false));
EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_delay_logging(true));
EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_delay_logging(false));
EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
int median = 0;
int std = 0;
float poor_fraction = 0;
EXPECT_EQ(apm_->kNotEnabledError, apm_->echo_cancellation()->GetDelayMetrics(
&median, &std, &poor_fraction));
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
EXPECT_TRUE(apm_->echo_cancellation()->aec_core() != NULL);
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
EXPECT_FALSE(apm_->echo_cancellation()->aec_core() != NULL);
}
TEST_F(ApmTest, DISABLED_EchoCancellationReportsCorrectDelays) {
// TODO(bjornv): Fix this test to work with DA-AEC.
// Enable AEC only.
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_drift_compensation(false));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_metrics(false));
EXPECT_EQ(apm_->kNoError,
apm_->echo_cancellation()->enable_delay_logging(true));
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
Config config;
config.Set<DelayAgnostic>(new DelayAgnostic(false));
apm_->SetExtraOptions(config);
@ -1360,9 +1464,8 @@ TEST_F(ApmTest, VoiceDetection) {
}
TEST_F(ApmTest, AllProcessingDisabledByDefault) {
AudioProcessing::Config config = apm_->GetConfig();
EXPECT_FALSE(config.echo_canceller.enabled);
EXPECT_FALSE(config.high_pass_filter.enabled);
EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
EXPECT_FALSE(apm_->gain_control()->is_enabled());
EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
EXPECT_FALSE(apm_->level_estimator()->is_enabled());
@ -1445,6 +1548,7 @@ TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
frame_->vad_activity_ = AudioFrame::kVadUnknown;
ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
ASSERT_EQ(kNoErr,
apm_->gain_control()->set_stream_analog_level(analog_level));
ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_));
@ -1504,10 +1608,7 @@ TEST_F(ApmTest, SplittingFilter) {
// first few frames of data being unaffected by the AEC.
// TODO(andrew): This test, and the one below, rely rather tenuously on the
// behavior of the AEC. Think of something more robust.
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
// Make sure we have extended filter enabled. This makes sure nothing is
// touched until we have a farend frame.
Config config;
@ -1516,8 +1617,10 @@ TEST_F(ApmTest, SplittingFilter) {
SetFrameTo(frame_, 1000);
frame_copy.CopyFrom(*frame_);
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
@ -1529,6 +1632,7 @@ TEST_F(ApmTest, SplittingFilter) {
SetFrameTo(frame_, 1000);
frame_copy.CopyFrom(*frame_);
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_FALSE(FrameDataAreEqual(*frame_, frame_copy));
}
@ -1600,6 +1704,7 @@ void ApmTest::ProcessDebugDump(const std::string& in_filename,
EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(msg.level()));
EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
apm_->echo_cancellation()->set_stream_drift_samples(msg.drift());
if (msg.has_keypress()) {
apm_->set_stream_key_pressed(msg.keypress());
} else {
@ -1820,6 +1925,8 @@ TEST_F(ApmTest, FloatAndIntInterfacesGiveSimilarResults) {
EXPECT_NOERR(apm_->set_stream_delay_ms(0));
EXPECT_NOERR(fapm->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
fapm->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(analog_level));
EXPECT_NOERR(fapm->gain_control()->set_stream_analog_level(analog_level));
@ -1856,6 +1963,8 @@ TEST_F(ApmTest, FloatAndIntInterfacesGiveSimilarResults) {
analog_level = fapm->gain_control()->stream_analog_level();
EXPECT_EQ(apm_->gain_control()->stream_analog_level(),
fapm->gain_control()->stream_analog_level());
EXPECT_EQ(apm_->echo_cancellation()->stream_has_echo(),
fapm->echo_cancellation()->stream_has_echo());
EXPECT_NEAR(apm_->noise_suppression()->speech_probability(),
fapm->noise_suppression()->speech_probability(),
0.01);
@ -1955,6 +2064,7 @@ TEST_F(ApmTest, Process) {
frame_->vad_activity_ = AudioFrame::kVadUnknown;
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
apm_->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(analog_level));
@ -2325,6 +2435,7 @@ class AudioProcessingTest
processing_config.reverse_output_stream(), rev_out_cb.channels()));
EXPECT_NOERR(ap->set_stream_delay_ms(0));
ap->echo_cancellation()->set_stream_drift_samples(0);
EXPECT_NOERR(ap->gain_control()->set_stream_analog_level(analog_level));
EXPECT_NOERR(ap->ProcessStream(
@ -2783,17 +2894,25 @@ std::unique_ptr<AudioProcessing> CreateApm(bool use_AEC2) {
}
// Disable all components except for an AEC and the residual echo detector.
AudioProcessing::Config apm_config;
apm_config.residual_echo_detector.enabled = true;
apm_config.high_pass_filter.enabled = false;
apm_config.gain_controller2.enabled = false;
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = !use_AEC2;
apm->ApplyConfig(apm_config);
AudioProcessing::Config config;
config.residual_echo_detector.enabled = true;
config.high_pass_filter.enabled = false;
config.gain_controller2.enabled = false;
apm->ApplyConfig(config);
EXPECT_EQ(apm->gain_control()->Enable(false), 0);
EXPECT_EQ(apm->level_estimator()->Enable(false), 0);
EXPECT_EQ(apm->noise_suppression()->Enable(false), 0);
EXPECT_EQ(apm->voice_detection()->Enable(false), 0);
if (use_AEC2) {
EXPECT_EQ(apm->echo_control_mobile()->Enable(false), 0);
EXPECT_EQ(apm->echo_cancellation()->enable_metrics(true), 0);
EXPECT_EQ(apm->echo_cancellation()->enable_delay_logging(true), 0);
EXPECT_EQ(apm->echo_cancellation()->Enable(true), 0);
} else {
EXPECT_EQ(apm->echo_cancellation()->Enable(false), 0);
EXPECT_EQ(apm->echo_control_mobile()->Enable(true), 0);
}
return apm;
}

View file

@ -26,9 +26,10 @@ void SetupComponent(int sample_rate_hz,
bool drift_compensation_enabled,
EchoCancellationImpl* echo_canceller) {
echo_canceller->Initialize(sample_rate_hz, 1, 1, 1);
echo_canceller->Enable(true);
echo_canceller->set_suppression_level(suppression_level);
echo_canceller->enable_drift_compensation(drift_compensation_enabled);
EchoCancellation* ec = static_cast<EchoCancellation*>(echo_canceller);
ec->Enable(true);
ec->set_suppression_level(suppression_level);
ec->enable_drift_compensation(drift_compensation_enabled);
Config config;
config.Set<DelayAgnostic>(new DelayAgnostic(true));
@ -55,7 +56,8 @@ void ProcessOneFrame(int sample_rate_hz,
echo_canceller->ProcessRenderAudio(render_audio);
if (drift_compensation_enabled) {
echo_canceller->set_stream_drift_samples(stream_drift_samples);
static_cast<EchoCancellation*>(echo_canceller)
->set_stream_drift_samples(stream_drift_samples);
}
echo_canceller->ProcessCaptureAudio(capture_audio_buffer, stream_delay_ms);
@ -116,7 +118,8 @@ void RunBitexactnessTest(int sample_rate_hz,
test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer,
&capture_output);
EXPECT_EQ(stream_has_echo_reference, echo_canceller.stream_has_echo());
EXPECT_EQ(stream_has_echo_reference,
static_cast<EchoCancellation*>(&echo_canceller)->stream_has_echo());
// Compare the output with the reference. Only the first values of the output
// from last frame processed are compared in order not having to specify all

View file

@ -108,12 +108,12 @@ EchoCancellationImpl::EchoCancellationImpl(rtc::CriticalSection* crit_render,
: crit_render_(crit_render),
crit_capture_(crit_capture),
drift_compensation_enabled_(false),
metrics_enabled_(true),
metrics_enabled_(false),
suppression_level_(kHighSuppression),
stream_drift_samples_(0),
was_stream_drift_set_(false),
stream_has_echo_(false),
delay_logging_enabled_(true),
delay_logging_enabled_(false),
extended_filter_enabled_(false),
delay_agnostic_enabled_(false),
enforce_zero_stream_delay_(EnforceZeroStreamDelay()) {

View file

@ -22,7 +22,7 @@ namespace webrtc {
class AudioBuffer;
class EchoCancellationImpl : EchoCancellation {
class EchoCancellationImpl : public EchoCancellation {
public:
EchoCancellationImpl(rtc::CriticalSection* crit_render,
rtc::CriticalSection* crit_capture);
@ -32,29 +32,10 @@ class EchoCancellationImpl : EchoCancellation {
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;
// 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;
// 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;
bool is_drift_compensation_enabled() const override;
void Initialize(int sample_rate_hz,
size_t num_reverse_channels_,
@ -76,10 +57,36 @@ class EchoCancellationImpl : EchoCancellation {
static size_t NumCancellersRequired(size_t num_output_channels,
size_t num_reverse_channels);
// Enable logging of various AEC statistics.
int enable_metrics(bool enable) override;
// Provides various statistics about the AEC.
int GetMetrics(Metrics* metrics) override;
// Enable logging of delay metrics.
int enable_delay_logging(bool enable) override;
// Provides delay metrics.
int GetDelayMetrics(int* median,
int* std,
float* fraction_poor_delays) override;
private:
class Canceller;
struct StreamProperties;
// EchoCancellation implementation.
int Enable(bool enable) override;
int enable_drift_compensation(bool enable) override;
void set_stream_drift_samples(int drift) override;
int set_suppression_level(SuppressionLevel level) override;
bool are_metrics_enabled() const override;
bool stream_has_echo() const override;
bool is_delay_logging_enabled() const override;
int GetDelayMetrics(int* median, int* std) override;
struct AecCore* aec_core() const override;
void AllocateRenderQueue();
int Configure();

View file

@ -11,136 +11,69 @@
#include <memory>
#include "modules/audio_processing/aec/aec_core.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/criticalsection.h"
#include "test/gtest.h"
namespace webrtc {
TEST(EchoCancellationInternalTest, ExtendedFilter) {
rtc::CriticalSection crit_render;
rtc::CriticalSection crit_capture;
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
EXPECT_TRUE(ap->echo_cancellation()->aec_core() == NULL);
EXPECT_TRUE(echo_canceller.aec_core() == nullptr);
EXPECT_EQ(ap->kNoError, ap->echo_cancellation()->Enable(true));
EXPECT_TRUE(ap->echo_cancellation()->is_enabled());
echo_canceller.Enable(true);
AecCore* aec_core = echo_canceller.aec_core();
AecCore* aec_core = ap->echo_cancellation()->aec_core();
ASSERT_TRUE(aec_core != NULL);
// Disabled by default.
EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
Config config;
config.Set<ExtendedFilter>(new ExtendedFilter(true));
echo_canceller.SetExtraOptions(config);
ap->SetExtraOptions(config);
EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
// Retains setting after initialization.
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
EXPECT_EQ(ap->kNoError, ap->Initialize());
EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
config.Set<ExtendedFilter>(new ExtendedFilter(false));
echo_canceller.SetExtraOptions(config);
ap->SetExtraOptions(config);
EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
// Retains setting after initialization.
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
EXPECT_EQ(ap->kNoError, ap->Initialize());
EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
}
TEST(EchoCancellationInternalTest, DelayAgnostic) {
rtc::CriticalSection crit_render;
rtc::CriticalSection crit_capture;
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 1, 1, 1);
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
EXPECT_TRUE(ap->echo_cancellation()->aec_core() == NULL);
EXPECT_TRUE(echo_canceller.aec_core() == NULL);
EXPECT_EQ(ap->kNoError, ap->echo_cancellation()->Enable(true));
EXPECT_TRUE(ap->echo_cancellation()->is_enabled());
EXPECT_EQ(0, echo_canceller.Enable(true));
EXPECT_TRUE(echo_canceller.is_enabled());
AecCore* aec_core = echo_canceller.aec_core();
AecCore* aec_core = ap->echo_cancellation()->aec_core();
ASSERT_TRUE(aec_core != NULL);
// Enabled by default.
EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
Config config;
config.Set<DelayAgnostic>(new DelayAgnostic(true));
echo_canceller.SetExtraOptions(config);
ap->SetExtraOptions(config);
EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
// Retains setting after initialization.
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
EXPECT_EQ(ap->kNoError, ap->Initialize());
EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
config.Set<DelayAgnostic>(new DelayAgnostic(false));
echo_canceller.SetExtraOptions(config);
ap->SetExtraOptions(config);
EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
// Retains setting after initialization.
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
EXPECT_EQ(ap->kNoError, ap->Initialize());
EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
}
TEST(EchoCancellationInternalTest, InterfaceConfiguration) {
rtc::CriticalSection crit_render;
rtc::CriticalSection crit_capture;
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
EXPECT_EQ(0, echo_canceller.enable_drift_compensation(true));
EXPECT_TRUE(echo_canceller.is_drift_compensation_enabled());
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,
};
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;
EXPECT_EQ(AudioProcessing::kNotEnabledError,
echo_canceller.GetMetrics(&metrics));
EXPECT_EQ(0, echo_canceller.Enable(true));
EXPECT_TRUE(echo_canceller.is_enabled());
EXPECT_EQ(0, echo_canceller.enable_metrics(true));
EXPECT_TRUE(echo_canceller.are_metrics_enabled());
EXPECT_EQ(0, echo_canceller.enable_metrics(false));
EXPECT_FALSE(echo_canceller.are_metrics_enabled());
EXPECT_EQ(0, echo_canceller.enable_delay_logging(true));
EXPECT_TRUE(echo_canceller.is_delay_logging_enabled());
EXPECT_EQ(0, echo_canceller.enable_delay_logging(false));
EXPECT_FALSE(echo_canceller.is_delay_logging_enabled());
EXPECT_EQ(0, echo_canceller.Enable(false));
EXPECT_FALSE(echo_canceller.is_enabled());
int median = 0;
int std = 0;
float poor_fraction = 0;
EXPECT_EQ(AudioProcessing::kNotEnabledError,
echo_canceller.GetDelayMetrics(&median, &std, &poor_fraction));
EXPECT_EQ(0, echo_canceller.Enable(true));
EXPECT_TRUE(echo_canceller.is_enabled());
EXPECT_EQ(0, echo_canceller.Enable(false));
EXPECT_FALSE(echo_canceller.is_enabled());
EXPECT_EQ(0, echo_canceller.Enable(true));
EXPECT_TRUE(echo_canceller.is_enabled());
EXPECT_TRUE(echo_canceller.aec_core() != NULL);
EXPECT_EQ(0, echo_canceller.Enable(false));
EXPECT_FALSE(echo_canceller.is_enabled());
EXPECT_FALSE(echo_canceller.aec_core() != NULL);
}
} // namespace webrtc

View file

@ -10,13 +10,11 @@
#include "modules/audio_processing/echo_cancellation_proxy.h"
#include "rtc_base/logging.h"
namespace webrtc {
EchoCancellationProxy::EchoCancellationProxy(
AudioProcessing* audio_processing,
EchoCancellationImpl* echo_cancellation)
EchoCancellation* echo_cancellation)
: audio_processing_(audio_processing),
echo_cancellation_(echo_cancellation) {}
@ -24,6 +22,8 @@ EchoCancellationProxy::~EchoCancellationProxy() = default;
int EchoCancellationProxy::Enable(bool enable) {
// Change the config in APM to mirror the applied settings.
// TODO(bugs.webrtc.org/9535): Remove the call to EchoCancellation::Enable
// when APM starts taking the config into account.
AudioProcessing::Config apm_config = audio_processing_->GetConfig();
bool aec2_enabled = apm_config.echo_canceller.enabled &&
!apm_config.echo_canceller.mobile_mode;
@ -32,6 +32,7 @@ int EchoCancellationProxy::Enable(bool enable) {
apm_config.echo_canceller.mobile_mode = false;
audio_processing_->ApplyConfig(apm_config);
}
echo_cancellation_->Enable(enable);
return AudioProcessing::kNoError;
}
@ -57,15 +58,7 @@ int EchoCancellationProxy::stream_drift_samples() const {
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;
return echo_cancellation_->set_suppression_level(level);
}
EchoCancellation::SuppressionLevel EchoCancellationProxy::suppression_level()

View file

@ -11,7 +11,6 @@
#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"
@ -22,7 +21,7 @@ namespace webrtc {
class EchoCancellationProxy : public EchoCancellation {
public:
EchoCancellationProxy(AudioProcessing* audio_processing,
EchoCancellationImpl* echo_cancellation);
EchoCancellation* echo_cancellation);
~EchoCancellationProxy() override;
int Enable(bool enable) override;
@ -47,7 +46,7 @@ class EchoCancellationProxy : public EchoCancellation {
private:
AudioProcessing* audio_processing_;
EchoCancellationImpl* echo_cancellation_;
EchoCancellation* echo_cancellation_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationProxy);
};

View file

@ -193,12 +193,13 @@ struct ExperimentalNs {
// AudioProcessing* apm = AudioProcessingBuilder().Create();
//
// AudioProcessing::Config config;
// config.echo_canceller.enabled = true;
// config.echo_canceller.mobile_mode = false;
// config.high_pass_filter.enabled = true;
// config.gain_controller2.enabled = true;
// apm->ApplyConfig(config)
//
// apm->echo_cancellation()->enable_drift_compensation(false);
// apm->echo_cancellation()->Enable(true);
//
// apm->noise_reduction()->set_level(kHighSuppression);
// apm->noise_reduction()->Enable(true);
//

View file

@ -15,7 +15,6 @@
#include "modules/audio_processing/test/protobuf_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
@ -147,6 +146,15 @@ void AecDumpBasedSimulator::PrepareProcessStreamCall(
}
}
if (!settings_.stream_drift_samples) {
if (msg.has_drift()) {
ap_->echo_cancellation()->set_stream_drift_samples(msg.drift());
}
} else {
ap_->echo_cancellation()->set_stream_drift_samples(
*settings_.stream_drift_samples);
}
if (!settings_.use_ts) {
if (msg.has_keypress()) {
ap_->set_stream_key_pressed(msg.keypress());
@ -298,11 +306,14 @@ void AecDumpBasedSimulator::HandleMessage(
if (msg.has_aec_drift_compensation_enabled() ||
settings_.use_drift_compensation) {
if (settings_.use_drift_compensation
bool enable = settings_.use_drift_compensation
? *settings_.use_drift_compensation
: msg.aec_drift_compensation_enabled()) {
RTC_LOG(LS_ERROR)
<< "Ignoring deprecated setting: AEC2 drift compensation";
: msg.aec_drift_compensation_enabled();
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_cancellation()->enable_drift_compensation(enable));
if (settings_.use_verbose_logging) {
std::cout << " aec_drift_compensation_enabled: "
<< (enable ? "true" : "false") << std::endl;
}
}
@ -319,22 +330,17 @@ void AecDumpBasedSimulator::HandleMessage(
}
if (msg.has_aec_suppression_level() || settings_.aec_suppression_level) {
auto level = static_cast<webrtc::EchoCancellation::SuppressionLevel>(
settings_.aec_suppression_level ? *settings_.aec_suppression_level
: msg.aec_suppression_level());
if (level ==
webrtc::EchoCancellation::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);
int level = settings_.aec_suppression_level
? *settings_.aec_suppression_level
: msg.aec_suppression_level();
RTC_CHECK_EQ(
AudioProcessing::kNoError,
ap_->echo_cancellation()->set_suppression_level(
static_cast<webrtc::EchoCancellation::SuppressionLevel>(level)));
if (settings_.use_verbose_logging) {
std::cout << " aec_suppression_level: " << level << std::endl;
}
}
}
if (msg.has_aecm_enabled() || settings_.use_aecm) {
bool enable =

View file

@ -705,13 +705,6 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
settings_.pre_amplifier_gain_factor;
}
bool use_aec2 = settings_.use_aec && *settings_.use_aec;
bool use_aec3 = settings_.use_aec3 && *settings_.use_aec3;
bool use_aecm = settings_.use_aecm && *settings_.use_aecm;
if (use_aec2 || use_aec3 || use_aecm) {
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = use_aecm;
}
if (settings_.use_aec3 && *settings_.use_aec3) {
EchoCanceller3Config cfg;
if (settings_.aec3_settings_filename) {
@ -720,21 +713,6 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
}
echo_control_factory.reset(new EchoCanceller3Factory(cfg));
}
if (settings_.use_drift_compensation && *settings_.use_drift_compensation) {
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 drift compensation";
}
if (settings_.aec_suppression_level) {
auto level = static_cast<webrtc::EchoCancellation::SuppressionLevel>(
*settings_.aec_suppression_level);
if (level == webrtc::EchoCancellation::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);
}
}
if (settings_.use_hpf) {
apm_config.high_pass_filter.enabled = *settings_.use_hpf;
}
@ -767,6 +745,14 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
ap_->ApplyConfig(apm_config);
if (settings_.use_aec) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_cancellation()->Enable(*settings_.use_aec));
}
if (settings_.use_aecm) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_control_mobile()->Enable(*settings_.use_aecm));
}
if (settings_.use_agc) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->Enable(*settings_.use_agc));
@ -804,6 +790,19 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
static_cast<webrtc::GainControl::Mode>(*settings_.agc_mode)));
}
if (settings_.use_drift_compensation) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_cancellation()->enable_drift_compensation(
*settings_.use_drift_compensation));
}
if (settings_.aec_suppression_level) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_cancellation()->set_suppression_level(
static_cast<webrtc::EchoCancellation::SuppressionLevel>(
*settings_.aec_suppression_level)));
}
if (settings_.aecm_routing_mode) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->echo_control_mobile()->set_routing_mode(

View file

@ -106,6 +106,9 @@ DEFINE_int(delay_agnostic,
DEFINE_int(extended_filter,
kParameterNotSpecifiedValue,
"Activate (1) or deactivate(0) the AEC extended filter mode");
DEFINE_int(drift_compensation,
kParameterNotSpecifiedValue,
"Activate (1) or deactivate(0) the drift compensation");
DEFINE_int(aec3,
kParameterNotSpecifiedValue,
"Activate (1) or deactivate(0) the experimental AEC mode AEC3");
@ -256,6 +259,8 @@ SimulationSettings CreateSettings() {
&settings.aec_suppression_level);
SetSettingIfFlagSet(FLAG_delay_agnostic, &settings.use_delay_agnostic);
SetSettingIfFlagSet(FLAG_extended_filter, &settings.use_extended_filter);
SetSettingIfFlagSet(FLAG_drift_compensation,
&settings.use_drift_compensation);
SetSettingIfFlagSet(FLAG_refined_adaptive_filter,
&settings.use_refined_adaptive_filter);
@ -356,12 +361,11 @@ void PerformBasicParameterSanityChecks(const SimulationSettings& settings) {
*settings.reverse_output_num_channels <= 0,
"Error: --reverse_output_num_channels must be positive!\n");
ReportConditionalErrorAndExit(settings.aec_suppression_level &&
((*settings.aec_suppression_level) < 1 ||
ReportConditionalErrorAndExit(
settings.aec_suppression_level &&
((*settings.aec_suppression_level) < 0 ||
(*settings.aec_suppression_level) > 2),
"Error: --aec_suppression_level must be "
"specified between 1 and 2. 0 is "
"deprecated.\n");
"Error: --aec_suppression_level must be specified between 0 and 2.\n");
ReportConditionalErrorAndExit(
settings.aecm_routing_mode && ((*settings.aecm_routing_mode) < 0 ||

View file

@ -123,6 +123,7 @@ void DebugDumpReplayer::OnStreamEvent(const audioproc::Stream& msg) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->set_stream_delay_ms(msg.delay()));
apm_->echo_cancellation()->set_stream_drift_samples(msg.drift());
if (msg.has_keypress()) {
apm_->set_stream_key_pressed(msg.keypress());
} else {
@ -212,11 +213,16 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
apm_config.echo_canceller.enabled = msg.aec_enabled() || msg.aecm_enabled();
apm_config.echo_canceller.mobile_mode = msg.aecm_enabled();
RTC_CHECK(msg.has_aec_drift_compensation_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->echo_cancellation()->enable_drift_compensation(
msg.aec_drift_compensation_enabled()));
RTC_CHECK(msg.has_aec_suppression_level());
apm_config.echo_canceller.legacy_moderate_suppression_level =
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->echo_cancellation()->set_suppression_level(
static_cast<EchoCancellation::SuppressionLevel>(
msg.aec_suppression_level()) ==
EchoCancellation::SuppressionLevel::kModerateSuppression;
msg.aec_suppression_level())));
RTC_CHECK(msg.has_aecm_comfort_noise_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError,

View file

@ -359,13 +359,12 @@ TEST_F(DebugDumpTest, ChangeOutputFormat) {
TEST_F(DebugDumpTest, ToggleAec) {
Config config;
AudioProcessing::Config apm_config;
DebugDumpGenerator generator(config, apm_config);
DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording();
generator.Process(100);
apm_config.echo_canceller.enabled = true;
generator.apm()->ApplyConfig(apm_config);
EchoCancellation* aec = generator.apm()->echo_cancellation();
EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(!aec->is_enabled()));
generator.Process(100);
generator.StopRecording();
@ -375,13 +374,12 @@ TEST_F(DebugDumpTest, ToggleAec) {
TEST_F(DebugDumpTest, ToggleDelayAgnosticAec) {
Config config;
config.Set<DelayAgnostic>(new DelayAgnostic(true));
AudioProcessing::Config apm_config;
DebugDumpGenerator generator(config, apm_config);
DebugDumpGenerator generator(config, AudioProcessing::Config());
generator.StartRecording();
generator.Process(100);
apm_config.echo_canceller.enabled = true;
generator.apm()->ApplyConfig(apm_config);
EchoCancellation* aec = generator.apm()->echo_cancellation();
EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(!aec->is_enabled()));
generator.Process(100);
generator.StopRecording();
@ -550,13 +548,15 @@ TEST_F(DebugDumpTest, ToggleAecLevel) {
AudioProcessing::Config apm_config;
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_config.echo_canceller.legacy_moderate_suppression_level = true;
DebugDumpGenerator generator(config, apm_config);
EchoCancellation* aec = generator.apm()->echo_cancellation();
EXPECT_EQ(AudioProcessing::kNoError,
aec->set_suppression_level(EchoCancellation::kLowSuppression));
generator.StartRecording();
generator.Process(100);
apm_config.echo_canceller.legacy_moderate_suppression_level = false;
generator.apm()->ApplyConfig(apm_config);
EXPECT_EQ(AudioProcessing::kNoError,
aec->set_suppression_level(EchoCancellation::kHighSuppression));
generator.Process(100);
generator.StopRecording();
VerifyDebugDump(generator.dump_file_name());

View file

@ -79,6 +79,9 @@ void WavBasedSimulator::PrepareProcessStreamCall() {
ap_->set_stream_delay_ms(
settings_.stream_delay ? *settings_.stream_delay : 0));
}
ap_->echo_cancellation()->set_stream_drift_samples(
settings_.stream_drift_samples ? *settings_.stream_drift_samples : 0);
}
void WavBasedSimulator::PrepareReverseProcessStreamCall() {