APM: Move the TransientSuppression activation to the apm_config

This CL moves the activation of the transient suppression to the APM
config.

Bug: webrtc:5298
Change-Id: Iba7975bec4654c3df8834fd5b7d1082ff53641dd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/163985
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Commit-Queue: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30137}
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index db9b789..ed1715c 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -350,11 +350,6 @@
                  !field_trial::IsEnabled(
                      "WebRTC-ApmExperimentalMultiChannelCaptureKillSwitch"),
                  EnforceSplitBandHpf()),
-#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
-      capture_(false),
-#else
-      capture_(config.Get<ExperimentalNs>().enabled),
-#endif
       capture_nonlocked_() {
   RTC_LOG(LS_INFO) << "Injected APM submodules:"
                    << "\nEcho control factory: " << !!echo_control_factory_
@@ -381,7 +376,11 @@
   // implemented.
   submodules_.gain_controller2.reset(new GainController2());
 
-  SetExtraOptions(config);
+  // TODO(webrtc:5298): Remove once the use of ExperimentalNs has been
+  // deprecated.
+#if !(defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS))
+  config_.transient_suppression.enabled = config.Get<ExperimentalNs>().enabled;
+#endif
 }
 
 AudioProcessingImpl::~AudioProcessingImpl() = default;
@@ -513,7 +512,7 @@
         submodules_.gain_control.get());
     submodules_.agc_manager->SetCaptureMuted(capture_.output_will_be_muted);
   }
-  InitializeTransient();
+  InitializeTransientSuppressor();
   InitializeHighPassFilter();
   InitializeVoiceDetector();
   InitializeResidualEchoDetector();
@@ -664,6 +663,9 @@
       config_.noise_suppression.enabled != config.noise_suppression.enabled ||
       config_.noise_suppression.level != config.noise_suppression.level;
 
+  const bool ts_config_changed = config_.transient_suppression.enabled !=
+                                 config.transient_suppression.enabled;
+
   config_ = config;
 
   if (aec_config_changed) {
@@ -674,6 +676,10 @@
     InitializeNoiseSuppressor();
   }
 
+  if (ts_config_changed) {
+    InitializeTransientSuppressor();
+  }
+
   InitializeHighPassFilter();
 
   if (agc1_config_changed) {
@@ -730,17 +736,8 @@
   }
 }
 
+// TODO(webrtc:5298): Remove.
 void AudioProcessingImpl::SetExtraOptions(const webrtc::Config& config) {
-  // Run in a single-threaded manner when setting the extra options.
-  rtc::CritScope cs_render(&crit_render_);
-  rtc::CritScope cs_capture(&crit_capture_);
-
-  if (capture_.transient_suppressor_enabled !=
-      config.Get<ExperimentalNs>().enabled) {
-    capture_.transient_suppressor_enabled =
-        config.Get<ExperimentalNs>().enabled;
-    InitializeTransient();
-  }
 }
 
 int AudioProcessingImpl::proc_sample_rate_hz() const {
@@ -1394,7 +1391,7 @@
 
   // TODO(aluebs): Investigate if the transient suppression placement should be
   // before or after the AGC.
-  if (capture_.transient_suppressor_enabled) {
+  if (submodules_.transient_suppressor) {
     float voice_probability = submodules_.agc_manager.get()
                                   ? submodules_.agc_manager->voice_probability()
                                   : 1.f;
@@ -1766,17 +1763,19 @@
       !!submodules_.legacy_noise_suppressor || !!submodules_.noise_suppressor,
       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, !!submodules_.transient_suppressor);
 }
 
-void AudioProcessingImpl::InitializeTransient() {
-  if (capture_.transient_suppressor_enabled) {
-    if (!submodules_.transient_suppressor.get()) {
+void AudioProcessingImpl::InitializeTransientSuppressor() {
+  if (config_.transient_suppression.enabled) {
+    if (!submodules_.transient_suppressor) {
       submodules_.transient_suppressor.reset(new TransientSuppressor());
     }
     submodules_.transient_suppressor->Initialize(proc_fullband_sample_rate_hz(),
                                                  capture_nonlocked_.split_rate,
                                                  num_proc_channels());
+  } else {
+    submodules_.transient_suppressor.reset();
   }
 }
 
@@ -2019,7 +2018,7 @@
   apm_config.ns_level = static_cast<int>(config_.noise_suppression.level);
 
   apm_config.transient_suppression_enabled =
-      capture_.transient_suppressor_enabled;
+      config_.transient_suppression.enabled;
   apm_config.experiments_description = experiments_description;
   apm_config.pre_amplifier_enabled = config_.pre_amplifier.enabled;
   apm_config.pre_amplifier_fixed_gain_factor =
@@ -2083,13 +2082,11 @@
   aec_dump_->AddAudioProcessingState(audio_proc_state);
 }
 
-AudioProcessingImpl::ApmCaptureState::ApmCaptureState(
-    bool transient_suppressor_enabled)
+AudioProcessingImpl::ApmCaptureState::ApmCaptureState()
     : delay_offset_ms(0),
       was_stream_delay_set(false),
       output_will_be_muted(false),
       key_pressed(false),
-      transient_suppressor_enabled(transient_suppressor_enabled),
       capture_processing_format(kSampleRate16kHz),
       split_rate(kSampleRate16kHz),
       echo_path_gain_change(false),
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index bcd1156..77eae38 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -225,24 +225,29 @@
   bool UpdateActiveSubmoduleStates()
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
 
-  // Methods requiring APM running in a single-threaded manner.
-  // Are called with both the render and capture locks already
-  // acquired.
-  void InitializeTransient()
-      RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
+  // Methods requiring APM running in a single-threaded manner, requiring both
+  // the render and capture lock to be acquired.
   int InitializeLocked(const ProcessingConfig& config)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
   void InitializeResidualEchoDetector()
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
-  void InitializeHighPassFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
-  void InitializeVoiceDetector() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
   void InitializeEchoController()
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
+
+  // Initializations of capture-only submodules, requiring the capture lock
+  // already acquired.
+  void InitializeHighPassFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
+  void InitializeVoiceDetector() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
+  void InitializeTransientSuppressor()
+      RTC_EXCLUSIVE_LOCKS_REQUIRED(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_);
+
+  // Initializations of render-only submodules, requiring the render lock
+  // already acquired.
   void InitializePreProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_);
 
   // Sample rate used for the fullband processing.
@@ -400,13 +405,12 @@
   } constants_;
 
   struct ApmCaptureState {
-    ApmCaptureState(bool transient_suppressor_enabled);
+    ApmCaptureState();
     ~ApmCaptureState();
     int delay_offset_ms;
     bool was_stream_delay_set;
     bool output_will_be_muted;
     bool key_pressed;
-    bool transient_suppressor_enabled;
     std::unique_ptr<AudioBuffer> capture_audio;
     std::unique_ptr<AudioBuffer> capture_fullband_audio;
     std::unique_ptr<AudioBuffer> linear_aec_output;
diff --git a/modules/audio_processing/include/audio_processing.cc b/modules/audio_processing/include/audio_processing.cc
index 282f07a..98ec590 100644
--- a/modules/audio_processing/include/audio_processing.cc
+++ b/modules/audio_processing/include/audio_processing.cc
@@ -88,6 +88,8 @@
           << " }, noise_suppression: { enabled: " << noise_suppression.enabled
           << ", level: "
           << NoiseSuppressionLevelToString(noise_suppression.level)
+          << " }, transient_suppression: { enabled: "
+          << transient_suppression.enabled
           << " }, voice_detection: { enabled: " << voice_detection.enabled
           << " }, gain_controller1: { enabled: " << gain_controller1.enabled
           << ", mode: " << GainController1ModeToString(gain_controller1.mode)
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index c7fc1c4..fe4b0dc 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -92,8 +92,12 @@
   bool digital_adaptive_disabled = false;
 };
 
+// To be deprecated: Please instead use the flag in the
+// AudioProcessing::Config::TransientSuppression.
+//
 // Use to enable experimental noise suppression. It can be set in the
 // constructor or using AudioProcessing::SetExtraOptions().
+// TODO(webrtc:5298): Remove.
 struct ExperimentalNs {
   ExperimentalNs() : enabled(false) {}
   explicit ExperimentalNs(bool enabled) : enabled(enabled) {}
@@ -246,6 +250,11 @@
       bool use_legacy_ns = false;
     } noise_suppression;
 
+    // Enables transient suppression.
+    struct TransientSuppression {
+      bool enabled = false;
+    } transient_suppression;
+
     // Enables reporting of |voice_detected| in webrtc::AudioProcessingStats.
     // In addition to |voice_detected|, VAD decision is provided through the
     // |AudioFrame| passed to |ProcessStream()|. The |vad_activity_| member will
diff --git a/modules/audio_processing/test/aec_dump_based_simulator.cc b/modules/audio_processing/test/aec_dump_based_simulator.cc
index e050f48..95a3e37 100644
--- a/modules/audio_processing/test/aec_dump_based_simulator.cc
+++ b/modules/audio_processing/test/aec_dump_based_simulator.cc
@@ -379,7 +379,7 @@
     if (msg.has_transient_suppression_enabled() || settings_.use_ts) {
       bool enable = settings_.use_ts ? *settings_.use_ts
                                      : msg.transient_suppression_enabled();
-      config.Set<ExperimentalNs>(new ExperimentalNs(enable));
+      apm_config.transient_suppression.enabled = enable;
       if (settings_.use_verbose_logging) {
         std::cout << " transient_suppression_enabled: "
                   << (enable ? "true" : "false") << std::endl;
diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc
index 1be7f87..f314732 100644
--- a/modules/audio_processing/test/audio_processing_simulator.cc
+++ b/modules/audio_processing/test/audio_processing_simulator.cc
@@ -400,7 +400,7 @@
   AudioProcessing::Config apm_config;
   std::unique_ptr<EchoControlFactory> echo_control_factory;
   if (settings_.use_ts) {
-    config.Set<ExperimentalNs>(new ExperimentalNs(*settings_.use_ts));
+    apm_config.transient_suppression.enabled = *settings_.use_ts;
   }
   if (settings_.multi_channel_render) {
     apm_config.pipeline.multi_channel_render = *settings_.multi_channel_render;
diff --git a/modules/audio_processing/test/debug_dump_replayer.cc b/modules/audio_processing/test/debug_dump_replayer.cc
index 7cb6ec8..d5cf673 100644
--- a/modules/audio_processing/test/debug_dump_replayer.cc
+++ b/modules/audio_processing/test/debug_dump_replayer.cc
@@ -185,10 +185,6 @@
   config.Set<ExperimentalAgc>(
       new ExperimentalAgc(msg.noise_robust_agc_enabled()));
 
-  RTC_CHECK(msg.has_transient_suppression_enabled());
-  config.Set<ExperimentalNs>(
-      new ExperimentalNs(msg.transient_suppression_enabled()));
-
   RTC_CHECK(msg.has_aec_extended_filter_enabled());
 
   // We only create APM once, since changes on these fields should not
@@ -225,6 +221,11 @@
       static_cast<AudioProcessing::Config::NoiseSuppression::Level>(
           msg.ns_level());
 
+  // TS configs.
+  RTC_CHECK(msg.has_transient_suppression_enabled());
+  apm_config.transient_suppression.enabled =
+      msg.transient_suppression_enabled();
+
   // AGC configs.
   RTC_CHECK(msg.has_agc_enabled());
   RTC_CHECK(msg.has_agc_mode());
diff --git a/modules/audio_processing/test/debug_dump_test.cc b/modules/audio_processing/test/debug_dump_test.cc
index 2828091..21458aa 100644
--- a/modules/audio_processing/test/debug_dump_test.cc
+++ b/modules/audio_processing/test/debug_dump_test.cc
@@ -519,8 +519,12 @@
 
 TEST_F(DebugDumpTest, TransientSuppressionOn) {
   Config config;
-  config.Set<ExperimentalNs>(new ExperimentalNs(true));
   DebugDumpGenerator generator(config, AudioProcessing::Config());
+
+  AudioProcessing::Config apm_config = generator.apm()->GetConfig();
+  apm_config.transient_suppression.enabled = true;
+  generator.apm()->ApplyConfig(apm_config);
+
   generator.StartRecording();
   generator.Process(100);
   generator.StopRecording();