| Index: webrtc/modules/audio_processing/audio_processing_impl.cc | 
| diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| index 222f749fb7b876fc55e53588a6d0914a192f90f1..bd311ad6b1615c75762f85061a8da5b7f73b03d2 100644 | 
| --- a/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| +++ b/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| @@ -82,15 +82,6 @@ const int AudioProcessing::kMaxNativeSampleRateHz = AudioProcessing:: | 
|  | 
| namespace { | 
|  | 
| -const int kInternalNativeRates[] = {AudioProcessing::kSampleRate8kHz, | 
| -                                    AudioProcessing::kSampleRate16kHz, | 
| -#ifdef WEBRTC_ARCH_ARM_FAMILY | 
| -                                    AudioProcessing::kSampleRate32kHz}; | 
| -#else | 
| -                                    AudioProcessing::kSampleRate32kHz, | 
| -                                    AudioProcessing::kSampleRate48kHz}; | 
| -#endif  // WEBRTC_ARCH_ARM_FAMILY | 
| - | 
| static bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) { | 
| switch (layout) { | 
| case AudioProcessing::kMono: | 
| @@ -105,18 +96,33 @@ static bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) { | 
| return false; | 
| } | 
|  | 
| -bool is_multi_band(int sample_rate_hz) { | 
| +bool SampleRateSupportsMultiBand(int sample_rate_hz) { | 
| return sample_rate_hz == AudioProcessing::kSampleRate32kHz || | 
| sample_rate_hz == AudioProcessing::kSampleRate48kHz; | 
| } | 
|  | 
| -int ClosestHigherNativeRate(int min_proc_rate) { | 
| -  for (int rate : kInternalNativeRates) { | 
| -    if (rate >= min_proc_rate) { | 
| +int FindNativeProcessRateToUse(int minimum_rate, bool band_splitting_required) { | 
| +#ifdef WEBRTC_ARCH_ARM_FAMILY | 
| +  const int kMaxSplittingNativeProcessRate = AudioProcessing::kSampleRate32kHz; | 
| +#else | 
| +  const int kMaxSplittingNativeProcessRate = AudioProcessing::kSampleRate48kHz; | 
| +#endif | 
| +  RTC_DCHECK_LE(kMaxSplittingNativeProcessRate, | 
| +                AudioProcessing::kMaxNativeSampleRateHz); | 
| +  const int uppermost_native_rate = band_splitting_required | 
| +                                        ? kMaxSplittingNativeProcessRate | 
| +                                        : AudioProcessing::kSampleRate48kHz; | 
| + | 
| +  for (auto rate : AudioProcessing::kNativeSampleRatesHz) { | 
| +    if (rate >= uppermost_native_rate) { | 
| +      return uppermost_native_rate; | 
| +    } | 
| +    if (rate >= minimum_rate) { | 
| return rate; | 
| } | 
| } | 
| -  return kInternalNativeRates[arraysize(kInternalNativeRates) - 1]; | 
| +  RTC_NOTREACHED(); | 
| +  return uppermost_native_rate; | 
| } | 
|  | 
| }  // namespace | 
| @@ -124,6 +130,87 @@ int ClosestHigherNativeRate(int min_proc_rate) { | 
| // Throughout webrtc, it's assumed that success is represented by zero. | 
| static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); | 
|  | 
| +AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates() {} | 
| + | 
| +bool AudioProcessingImpl::ApmSubmoduleStates::Update( | 
| +    bool high_pass_filter_enabled, | 
| +    bool echo_canceller_enabled, | 
| +    bool mobile_echo_controller_enabled, | 
| +    bool noise_suppressor_enabled, | 
| +    bool intelligibility_enhancer_enabled, | 
| +    bool beamformer_enabled, | 
| +    bool adaptive_gain_controller_enabled, | 
| +    bool level_controller_enabled, | 
| +    bool voice_activity_detector_enabled, | 
| +    bool level_estimator_enabled, | 
| +    bool transient_suppressor_enabled) { | 
| +  bool changed = false; | 
| +  changed |= (high_pass_filter_enabled != high_pass_filter_enabled_); | 
| +  changed |= (echo_canceller_enabled != echo_canceller_enabled_); | 
| +  changed |= | 
| +      (mobile_echo_controller_enabled != mobile_echo_controller_enabled_); | 
| +  changed |= (noise_suppressor_enabled != noise_suppressor_enabled_); | 
| +  changed |= | 
| +      (intelligibility_enhancer_enabled != intelligibility_enhancer_enabled_); | 
| +  changed |= (beamformer_enabled != beamformer_enabled_); | 
| +  changed |= | 
| +      (adaptive_gain_controller_enabled != adaptive_gain_controller_enabled_); | 
| +  changed |= (level_controller_enabled != level_controller_enabled_); | 
| +  changed |= (level_estimator_enabled != level_estimator_enabled_); | 
| +  changed |= | 
| +      (voice_activity_detector_enabled != voice_activity_detector_enabled_); | 
| +  changed |= (transient_suppressor_enabled != transient_suppressor_enabled_); | 
| +  if (changed) { | 
| +    high_pass_filter_enabled_ = high_pass_filter_enabled; | 
| +    echo_canceller_enabled_ = echo_canceller_enabled; | 
| +    mobile_echo_controller_enabled_ = mobile_echo_controller_enabled; | 
| +    noise_suppressor_enabled_ = noise_suppressor_enabled; | 
| +    intelligibility_enhancer_enabled_ = intelligibility_enhancer_enabled; | 
| +    beamformer_enabled_ = beamformer_enabled; | 
| +    adaptive_gain_controller_enabled_ = adaptive_gain_controller_enabled; | 
| +    level_controller_enabled_ = level_controller_enabled; | 
| +    level_estimator_enabled_ = level_estimator_enabled; | 
| +    voice_activity_detector_enabled_ = voice_activity_detector_enabled; | 
| +    transient_suppressor_enabled_ = transient_suppressor_enabled; | 
| +  } | 
| + | 
| +  changed |= first_update_; | 
| +  first_update_ = false; | 
| +  return changed; | 
| +} | 
| + | 
| +bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandSubModulesActive() | 
| +    const { | 
| +#if WEBRTC_INTELLIGIBILITY_ENHANCER | 
| +  return CaptureMultiBandProcessingActive() || | 
| +         intelligibility_enhancer_enabled_ || voice_activity_detector_enabled_; | 
| +#else | 
| +  return CaptureMultiBandProcessingActive() || voice_activity_detector_enabled_; | 
| +#endif | 
| +} | 
| + | 
| +bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive() | 
| +    const { | 
| +  return high_pass_filter_enabled_ || echo_canceller_enabled_ || | 
| +         mobile_echo_controller_enabled_ || noise_suppressor_enabled_ || | 
| +         beamformer_enabled_ || adaptive_gain_controller_enabled_; | 
| +} | 
| + | 
| +bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandSubModulesActive() | 
| +    const { | 
| +  return RenderMultiBandProcessingActive() || echo_canceller_enabled_ || | 
| +         mobile_echo_controller_enabled_ || adaptive_gain_controller_enabled_; | 
| +} | 
| + | 
| +bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandProcessingActive() | 
| +    const { | 
| +#if WEBRTC_INTELLIGIBILITY_ENHANCER | 
| +  return intelligibility_enhancer_enabled_; | 
| +#else | 
| +  return false; | 
| +#endif | 
| +} | 
| + | 
| struct AudioProcessingImpl::ApmPublicSubmodules { | 
| ApmPublicSubmodules() {} | 
| // Accessed externally of APM without any lock acquired. | 
| @@ -275,12 +362,13 @@ int AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) { | 
|  | 
| int AudioProcessingImpl::MaybeInitializeRender( | 
| const ProcessingConfig& processing_config) { | 
| -  return MaybeInitialize(processing_config); | 
| +  return MaybeInitialize(processing_config, false); | 
| } | 
|  | 
| int AudioProcessingImpl::MaybeInitializeCapture( | 
| -    const ProcessingConfig& processing_config) { | 
| -  return MaybeInitialize(processing_config); | 
| +    const ProcessingConfig& processing_config, | 
| +    bool force_initialization) { | 
| +  return MaybeInitialize(processing_config, force_initialization); | 
| } | 
|  | 
| #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 
| @@ -300,9 +388,10 @@ AudioProcessingImpl::ApmDebugDumpState::~ApmDebugDumpState() {} | 
| // Calls InitializeLocked() if any of the audio parameters have changed from | 
| // their current values (needs to be called while holding the crit_render_lock). | 
| int AudioProcessingImpl::MaybeInitialize( | 
| -    const ProcessingConfig& processing_config) { | 
| +    const ProcessingConfig& processing_config, | 
| +    bool force_initialization) { | 
| // Called from both threads. Thread check is therefore not possible. | 
| -  if (processing_config == formats_.api_format) { | 
| +  if (processing_config == formats_.api_format && !force_initialization) { | 
| return kNoError; | 
| } | 
|  | 
| @@ -326,7 +415,8 @@ int AudioProcessingImpl::InitializeLocked() { | 
| formats_.rev_proc_format.num_frames(), | 
| formats_.rev_proc_format.num_channels(), | 
| rev_audio_buffer_out_num_frames)); | 
| -    if (rev_conversion_needed()) { | 
| +    if (formats_.api_format.reverse_input_stream() != | 
| +        formats_.api_format.reverse_output_stream()) { | 
| render_.render_converter = AudioConverter::Create( | 
| formats_.api_format.reverse_input_stream().num_channels(), | 
| formats_.api_format.reverse_input_stream().num_frames(), | 
| @@ -397,17 +487,25 @@ int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { | 
|  | 
| formats_.api_format = config; | 
|  | 
| -  capture_nonlocked_.fwd_proc_format = StreamConfig(ClosestHigherNativeRate( | 
| +  int fwd_proc_rate = FindNativeProcessRateToUse( | 
| std::min(formats_.api_format.input_stream().sample_rate_hz(), | 
| -               formats_.api_format.output_stream().sample_rate_hz()))); | 
| +               formats_.api_format.output_stream().sample_rate_hz()), | 
| +      submodule_states_.CaptureMultiBandSubModulesActive() || | 
| +          submodule_states_.RenderMultiBandSubModulesActive()); | 
|  | 
| -  int rev_proc_rate = ClosestHigherNativeRate(std::min( | 
| -      formats_.api_format.reverse_input_stream().sample_rate_hz(), | 
| -      formats_.api_format.reverse_output_stream().sample_rate_hz())); | 
| +  capture_nonlocked_.fwd_proc_format = StreamConfig(fwd_proc_rate); | 
| + | 
| +  int rev_proc_rate = FindNativeProcessRateToUse( | 
| +      std::min(formats_.api_format.reverse_input_stream().sample_rate_hz(), | 
| +               formats_.api_format.reverse_output_stream().sample_rate_hz()), | 
| +      submodule_states_.CaptureMultiBandSubModulesActive() || | 
| +          submodule_states_.RenderMultiBandSubModulesActive()); | 
| // TODO(aluebs): Remove this restriction once we figure out why the 3-band | 
| // splitting filter degrades the AEC performance. | 
| if (rev_proc_rate > kSampleRate32kHz) { | 
| -    rev_proc_rate = is_rev_processed() ? kSampleRate32kHz : kSampleRate16kHz; | 
| +    rev_proc_rate = submodule_states_.RenderMultiBandProcessingActive() | 
| +                        ? kSampleRate32kHz | 
| +                        : kSampleRate16kHz; | 
| } | 
| // If the forward sample rate is 8 kHz, the reverse stream is also processed | 
| // at this rate. | 
| @@ -556,6 +654,7 @@ int AudioProcessingImpl::ProcessStream(const float* const* src, | 
| float* const* dest) { | 
| TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_StreamConfig"); | 
| ProcessingConfig processing_config; | 
| +  bool reinitialization_required = false; | 
| { | 
| // Acquire the capture lock in order to safely call the function | 
| // that retrieves the render side data. This function accesses apm | 
| @@ -570,6 +669,7 @@ int AudioProcessingImpl::ProcessStream(const float* const* src, | 
| } | 
|  | 
| processing_config = formats_.api_format; | 
| +    reinitialization_required = UpdateActiveSubmoduleStates(); | 
| } | 
|  | 
| processing_config.input_stream() = input_config; | 
| @@ -578,7 +678,8 @@ int AudioProcessingImpl::ProcessStream(const float* const* src, | 
| { | 
| // Do conditional reinitialization. | 
| rtc::CritScope cs_render(&crit_render_); | 
| -    RETURN_ON_ERR(MaybeInitializeCapture(processing_config)); | 
| +    RETURN_ON_ERR( | 
| +        MaybeInitializeCapture(processing_config, reinitialization_required)); | 
| } | 
| rtc::CritScope cs_capture(&crit_capture_); | 
| assert(processing_config.input_stream().num_frames() == | 
| @@ -646,6 +747,7 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 
| } | 
|  | 
| ProcessingConfig processing_config; | 
| +  bool reinitialization_required = false; | 
| { | 
| // Aquire lock for the access of api_format. | 
| // The lock is released immediately due to the conditional | 
| @@ -654,6 +756,8 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 
| // TODO(ajm): The input and output rates and channels are currently | 
| // constrained to be identical in the int16 interface. | 
| processing_config = formats_.api_format; | 
| + | 
| +    reinitialization_required = UpdateActiveSubmoduleStates(); | 
| } | 
| processing_config.input_stream().set_sample_rate_hz(frame->sample_rate_hz_); | 
| processing_config.input_stream().set_num_channels(frame->num_channels_); | 
| @@ -663,7 +767,8 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 
| { | 
| // Do conditional reinitialization. | 
| rtc::CritScope cs_render(&crit_render_); | 
| -    RETURN_ON_ERR(MaybeInitializeCapture(processing_config)); | 
| +    RETURN_ON_ERR( | 
| +        MaybeInitializeCapture(processing_config, reinitialization_required)); | 
| } | 
| rtc::CritScope cs_capture(&crit_capture_); | 
| if (frame->samples_per_channel_ != | 
| @@ -685,7 +790,8 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 
|  | 
| capture_.capture_audio->DeinterleaveFrom(frame); | 
| RETURN_ON_ERR(ProcessStreamLocked()); | 
| -  capture_.capture_audio->InterleaveTo(frame, output_copy_needed()); | 
| +  capture_.capture_audio->InterleaveTo( | 
| +      frame, submodule_states_.CaptureMultiBandProcessingActive()); | 
|  | 
| #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 
| if (debug_dump_.debug_file->is_open()) { | 
| @@ -731,7 +837,9 @@ int AudioProcessingImpl::ProcessStreamLocked() { | 
| capture_nonlocked_.fwd_proc_format.num_frames()); | 
| } | 
|  | 
| -  if (fwd_analysis_needed()) { | 
| +  if (submodule_states_.CaptureMultiBandSubModulesActive() && | 
| +      SampleRateSupportsMultiBand( | 
| +          capture_nonlocked_.fwd_proc_format.sample_rate_hz())) { | 
| ca->SplitIntoFrequencyBands(); | 
| } | 
|  | 
| @@ -802,7 +910,9 @@ int AudioProcessingImpl::ProcessStreamLocked() { | 
| RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio( | 
| ca, echo_cancellation()->stream_has_echo())); | 
|  | 
| -  if (fwd_synthesis_needed()) { | 
| +  if (submodule_states_.CaptureMultiBandProcessingActive() && | 
| +      SampleRateSupportsMultiBand( | 
| +          capture_nonlocked_.fwd_proc_format.sample_rate_hz())) { | 
| ca->MergeFrequencyBands(); | 
| } | 
|  | 
| @@ -856,10 +966,11 @@ int AudioProcessingImpl::ProcessReverseStream( | 
| rtc::CritScope cs(&crit_render_); | 
| RETURN_ON_ERR(AnalyzeReverseStreamLocked(src, reverse_input_config, | 
| reverse_output_config)); | 
| -  if (is_rev_processed()) { | 
| +  if (submodule_states_.RenderMultiBandProcessingActive()) { | 
| render_.render_audio->CopyTo(formats_.api_format.reverse_output_stream(), | 
| dest); | 
| -  } else if (render_check_rev_conversion_needed()) { | 
| +  } else if (formats_.api_format.reverse_input_stream() != | 
| +             formats_.api_format.reverse_output_stream()) { | 
| render_.render_converter->Convert(src, reverse_input_config.num_samples(), | 
| dest, | 
| reverse_output_config.num_samples()); | 
| @@ -961,15 +1072,15 @@ int AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) { | 
| #endif | 
| render_.render_audio->DeinterleaveFrom(frame); | 
| RETURN_ON_ERR(ProcessReverseStreamLocked()); | 
| -  if (is_rev_processed()) { | 
| -    render_.render_audio->InterleaveTo(frame, true); | 
| -  } | 
| +  render_.render_audio->InterleaveTo( | 
| +      frame, submodule_states_.RenderMultiBandProcessingActive()); | 
| return kNoError; | 
| } | 
|  | 
| int AudioProcessingImpl::ProcessReverseStreamLocked() { | 
| AudioBuffer* ra = render_.render_audio.get();  // For brevity. | 
| -  if (rev_analysis_needed()) { | 
| +  if (submodule_states_.RenderMultiBandSubModulesActive() && | 
| +      SampleRateSupportsMultiBand(formats_.rev_proc_format.sample_rate_hz())) { | 
| ra->SplitIntoFrequencyBands(); | 
| } | 
|  | 
| @@ -988,7 +1099,8 @@ int AudioProcessingImpl::ProcessReverseStreamLocked() { | 
| RETURN_ON_ERR(public_submodules_->gain_control->ProcessRenderAudio(ra)); | 
| } | 
|  | 
| -  if (rev_synthesis_needed()) { | 
| +  if (submodule_states_.RenderMultiBandProcessingActive() && | 
| +      SampleRateSupportsMultiBand(formats_.rev_proc_format.sample_rate_hz())) { | 
| ra->MergeFrequencyBands(); | 
| } | 
|  | 
| @@ -1122,20 +1234,14 @@ int AudioProcessingImpl::StopDebugRecording() { | 
| } | 
|  | 
| EchoCancellation* AudioProcessingImpl::echo_cancellation() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->echo_cancellation.get(); | 
| } | 
|  | 
| EchoControlMobile* AudioProcessingImpl::echo_control_mobile() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->echo_control_mobile.get(); | 
| } | 
|  | 
| GainControl* AudioProcessingImpl::gain_control() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| if (constants_.use_experimental_agc) { | 
| return public_submodules_->gain_control_for_experimental_agc.get(); | 
| } | 
| @@ -1143,103 +1249,34 @@ GainControl* AudioProcessingImpl::gain_control() const { | 
| } | 
|  | 
| HighPassFilter* AudioProcessingImpl::high_pass_filter() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->high_pass_filter.get(); | 
| } | 
|  | 
| LevelEstimator* AudioProcessingImpl::level_estimator() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->level_estimator.get(); | 
| } | 
|  | 
| NoiseSuppression* AudioProcessingImpl::noise_suppression() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->noise_suppression.get(); | 
| } | 
|  | 
| VoiceDetection* AudioProcessingImpl::voice_detection() const { | 
| -  // Adding a lock here has no effect as it allows any access to the submodule | 
| -  // from the returned pointer. | 
| return public_submodules_->voice_detection.get(); | 
| } | 
|  | 
| -bool AudioProcessingImpl::is_fwd_processed() const { | 
| -  // The beamformer, noise suppressor and highpass filter | 
| -  // modify the data. | 
| -  if (capture_nonlocked_.beamformer_enabled || | 
| -      public_submodules_->high_pass_filter->is_enabled() || | 
| -      public_submodules_->noise_suppression->is_enabled() || | 
| -      public_submodules_->echo_cancellation->is_enabled() || | 
| -      public_submodules_->echo_control_mobile->is_enabled() || | 
| -      public_submodules_->gain_control->is_enabled()) { | 
| -    return true; | 
| -  } | 
| - | 
| -  // The capture data is otherwise unchanged. | 
| -  return false; | 
| -} | 
| - | 
| -bool AudioProcessingImpl::output_copy_needed() const { | 
| -  // Check if we've upmixed or downmixed the audio. | 
| -  return ((formats_.api_format.output_stream().num_channels() != | 
| -           formats_.api_format.input_stream().num_channels()) || | 
| -          is_fwd_processed() || capture_.transient_suppressor_enabled || | 
| -          capture_nonlocked_.level_controller_enabled); | 
| -} | 
| - | 
| -bool AudioProcessingImpl::fwd_synthesis_needed() const { | 
| -  return (is_fwd_processed() && | 
| -          is_multi_band(capture_nonlocked_.fwd_proc_format.sample_rate_hz())); | 
| -} | 
| - | 
| -bool AudioProcessingImpl::fwd_analysis_needed() const { | 
| -  if (!is_fwd_processed() && | 
| -      !public_submodules_->voice_detection->is_enabled() && | 
| -      !capture_.transient_suppressor_enabled) { | 
| -    // Only public_submodules_->level_estimator is enabled. | 
| -    return false; | 
| -  } else if (is_multi_band( | 
| -                 capture_nonlocked_.fwd_proc_format.sample_rate_hz())) { | 
| -    // Something besides public_submodules_->level_estimator is enabled, and we | 
| -    // have super-wb. | 
| -    return true; | 
| -  } | 
| -  return false; | 
| -} | 
| - | 
| -bool AudioProcessingImpl::is_rev_processed() const { | 
| -#if WEBRTC_INTELLIGIBILITY_ENHANCER | 
| -  return capture_nonlocked_.intelligibility_enabled; | 
| -#else | 
| -  return false; | 
| -#endif | 
| -} | 
| - | 
| -bool AudioProcessingImpl::rev_synthesis_needed() const { | 
| -  return (is_rev_processed() && | 
| -          is_multi_band(formats_.rev_proc_format.sample_rate_hz())); | 
| -} | 
| - | 
| -bool AudioProcessingImpl::rev_analysis_needed() const { | 
| -  return is_multi_band(formats_.rev_proc_format.sample_rate_hz()) && | 
| -         (is_rev_processed() || | 
| -          public_submodules_->echo_cancellation | 
| -              ->is_enabled_render_side_query() || | 
| -          public_submodules_->echo_control_mobile | 
| -              ->is_enabled_render_side_query() || | 
| -          public_submodules_->gain_control->is_enabled_render_side_query()); | 
| -} | 
| - | 
| -bool AudioProcessingImpl::render_check_rev_conversion_needed() const { | 
| -  return rev_conversion_needed(); | 
| -} | 
| - | 
| -bool AudioProcessingImpl::rev_conversion_needed() const { | 
| -  return (formats_.api_format.reverse_input_stream() != | 
| -          formats_.api_format.reverse_output_stream()); | 
| +bool AudioProcessingImpl::UpdateActiveSubmoduleStates() { | 
| +  return submodule_states_.Update( | 
| +      public_submodules_->high_pass_filter->is_enabled(), | 
| +      public_submodules_->echo_cancellation->is_enabled(), | 
| +      public_submodules_->echo_control_mobile->is_enabled(), | 
| +      public_submodules_->noise_suppression->is_enabled(), | 
| +      capture_nonlocked_.intelligibility_enabled, | 
| +      capture_nonlocked_.beamformer_enabled, | 
| +      public_submodules_->gain_control->is_enabled(), | 
| +      capture_nonlocked_.level_controller_enabled, | 
| +      public_submodules_->voice_detection->is_enabled(), | 
| +      public_submodules_->level_estimator->is_enabled(), | 
| +      capture_.transient_suppressor_enabled); | 
| } | 
|  | 
| void AudioProcessingImpl::InitializeExperimentalAgc() { | 
|  |