diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index 376dae2217..1341f76c17 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -56,6 +56,7 @@ rtc_source_set("api") { "../../rtc_base:deprecation", "../../rtc_base:macromagic", "../../rtc_base:rtc_base_approved", + "../../rtc_base/system:arch", "../../rtc_base/system:rtc_export", "//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/types:optional", @@ -187,7 +188,6 @@ rtc_static_library("audio_processing") { "../../rtc_base:gtest_prod", "../../rtc_base:safe_minmax", "../../rtc_base:sanitizer", - "../../rtc_base/system:arch", "../../rtc_base/system:rtc_export", "../../system_wrappers:cpu_features_api", "../../system_wrappers:field_trial", diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index d639fd57f6..55bdaae208 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -85,15 +85,11 @@ bool SampleRateSupportsMultiBand(int sample_rate_hz) { } // Identify the native processing rate that best handles a sample rate. -int SuitableProcessRate(int minimum_rate, bool band_splitting_required) { -#ifdef WEBRTC_ARCH_ARM_FAMILY - constexpr int kMaxSplittingRate = 32000; -#else - constexpr int kMaxSplittingRate = 48000; -#endif - static_assert(kMaxSplittingRate <= 48000, ""); +int SuitableProcessRate(int minimum_rate, + int max_splitting_rate, + bool band_splitting_required) { const int uppermost_native_rate = - band_splitting_required ? kMaxSplittingRate : 48000; + band_splitting_required ? max_splitting_rate : 48000; for (auto rate : {16000, 32000, 48000}) { if (rate >= uppermost_native_rate) { return uppermost_native_rate; @@ -591,9 +587,18 @@ int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { formats_.api_format = config; + // Choose maximum rate to use for the split filtering. + RTC_DCHECK(config_.pipeline.maximum_internal_processing_rate == 48000 || + config_.pipeline.maximum_internal_processing_rate == 32000); + int max_splitting_rate = 48000; + if (config_.pipeline.maximum_internal_processing_rate == 32000) { + max_splitting_rate = config_.pipeline.maximum_internal_processing_rate; + } + int capture_processing_rate = SuitableProcessRate( std::min(formats_.api_format.input_stream().sample_rate_hz(), formats_.api_format.output_stream().sample_rate_hz()), + max_splitting_rate, submodule_states_.CaptureMultiBandSubModulesActive() || submodule_states_.RenderMultiBandSubModulesActive()); RTC_DCHECK_NE(8000, capture_processing_rate); @@ -606,21 +611,13 @@ int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { render_processing_rate = SuitableProcessRate( std::min(formats_.api_format.reverse_input_stream().sample_rate_hz(), formats_.api_format.reverse_output_stream().sample_rate_hz()), + max_splitting_rate, submodule_states_.CaptureMultiBandSubModulesActive() || submodule_states_.RenderMultiBandSubModulesActive()); } else { render_processing_rate = capture_processing_rate; } - // TODO(aluebs): Remove this restriction once we figure out why the 3-band - // splitting filter degrades the AEC performance. - if (render_processing_rate > kSampleRate32kHz && - !capture_nonlocked_.echo_controller_enabled) { - render_processing_rate = submodule_states_.RenderMultiBandProcessingActive() - ? kSampleRate32kHz - : kSampleRate16kHz; - } - // If the forward sample rate is 8 kHz, the render stream is also processed // at this rate. if (capture_nonlocked_.capture_processing_format.sample_rate_hz() == diff --git a/modules/audio_processing/include/audio_processing.cc b/modules/audio_processing/include/audio_processing.cc index 46bb13417a..ce75e1ab30 100644 --- a/modules/audio_processing/include/audio_processing.cc +++ b/modules/audio_processing/include/audio_processing.cc @@ -11,6 +11,7 @@ #include "modules/audio_processing/include/audio_processing.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/system/arch.h" namespace webrtc { namespace { @@ -51,11 +52,22 @@ std::string GainController2LevelEstimatorToString( } } +int GetDefaultMaxInternalRate() { +#ifdef WEBRTC_ARCH_ARM_FAMILY + return 32000; +#else + return 48000; +#endif +} + } // namespace void CustomProcessing::SetRuntimeSetting( AudioProcessing::RuntimeSetting setting) {} +AudioProcessing::Config::Pipeline::Pipeline() + : maximum_internal_processing_rate(GetDefaultMaxInternalRate()) {} + std::string AudioProcessing::Config::ToString() const { char buf[1024]; rtc::SimpleStringBuilder builder(buf); diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index fb62f7793a..114bfcd402 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -245,6 +245,17 @@ class AudioProcessing : public rtc::RefCountInterface { // submodule resets, affecting the audio quality. Use the RuntimeSetting // construct for runtime configuration. struct Config { + // Sets the properties of the audio processing pipeline. + struct Pipeline { + Pipeline(); + + // Maximum allowed processing rate used internally. May only be set to + // 32000 or 48000 and any differing values will be treated as 48000. The + // default rate is currently selected based on the CPU architecture, but + // that logic may change. + int maximum_internal_processing_rate; + } pipeline; + // Enabled the pre-amplifier. It amplifies the capture signal // before any other processing is done. struct PreAmplifier { diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc index 65a52d59f0..1565e7109a 100644 --- a/modules/audio_processing/test/audio_processing_simulator.cc +++ b/modules/audio_processing/test/audio_processing_simulator.cc @@ -470,6 +470,11 @@ void AudioProcessingSimulator::CreateAudioProcessor() { apm_config.residual_echo_detector.enabled = *settings_.use_ed; } + if (settings_.maximum_internal_processing_rate) { + apm_config.pipeline.maximum_internal_processing_rate = + *settings_.maximum_internal_processing_rate; + } + RTC_CHECK(ap_builder_); if (echo_control_factory) { ap_builder_->SetEchoControlFactory(std::move(echo_control_factory)); diff --git a/modules/audio_processing/test/audio_processing_simulator.h b/modules/audio_processing/test/audio_processing_simulator.h index 6f84813b35..d4915939e1 100644 --- a/modules/audio_processing/test/audio_processing_simulator.h +++ b/modules/audio_processing/test/audio_processing_simulator.h @@ -81,6 +81,7 @@ struct SimulationSettings { absl::optional pre_amplifier_gain_factor; absl::optional vad_likelihood; absl::optional ns_level; + absl::optional maximum_internal_processing_rate; absl::optional use_refined_adaptive_filter; int initial_mic_level; bool simulate_mic_gain = false; diff --git a/modules/audio_processing/test/audioproc_float_impl.cc b/modules/audio_processing/test/audioproc_float_impl.cc index 41d137b701..a96641b416 100644 --- a/modules/audio_processing/test/audioproc_float_impl.cc +++ b/modules/audio_processing/test/audioproc_float_impl.cc @@ -193,6 +193,11 @@ ABSL_FLAG(int, ns_level, kParameterNotSpecifiedValue, "Specify the NS level (0-3)"); +ABSL_FLAG(int, + maximum_internal_processing_rate, + kParameterNotSpecifiedValue, + "Set a maximum internal processing rate (32000 or 48000) to override " + "the default rate"); ABSL_FLAG(int, stream_delay, kParameterNotSpecifiedValue, @@ -417,6 +422,8 @@ SimulationSettings CreateSettings() { SetSettingIfSpecified(absl::GetFlag(FLAGS_vad_likelihood), &settings.vad_likelihood); SetSettingIfSpecified(absl::GetFlag(FLAGS_ns_level), &settings.ns_level); + SetSettingIfSpecified(absl::GetFlag(FLAGS_maximum_internal_processing_rate), + &settings.maximum_internal_processing_rate); SetSettingIfSpecified(absl::GetFlag(FLAGS_stream_delay), &settings.stream_delay); SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_stream_delay),