Remove the noise_suppression() pointer to submodule interface

Bug: webrtc:9878
Change-Id: I356afddb56cc1957e9d0415e2723f66e0e4ac522
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/137517
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Commit-Queue: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29499}
diff --git a/media/engine/apm_helpers.cc b/media/engine/apm_helpers.cc
index 374c095..31bdd4b 100644
--- a/media/engine/apm_helpers.cc
+++ b/media/engine/apm_helpers.cc
@@ -47,19 +47,5 @@
   apm->ApplyConfig(apm_config);
   RTC_LOG(LS_INFO) << "Echo control set to " << enable << " with mode " << mode;
 }
-
-void SetNsStatus(AudioProcessing* apm, bool enable) {
-  RTC_DCHECK(apm);
-  NoiseSuppression* ns = apm->noise_suppression();
-  if (ns->set_level(NoiseSuppression::kHigh) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to set high NS level.";
-    return;
-  }
-  if (ns->Enable(enable) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to enable/disable NS: " << enable;
-    return;
-  }
-  RTC_LOG(LS_INFO) << "NS set to " << enable;
-}
 }  // namespace apm_helpers
 }  // namespace webrtc
diff --git a/media/engine/apm_helpers.h b/media/engine/apm_helpers.h
index ac61768..7bedda7 100644
--- a/media/engine/apm_helpers.h
+++ b/media/engine/apm_helpers.h
@@ -28,7 +28,6 @@
 void SetEcStatus(AudioProcessing* apm, bool enable, EcModes mode);
 void SetEcMetricsStatus(AudioProcessing* apm, bool enable);
 void SetAecmMode(AudioProcessing* apm, bool enable_cng);
-void SetNsStatus(AudioProcessing* apm, bool enable);
 
 }  // namespace apm_helpers
 }  // namespace webrtc
diff --git a/media/engine/apm_helpers_unittest.cc b/media/engine/apm_helpers_unittest.cc
index e418795..dac24b3 100644
--- a/media/engine/apm_helpers_unittest.cc
+++ b/media/engine/apm_helpers_unittest.cc
@@ -70,22 +70,4 @@
   EXPECT_TRUE(config.echo_canceller.enabled);
   EXPECT_TRUE(config.echo_canceller.mobile_mode);
 }
-
-TEST(ApmHelpersTest, NsStatus_DefaultMode) {
-  TestHelper helper;
-  NoiseSuppression* ns = helper.apm()->noise_suppression();
-  EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
-  EXPECT_FALSE(ns->is_enabled());
-}
-
-TEST(ApmHelpersTest, NsStatus_EnableDisable) {
-  TestHelper helper;
-  NoiseSuppression* ns = helper.apm()->noise_suppression();
-  apm_helpers::SetNsStatus(helper.apm(), true);
-  EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
-  EXPECT_TRUE(ns->is_enabled());
-  apm_helpers::SetNsStatus(helper.apm(), false);
-  EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
-  EXPECT_FALSE(ns->is_enabled());
-}
 }  // namespace webrtc
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 4c3bc84..a7d40b5 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -430,7 +430,6 @@
             << "Disabling NS since built-in NS will be used instead";
       }
     }
-    webrtc::apm_helpers::SetNsStatus(apm(), *options.noise_suppression);
   }
 
   if (options.stereo_swapping) {
@@ -500,6 +499,14 @@
     apm_config.residual_echo_detector.enabled = *options.residual_echo_detector;
   }
 
+  if (options.noise_suppression) {
+    const bool enabled = *options.noise_suppression;
+    apm_config.noise_suppression.enabled = enabled;
+    apm_config.noise_suppression.level =
+        webrtc::AudioProcessing::Config::NoiseSuppression::Level::kHigh;
+    RTC_LOG(LS_INFO) << "NS set to " << enabled;
+  }
+
   if (options.typing_detection) {
     RTC_LOG(LS_INFO) << "Typing detection is enabled? "
                      << *options.typing_detection;
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 711cbbb..bcffa40 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -88,8 +88,9 @@
         webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
 #endif
 
-constexpr webrtc::NoiseSuppression::Level kDefaultNsLevel =
-    webrtc::NoiseSuppression::kHigh;
+constexpr webrtc::AudioProcessing::Config::NoiseSuppression::Level
+    kDefaultNsLevel =
+        webrtc::AudioProcessing::Config::NoiseSuppression::Level::kHigh;
 
 void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
   RTC_DCHECK(adm);
@@ -180,7 +181,6 @@
       : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
         apm_(new rtc::RefCountedObject<
              StrictMock<webrtc::test::MockAudioProcessing>>()),
-        apm_ns_(*apm_->noise_suppression()),
         call_(),
         override_field_trials_(field_trials) {
     // AudioDeviceModule.
@@ -191,8 +191,6 @@
     EXPECT_CALL(*apm_, SetExtraOptions(::testing::_));
     EXPECT_CALL(*apm_, DetachAecDump());
     // Default Options.
-    EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-    EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
     // TODO(kwiberg): We should use mock factories here, but a bunch of
     // the tests here probe the specific set of codecs provided by the builtin
     // factories. Those tests should probably be moved elsewhere.
@@ -209,6 +207,8 @@
     EXPECT_TRUE(IsEchoCancellationEnabled());
     EXPECT_TRUE(IsHighPassFilterEnabled());
     EXPECT_TRUE(IsTypingDetectionEnabled());
+    EXPECT_TRUE(apm_config_.noise_suppression.enabled);
+    EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
     VerifyGainControlEnabledCorrectly();
     VerifyGainControlDefaultSettings();
   }
@@ -771,7 +771,6 @@
   std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
   StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
   rtc::scoped_refptr<StrictMock<webrtc::test::MockAudioProcessing>> apm_;
-  webrtc::test::MockNoiseSuppression& apm_ns_;
   cricket::FakeCall call_;
   std::unique_ptr<cricket::WebRtcVoiceEngine> engine_;
   cricket::VoiceMediaChannel* channel_ = nullptr;
@@ -2887,8 +2886,6 @@
   EXPECT_TRUE(apm_config_.gain_controller1.enabled);
 
   // Turn off other options.
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
   send_parameters_.options.noise_suppression = false;
   send_parameters_.options.highpass_filter = false;
   send_parameters_.options.stereo_swapping = true;
@@ -2896,13 +2893,15 @@
   EXPECT_TRUE(IsEchoCancellationEnabled());
   EXPECT_FALSE(IsHighPassFilterEnabled());
   EXPECT_TRUE(apm_config_.gain_controller1.enabled);
+  EXPECT_FALSE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
 
   // Set options again to ensure it has no impact.
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
   SetSendParameters(send_parameters_);
   EXPECT_TRUE(IsEchoCancellationEnabled());
   EXPECT_TRUE(apm_config_.gain_controller1.enabled);
+  EXPECT_FALSE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
 }
 
 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
@@ -2947,11 +2946,11 @@
   parameters_options_all.options.echo_cancellation = true;
   parameters_options_all.options.auto_gain_control = true;
   parameters_options_all.options.noise_suppression = true;
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).Times(2).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(true)).Times(2).WillRepeatedly(Return(0));
   EXPECT_TRUE(channel1->SetSendParameters(parameters_options_all));
   EXPECT_TRUE(IsEchoCancellationEnabled());
   VerifyGainControlEnabledCorrectly();
+  EXPECT_TRUE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
   EXPECT_EQ(parameters_options_all.options, channel1->options());
   EXPECT_TRUE(channel2->SetSendParameters(parameters_options_all));
   EXPECT_TRUE(IsEchoCancellationEnabled());
@@ -2961,10 +2960,10 @@
   // unset NS
   cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
   parameters_options_no_ns.options.noise_suppression = false;
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
   EXPECT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
   EXPECT_TRUE(IsEchoCancellationEnabled());
+  EXPECT_FALSE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
   VerifyGainControlEnabledCorrectly();
   cricket::AudioOptions expected_options = parameters_options_all.options;
   expected_options.echo_cancellation = true;
@@ -2975,44 +2974,44 @@
   // unset AGC
   cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
   parameters_options_no_agc.options.auto_gain_control = false;
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
   EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
   EXPECT_TRUE(IsEchoCancellationEnabled());
   EXPECT_FALSE(apm_config_.gain_controller1.enabled);
+  EXPECT_TRUE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
   expected_options.echo_cancellation = true;
   expected_options.auto_gain_control = false;
   expected_options.noise_suppression = true;
   EXPECT_EQ(expected_options, channel2->options());
 
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
   EXPECT_TRUE(channel_->SetSendParameters(parameters_options_all));
   EXPECT_TRUE(IsEchoCancellationEnabled());
   VerifyGainControlEnabledCorrectly();
+  EXPECT_TRUE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
 
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
   channel1->SetSend(true);
   EXPECT_TRUE(IsEchoCancellationEnabled());
   VerifyGainControlEnabledCorrectly();
+  EXPECT_FALSE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
 
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(true)).WillOnce(Return(0));
   channel2->SetSend(true);
   EXPECT_TRUE(IsEchoCancellationEnabled());
   EXPECT_FALSE(apm_config_.gain_controller1.enabled);
+  EXPECT_TRUE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
 
   // Make sure settings take effect while we are sending.
   cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
       send_parameters_;
   parameters_options_no_agc_nor_ns.options.auto_gain_control = false;
   parameters_options_no_agc_nor_ns.options.noise_suppression = false;
-  EXPECT_CALL(apm_ns_, set_level(kDefaultNsLevel)).WillOnce(Return(0));
-  EXPECT_CALL(apm_ns_, Enable(false)).WillOnce(Return(0));
   EXPECT_TRUE(channel2->SetSendParameters(parameters_options_no_agc_nor_ns));
   EXPECT_TRUE(IsEchoCancellationEnabled());
   EXPECT_FALSE(apm_config_.gain_controller1.enabled);
+  EXPECT_FALSE(apm_config_.noise_suppression.enabled);
+  EXPECT_EQ(apm_config_.noise_suppression.level, kDefaultNsLevel);
   expected_options.echo_cancellation = true;
   expected_options.auto_gain_control = false;
   expected_options.noise_suppression = false;
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index df06c14..b37fa4c 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -134,8 +134,8 @@
     "include/aec_dump.h",
     "level_estimator.cc",
     "level_estimator.h",
-    "noise_suppression_impl.cc",
-    "noise_suppression_impl.h",
+    "noise_suppression.cc",
+    "noise_suppression.h",
     "render_queue_item_verifier.h",
     "residual_echo_detector.cc",
     "residual_echo_detector.h",
@@ -171,7 +171,6 @@
     ":audio_processing_statistics",
     ":config",
     ":high_pass_filter",
-    ":noise_suppression_proxy",
     "../../api:array_view",
     "../../api:function_view",
     "../../api/audio:aec3_config",
@@ -222,17 +221,6 @@
   ]
 }
 
-rtc_source_set("noise_suppression_proxy") {
-  sources = [
-    "noise_suppression_proxy.cc",
-    "noise_suppression_proxy.h",
-  ]
-  deps = [
-    ":api",
-    "../../rtc_base:macromagic",
-  ]
-}
-
 rtc_source_set("audio_processing_statistics") {
   visibility = [ "*" ]
   sources = [
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index 39de770..760e81d 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -35,8 +35,7 @@
 #include "modules/audio_processing/include/audio_frame_view.h"
 #include "modules/audio_processing/level_estimator.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "modules/audio_processing/noise_suppression_impl.h"
-#include "modules/audio_processing/noise_suppression_proxy.h"
+#include "modules/audio_processing/noise_suppression.h"
 #include "modules/audio_processing/residual_echo_detector.h"
 #include "modules/audio_processing/transient/transient_suppressor.h"
 #include "modules/audio_processing/voice_detection.h"
@@ -107,13 +106,13 @@
   using NsConfig = AudioProcessing::Config::NoiseSuppression;
   switch (level) {
     case NsConfig::kLow:
-      return NoiseSuppression::kLow;
+      return NoiseSuppression::Level::kLow;
     case NsConfig::kModerate:
-      return NoiseSuppression::kModerate;
+      return NoiseSuppression::Level::kModerate;
     case NsConfig::kHigh:
-      return NoiseSuppression::kHigh;
+      return NoiseSuppression::Level::kHigh;
     case NsConfig::kVeryHigh:
-      return NoiseSuppression::kVeryHigh;
+      return NoiseSuppression::Level::kVeryHigh;
     default:
       RTC_NOTREACHED();
   }
@@ -254,11 +253,8 @@
 
 struct AudioProcessingImpl::ApmPublicSubmodules {
   ApmPublicSubmodules() {}
-  // Accessed externally of APM without any lock acquired.
-  // TODO(bugs.webrtc.org/9947): Move these submodules into private_submodules_
-  // when their pointer-to-submodule API functions are gone.
-  std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
-  std::unique_ptr<NoiseSuppressionProxy> noise_suppression_proxy;
+  // Historically accessed externally of APM without any lock acquired.
+  // TODO(bugs.webrtc.org/9947): Move these submodules into private_submodules_.
   std::unique_ptr<GainControlImpl> gain_control;
   std::unique_ptr<GainControlForExperimentalAgc>
       gain_control_for_experimental_agc;
@@ -284,6 +280,7 @@
   std::unique_ptr<EchoCancellationImpl> echo_cancellation;
   std::unique_ptr<EchoControl> echo_controller;
   std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
+  std::unique_ptr<NoiseSuppression> noise_suppressor;
   std::unique_ptr<CustomProcessing> capture_post_processor;
   std::unique_ptr<CustomProcessing> render_pre_processor;
   std::unique_ptr<GainApplier> pre_amplifier;
@@ -403,10 +400,6 @@
       static_cast<bool>(echo_control_factory_);
 
   public_submodules_->gain_control.reset(new GainControlImpl());
-  public_submodules_->noise_suppression.reset(
-      new NoiseSuppressionImpl(&crit_capture_));
-  public_submodules_->noise_suppression_proxy.reset(new NoiseSuppressionProxy(
-      this, public_submodules_->noise_suppression.get()));
   public_submodules_->gain_control_for_experimental_agc.reset(
       new GainControlForExperimentalAgc(
           public_submodules_->gain_control.get()));
@@ -556,12 +549,11 @@
   }
   InitializeTransient();
   InitializeHighPassFilter();
-  public_submodules_->noise_suppression->Initialize(num_proc_channels(),
-                                                    proc_sample_rate_hz());
   InitializeVoiceDetector();
   InitializeResidualEchoDetector();
   InitializeEchoController();
   InitializeGainController2();
+  InitializeNoiseSuppressor();
   InitializeAnalyzer();
   InitializePostProcessor();
   InitializePreProcessor();
@@ -702,16 +694,19 @@
   const bool voice_detection_config_changed =
       config_.voice_detection.enabled != config.voice_detection.enabled;
 
+  const bool ns_config_changed =
+      config_.noise_suppression.enabled != config.noise_suppression.enabled ||
+      config_.noise_suppression.level != config.noise_suppression.level;
+
   config_ = config;
 
   if (aec_config_changed) {
     InitializeEchoController();
   }
 
-  public_submodules_->noise_suppression->Enable(
-      config.noise_suppression.enabled);
-  public_submodules_->noise_suppression->set_level(
-      NsConfigLevelToInterfaceLevel(config.noise_suppression.level));
+  if (ns_config_changed) {
+    InitializeNoiseSuppressor();
+  }
 
   InitializeHighPassFilter();
 
@@ -1407,7 +1402,9 @@
   }
   RETURN_ON_ERR(
       public_submodules_->gain_control->AnalyzeCaptureAudio(capture_buffer));
-  public_submodules_->noise_suppression->AnalyzeCaptureAudio(capture_buffer);
+  if (private_submodules_->noise_suppressor) {
+    private_submodules_->noise_suppressor->AnalyzeCaptureAudio(capture_buffer);
+  }
 
   if (private_submodules_->echo_control_mobile) {
     // Ensure that the stream delay was set before the call to the
@@ -1416,13 +1413,13 @@
       return AudioProcessing::kStreamParameterNotSetError;
     }
 
-    if (public_submodules_->noise_suppression->is_enabled()) {
+    if (private_submodules_->noise_suppressor) {
       private_submodules_->echo_control_mobile->CopyLowPassReference(
           capture_buffer);
+      private_submodules_->noise_suppressor->ProcessCaptureAudio(
+          capture_buffer);
     }
 
-    public_submodules_->noise_suppression->ProcessCaptureAudio(capture_buffer);
-
     RETURN_ON_ERR(private_submodules_->echo_control_mobile->ProcessCaptureAudio(
         capture_buffer, stream_delay_ms()));
   } else {
@@ -1447,7 +1444,10 @@
           capture_buffer, stream_delay_ms()));
     }
 
-    public_submodules_->noise_suppression->ProcessCaptureAudio(capture_buffer);
+    if (private_submodules_->noise_suppressor) {
+      private_submodules_->noise_suppressor->ProcessCaptureAudio(
+          capture_buffer);
+    }
   }
 
   if (config_.voice_detection.enabled) {
@@ -1824,10 +1824,6 @@
   return stats;
 }
 
-NoiseSuppression* AudioProcessingImpl::noise_suppression() const {
-  return public_submodules_->noise_suppression_proxy.get();
-}
-
 void AudioProcessingImpl::MutateConfig(
     rtc::FunctionView<void(AudioProcessing::Config*)> mutator) {
   rtc::CritScope cs_render(&crit_render_);
@@ -1848,12 +1844,11 @@
       !!private_submodules_->echo_cancellation,
       !!private_submodules_->echo_control_mobile,
       config_.residual_echo_detector.enabled,
-      public_submodules_->noise_suppression->is_enabled(),
+      !!private_submodules_->noise_suppressor,
       public_submodules_->gain_control->is_enabled(),
       config_.gain_controller2.enabled, config_.pre_amplifier.enabled,
       capture_nonlocked_.echo_controller_enabled,
-      config_.voice_detection.enabled,
-      capture_.transient_suppressor_enabled);
+      config_.voice_detection.enabled, capture_.transient_suppressor_enabled);
 }
 
 void AudioProcessingImpl::InitializeTransient() {
@@ -1993,6 +1988,17 @@
   }
 }
 
+void AudioProcessingImpl::InitializeNoiseSuppressor() {
+  if (config_.noise_suppression.enabled) {
+    auto ns_level =
+        NsConfigLevelToInterfaceLevel(config_.noise_suppression.level);
+    private_submodules_->noise_suppressor = std::make_unique<NoiseSuppression>(
+        num_proc_channels(), proc_sample_rate_hz(), ns_level);
+  } else {
+    private_submodules_->noise_suppressor.reset();
+  }
+}
+
 void AudioProcessingImpl::InitializePreAmplifier() {
   if (config_.pre_amplifier.enabled) {
     private_submodules_->pre_amplifier.reset(
@@ -2092,9 +2098,8 @@
 
   apm_config.hpf_enabled = config_.high_pass_filter.enabled;
 
-  apm_config.ns_enabled = public_submodules_->noise_suppression->is_enabled();
-  apm_config.ns_level =
-      static_cast<int>(public_submodules_->noise_suppression->level());
+  apm_config.ns_enabled = config_.noise_suppression.enabled;
+  apm_config.ns_level = static_cast<int>(config_.noise_suppression.level);
 
   apm_config.transient_suppression_enabled =
       capture_.transient_suppressor_enabled;
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index 8af8b22..24ae158 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -115,13 +115,6 @@
 
   AudioProcessingStats GetStatistics(bool has_remote_tracks) const override;
 
-  // Methods returning pointers to APM submodules.
-  // No locks are aquired in those, as those locks
-  // would offer no protection (the submodules are
-  // created only once in a single-treaded manner
-  // during APM creation).
-  NoiseSuppression* noise_suppression() const override;
-
   // TODO(peah): Remove MutateConfig once the new API allows that.
   void MutateConfig(rtc::FunctionView<void(AudioProcessing::Config*)> mutator);
   AudioProcessing::Config GetConfig() const override;
@@ -238,6 +231,7 @@
   void InitializeEchoController()
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
   void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
+  void InitializeNoiseSuppressor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
   void InitializePreAmplifier() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
   void InitializePostProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
   void InitializeAnalyzer() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
diff --git a/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
index 08b1ee8..169d83d 100644
--- a/modules/audio_processing/audio_processing_impl_locking_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
@@ -590,9 +590,7 @@
   EXPECT_TRUE(apm_config.gain_controller1.enabled);
   EXPECT_TRUE(apm_config.noise_suppression.enabled);
 
-  // The below return values are not testable.
-  apm_->noise_suppression()->speech_probability();
-
+  // The below return value is not testable.
   apm_->GetStatistics(/*has_remote_tracks=*/true);
 }
 
diff --git a/modules/audio_processing/audio_processing_performance_unittest.cc b/modules/audio_processing/audio_processing_performance_unittest.cc
index 8fcf992..ebb2480 100644
--- a/modules/audio_processing/audio_processing_performance_unittest.cc
+++ b/modules/audio_processing/audio_processing_performance_unittest.cc
@@ -446,10 +446,10 @@
   void SetUp() override {
     // Lambda function for setting the default APM runtime settings for desktop.
     auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) {
-      ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
       AudioProcessing::Config apm_config = apm->GetConfig();
       apm_config.echo_canceller.enabled = true;
       apm_config.echo_canceller.mobile_mode = false;
+      apm_config.noise_suppression.enabled = true;
       apm_config.gain_controller1.enabled = true;
       apm_config.gain_controller1.mode =
           AudioProcessing::Config::GainController1::kAdaptiveDigital;
@@ -460,14 +460,13 @@
 
     // Lambda function for setting the default APM runtime settings for mobile.
     auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) {
-      ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
       AudioProcessing::Config apm_config = apm->GetConfig();
       apm_config.echo_canceller.enabled = true;
       apm_config.echo_canceller.mobile_mode = true;
+      apm_config.noise_suppression.enabled = true;
       apm_config.gain_controller1.mode =
           AudioProcessing::Config::GainController1::kAdaptiveDigital;
       apm_config.level_estimation.enabled = true;
-      apm_config.level_estimation.enabled = true;
       apm_config.voice_detection.enabled = true;
       apm->ApplyConfig(apm_config);
     };
@@ -475,11 +474,11 @@
     // Lambda function for turning off all of the APM runtime settings
     // submodules.
     auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) {
-      ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false));
       AudioProcessing::Config apm_config = apm->GetConfig();
       apm_config.echo_canceller.enabled = false;
       apm_config.gain_controller1.enabled = false;
       apm_config.level_estimation.enabled = false;
+      apm_config.noise_suppression.enabled = false;
       apm_config.voice_detection.enabled = false;
       apm->ApplyConfig(apm_config);
     };
diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc
index 78a7220..5f2ce87 100644
--- a/modules/audio_processing/audio_processing_unittest.cc
+++ b/modules/audio_processing/audio_processing_unittest.cc
@@ -191,12 +191,12 @@
   apm_config.gain_controller1.analog_level_maximum = 255;
 #endif
 
+  apm_config.noise_suppression.enabled = true;
+
   apm_config.high_pass_filter.enabled = true;
   apm_config.level_estimation.enabled = true;
   apm_config.voice_detection.enabled = true;
   ap->ApplyConfig(apm_config);
-
-  EXPECT_NOERR(ap->noise_suppression()->Enable(true));
 }
 
 // These functions are only used by ApmTest.Process.
@@ -1036,23 +1036,6 @@
   }
 }
 
-TEST_F(ApmTest, NoiseSuppression) {
-  // Test valid suppression levels.
-  NoiseSuppression::Level level[] = {
-      NoiseSuppression::kLow, NoiseSuppression::kModerate,
-      NoiseSuppression::kHigh, NoiseSuppression::kVeryHigh};
-  for (size_t i = 0; i < arraysize(level); i++) {
-    EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->set_level(level[i]));
-    EXPECT_EQ(level[i], apm_->noise_suppression()->level());
-  }
-
-  // Turn NS on/off
-  EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
-  EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
-  EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
-  EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
-}
-
 TEST_F(ApmTest, HighPassFilter) {
   // Turn HP filter on/off
   AudioProcessing::Config apm_config;
@@ -1068,8 +1051,8 @@
   EXPECT_FALSE(config.high_pass_filter.enabled);
   EXPECT_FALSE(config.gain_controller1.enabled);
   EXPECT_FALSE(config.level_estimation.enabled);
+  EXPECT_FALSE(config.noise_suppression.enabled);
   EXPECT_FALSE(config.voice_detection.enabled);
-  EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
 }
 
 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabled) {
@@ -1502,7 +1485,6 @@
     int analog_level = 127;
     int analog_level_average = 0;
     int max_output_average = 0;
-    float ns_speech_prob_average = 0.0f;
     float rms_dbfs_average = 0.0f;
 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
     int stats_index = 0;
@@ -1533,8 +1515,6 @@
       has_voice_count += *stats.voice_detected ? 1 : 0;
       rms_dbfs_average += *stats.output_rms_dbfs;
 
-      ns_speech_prob_average += apm_->noise_suppression()->speech_probability();
-
       size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_;
       size_t write_count =
           fwrite(frame_->data(), sizeof(int16_t), frame_size, out_file_);
@@ -1587,7 +1567,6 @@
     }
     max_output_average /= frame_count;
     analog_level_average /= frame_count;
-    ns_speech_prob_average /= frame_count;
     rms_dbfs_average /= frame_count;
 
     if (!absl::GetFlag(FLAGS_write_apm_ref_data)) {
@@ -1618,8 +1597,6 @@
                   kMaxOutputAverageNear);
 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
       const double kFloatNear = 0.0005;
-      EXPECT_NEAR(test->ns_speech_probability_average(), ns_speech_prob_average,
-                  kFloatNear);
       EXPECT_NEAR(test->rms_dbfs_average(), rms_dbfs_average, kFloatNear);
 #endif
     } else {
@@ -1629,9 +1606,6 @@
       test->set_max_output_average(max_output_average);
 
 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
-      EXPECT_LE(0.0f, ns_speech_prob_average);
-      EXPECT_GE(1.0f, ns_speech_prob_average);
-      test->set_ns_speech_probability_average(ns_speech_prob_average);
       test->set_rms_dbfs_average(rms_dbfs_average);
 #endif
     }
@@ -1658,7 +1632,9 @@
 
   std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
   // Enable one component just to ensure some processing takes place.
-  ap->noise_suppression()->Enable(true);
+  AudioProcessing::Config config;
+  config.noise_suppression.enabled = true;
+  ap->ApplyConfig(config);
   for (size_t i = 0; i < arraysize(cf); ++i) {
     const int in_rate = 44100;
     const int out_rate = 48000;
@@ -2432,8 +2408,10 @@
   apm_config.gain_controller2.enabled = false;
   apm_config.echo_canceller.enabled = true;
   apm_config.echo_canceller.mobile_mode = mobile_aec;
+  apm_config.noise_suppression.enabled = false;
+  apm_config.level_estimation.enabled = false;
+  apm_config.voice_detection.enabled = false;
   apm->ApplyConfig(apm_config);
-  EXPECT_EQ(apm->noise_suppression()->Enable(false), 0);
   return apm;
 }
 
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 79cbc28..0087f0b 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -47,7 +47,6 @@
 class ProcessingConfig;
 
 class EchoDetector;
-class NoiseSuppression;
 class CustomAudioAnalyzer;
 class CustomProcessing;
 
@@ -677,17 +676,6 @@
   // remote track.
   virtual AudioProcessingStats GetStatistics(bool has_remote_tracks) const = 0;
 
-  // DEPRECATED.
-  // TODO(https://crbug.com/webrtc/9878): Remove.
-  // Configure via AudioProcessing::ApplyConfig during setup.
-  // Set runtime settings via AudioProcessing::SetRuntimeSetting.
-  // Get stats via AudioProcessing::GetStatistics.
-  //
-  // These provide access to the component interfaces and should never return
-  // NULL. The pointers will be valid for the lifetime of the APM instance.
-  // The memory for these objects is entirely managed internally.
-  virtual NoiseSuppression* noise_suppression() const = 0;
-
   // Returns the last applied configuration.
   virtual AudioProcessing::Config GetConfig() const = 0;
 
@@ -874,34 +862,6 @@
   StreamConfig streams[StreamName::kNumStreamNames];
 };
 
-// The noise suppression (NS) component attempts to remove noise while
-// retaining speech. Recommended to be enabled on the client-side.
-//
-// Recommended to be enabled on the client-side.
-class NoiseSuppression {
- public:
-  virtual int Enable(bool enable) = 0;
-  virtual bool is_enabled() const = 0;
-
-  // Determines the aggressiveness of the suppression. Increasing the level
-  // will reduce the noise level at the expense of a higher speech distortion.
-  enum Level { kLow, kModerate, kHigh, kVeryHigh };
-
-  virtual int set_level(Level level) = 0;
-  virtual Level level() const = 0;
-
-  // Returns the internally computed prior speech probability of current frame
-  // averaged over output channels. This is not supported in fixed point, for
-  // which |kUnsupportedFunctionError| is returned.
-  virtual float speech_probability() const = 0;
-
-  // Returns the noise estimate per frequency bin averaged over all channels.
-  virtual std::vector<float> NoiseEstimate() = 0;
-
- protected:
-  virtual ~NoiseSuppression() {}
-};
-
 // Experimental interface for a custom analysis submodule.
 class CustomAudioAnalyzer {
  public:
diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h
index baf500f..3f66ce6 100644
--- a/modules/audio_processing/include/mock_audio_processing.h
+++ b/modules/audio_processing/include/mock_audio_processing.h
@@ -22,17 +22,6 @@
 namespace webrtc {
 
 namespace test {
-class MockNoiseSuppression : public NoiseSuppression {
- public:
-  virtual ~MockNoiseSuppression() {}
-  MOCK_METHOD1(Enable, int(bool enable));
-  MOCK_CONST_METHOD0(is_enabled, bool());
-  MOCK_METHOD1(set_level, int(Level level));
-  MOCK_CONST_METHOD0(level, Level());
-  MOCK_CONST_METHOD0(speech_probability, float());
-  MOCK_METHOD0(NoiseEstimate, std::vector<float>());
-};
-
 class MockCustomProcessing : public CustomProcessing {
  public:
   virtual ~MockCustomProcessing() {}
@@ -65,8 +54,7 @@
 
 class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
  public:
-  MockAudioProcessing()
-      : noise_suppression_(new ::testing::NiceMock<MockNoiseSuppression>()) {}
+  MockAudioProcessing() {}
 
   virtual ~MockAudioProcessing() {}
 
@@ -132,14 +120,8 @@
 
   MOCK_METHOD0(UpdateHistogramsOnCallEnd, void());
   MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool));
-  virtual MockNoiseSuppression* noise_suppression() const {
-    return noise_suppression_.get();
-  }
 
   MOCK_CONST_METHOD0(GetConfig, AudioProcessing::Config());
-
- private:
-  std::unique_ptr<MockNoiseSuppression> noise_suppression_;
 };
 
 }  // namespace test
diff --git a/modules/audio_processing/noise_suppression_impl.cc b/modules/audio_processing/noise_suppression.cc
similarity index 64%
rename from modules/audio_processing/noise_suppression_impl.cc
rename to modules/audio_processing/noise_suppression.cc
index 151af61..b8ddd30 100644
--- a/modules/audio_processing/noise_suppression_impl.cc
+++ b/modules/audio_processing/noise_suppression.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *  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
@@ -8,11 +8,10 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/audio_processing/noise_suppression_impl.h"
+#include "modules/audio_processing/noise_suppression.h"
 
 #include "modules/audio_processing/audio_buffer.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/constructor_magic.h"
 #if defined(WEBRTC_NS_FLOAT)
 #include "modules/audio_processing/ns/noise_suppression.h"
 
@@ -32,7 +31,25 @@
 #endif
 
 namespace webrtc {
-class NoiseSuppressionImpl::Suppressor {
+namespace {
+int NoiseSuppressionLevelToPolicy(NoiseSuppression::Level level) {
+  switch (level) {
+    case NoiseSuppression::Level::kLow:
+      return 0;
+    case NoiseSuppression::Level::kModerate:
+      return 1;
+    case NoiseSuppression::Level::kHigh:
+      return 2;
+    case NoiseSuppression::Level::kVeryHigh:
+      return 3;
+    default:
+      RTC_NOTREACHED();
+  }
+  return 1;
+}
+}  // namespace
+
+class NoiseSuppression::Suppressor {
  public:
   explicit Suppressor(int sample_rate_hz) {
     state_ = NS_CREATE();
@@ -41,43 +58,32 @@
     RTC_DCHECK_EQ(0, error);
   }
   ~Suppressor() { NS_FREE(state_); }
+
+  Suppressor(Suppressor&) = delete;
+  Suppressor& operator=(Suppressor&) = delete;
+
   NsState* state() { return state_; }
 
  private:
   NsState* state_ = nullptr;
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Suppressor);
 };
 
-NoiseSuppressionImpl::NoiseSuppressionImpl(rtc::CriticalSection* crit)
-    : crit_(crit) {
-  RTC_DCHECK(crit);
-}
-
-NoiseSuppressionImpl::~NoiseSuppressionImpl() {}
-
-void NoiseSuppressionImpl::Initialize(size_t channels, int sample_rate_hz) {
-  rtc::CritScope cs(crit_);
-  channels_ = channels;
-  sample_rate_hz_ = sample_rate_hz;
-  std::vector<std::unique_ptr<Suppressor>> new_suppressors;
-  if (enabled_) {
-    new_suppressors.resize(channels);
-    for (size_t i = 0; i < channels; i++) {
-      new_suppressors[i].reset(new Suppressor(sample_rate_hz));
-    }
+NoiseSuppression::NoiseSuppression(size_t channels,
+                                   int sample_rate_hz,
+                                   Level level) {
+  const int policy = NoiseSuppressionLevelToPolicy(level);
+  for (size_t i = 0; i < channels; ++i) {
+    suppressors_.push_back(std::make_unique<Suppressor>(sample_rate_hz));
+    int error = NS_SET_POLICY(suppressors_[i]->state(), policy);
+    RTC_DCHECK_EQ(0, error);
   }
-  suppressors_.swap(new_suppressors);
-  set_level(level_);
 }
 
-void NoiseSuppressionImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
+NoiseSuppression::~NoiseSuppression() {}
+
+void NoiseSuppression::AnalyzeCaptureAudio(AudioBuffer* audio) {
   RTC_DCHECK(audio);
 #if defined(WEBRTC_NS_FLOAT)
-  rtc::CritScope cs(crit_);
-  if (!enabled_) {
-    return;
-  }
-
   RTC_DCHECK_GE(160, audio->num_frames_per_band());
   RTC_DCHECK_EQ(suppressors_.size(), audio->num_channels());
   for (size_t i = 0; i < suppressors_.size(); i++) {
@@ -87,13 +93,8 @@
 #endif
 }
 
-void NoiseSuppressionImpl::ProcessCaptureAudio(AudioBuffer* audio) {
+void NoiseSuppression::ProcessCaptureAudio(AudioBuffer* audio) {
   RTC_DCHECK(audio);
-  rtc::CritScope cs(crit_);
-  if (!enabled_) {
-    return;
-  }
-
   RTC_DCHECK_GE(160, audio->num_frames_per_band());
   RTC_DCHECK_EQ(suppressors_.size(), audio->num_channels());
   for (size_t i = 0; i < suppressors_.size(); i++) {
@@ -115,54 +116,7 @@
   }
 }
 
-int NoiseSuppressionImpl::Enable(bool enable) {
-  rtc::CritScope cs(crit_);
-  if (enabled_ != enable) {
-    enabled_ = enable;
-    Initialize(channels_, sample_rate_hz_);
-  }
-  return AudioProcessing::kNoError;
-}
-
-bool NoiseSuppressionImpl::is_enabled() const {
-  rtc::CritScope cs(crit_);
-  return enabled_;
-}
-
-int NoiseSuppressionImpl::set_level(Level level) {
-  int policy = 1;
-  switch (level) {
-    case NoiseSuppression::kLow:
-      policy = 0;
-      break;
-    case NoiseSuppression::kModerate:
-      policy = 1;
-      break;
-    case NoiseSuppression::kHigh:
-      policy = 2;
-      break;
-    case NoiseSuppression::kVeryHigh:
-      policy = 3;
-      break;
-    default:
-      RTC_NOTREACHED();
-  }
-  rtc::CritScope cs(crit_);
-  level_ = level;
-  for (auto& suppressor : suppressors_) {
-    int error = NS_SET_POLICY(suppressor->state(), policy);
-    RTC_DCHECK_EQ(0, error);
-  }
-  return AudioProcessing::kNoError;
-}
-
-NoiseSuppression::Level NoiseSuppressionImpl::level() const {
-  rtc::CritScope cs(crit_);
-  return level_;
-}
-
-float NoiseSuppressionImpl::speech_probability() const {
-  rtc::CritScope cs(crit_);
+float NoiseSuppression::speech_probability() const {
 #if defined(WEBRTC_NS_FLOAT)
   float probability_average = 0.0f;
   for (auto& suppressor : suppressors_) {
@@ -180,8 +134,7 @@
 #endif
 }
 
-std::vector<float> NoiseSuppressionImpl::NoiseEstimate() {
-  rtc::CritScope cs(crit_);
+std::vector<float> NoiseSuppression::NoiseEstimate() {
   std::vector<float> noise_estimate;
 #if defined(WEBRTC_NS_FLOAT)
   const float kNumChannelsFraction = 1.f / suppressors_.size();
@@ -208,7 +161,7 @@
   return noise_estimate;
 }
 
-size_t NoiseSuppressionImpl::num_noise_bins() {
+size_t NoiseSuppression::num_noise_bins() {
 #if defined(WEBRTC_NS_FLOAT)
   return WebRtcNs_num_freq();
 #elif defined(WEBRTC_NS_FIXED)
diff --git a/modules/audio_processing/noise_suppression.h b/modules/audio_processing/noise_suppression.h
new file mode 100644
index 0000000..df5aed4
--- /dev/null
+++ b/modules/audio_processing/noise_suppression.h
@@ -0,0 +1,57 @@
+/*
+ *  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_NOISE_SUPPRESSION_H_
+#define MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_H_
+
+#include <memory>
+#include <vector>
+
+namespace webrtc {
+
+class AudioBuffer;
+
+// The noise suppression (NS) component attempts to remove noise while
+// retaining speech. Recommended to be enabled on the client-side.
+class NoiseSuppression {
+ public:
+  // Determines the aggressiveness of the suppression. Increasing the level
+  // will reduce the noise level at the expense of a higher speech distortion.
+  enum class Level { kLow, kModerate, kHigh, kVeryHigh };
+
+  NoiseSuppression(size_t channels, int sample_rate_hz, Level level);
+  ~NoiseSuppression();
+
+  NoiseSuppression(NoiseSuppression&) = delete;
+  NoiseSuppression& operator=(NoiseSuppression&) = delete;
+
+  void AnalyzeCaptureAudio(AudioBuffer* audio);
+  void ProcessCaptureAudio(AudioBuffer* audio);
+
+  // LEGACY: Returns the internally computed prior speech probability of current
+  // frame averaged over output channels. This is not supported in fixed point,
+  // for which |kUnsupportedFunctionError| is returned.
+  float speech_probability() const;
+
+  // LEGACY: Returns the size of the noise vector returned by NoiseEstimate().
+  static size_t num_noise_bins();
+
+  // LEGACY: Returns the noise estimate per frequency bin averaged over all
+  // channels.
+  std::vector<float> NoiseEstimate();
+
+ private:
+  class Suppressor;
+
+  std::vector<std::unique_ptr<Suppressor>> suppressors_;
+};
+}  // namespace webrtc
+
+#endif  // MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_H_
diff --git a/modules/audio_processing/noise_suppression_impl.h b/modules/audio_processing/noise_suppression_impl.h
deleted file mode 100644
index 414ca31..0000000
--- a/modules/audio_processing/noise_suppression_impl.h
+++ /dev/null
@@ -1,56 +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_NOISE_SUPPRESSION_IMPL_H_
-#define MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_IMPL_H_
-
-#include <memory>
-#include <vector>
-
-#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 NoiseSuppressionImpl : public NoiseSuppression {
- public:
-  explicit NoiseSuppressionImpl(rtc::CriticalSection* crit);
-  ~NoiseSuppressionImpl() override;
-
-  // TODO(peah): Fold into ctor, once public API is removed.
-  void Initialize(size_t channels, int sample_rate_hz);
-  void AnalyzeCaptureAudio(AudioBuffer* audio);
-  void ProcessCaptureAudio(AudioBuffer* audio);
-
-  // NoiseSuppression implementation.
-  int Enable(bool enable) override;
-  bool is_enabled() const override;
-  int set_level(Level level) override;
-  Level level() const override;
-  float speech_probability() const override;
-  std::vector<float> NoiseEstimate() override;
-  static size_t num_noise_bins();
-
- private:
-  class Suppressor;
-  rtc::CriticalSection* const crit_;
-  bool enabled_ RTC_GUARDED_BY(crit_) = false;
-  Level level_ RTC_GUARDED_BY(crit_) = kModerate;
-  size_t channels_ RTC_GUARDED_BY(crit_) = 0;
-  int sample_rate_hz_ RTC_GUARDED_BY(crit_) = 0;
-  std::vector<std::unique_ptr<Suppressor>> suppressors_ RTC_GUARDED_BY(crit_);
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(NoiseSuppressionImpl);
-};
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_IMPL_H_
diff --git a/modules/audio_processing/noise_suppression_proxy.cc b/modules/audio_processing/noise_suppression_proxy.cc
deleted file mode 100644
index a83c9b2..0000000
--- a/modules/audio_processing/noise_suppression_proxy.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  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/noise_suppression_proxy.h"
-
-namespace webrtc {
-NoiseSuppressionProxy::NoiseSuppressionProxy(AudioProcessing* apm,
-                                             NoiseSuppression* ns)
-    : apm_(apm), ns_(ns) {}
-
-NoiseSuppressionProxy::~NoiseSuppressionProxy() {}
-
-int NoiseSuppressionProxy::Enable(bool enable) {
-  AudioProcessing::Config config = apm_->GetConfig();
-  if (config.noise_suppression.enabled != enable) {
-    config.noise_suppression.enabled = enable;
-    apm_->ApplyConfig(config);
-  }
-  return AudioProcessing::kNoError;
-}
-
-bool NoiseSuppressionProxy::is_enabled() const {
-  return ns_->is_enabled();
-}
-
-int NoiseSuppressionProxy::set_level(Level level) {
-  AudioProcessing::Config config = apm_->GetConfig();
-  using NsConfig = AudioProcessing::Config::NoiseSuppression;
-  NsConfig::Level new_level;
-  switch (level) {
-    case NoiseSuppression::kLow:
-      new_level = NsConfig::kLow;
-      break;
-    case NoiseSuppression::kModerate:
-      new_level = NsConfig::kModerate;
-      break;
-    case NoiseSuppression::kHigh:
-      new_level = NsConfig::kHigh;
-      break;
-    case NoiseSuppression::kVeryHigh:
-      new_level = NsConfig::kVeryHigh;
-      break;
-    default:
-      RTC_NOTREACHED();
-  }
-  if (config.noise_suppression.level != new_level) {
-    config.noise_suppression.level = new_level;
-    apm_->ApplyConfig(config);
-  }
-  return AudioProcessing::kNoError;
-}
-
-NoiseSuppression::Level NoiseSuppressionProxy::level() const {
-  return ns_->level();
-}
-
-float NoiseSuppressionProxy::speech_probability() const {
-  return ns_->speech_probability();
-}
-
-std::vector<float> NoiseSuppressionProxy::NoiseEstimate() {
-  return ns_->NoiseEstimate();
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/noise_suppression_proxy.h b/modules/audio_processing/noise_suppression_proxy.h
deleted file mode 100644
index 959887f..0000000
--- a/modules/audio_processing/noise_suppression_proxy.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  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_NOISE_SUPPRESSION_PROXY_H_
-#define MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_PROXY_H_
-
-#include <vector>
-
-#include "modules/audio_processing/include/audio_processing.h"
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-// This class ensures interoperability with the pointer-to-submodule interface
-// AudioProcessing::noise_suppression() and AudioProcessing::ApplyConfig:
-// Enable(..) and set_level(..) calls are applied via
-// AudioProcessing::ApplyConfig, while all other function calls are forwarded
-// directly to a wrapped NoiseSuppression instance.
-class NoiseSuppressionProxy : public NoiseSuppression {
- public:
-  NoiseSuppressionProxy(AudioProcessing* apm, NoiseSuppression* ns);
-  ~NoiseSuppressionProxy() override;
-
-  // NoiseSuppression implementation.
-  int Enable(bool enable) override;
-  bool is_enabled() const override;
-  int set_level(Level level) override;
-  Level level() const override;
-  float speech_probability() const override;
-  std::vector<float> NoiseEstimate() override;
-
- private:
-  AudioProcessing* apm_;
-  NoiseSuppression* ns_;
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(NoiseSuppressionProxy);
-};
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_PROXY_H_
diff --git a/modules/audio_processing/noise_suppression_unittest.cc b/modules/audio_processing/noise_suppression_unittest.cc
index 596c13a..649fc93 100644
--- a/modules/audio_processing/noise_suppression_unittest.cc
+++ b/modules/audio_processing/noise_suppression_unittest.cc
@@ -11,7 +11,7 @@
 
 #include "api/array_view.h"
 #include "modules/audio_processing/audio_buffer.h"
-#include "modules/audio_processing/noise_suppression_impl.h"
+#include "modules/audio_processing/noise_suppression.h"
 #include "modules/audio_processing/test/audio_buffer_tools.h"
 #include "modules/audio_processing/test/bitexactness_tools.h"
 #include "test/gtest.h"
@@ -24,7 +24,7 @@
 // Process one frame of data and produce the output.
 void ProcessOneFrame(int sample_rate_hz,
                      AudioBuffer* capture_buffer,
-                     NoiseSuppressionImpl* noise_suppressor) {
+                     NoiseSuppression* noise_suppressor) {
   if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
     capture_buffer->SplitIntoFrequencyBands();
   }
@@ -41,15 +41,11 @@
 // any errors.
 void RunBitexactnessTest(int sample_rate_hz,
                          size_t num_channels,
-                         NoiseSuppressionImpl::Level level,
+                         NoiseSuppression::Level level,
                          float speech_probability_reference,
                          rtc::ArrayView<const float> noise_estimate_reference,
                          rtc::ArrayView<const float> output_reference) {
-  rtc::CriticalSection crit_capture;
-  NoiseSuppressionImpl noise_suppressor(&crit_capture);
-  noise_suppressor.Initialize(num_channels, sample_rate_hz);
-  noise_suppressor.Enable(true);
-  noise_suppressor.set_level(level);
+  NoiseSuppression noise_suppressor(num_channels, sample_rate_hz, level);
 
   int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100);
   const StreamConfig capture_config(sample_rate_hz, num_channels, false);
@@ -280,5 +276,4 @@
                       kSpeechProbabilityReference, kNoiseEstimateReference,
                       kOutputReference);
 }
-
 }  // namespace webrtc
diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc
index ccd3505..8c6a46d 100644
--- a/modules/audio_processing/test/audio_processing_simulator.cc
+++ b/modules/audio_processing/test/audio_processing_simulator.cc
@@ -504,6 +504,17 @@
         *settings_.maximum_internal_processing_rate;
   }
 
+  if (settings_.use_ns) {
+    apm_config.noise_suppression.enabled = *settings_.use_ns;
+  }
+  if (settings_.ns_level) {
+    const int level = *settings_.ns_level;
+    RTC_CHECK_GE(level, 0);
+    RTC_CHECK_LE(level, 3);
+    apm_config.noise_suppression.level =
+        static_cast<AudioProcessing::Config::NoiseSuppression::Level>(level);
+  }
+
   RTC_CHECK(ap_builder_);
   if (echo_control_factory) {
     ap_builder_->SetEchoControlFactory(std::move(echo_control_factory));
@@ -514,17 +525,6 @@
 
   ap_->ApplyConfig(apm_config);
 
-  if (settings_.use_ns) {
-    RTC_CHECK_EQ(AudioProcessing::kNoError,
-                 ap_->noise_suppression()->Enable(*settings_.use_ns));
-  }
-  if (settings_.ns_level) {
-    RTC_CHECK_EQ(
-        AudioProcessing::kNoError,
-        ap_->noise_suppression()->set_level(
-            static_cast<NoiseSuppression::Level>(*settings_.ns_level)));
-  }
-
   if (settings_.use_ts) {
     ap_->set_stream_key_pressed(*settings_.use_ts);
   }