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();