mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00
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:
parent
cd56486ffd
commit
271812a893
17 changed files with 345 additions and 268 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
//
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue