Reland "Remove APM internal usage of EchoCancellation"
Original CL: https://webrtc-review.googlesource.com/c/src/+/97603 - 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. The 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. Revert CL: https://webrtc-review.googlesource.com/c/src/+/100305 Bug: webrtc:9535 TBR: gustaf@webrtc.org Change-Id: I9248046b3a6a82df6221e502481836948643a991 Reviewed-on: https://webrtc-review.googlesource.com/100461 Reviewed-by: Sam Zackrisson <saza@webrtc.org> Commit-Queue: Sam Zackrisson <saza@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24749}
This commit is contained in:
parent
92e0038c44
commit
cdf0e6d4c5
@ -672,13 +672,17 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
|
||||
rtc::CritScope cs_render(&crit_render_);
|
||||
rtc::CritScope cs_capture(&crit_capture_);
|
||||
|
||||
static_cast<EchoCancellation*>(public_submodules_->echo_cancellation.get())
|
||||
->Enable(config_.echo_canceller.enabled &&
|
||||
!config_.echo_canceller.mobile_mode);
|
||||
public_submodules_->echo_cancellation->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: "
|
||||
@ -1306,7 +1310,8 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
|
||||
capture_buffer->num_frames_per_band(), capture_nonlocked_.split_rate);
|
||||
}
|
||||
RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(
|
||||
capture_buffer, echo_cancellation()->stream_has_echo()));
|
||||
capture_buffer,
|
||||
public_submodules_->echo_cancellation->stream_has_echo()));
|
||||
|
||||
if (submodule_states_.CaptureMultiBandProcessingActive() &&
|
||||
SampleRateSupportsMultiBand(
|
||||
@ -1852,15 +1857,15 @@ void AudioProcessingImpl::InitializePreProcessor() {
|
||||
void AudioProcessingImpl::MaybeUpdateHistograms() {
|
||||
static const int kMinDiffDelayMs = 60;
|
||||
|
||||
if (echo_cancellation()->is_enabled()) {
|
||||
if (public_submodules_->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 &&
|
||||
echo_cancellation()->stream_has_echo()) {
|
||||
public_submodules_->echo_cancellation->stream_has_echo()) {
|
||||
capture_.stream_delay_jumps = 0;
|
||||
}
|
||||
if (capture_.aec_system_delay_jumps == -1 &&
|
||||
echo_cancellation()->stream_has_echo()) {
|
||||
public_submodules_->echo_cancellation->stream_has_echo()) {
|
||||
capture_.aec_system_delay_jumps = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -540,31 +540,23 @@ 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));
|
||||
|
||||
config.Set<ExtendedFilter>(
|
||||
new ExtendedFilter(test_config_.aec_type ==
|
||||
AecType::BasicWebRtcAecSettingsWithExtentedFilter));
|
||||
config.Set<DelayAgnostic>(
|
||||
new DelayAgnostic(test_config_.aec_type ==
|
||||
AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec));
|
||||
|
||||
config.Set<DelayAgnostic>(
|
||||
new DelayAgnostic(test_config_.aec_type ==
|
||||
AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec));
|
||||
|
||||
apm_->SetExtraOptions(config);
|
||||
}
|
||||
apm_->SetExtraOptions(config);
|
||||
}
|
||||
|
||||
void AudioProcessingImplLockTest::TearDown() {
|
||||
@ -585,15 +577,15 @@ StatsProcessor::StatsProcessor(RandomGenerator* rand_gen,
|
||||
bool StatsProcessor::Process() {
|
||||
SleepRandomMs(100, rand_gen_);
|
||||
|
||||
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));
|
||||
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,
|
||||
(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,11 +452,10 @@ 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));
|
||||
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));
|
||||
AudioProcessing::Config apm_config = apm->GetConfig();
|
||||
apm_config.echo_canceller.enabled = true;
|
||||
apm_config.echo_canceller.mobile_mode = false;
|
||||
apm->ApplyConfig(apm_config);
|
||||
};
|
||||
|
||||
// Lambda function for setting the default APM runtime settings for mobile.
|
||||
@ -468,8 +467,10 @@ 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));
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false));
|
||||
AudioProcessing::Config apm_config = apm->GetConfig();
|
||||
apm_config.echo_canceller.enabled = true;
|
||||
apm_config.echo_canceller.mobile_mode = true;
|
||||
apm->ApplyConfig(apm_config);
|
||||
};
|
||||
|
||||
// Lambda function for turning off all of the APM runtime settings
|
||||
@ -482,11 +483,9 @@ 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));
|
||||
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));
|
||||
AudioProcessing::Config apm_config = apm->GetConfig();
|
||||
apm_config.echo_canceller.enabled = false;
|
||||
apm->ApplyConfig(apm_config);
|
||||
};
|
||||
|
||||
// Lambda function for adding default desktop APM settings to a config.
|
||||
|
||||
@ -188,11 +188,7 @@ void EnableAllAPComponents(AudioProcessing* ap) {
|
||||
EXPECT_NOERR(ap->gain_control()->Enable(true));
|
||||
#elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
|
||||
apm_config.echo_canceller.mobile_mode = false;
|
||||
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));
|
||||
apm_config.echo_canceller.legacy_moderate_suppression_level = true;
|
||||
|
||||
EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
|
||||
EXPECT_NOERR(ap->gain_control()->set_analog_level_limits(0, 255));
|
||||
@ -580,7 +576,6 @@ 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));
|
||||
@ -665,13 +660,8 @@ 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.
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->GetDelayMetrics(&median, &std,
|
||||
&poor_fraction));
|
||||
static_cast<void>(apm_->GetStatistics(true /* has_remote_tracks */));
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,12 +684,10 @@ 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.
|
||||
int median;
|
||||
int std;
|
||||
float poor_fraction;
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->GetDelayMetrics(&median, &std,
|
||||
&poor_fraction));
|
||||
AudioProcessingStats stats =
|
||||
apm_->GetStatistics(true /* has_remote_tracks */);
|
||||
ASSERT_TRUE(stats.delay_median_ms.has_value());
|
||||
int32_t median = *stats.delay_median_ms;
|
||||
EXPECT_GE(expected_median_high, median);
|
||||
EXPECT_LE(expected_median_low, median);
|
||||
}
|
||||
@ -721,19 +709,16 @@ void ApmTest::StreamParametersTest(Format format) {
|
||||
ProcessStreamChooser(format));
|
||||
|
||||
// Other stream parameters set correctly.
|
||||
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->enable_drift_compensation(true));
|
||||
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_->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));
|
||||
@ -746,34 +731,12 @@ 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));
|
||||
@ -782,7 +745,6 @@ 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));
|
||||
@ -906,79 +868,13 @@ 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.
|
||||
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));
|
||||
AudioProcessing::Config apm_config = apm_->GetConfig();
|
||||
apm_config.echo_canceller.enabled = true;
|
||||
apm_config.echo_canceller.mobile_mode = false;
|
||||
apm_->ApplyConfig(apm_config);
|
||||
Config config;
|
||||
config.Set<DelayAgnostic>(new DelayAgnostic(false));
|
||||
apm_->SetExtraOptions(config);
|
||||
@ -1446,8 +1342,9 @@ TEST_F(ApmTest, VoiceDetection) {
|
||||
}
|
||||
|
||||
TEST_F(ApmTest, AllProcessingDisabledByDefault) {
|
||||
EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
|
||||
EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
|
||||
AudioProcessing::Config config = apm_->GetConfig();
|
||||
EXPECT_FALSE(config.echo_canceller.enabled);
|
||||
EXPECT_FALSE(config.high_pass_filter.enabled);
|
||||
EXPECT_FALSE(apm_->gain_control()->is_enabled());
|
||||
EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
|
||||
EXPECT_FALSE(apm_->level_estimator()->is_enabled());
|
||||
@ -1530,7 +1427,6 @@ 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_));
|
||||
@ -1590,7 +1486,10 @@ 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.
|
||||
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->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);
|
||||
// Make sure we have extended filter enabled. This makes sure nothing is
|
||||
// touched until we have a farend frame.
|
||||
Config config;
|
||||
@ -1599,10 +1498,8 @@ 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));
|
||||
|
||||
@ -1614,7 +1511,6 @@ 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));
|
||||
}
|
||||
@ -1686,7 +1582,6 @@ 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 {
|
||||
@ -1907,8 +1802,6 @@ 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));
|
||||
|
||||
@ -1945,8 +1838,6 @@ 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);
|
||||
@ -2045,7 +1936,6 @@ 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));
|
||||
|
||||
@ -2411,7 +2301,6 @@ 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(
|
||||
@ -2870,25 +2759,17 @@ std::unique_ptr<AudioProcessing> CreateApm(bool use_AEC2) {
|
||||
}
|
||||
|
||||
// Disable all components except for an AEC and the residual echo detector.
|
||||
AudioProcessing::Config config;
|
||||
config.residual_echo_detector.enabled = true;
|
||||
config.high_pass_filter.enabled = false;
|
||||
config.gain_controller2.enabled = false;
|
||||
apm->ApplyConfig(config);
|
||||
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);
|
||||
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,10 +26,9 @@ void SetupComponent(int sample_rate_hz,
|
||||
bool drift_compensation_enabled,
|
||||
EchoCancellationImpl* echo_canceller) {
|
||||
echo_canceller->Initialize(sample_rate_hz, 1, 1, 1);
|
||||
EchoCancellation* ec = static_cast<EchoCancellation*>(echo_canceller);
|
||||
ec->Enable(true);
|
||||
ec->set_suppression_level(suppression_level);
|
||||
ec->enable_drift_compensation(drift_compensation_enabled);
|
||||
echo_canceller->Enable(true);
|
||||
echo_canceller->set_suppression_level(suppression_level);
|
||||
echo_canceller->enable_drift_compensation(drift_compensation_enabled);
|
||||
|
||||
Config config;
|
||||
config.Set<DelayAgnostic>(new DelayAgnostic(true));
|
||||
@ -56,8 +55,7 @@ void ProcessOneFrame(int sample_rate_hz,
|
||||
echo_canceller->ProcessRenderAudio(render_audio);
|
||||
|
||||
if (drift_compensation_enabled) {
|
||||
static_cast<EchoCancellation*>(echo_canceller)
|
||||
->set_stream_drift_samples(stream_drift_samples);
|
||||
echo_canceller->set_stream_drift_samples(stream_drift_samples);
|
||||
}
|
||||
|
||||
echo_canceller->ProcessCaptureAudio(capture_audio_buffer, stream_delay_ms);
|
||||
@ -118,8 +116,7 @@ void RunBitexactnessTest(int sample_rate_hz,
|
||||
test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer,
|
||||
&capture_output);
|
||||
|
||||
EXPECT_EQ(stream_has_echo_reference,
|
||||
static_cast<EchoCancellation*>(&echo_canceller)->stream_has_echo());
|
||||
EXPECT_EQ(stream_has_echo_reference, 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_(false),
|
||||
metrics_enabled_(true),
|
||||
suppression_level_(kHighSuppression),
|
||||
stream_drift_samples_(0),
|
||||
was_stream_drift_set_(false),
|
||||
stream_has_echo_(false),
|
||||
delay_logging_enabled_(false),
|
||||
delay_logging_enabled_(true),
|
||||
extended_filter_enabled_(false),
|
||||
delay_agnostic_enabled_(false),
|
||||
enforce_zero_stream_delay_(EnforceZeroStreamDelay()) {
|
||||
|
||||
@ -22,7 +22,7 @@ namespace webrtc {
|
||||
|
||||
class AudioBuffer;
|
||||
|
||||
class EchoCancellationImpl : public EchoCancellation {
|
||||
class EchoCancellationImpl : EchoCancellation {
|
||||
public:
|
||||
EchoCancellationImpl(rtc::CriticalSection* crit_render,
|
||||
rtc::CriticalSection* crit_capture);
|
||||
@ -32,10 +32,29 @@ class EchoCancellationImpl : public EchoCancellation {
|
||||
int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
|
||||
|
||||
// EchoCancellation implementation.
|
||||
int Enable(bool enable) override;
|
||||
bool is_enabled() const override;
|
||||
int stream_drift_samples() const override;
|
||||
SuppressionLevel suppression_level() 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;
|
||||
|
||||
void Initialize(int sample_rate_hz,
|
||||
size_t num_reverse_channels_,
|
||||
@ -57,36 +76,10 @@ class EchoCancellationImpl : public 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,69 +11,136 @@
|
||||
#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) {
|
||||
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
|
||||
EXPECT_TRUE(ap->echo_cancellation()->aec_core() == NULL);
|
||||
rtc::CriticalSection crit_render;
|
||||
rtc::CriticalSection crit_capture;
|
||||
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
|
||||
|
||||
EXPECT_EQ(ap->kNoError, ap->echo_cancellation()->Enable(true));
|
||||
EXPECT_TRUE(ap->echo_cancellation()->is_enabled());
|
||||
EXPECT_TRUE(echo_canceller.aec_core() == nullptr);
|
||||
|
||||
AecCore* aec_core = ap->echo_cancellation()->aec_core();
|
||||
echo_canceller.Enable(true);
|
||||
|
||||
AecCore* aec_core = echo_canceller.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));
|
||||
ap->SetExtraOptions(config);
|
||||
echo_canceller.SetExtraOptions(config);
|
||||
EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
|
||||
|
||||
// Retains setting after initialization.
|
||||
EXPECT_EQ(ap->kNoError, ap->Initialize());
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
|
||||
EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
|
||||
|
||||
config.Set<ExtendedFilter>(new ExtendedFilter(false));
|
||||
ap->SetExtraOptions(config);
|
||||
echo_canceller.SetExtraOptions(config);
|
||||
EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
|
||||
|
||||
// Retains setting after initialization.
|
||||
EXPECT_EQ(ap->kNoError, ap->Initialize());
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
|
||||
EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
|
||||
}
|
||||
|
||||
TEST(EchoCancellationInternalTest, DelayAgnostic) {
|
||||
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
|
||||
EXPECT_TRUE(ap->echo_cancellation()->aec_core() == NULL);
|
||||
rtc::CriticalSection crit_render;
|
||||
rtc::CriticalSection crit_capture;
|
||||
EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 1, 1, 1);
|
||||
|
||||
EXPECT_EQ(ap->kNoError, ap->echo_cancellation()->Enable(true));
|
||||
EXPECT_TRUE(ap->echo_cancellation()->is_enabled());
|
||||
EXPECT_TRUE(echo_canceller.aec_core() == NULL);
|
||||
|
||||
AecCore* aec_core = ap->echo_cancellation()->aec_core();
|
||||
EXPECT_EQ(0, echo_canceller.Enable(true));
|
||||
EXPECT_TRUE(echo_canceller.is_enabled());
|
||||
|
||||
AecCore* aec_core = echo_canceller.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));
|
||||
ap->SetExtraOptions(config);
|
||||
echo_canceller.SetExtraOptions(config);
|
||||
EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
|
||||
|
||||
// Retains setting after initialization.
|
||||
EXPECT_EQ(ap->kNoError, ap->Initialize());
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
|
||||
EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
|
||||
|
||||
config.Set<DelayAgnostic>(new DelayAgnostic(false));
|
||||
ap->SetExtraOptions(config);
|
||||
echo_canceller.SetExtraOptions(config);
|
||||
EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
|
||||
|
||||
// Retains setting after initialization.
|
||||
EXPECT_EQ(ap->kNoError, ap->Initialize());
|
||||
echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
|
||||
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,11 +10,13 @@
|
||||
|
||||
#include "modules/audio_processing/echo_cancellation_proxy.h"
|
||||
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
EchoCancellationProxy::EchoCancellationProxy(
|
||||
AudioProcessing* audio_processing,
|
||||
EchoCancellation* echo_cancellation)
|
||||
EchoCancellationImpl* echo_cancellation)
|
||||
: audio_processing_(audio_processing),
|
||||
echo_cancellation_(echo_cancellation) {}
|
||||
|
||||
@ -22,8 +24,6 @@ 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,7 +32,6 @@ int EchoCancellationProxy::Enable(bool enable) {
|
||||
apm_config.echo_canceller.mobile_mode = false;
|
||||
audio_processing_->ApplyConfig(apm_config);
|
||||
}
|
||||
echo_cancellation_->Enable(enable);
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
@ -58,7 +57,15 @@ int EchoCancellationProxy::stream_drift_samples() const {
|
||||
|
||||
int EchoCancellationProxy::set_suppression_level(
|
||||
EchoCancellation::SuppressionLevel level) {
|
||||
return echo_cancellation_->set_suppression_level(level);
|
||||
if (level == EchoCancellation::SuppressionLevel::kLowSuppression) {
|
||||
RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 low suppression";
|
||||
return AudioProcessing::kBadParameterError;
|
||||
}
|
||||
AudioProcessing::Config apm_config = audio_processing_->GetConfig();
|
||||
apm_config.echo_canceller.legacy_moderate_suppression_level =
|
||||
(level == EchoCancellation::SuppressionLevel::kModerateSuppression);
|
||||
audio_processing_->ApplyConfig(apm_config);
|
||||
return AudioProcessing::kNoError;
|
||||
}
|
||||
|
||||
EchoCancellation::SuppressionLevel EchoCancellationProxy::suppression_level()
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#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"
|
||||
@ -21,7 +22,7 @@ namespace webrtc {
|
||||
class EchoCancellationProxy : public EchoCancellation {
|
||||
public:
|
||||
EchoCancellationProxy(AudioProcessing* audio_processing,
|
||||
EchoCancellation* echo_cancellation);
|
||||
EchoCancellationImpl* echo_cancellation);
|
||||
~EchoCancellationProxy() override;
|
||||
|
||||
int Enable(bool enable) override;
|
||||
@ -46,7 +47,7 @@ class EchoCancellationProxy : public EchoCancellation {
|
||||
|
||||
private:
|
||||
AudioProcessing* audio_processing_;
|
||||
EchoCancellation* echo_cancellation_;
|
||||
EchoCancellationImpl* echo_cancellation_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationProxy);
|
||||
};
|
||||
|
||||
@ -193,13 +193,12 @@ 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,6 +15,7 @@
|
||||
|
||||
#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 {
|
||||
@ -146,15 +147,6 @@ 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());
|
||||
@ -306,14 +298,11 @@ void AecDumpBasedSimulator::HandleMessage(
|
||||
|
||||
if (msg.has_aec_drift_compensation_enabled() ||
|
||||
settings_.use_drift_compensation) {
|
||||
bool enable = settings_.use_drift_compensation
|
||||
? *settings_.use_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;
|
||||
if (settings_.use_drift_compensation
|
||||
? *settings_.use_drift_compensation
|
||||
: msg.aec_drift_compensation_enabled()) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "Ignoring deprecated setting: AEC2 drift compensation";
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,15 +319,20 @@ void AecDumpBasedSimulator::HandleMessage(
|
||||
}
|
||||
|
||||
if (msg.has_aec_suppression_level() || settings_.aec_suppression_level) {
|
||||
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;
|
||||
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);
|
||||
if (settings_.use_verbose_logging) {
|
||||
std::cout << " aec_suppression_level: " << level << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -924,6 +924,14 @@ 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) {
|
||||
@ -942,6 +950,21 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -974,14 +997,6 @@ 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));
|
||||
@ -1019,19 +1034,6 @@ 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,9 +106,6 @@ 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");
|
||||
@ -262,8 +259,6 @@ 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);
|
||||
|
||||
@ -365,11 +360,12 @@ 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) < 0 ||
|
||||
(*settings.aec_suppression_level) > 2),
|
||||
"Error: --aec_suppression_level must be specified between 0 and 2.\n");
|
||||
ReportConditionalErrorAndExit(settings.aec_suppression_level &&
|
||||
((*settings.aec_suppression_level) < 1 ||
|
||||
(*settings.aec_suppression_level) > 2),
|
||||
"Error: --aec_suppression_level must be "
|
||||
"specified between 1 and 2. 0 is "
|
||||
"deprecated.\n");
|
||||
|
||||
ReportConditionalErrorAndExit(
|
||||
settings.aecm_routing_mode && ((*settings.aecm_routing_mode) < 0 ||
|
||||
|
||||
@ -123,7 +123,6 @@ 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 {
|
||||
@ -213,16 +212,11 @@ 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());
|
||||
RTC_CHECK_EQ(AudioProcessing::kNoError,
|
||||
apm_->echo_cancellation()->set_suppression_level(
|
||||
static_cast<EchoCancellation::SuppressionLevel>(
|
||||
msg.aec_suppression_level())));
|
||||
apm_config.echo_canceller.legacy_moderate_suppression_level =
|
||||
static_cast<EchoCancellation::SuppressionLevel>(
|
||||
msg.aec_suppression_level()) ==
|
||||
EchoCancellation::SuppressionLevel::kModerateSuppression;
|
||||
|
||||
RTC_CHECK(msg.has_aecm_comfort_noise_enabled());
|
||||
RTC_CHECK_EQ(AudioProcessing::kNoError,
|
||||
|
||||
@ -359,12 +359,13 @@ TEST_F(DebugDumpTest, ChangeOutputFormat) {
|
||||
|
||||
TEST_F(DebugDumpTest, ToggleAec) {
|
||||
Config config;
|
||||
DebugDumpGenerator generator(config, AudioProcessing::Config());
|
||||
AudioProcessing::Config apm_config;
|
||||
DebugDumpGenerator generator(config, apm_config);
|
||||
generator.StartRecording();
|
||||
generator.Process(100);
|
||||
|
||||
EchoCancellation* aec = generator.apm()->echo_cancellation();
|
||||
EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(!aec->is_enabled()));
|
||||
apm_config.echo_canceller.enabled = true;
|
||||
generator.apm()->ApplyConfig(apm_config);
|
||||
|
||||
generator.Process(100);
|
||||
generator.StopRecording();
|
||||
@ -374,12 +375,13 @@ TEST_F(DebugDumpTest, ToggleAec) {
|
||||
TEST_F(DebugDumpTest, ToggleDelayAgnosticAec) {
|
||||
Config config;
|
||||
config.Set<DelayAgnostic>(new DelayAgnostic(true));
|
||||
DebugDumpGenerator generator(config, AudioProcessing::Config());
|
||||
AudioProcessing::Config apm_config;
|
||||
DebugDumpGenerator generator(config, apm_config);
|
||||
generator.StartRecording();
|
||||
generator.Process(100);
|
||||
|
||||
EchoCancellation* aec = generator.apm()->echo_cancellation();
|
||||
EXPECT_EQ(AudioProcessing::kNoError, aec->Enable(!aec->is_enabled()));
|
||||
apm_config.echo_canceller.enabled = true;
|
||||
generator.apm()->ApplyConfig(apm_config);
|
||||
|
||||
generator.Process(100);
|
||||
generator.StopRecording();
|
||||
@ -548,15 +550,13 @@ 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);
|
||||
|
||||
EXPECT_EQ(AudioProcessing::kNoError,
|
||||
aec->set_suppression_level(EchoCancellation::kHighSuppression));
|
||||
apm_config.echo_canceller.legacy_moderate_suppression_level = false;
|
||||
generator.apm()->ApplyConfig(apm_config);
|
||||
generator.Process(100);
|
||||
generator.StopRecording();
|
||||
VerifyDebugDump(generator.dump_file_name());
|
||||
|
||||
@ -79,9 +79,6 @@ 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…
x
Reference in New Issue
Block a user