Remove AudioProcessing::level_estimator() getter

The new configuration path is via AudioProcessing::ApplyConfig and
AudioProcessing::GetStatistics.

Bug: webrtc:9878
Change-Id: Ic912d67455fcef4895566edb8fef62baf62d7cfe
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156440
Commit-Queue: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29454}
This commit is contained in:
saza
2019-10-11 19:31:07 +02:00
committed by Commit Bot
parent c67a4d63dd
commit 6787f232ae
14 changed files with 99 additions and 264 deletions

View File

@ -132,8 +132,8 @@ rtc_static_library("audio_processing") {
"gain_controller2.h", "gain_controller2.h",
"include/aec_dump.cc", "include/aec_dump.cc",
"include/aec_dump.h", "include/aec_dump.h",
"level_estimator_impl.cc", "level_estimator.cc",
"level_estimator_impl.h", "level_estimator.h",
"noise_suppression_impl.cc", "noise_suppression_impl.cc",
"noise_suppression_impl.h", "noise_suppression_impl.h",
"render_queue_item_verifier.h", "render_queue_item_verifier.h",

View File

@ -34,7 +34,7 @@
#include "modules/audio_processing/gain_controller2.h" #include "modules/audio_processing/gain_controller2.h"
#include "modules/audio_processing/high_pass_filter.h" #include "modules/audio_processing/high_pass_filter.h"
#include "modules/audio_processing/include/audio_frame_view.h" #include "modules/audio_processing/include/audio_frame_view.h"
#include "modules/audio_processing/level_estimator_impl.h" #include "modules/audio_processing/level_estimator.h"
#include "modules/audio_processing/logging/apm_data_dumper.h" #include "modules/audio_processing/logging/apm_data_dumper.h"
#include "modules/audio_processing/noise_suppression_impl.h" #include "modules/audio_processing/noise_suppression_impl.h"
#include "modules/audio_processing/noise_suppression_proxy.h" #include "modules/audio_processing/noise_suppression_proxy.h"
@ -166,7 +166,6 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
bool pre_amplifier_enabled, bool pre_amplifier_enabled,
bool echo_controller_enabled, bool echo_controller_enabled,
bool voice_detector_enabled, bool voice_detector_enabled,
bool level_estimator_enabled,
bool transient_suppressor_enabled) { bool transient_suppressor_enabled) {
bool changed = false; bool changed = false;
changed |= (high_pass_filter_enabled != high_pass_filter_enabled_); changed |= (high_pass_filter_enabled != high_pass_filter_enabled_);
@ -181,7 +180,6 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
changed |= (gain_controller2_enabled != gain_controller2_enabled_); changed |= (gain_controller2_enabled != gain_controller2_enabled_);
changed |= (pre_amplifier_enabled_ != pre_amplifier_enabled); changed |= (pre_amplifier_enabled_ != pre_amplifier_enabled);
changed |= (echo_controller_enabled != echo_controller_enabled_); changed |= (echo_controller_enabled != echo_controller_enabled_);
changed |= (level_estimator_enabled != level_estimator_enabled_);
changed |= (voice_detector_enabled != voice_detector_enabled_); changed |= (voice_detector_enabled != voice_detector_enabled_);
changed |= (transient_suppressor_enabled != transient_suppressor_enabled_); changed |= (transient_suppressor_enabled != transient_suppressor_enabled_);
if (changed) { if (changed) {
@ -194,7 +192,6 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
gain_controller2_enabled_ = gain_controller2_enabled; gain_controller2_enabled_ = gain_controller2_enabled;
pre_amplifier_enabled_ = pre_amplifier_enabled; pre_amplifier_enabled_ = pre_amplifier_enabled;
echo_controller_enabled_ = echo_controller_enabled; echo_controller_enabled_ = echo_controller_enabled;
level_estimator_enabled_ = level_estimator_enabled;
voice_detector_enabled_ = voice_detector_enabled; voice_detector_enabled_ = voice_detector_enabled;
transient_suppressor_enabled_ = transient_suppressor_enabled; transient_suppressor_enabled_ = transient_suppressor_enabled;
} }
@ -261,7 +258,6 @@ struct AudioProcessingImpl::ApmPublicSubmodules {
// Accessed externally of APM without any lock acquired. // Accessed externally of APM without any lock acquired.
// TODO(bugs.webrtc.org/9947): Move these submodules into private_submodules_ // TODO(bugs.webrtc.org/9947): Move these submodules into private_submodules_
// when their pointer-to-submodule API functions are gone. // when their pointer-to-submodule API functions are gone.
std::unique_ptr<LevelEstimatorImpl> level_estimator;
std::unique_ptr<NoiseSuppressionImpl> noise_suppression; std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
std::unique_ptr<NoiseSuppressionProxy> noise_suppression_proxy; std::unique_ptr<NoiseSuppressionProxy> noise_suppression_proxy;
std::unique_ptr<GainControlImpl> gain_control; std::unique_ptr<GainControlImpl> gain_control;
@ -294,7 +290,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules {
std::unique_ptr<CustomProcessing> render_pre_processor; std::unique_ptr<CustomProcessing> render_pre_processor;
std::unique_ptr<GainApplier> pre_amplifier; std::unique_ptr<GainApplier> pre_amplifier;
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer; std::unique_ptr<CustomAudioAnalyzer> capture_analyzer;
std::unique_ptr<LevelEstimatorImpl> output_level_estimator; std::unique_ptr<LevelEstimator> output_level_estimator;
std::unique_ptr<VoiceDetection> voice_detector; std::unique_ptr<VoiceDetection> voice_detector;
}; };
@ -409,8 +405,6 @@ AudioProcessingImpl::AudioProcessingImpl(
static_cast<bool>(echo_control_factory_); static_cast<bool>(echo_control_factory_);
public_submodules_->gain_control.reset(new GainControlImpl()); public_submodules_->gain_control.reset(new GainControlImpl());
public_submodules_->level_estimator.reset(
new LevelEstimatorImpl(&crit_capture_));
public_submodules_->noise_suppression.reset( public_submodules_->noise_suppression.reset(
new NoiseSuppressionImpl(&crit_capture_)); new NoiseSuppressionImpl(&crit_capture_));
public_submodules_->noise_suppression_proxy.reset(new NoiseSuppressionProxy( public_submodules_->noise_suppression_proxy.reset(new NoiseSuppressionProxy(
@ -569,7 +563,6 @@ int AudioProcessingImpl::InitializeLocked() {
public_submodules_->noise_suppression->Initialize(num_proc_channels(), public_submodules_->noise_suppression->Initialize(num_proc_channels(),
proc_sample_rate_hz()); proc_sample_rate_hz());
InitializeVoiceDetector(); InitializeVoiceDetector();
public_submodules_->level_estimator->Initialize();
InitializeResidualEchoDetector(); InitializeResidualEchoDetector();
InitializeEchoController(); InitializeEchoController();
InitializeGainController2(); InitializeGainController2();
@ -751,9 +744,8 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
if (config_.level_estimation.enabled && if (config_.level_estimation.enabled &&
!private_submodules_->output_level_estimator) { !private_submodules_->output_level_estimator) {
private_submodules_->output_level_estimator.reset( private_submodules_->output_level_estimator =
new LevelEstimatorImpl(&crit_capture_)); std::make_unique<LevelEstimator>();
private_submodules_->output_level_estimator->Enable(true);
} }
if (voice_detection_config_changed) { if (voice_detection_config_changed) {
@ -1541,7 +1533,6 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
} }
// The level estimator operates on the recombined data. // The level estimator operates on the recombined data.
public_submodules_->level_estimator->ProcessStream(*capture_buffer);
if (config_.level_estimation.enabled) { if (config_.level_estimation.enabled) {
private_submodules_->output_level_estimator->ProcessStream(*capture_buffer); private_submodules_->output_level_estimator->ProcessStream(*capture_buffer);
capture_.stats.output_rms_dbfs = capture_.stats.output_rms_dbfs =
@ -1841,10 +1832,6 @@ GainControl* AudioProcessingImpl::gain_control() const {
return public_submodules_->gain_control_config_proxy.get(); return public_submodules_->gain_control_config_proxy.get();
} }
LevelEstimator* AudioProcessingImpl::level_estimator() const {
return public_submodules_->level_estimator.get();
}
NoiseSuppression* AudioProcessingImpl::noise_suppression() const { NoiseSuppression* AudioProcessingImpl::noise_suppression() const {
return public_submodules_->noise_suppression_proxy.get(); return public_submodules_->noise_suppression_proxy.get();
} }
@ -1874,7 +1861,6 @@ bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
config_.gain_controller2.enabled, config_.pre_amplifier.enabled, config_.gain_controller2.enabled, config_.pre_amplifier.enabled,
capture_nonlocked_.echo_controller_enabled, capture_nonlocked_.echo_controller_enabled,
config_.voice_detection.enabled, config_.voice_detection.enabled,
public_submodules_->level_estimator->is_enabled(),
capture_.transient_suppressor_enabled); capture_.transient_suppressor_enabled);
} }

View File

@ -120,7 +120,6 @@ class AudioProcessingImpl : public AudioProcessing {
// created only once in a single-treaded manner // created only once in a single-treaded manner
// during APM creation). // during APM creation).
GainControl* gain_control() const override; GainControl* gain_control() const override;
LevelEstimator* level_estimator() const override;
NoiseSuppression* noise_suppression() const override; NoiseSuppression* noise_suppression() const override;
// TODO(peah): Remove MutateConfig once the new API allows that. // TODO(peah): Remove MutateConfig once the new API allows that.
@ -182,7 +181,6 @@ class AudioProcessingImpl : public AudioProcessing {
bool pre_amplifier_enabled, bool pre_amplifier_enabled,
bool echo_controller_enabled, bool echo_controller_enabled,
bool voice_detector_enabled, bool voice_detector_enabled,
bool level_estimator_enabled,
bool transient_suppressor_enabled); bool transient_suppressor_enabled);
bool CaptureMultiBandSubModulesActive() const; bool CaptureMultiBandSubModulesActive() const;
bool CaptureMultiBandProcessingPresent() const; bool CaptureMultiBandProcessingPresent() const;
@ -207,7 +205,6 @@ class AudioProcessingImpl : public AudioProcessing {
bool gain_controller2_enabled_ = false; bool gain_controller2_enabled_ = false;
bool pre_amplifier_enabled_ = false; bool pre_amplifier_enabled_ = false;
bool echo_controller_enabled_ = false; bool echo_controller_enabled_ = false;
bool level_estimator_enabled_ = false;
bool voice_detector_enabled_ = false; bool voice_detector_enabled_ = false;
bool transient_suppressor_enabled_ = false; bool transient_suppressor_enabled_ = false;
bool first_update_ = true; bool first_update_ = true;

View File

@ -446,7 +446,6 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
void SetUp() override { void SetUp() override {
// Lambda function for setting the default APM runtime settings for desktop. // Lambda function for setting the default APM runtime settings for desktop.
auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) { auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true)); ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital)); apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
@ -455,13 +454,13 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
AudioProcessing::Config apm_config = apm->GetConfig(); AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true; apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false; apm_config.echo_canceller.mobile_mode = false;
apm_config.level_estimation.enabled = true;
apm_config.voice_detection.enabled = true; apm_config.voice_detection.enabled = true;
apm->ApplyConfig(apm_config); apm->ApplyConfig(apm_config);
}; };
// Lambda function for setting the default APM runtime settings for mobile. // Lambda function for setting the default APM runtime settings for mobile.
auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) { auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true)); ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital)); apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
@ -470,6 +469,7 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
AudioProcessing::Config apm_config = apm->GetConfig(); AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true; apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = true; apm_config.echo_canceller.mobile_mode = true;
apm_config.level_estimation.enabled = true;
apm_config.voice_detection.enabled = true; apm_config.voice_detection.enabled = true;
apm->ApplyConfig(apm_config); apm->ApplyConfig(apm_config);
}; };
@ -477,7 +477,6 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
// Lambda function for turning off all of the APM runtime settings // Lambda function for turning off all of the APM runtime settings
// submodules. // submodules.
auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) { auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false)); ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
ASSERT_EQ(apm->kNoError, ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital)); apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
@ -485,6 +484,7 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false)); ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false));
AudioProcessing::Config apm_config = apm->GetConfig(); AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = false; apm_config.echo_canceller.enabled = false;
apm_config.level_estimation.enabled = false;
apm_config.voice_detection.enabled = false; apm_config.voice_detection.enabled = false;
apm->ApplyConfig(apm_config); apm->ApplyConfig(apm_config);
}; };

View File

@ -196,7 +196,6 @@ void EnableAllAPComponents(AudioProcessing* ap) {
apm_config.voice_detection.enabled = true; apm_config.voice_detection.enabled = true;
ap->ApplyConfig(apm_config); ap->ApplyConfig(apm_config);
EXPECT_NOERR(ap->level_estimator()->Enable(true));
EXPECT_NOERR(ap->noise_suppression()->Enable(true)); EXPECT_NOERR(ap->noise_suppression()->Enable(true));
} }
@ -1048,71 +1047,6 @@ TEST_F(ApmTest, HighPassFilter) {
apm_->ApplyConfig(apm_config); apm_->ApplyConfig(apm_config);
} }
TEST_F(ApmTest, LevelEstimator) {
// Turn level estimator on/off
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
EXPECT_FALSE(apm_->level_estimator()->is_enabled());
EXPECT_EQ(apm_->kNotEnabledError, apm_->level_estimator()->RMS());
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
EXPECT_TRUE(apm_->level_estimator()->is_enabled());
// Run this test in wideband; in super-wb, the splitting filter distorts the
// audio enough to cause deviation from the expectation for small values.
frame_->samples_per_channel_ = 160;
frame_->num_channels_ = 2;
frame_->sample_rate_hz_ = 16000;
// Min value if no frames have been processed.
EXPECT_EQ(127, apm_->level_estimator()->RMS());
// Min value on zero frames.
SetFrameTo(frame_, 0);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(127, apm_->level_estimator()->RMS());
// Try a few RMS values.
// (These also test that the value resets after retrieving it.)
SetFrameTo(frame_, 32767);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(0, apm_->level_estimator()->RMS());
SetFrameTo(frame_, 30000);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(1, apm_->level_estimator()->RMS());
SetFrameTo(frame_, 10000);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(10, apm_->level_estimator()->RMS());
SetFrameTo(frame_, 10);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(70, apm_->level_estimator()->RMS());
// Verify reset after enable/disable.
SetFrameTo(frame_, 32767);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
SetFrameTo(frame_, 1);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(90, apm_->level_estimator()->RMS());
// Verify reset after initialize.
SetFrameTo(frame_, 32767);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->Initialize());
SetFrameTo(frame_, 1);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(90, apm_->level_estimator()->RMS());
}
TEST_F(ApmTest, AllProcessingDisabledByDefault) { TEST_F(ApmTest, AllProcessingDisabledByDefault) {
AudioProcessing::Config config = apm_->GetConfig(); AudioProcessing::Config config = apm_->GetConfig();
EXPECT_FALSE(config.echo_canceller.enabled); EXPECT_FALSE(config.echo_canceller.enabled);
@ -1120,7 +1054,6 @@ TEST_F(ApmTest, AllProcessingDisabledByDefault) {
EXPECT_FALSE(config.level_estimation.enabled); EXPECT_FALSE(config.level_estimation.enabled);
EXPECT_FALSE(config.voice_detection.enabled); EXPECT_FALSE(config.voice_detection.enabled);
EXPECT_FALSE(apm_->gain_control()->is_enabled()); EXPECT_FALSE(apm_->gain_control()->is_enabled());
EXPECT_FALSE(apm_->level_estimator()->is_enabled());
EXPECT_FALSE(apm_->noise_suppression()->is_enabled()); EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
} }
@ -1215,18 +1148,20 @@ TEST_F(ApmTest, SplittingFilter) {
EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy)); EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
// 2. Only the level estimator is enabled... // 2. Only the level estimator is enabled...
auto apm_config = apm_->GetConfig();
SetFrameTo(frame_, 1000); SetFrameTo(frame_, 1000);
frame_copy.CopyFrom(*frame_); frame_copy.CopyFrom(*frame_);
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true)); apm_config.level_estimation.enabled = true;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy)); EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false)); apm_config.level_estimation.enabled = false;
apm_->ApplyConfig(apm_config);
// 3. Only GetStatistics-reporting VAD is enabled... // 3. Only GetStatistics-reporting VAD is enabled...
SetFrameTo(frame_, 1000); SetFrameTo(frame_, 1000);
frame_copy.CopyFrom(*frame_); frame_copy.CopyFrom(*frame_);
auto apm_config = apm_->GetConfig();
apm_config.voice_detection.enabled = true; apm_config.voice_detection.enabled = true;
apm_->ApplyConfig(apm_config); apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
@ -1238,14 +1173,14 @@ TEST_F(ApmTest, SplittingFilter) {
// 4. Both the VAD and the level estimator are enabled... // 4. Both the VAD and the level estimator are enabled...
SetFrameTo(frame_, 1000); SetFrameTo(frame_, 1000);
frame_copy.CopyFrom(*frame_); frame_copy.CopyFrom(*frame_);
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
apm_config.voice_detection.enabled = true; apm_config.voice_detection.enabled = true;
apm_config.level_estimation.enabled = true;
apm_->ApplyConfig(apm_config); apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy)); EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
apm_config.voice_detection.enabled = false; apm_config.voice_detection.enabled = false;
apm_config.level_estimation.enabled = false;
apm_->ApplyConfig(apm_config); apm_->ApplyConfig(apm_config);
// Check the test is valid. We should have distortion from the filter // Check the test is valid. We should have distortion from the filter
@ -2491,7 +2426,6 @@ std::unique_ptr<AudioProcessing> CreateApm(bool mobile_aec) {
apm_config.echo_canceller.mobile_mode = mobile_aec; apm_config.echo_canceller.mobile_mode = mobile_aec;
apm->ApplyConfig(apm_config); apm->ApplyConfig(apm_config);
EXPECT_EQ(apm->gain_control()->Enable(false), 0); 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->noise_suppression()->Enable(false), 0);
return apm; return apm;
} }

View File

@ -49,7 +49,6 @@ class ProcessingConfig;
class EchoDetector; class EchoDetector;
class GainControl; class GainControl;
class LevelEstimator;
class NoiseSuppression; class NoiseSuppression;
class CustomAudioAnalyzer; class CustomAudioAnalyzer;
class CustomProcessing; class CustomProcessing;
@ -685,7 +684,6 @@ class AudioProcessing : public rtc::RefCountInterface {
// NULL. The pointers will be valid for the lifetime of the APM instance. // NULL. The pointers will be valid for the lifetime of the APM instance.
// The memory for these objects is entirely managed internally. // The memory for these objects is entirely managed internally.
virtual GainControl* gain_control() const = 0; virtual GainControl* gain_control() const = 0;
virtual LevelEstimator* level_estimator() const = 0;
virtual NoiseSuppression* noise_suppression() const = 0; virtual NoiseSuppression* noise_suppression() const = 0;
// Returns the last applied configuration. // Returns the last applied configuration.
@ -874,28 +872,6 @@ class ProcessingConfig {
StreamConfig streams[StreamName::kNumStreamNames]; StreamConfig streams[StreamName::kNumStreamNames];
}; };
// An estimation component used to retrieve level metrics.
class LevelEstimator {
public:
virtual int Enable(bool enable) = 0;
virtual bool is_enabled() const = 0;
// Returns the root mean square (RMS) level in dBFs (decibels from digital
// full-scale), or alternately dBov. It is computed over all primary stream
// frames since the last call to RMS(). The returned value is positive but
// should be interpreted as negative. It is constrained to [0, 127].
//
// The computation follows: https://tools.ietf.org/html/rfc6465
// with the intent that it can provide the RTP audio level indication.
//
// Frames passed to ProcessStream() with an |_energy| of zero are considered
// to have been muted. The RMS of the frame will be interpreted as -127.
virtual int RMS() = 0;
protected:
virtual ~LevelEstimator() {}
};
// The noise suppression (NS) component attempts to remove noise while // The noise suppression (NS) component attempts to remove noise while
// retaining speech. Recommended to be enabled on the client-side. // retaining speech. Recommended to be enabled on the client-side.
// //

View File

@ -43,14 +43,6 @@ class MockGainControl : public GainControl {
MOCK_CONST_METHOD0(stream_is_saturated, bool()); MOCK_CONST_METHOD0(stream_is_saturated, bool());
}; };
class MockLevelEstimator : public LevelEstimator {
public:
virtual ~MockLevelEstimator() {}
MOCK_METHOD1(Enable, int(bool enable));
MOCK_CONST_METHOD0(is_enabled, bool());
MOCK_METHOD0(RMS, int());
};
class MockNoiseSuppression : public NoiseSuppression { class MockNoiseSuppression : public NoiseSuppression {
public: public:
virtual ~MockNoiseSuppression() {} virtual ~MockNoiseSuppression() {}
@ -96,7 +88,6 @@ class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
public: public:
MockAudioProcessing() MockAudioProcessing()
: gain_control_(new ::testing::NiceMock<MockGainControl>()), : gain_control_(new ::testing::NiceMock<MockGainControl>()),
level_estimator_(new ::testing::NiceMock<MockLevelEstimator>()),
noise_suppression_(new ::testing::NiceMock<MockNoiseSuppression>()) {} noise_suppression_(new ::testing::NiceMock<MockNoiseSuppression>()) {}
virtual ~MockAudioProcessing() {} virtual ~MockAudioProcessing() {}
@ -164,9 +155,6 @@ class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
MOCK_METHOD0(UpdateHistogramsOnCallEnd, void()); MOCK_METHOD0(UpdateHistogramsOnCallEnd, void());
MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool)); MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool));
virtual MockGainControl* gain_control() const { return gain_control_.get(); } virtual MockGainControl* gain_control() const { return gain_control_.get(); }
virtual MockLevelEstimator* level_estimator() const {
return level_estimator_.get();
}
virtual MockNoiseSuppression* noise_suppression() const { virtual MockNoiseSuppression* noise_suppression() const {
return noise_suppression_.get(); return noise_suppression_.get();
} }
@ -175,7 +163,6 @@ class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
private: private:
std::unique_ptr<MockGainControl> gain_control_; std::unique_ptr<MockGainControl> gain_control_;
std::unique_ptr<MockLevelEstimator> level_estimator_;
std::unique_ptr<MockNoiseSuppression> noise_suppression_; std::unique_ptr<MockNoiseSuppression> noise_suppression_;
}; };

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_processing/level_estimator.h"
#include "api/array_view.h"
namespace webrtc {
LevelEstimator::LevelEstimator() {
rms_.Reset();
}
LevelEstimator::~LevelEstimator() = default;
void LevelEstimator::ProcessStream(const AudioBuffer& audio) {
for (size_t i = 0; i < audio.num_channels(); i++) {
rms_.Analyze(rtc::ArrayView<const float>(audio.channels_const()[i],
audio.num_frames()));
}
}
} // namespace webrtc

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_H_
#define MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_H_
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/rms_level.h"
namespace webrtc {
// An estimation component used to retrieve level metrics.
class LevelEstimator {
public:
LevelEstimator();
~LevelEstimator();
LevelEstimator(LevelEstimator&) = delete;
LevelEstimator& operator=(LevelEstimator&) = delete;
void ProcessStream(const AudioBuffer& audio);
// Returns the root mean square (RMS) level in dBFs (decibels from digital
// full-scale), or alternately dBov. It is computed over all primary stream
// frames since the last call to RMS(). The returned value is positive but
// should be interpreted as negative. It is constrained to [0, 127].
//
// The computation follows: https://tools.ietf.org/html/rfc6465
// with the intent that it can provide the RTP audio level indication.
//
// Frames passed to ProcessStream() with an |_energy| of zero are considered
// to have been muted. The RMS of the frame will be interpreted as -127.
int RMS() { return rms_.Average(); }
private:
RmsLevel rms_;
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_H_

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_processing/level_estimator_impl.h"
#include <stddef.h>
#include <stdint.h>
#include "api/array_view.h"
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/rms_level.h"
#include "rtc_base/checks.h"
namespace webrtc {
LevelEstimatorImpl::LevelEstimatorImpl(rtc::CriticalSection* crit)
: crit_(crit), rms_(new RmsLevel()) {
RTC_DCHECK(crit);
}
LevelEstimatorImpl::~LevelEstimatorImpl() {}
void LevelEstimatorImpl::Initialize() {
rtc::CritScope cs(crit_);
rms_->Reset();
}
void LevelEstimatorImpl::ProcessStream(const AudioBuffer& audio) {
rtc::CritScope cs(crit_);
if (!enabled_) {
return;
}
for (size_t i = 0; i < audio.num_channels(); i++) {
rms_->Analyze(rtc::ArrayView<const float>(audio.channels_const()[i],
audio.num_frames()));
}
}
int LevelEstimatorImpl::Enable(bool enable) {
rtc::CritScope cs(crit_);
if (enable && !enabled_) {
rms_->Reset();
}
enabled_ = enable;
return AudioProcessing::kNoError;
}
bool LevelEstimatorImpl::is_enabled() const {
rtc::CritScope cs(crit_);
return enabled_;
}
int LevelEstimatorImpl::RMS() {
rtc::CritScope cs(crit_);
if (!enabled_) {
return AudioProcessing::kNotEnabledError;
}
return rms_->Average();
}
} // namespace webrtc

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_IMPL_H_
#define MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_IMPL_H_
#include <memory>
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/critical_section.h"
namespace webrtc {
class AudioBuffer;
class RmsLevel;
class LevelEstimatorImpl : public LevelEstimator {
public:
explicit LevelEstimatorImpl(rtc::CriticalSection* crit);
~LevelEstimatorImpl() override;
// TODO(peah): Fold into ctor, once public API is removed.
void Initialize();
void ProcessStream(const AudioBuffer& audio);
// LevelEstimator implementation.
int Enable(bool enable) override;
bool is_enabled() const override;
int RMS() override;
private:
rtc::CriticalSection* const crit_ = nullptr;
bool enabled_ RTC_GUARDED_BY(crit_) = false;
std::unique_ptr<RmsLevel> rms_ RTC_GUARDED_BY(crit_);
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LevelEstimatorImpl);
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_LEVEL_ESTIMATOR_IMPL_H_

View File

@ -11,7 +11,7 @@
#include "api/array_view.h" #include "api/array_view.h"
#include "modules/audio_processing/audio_buffer.h" #include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/level_estimator_impl.h" #include "modules/audio_processing/level_estimator.h"
#include "modules/audio_processing/test/audio_buffer_tools.h" #include "modules/audio_processing/test/audio_buffer_tools.h"
#include "modules/audio_processing/test/bitexactness_tools.h" #include "modules/audio_processing/test/bitexactness_tools.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -26,11 +26,7 @@ const int kNumFramesToProcess = 1000;
void RunBitexactnessTest(int sample_rate_hz, void RunBitexactnessTest(int sample_rate_hz,
size_t num_channels, size_t num_channels,
int rms_reference) { int rms_reference) {
rtc::CriticalSection crit_capture; LevelEstimator level_estimator;
LevelEstimatorImpl level_estimator(&crit_capture);
level_estimator.Initialize();
level_estimator.Enable(true);
int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100); int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100);
StreamConfig capture_config(sample_rate_hz, num_channels, false); StreamConfig capture_config(sample_rate_hz, num_channels, false);
AudioBuffer capture_buffer( AudioBuffer capture_buffer(

View File

@ -455,6 +455,10 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
apm_config.high_pass_filter.enabled = *settings_.use_hpf; apm_config.high_pass_filter.enabled = *settings_.use_hpf;
} }
if (settings_.use_le) {
apm_config.level_estimation.enabled = *settings_.use_le;
}
if (settings_.use_vad) { if (settings_.use_vad) {
apm_config.voice_detection.enabled = *settings_.use_vad; apm_config.voice_detection.enabled = *settings_.use_vad;
} }
@ -502,10 +506,6 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->noise_suppression()->Enable(*settings_.use_ns)); ap_->noise_suppression()->Enable(*settings_.use_ns));
} }
if (settings_.use_le) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->level_estimator()->Enable(*settings_.use_le));
}
if (settings_.use_agc_limiter) { if (settings_.use_agc_limiter) {
RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter( RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter(
*settings_.use_agc_limiter)); *settings_.use_agc_limiter));

View File

@ -142,10 +142,9 @@ std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data,
use_agc2_adaptive_digital_saturation_protector; use_agc2_adaptive_digital_saturation_protector;
apm_config.noise_suppression.enabled = use_ns; apm_config.noise_suppression.enabled = use_ns;
apm_config.voice_detection.enabled = use_vad; apm_config.voice_detection.enabled = use_vad;
apm_config.level_estimation.enabled = use_le;
apm->ApplyConfig(apm_config); apm->ApplyConfig(apm_config);
apm->level_estimator()->Enable(use_le);
return apm; return apm;
} }