tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_processing_impl.cc (89461B)


      1 /*
      2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/audio_processing/audio_processing_impl.h"
     12 
     13 #include <algorithm>
     14 #include <array>
     15 #include <atomic>
     16 #include <cstdint>
     17 #include <cstdio>
     18 #include <cstring>
     19 #include <memory>
     20 #include <optional>
     21 #include <string>
     22 #include <utility>
     23 #include <vector>
     24 
     25 #include "absl/base/nullability.h"
     26 #include "absl/strings/string_view.h"
     27 #include "api/array_view.h"
     28 #include "api/audio/audio_processing.h"
     29 #include "api/audio/audio_processing_statistics.h"
     30 #include "api/audio/audio_view.h"
     31 #include "api/audio/echo_canceller3_config.h"
     32 #include "api/audio/echo_control.h"
     33 #include "api/audio/neural_residual_echo_estimator.h"
     34 #include "api/environment/environment.h"
     35 #include "api/field_trials_view.h"
     36 #include "api/scoped_refptr.h"
     37 #include "api/task_queue/task_queue_base.h"
     38 #include "common_audio/audio_converter.h"
     39 #include "common_audio/include/audio_util.h"
     40 #include "modules/audio_processing/aec3/echo_canceller3.h"
     41 #include "modules/audio_processing/aec_dump/aec_dump_factory.h"
     42 #include "modules/audio_processing/agc/agc_manager_direct.h"
     43 #include "modules/audio_processing/agc/gain_control.h"
     44 #include "modules/audio_processing/agc2/input_volume_controller.h"
     45 #include "modules/audio_processing/agc2/input_volume_stats_reporter.h"
     46 #include "modules/audio_processing/audio_buffer.h"
     47 #include "modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.h"
     48 #include "modules/audio_processing/echo_control_mobile_impl.h"
     49 #include "modules/audio_processing/gain_control_impl.h"
     50 #include "modules/audio_processing/gain_controller2.h"
     51 #include "modules/audio_processing/high_pass_filter.h"
     52 #include "modules/audio_processing/include/aec_dump.h"
     53 #include "modules/audio_processing/logging/apm_data_dumper.h"
     54 #include "modules/audio_processing/ns/noise_suppressor.h"
     55 #include "modules/audio_processing/ns/ns_config.h"
     56 #include "modules/audio_processing/post_filter.h"
     57 #include "modules/audio_processing/render_queue_item_verifier.h"
     58 #include "modules/audio_processing/rms_level.h"
     59 #include "rtc_base/checks.h"
     60 #include "rtc_base/denormal_disabler.h"
     61 #include "rtc_base/logging.h"
     62 #include "rtc_base/swap_queue.h"
     63 #include "rtc_base/synchronization/mutex.h"
     64 #include "rtc_base/time_utils.h"
     65 #include "rtc_base/trace_event.h"
     66 #include "system_wrappers/include/metrics.h"
     67 
     68 #define RETURN_ON_ERR(expr) \
     69  do {                      \
     70    int err = (expr);       \
     71    if (err != kNoError) {  \
     72      return err;           \
     73    }                       \
     74  } while (0)
     75 
     76 namespace webrtc {
     77 
     78 namespace {
     79 
     80 bool SampleRateSupportsMultiBand(int sample_rate_hz) {
     81  return sample_rate_hz == AudioProcessing::kSampleRate32kHz ||
     82         sample_rate_hz == AudioProcessing::kSampleRate48kHz;
     83 }
     84 
     85 // Checks whether the high-pass filter should be done in the full-band.
     86 bool EnforceSplitBandHpf(const FieldTrialsView& field_trials) {
     87  return field_trials.IsEnabled("WebRTC-FullBandHpfKillSwitch");
     88 }
     89 
     90 // Identify the native processing rate that best handles a sample rate.
     91 int SuitableProcessRate(int minimum_rate,
     92                        int max_splitting_rate,
     93                        bool band_splitting_required) {
     94  const int uppermost_native_rate =
     95      band_splitting_required ? max_splitting_rate : 48000;
     96  for (auto rate : {16000, 32000, 48000}) {
     97    if (rate >= uppermost_native_rate) {
     98      return uppermost_native_rate;
     99    }
    100    if (rate >= minimum_rate) {
    101      return rate;
    102    }
    103  }
    104  RTC_DCHECK_NOTREACHED();
    105  return uppermost_native_rate;
    106 }
    107 
    108 GainControl::Mode Agc1ConfigModeToInterfaceMode(
    109    AudioProcessing::Config::GainController1::Mode mode) {
    110  using Agc1Config = AudioProcessing::Config::GainController1;
    111  switch (mode) {
    112    case Agc1Config::kAdaptiveAnalog:
    113      return GainControl::kAdaptiveAnalog;
    114    case Agc1Config::kAdaptiveDigital:
    115      return GainControl::kAdaptiveDigital;
    116    case Agc1Config::kFixedDigital:
    117      return GainControl::kFixedDigital;
    118  }
    119  RTC_CHECK_NOTREACHED();
    120 }
    121 
    122 bool MinimizeProcessingForUnusedOutput(const FieldTrialsView& field_trials) {
    123  return !field_trials.IsEnabled("WebRTC-MutedStateKillSwitch");
    124 }
    125 
    126 // Maximum lengths that frame of samples being passed from the render side to
    127 // the capture side can have (does not apply to AEC3).
    128 const size_t kMaxAllowedValuesOfSamplesPerBand = 160;
    129 const size_t kMaxAllowedValuesOfSamplesPerFrame = 480;
    130 
    131 // Maximum number of frames to buffer in the render queue.
    132 // TODO(peah): Decrease this once we properly handle hugely unbalanced
    133 // reverse and forward call numbers.
    134 const size_t kMaxNumFramesToBuffer = 100;
    135 
    136 void PackRenderAudioBufferForEchoDetector(const AudioBuffer& audio,
    137                                          std::vector<float>& packed_buffer) {
    138  packed_buffer.clear();
    139  packed_buffer.insert(packed_buffer.end(), audio.channels_const()[0],
    140                       audio.channels_const()[0] + audio.num_frames());
    141 }
    142 
    143 // Options for gracefully handling processing errors.
    144 enum class FormatErrorOutputOption {
    145  kOutputExactCopyOfInput,
    146  kOutputBroadcastCopyOfFirstInputChannel,
    147  kOutputSilence,
    148  kDoNothing
    149 };
    150 
    151 enum class AudioFormatValidity {
    152  // Format is supported by APM.
    153  kValidAndSupported,
    154  // Format has a reasonable interpretation but is not supported.
    155  kValidButUnsupportedSampleRate,
    156  // The remaining enums values signal that the audio does not have a reasonable
    157  // interpretation and cannot be used.
    158  kInvalidSampleRate,
    159  kInvalidChannelCount
    160 };
    161 
    162 AudioFormatValidity ValidateAudioFormat(const StreamConfig& config) {
    163  if (config.sample_rate_hz() < 0)
    164    return AudioFormatValidity::kInvalidSampleRate;
    165  if (config.num_channels() == 0)
    166    return AudioFormatValidity::kInvalidChannelCount;
    167 
    168  // Format has a reasonable interpretation, but may still be unsupported.
    169  if (config.sample_rate_hz() < 8000 ||
    170      config.sample_rate_hz() > AudioBuffer::kMaxSampleRate)
    171    return AudioFormatValidity::kValidButUnsupportedSampleRate;
    172 
    173  // Format is fully supported.
    174  return AudioFormatValidity::kValidAndSupported;
    175 }
    176 
    177 int AudioFormatValidityToErrorCode(AudioFormatValidity validity) {
    178  switch (validity) {
    179    case AudioFormatValidity::kValidAndSupported:
    180      return AudioProcessing::kNoError;
    181    case AudioFormatValidity::kValidButUnsupportedSampleRate:  // fall-through
    182    case AudioFormatValidity::kInvalidSampleRate:
    183      return AudioProcessing::kBadSampleRateError;
    184    case AudioFormatValidity::kInvalidChannelCount:
    185      return AudioProcessing::kBadNumberChannelsError;
    186  }
    187  RTC_DCHECK(false);
    188 }
    189 
    190 // Returns an AudioProcessing::Error together with the best possible option for
    191 // output audio content.
    192 std::pair<int, FormatErrorOutputOption> ChooseErrorOutputOption(
    193    const StreamConfig& input_config,
    194    const StreamConfig& output_config) {
    195  AudioFormatValidity input_validity = ValidateAudioFormat(input_config);
    196  AudioFormatValidity output_validity = ValidateAudioFormat(output_config);
    197 
    198  if (input_validity == AudioFormatValidity::kValidAndSupported &&
    199      output_validity == AudioFormatValidity::kValidAndSupported &&
    200      (output_config.num_channels() == 1 ||
    201       output_config.num_channels() == input_config.num_channels())) {
    202    return {AudioProcessing::kNoError, FormatErrorOutputOption::kDoNothing};
    203  }
    204 
    205  int error_code = AudioFormatValidityToErrorCode(input_validity);
    206  if (error_code == AudioProcessing::kNoError) {
    207    error_code = AudioFormatValidityToErrorCode(output_validity);
    208  }
    209  if (error_code == AudioProcessing::kNoError) {
    210    // The individual formats are valid but there is some error - must be
    211    // channel mismatch.
    212    error_code = AudioProcessing::kBadNumberChannelsError;
    213  }
    214 
    215  FormatErrorOutputOption output_option;
    216  if (output_validity != AudioFormatValidity::kValidAndSupported &&
    217      output_validity != AudioFormatValidity::kValidButUnsupportedSampleRate) {
    218    // The output format is uninterpretable: cannot do anything.
    219    output_option = FormatErrorOutputOption::kDoNothing;
    220  } else if (input_validity != AudioFormatValidity::kValidAndSupported &&
    221             input_validity !=
    222                 AudioFormatValidity::kValidButUnsupportedSampleRate) {
    223    // The input format is uninterpretable: cannot use it, must output silence.
    224    output_option = FormatErrorOutputOption::kOutputSilence;
    225  } else if (input_config.sample_rate_hz() != output_config.sample_rate_hz()) {
    226    // Sample rates do not match: Cannot copy input into output, output silence.
    227    // Note: If the sample rates are in a supported range, we could resample.
    228    // However, that would significantly increase complexity of this error
    229    // handling code.
    230    output_option = FormatErrorOutputOption::kOutputSilence;
    231  } else if (input_config.num_channels() != output_config.num_channels()) {
    232    // Channel counts do not match: We cannot easily map input channels to
    233    // output channels.
    234    output_option =
    235        FormatErrorOutputOption::kOutputBroadcastCopyOfFirstInputChannel;
    236  } else {
    237    // The formats match exactly.
    238    RTC_DCHECK(input_config == output_config);
    239    output_option = FormatErrorOutputOption::kOutputExactCopyOfInput;
    240  }
    241  return std::make_pair(error_code, output_option);
    242 }
    243 
    244 // Checks if the audio format is supported. If not, the output is populated in a
    245 // best-effort manner and an APM error code is returned.
    246 int HandleUnsupportedAudioFormats(const int16_t* const src,
    247                                  const StreamConfig& input_config,
    248                                  const StreamConfig& output_config,
    249                                  int16_t* const dest) {
    250  RTC_DCHECK(src);
    251  RTC_DCHECK(dest);
    252 
    253  auto [error_code, output_option] =
    254      ChooseErrorOutputOption(input_config, output_config);
    255  if (error_code == AudioProcessing::kNoError)
    256    return AudioProcessing::kNoError;
    257 
    258  const size_t num_output_channels = output_config.num_channels();
    259  switch (output_option) {
    260    case FormatErrorOutputOption::kOutputSilence:
    261      memset(dest, 0, output_config.num_samples() * sizeof(int16_t));
    262      break;
    263    case FormatErrorOutputOption::kOutputBroadcastCopyOfFirstInputChannel:
    264      for (size_t i = 0; i < output_config.num_frames(); ++i) {
    265        int16_t sample = src[input_config.num_channels() * i];
    266        for (size_t ch = 0; ch < num_output_channels; ++ch) {
    267          dest[ch + num_output_channels * i] = sample;
    268        }
    269      }
    270      break;
    271    case FormatErrorOutputOption::kOutputExactCopyOfInput:
    272      memcpy(dest, src, output_config.num_samples() * sizeof(int16_t));
    273      break;
    274    case FormatErrorOutputOption::kDoNothing:
    275      break;
    276  }
    277  return error_code;
    278 }
    279 
    280 // Checks if the audio format is supported. If not, the output is populated in a
    281 // best-effort manner and an APM error code is returned.
    282 int HandleUnsupportedAudioFormats(const float* const* src,
    283                                  const StreamConfig& input_config,
    284                                  const StreamConfig& output_config,
    285                                  float* const* dest) {
    286  RTC_DCHECK(src);
    287  RTC_DCHECK(dest);
    288  for (size_t i = 0; i < input_config.num_channels(); ++i) {
    289    RTC_DCHECK(src[i]);
    290  }
    291  for (size_t i = 0; i < output_config.num_channels(); ++i) {
    292    RTC_DCHECK(dest[i]);
    293  }
    294 
    295  auto [error_code, output_option] =
    296      ChooseErrorOutputOption(input_config, output_config);
    297  if (error_code == AudioProcessing::kNoError)
    298    return AudioProcessing::kNoError;
    299 
    300  const size_t num_output_channels = output_config.num_channels();
    301  switch (output_option) {
    302    case FormatErrorOutputOption::kOutputSilence:
    303      for (size_t ch = 0; ch < num_output_channels; ++ch) {
    304        memset(dest[ch], 0, output_config.num_frames() * sizeof(float));
    305      }
    306      break;
    307    case FormatErrorOutputOption::kOutputBroadcastCopyOfFirstInputChannel:
    308      for (size_t ch = 0; ch < num_output_channels; ++ch) {
    309        memcpy(dest[ch], src[0], output_config.num_frames() * sizeof(float));
    310      }
    311      break;
    312    case FormatErrorOutputOption::kOutputExactCopyOfInput:
    313      for (size_t ch = 0; ch < num_output_channels; ++ch) {
    314        memcpy(dest[ch], src[ch], output_config.num_frames() * sizeof(float));
    315      }
    316      break;
    317    case FormatErrorOutputOption::kDoNothing:
    318      break;
    319  }
    320  return error_code;
    321 }
    322 
    323 using DownmixMethod = AudioProcessing::Config::Pipeline::DownmixMethod;
    324 
    325 void SetDownmixMethod(AudioBuffer& buffer, DownmixMethod method) {
    326  switch (method) {
    327    case DownmixMethod::kAverageChannels:
    328      buffer.set_downmixing_by_averaging();
    329      break;
    330    case DownmixMethod::kUseFirstChannel:
    331      buffer.set_downmixing_to_specific_channel(/*channel=*/0);
    332      break;
    333  }
    334 }
    335 
    336 constexpr int kUnspecifiedDataDumpInputVolume = -100;
    337 
    338 }  // namespace
    339 
    340 // Throughout webrtc, it's assumed that success is represented by zero.
    341 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero");
    342 
    343 AudioProcessingImpl::SubmoduleStates::SubmoduleStates(
    344    bool capture_post_processor_enabled,
    345    bool render_pre_processor_enabled,
    346    bool capture_analyzer_enabled)
    347    : capture_post_processor_enabled_(capture_post_processor_enabled),
    348      render_pre_processor_enabled_(render_pre_processor_enabled),
    349      capture_analyzer_enabled_(capture_analyzer_enabled) {}
    350 
    351 bool AudioProcessingImpl::SubmoduleStates::Update(
    352    bool high_pass_filter_enabled,
    353    bool mobile_echo_controller_enabled,
    354    bool noise_suppressor_enabled,
    355    bool adaptive_gain_controller_enabled,
    356    bool gain_controller2_enabled,
    357    bool gain_adjustment_enabled,
    358    bool echo_controller_enabled) {
    359  bool changed = false;
    360  changed |= (high_pass_filter_enabled != high_pass_filter_enabled_);
    361  changed |=
    362      (mobile_echo_controller_enabled != mobile_echo_controller_enabled_);
    363  changed |= (noise_suppressor_enabled != noise_suppressor_enabled_);
    364  changed |=
    365      (adaptive_gain_controller_enabled != adaptive_gain_controller_enabled_);
    366  changed |= (gain_controller2_enabled != gain_controller2_enabled_);
    367  changed |= (gain_adjustment_enabled != gain_adjustment_enabled_);
    368  changed |= (echo_controller_enabled != echo_controller_enabled_);
    369  if (changed) {
    370    high_pass_filter_enabled_ = high_pass_filter_enabled;
    371    mobile_echo_controller_enabled_ = mobile_echo_controller_enabled;
    372    noise_suppressor_enabled_ = noise_suppressor_enabled;
    373    adaptive_gain_controller_enabled_ = adaptive_gain_controller_enabled;
    374    gain_controller2_enabled_ = gain_controller2_enabled;
    375    gain_adjustment_enabled_ = gain_adjustment_enabled;
    376    echo_controller_enabled_ = echo_controller_enabled;
    377  }
    378 
    379  changed |= first_update_;
    380  first_update_ = false;
    381  return changed;
    382 }
    383 
    384 bool AudioProcessingImpl::SubmoduleStates::CaptureMultiBandSubModulesActive()
    385    const {
    386  return CaptureMultiBandProcessingPresent();
    387 }
    388 
    389 bool AudioProcessingImpl::SubmoduleStates::CaptureMultiBandProcessingPresent()
    390    const {
    391  // If echo controller is present, assume it performs active processing.
    392  return CaptureMultiBandProcessingActive(/*ec_processing_active=*/true);
    393 }
    394 
    395 bool AudioProcessingImpl::SubmoduleStates::CaptureMultiBandProcessingActive(
    396    bool ec_processing_active) const {
    397  return high_pass_filter_enabled_ || mobile_echo_controller_enabled_ ||
    398         noise_suppressor_enabled_ || adaptive_gain_controller_enabled_ ||
    399         (echo_controller_enabled_ && ec_processing_active);
    400 }
    401 
    402 bool AudioProcessingImpl::SubmoduleStates::CaptureFullBandProcessingActive()
    403    const {
    404  return gain_controller2_enabled_ || capture_post_processor_enabled_ ||
    405         gain_adjustment_enabled_;
    406 }
    407 
    408 bool AudioProcessingImpl::SubmoduleStates::CaptureAnalyzerActive() const {
    409  return capture_analyzer_enabled_;
    410 }
    411 
    412 bool AudioProcessingImpl::SubmoduleStates::RenderMultiBandSubModulesActive()
    413    const {
    414  return RenderMultiBandProcessingActive() || mobile_echo_controller_enabled_ ||
    415         adaptive_gain_controller_enabled_ || echo_controller_enabled_;
    416 }
    417 
    418 bool AudioProcessingImpl::SubmoduleStates::RenderFullBandProcessingActive()
    419    const {
    420  return render_pre_processor_enabled_;
    421 }
    422 
    423 bool AudioProcessingImpl::SubmoduleStates::RenderMultiBandProcessingActive()
    424    const {
    425  return false;
    426 }
    427 
    428 bool AudioProcessingImpl::SubmoduleStates::HighPassFilteringRequired() const {
    429  return high_pass_filter_enabled_ || mobile_echo_controller_enabled_ ||
    430         noise_suppressor_enabled_;
    431 }
    432 
    433 AudioProcessingImpl::AudioProcessingImpl(const Environment& env)
    434    : AudioProcessingImpl(env,
    435                          /*config=*/{},
    436                          /*echo_canceller_config=*/std::nullopt,
    437                          /*echo_canceller_multichannel_config=*/std::nullopt,
    438                          /*capture_post_processor=*/nullptr,
    439                          /*render_pre_processor=*/nullptr,
    440                          /*echo_control_factory=*/nullptr,
    441                          /*echo_detector=*/nullptr,
    442                          /*capture_analyzer=*/nullptr,
    443                          /*neural_residual_echo_estimator=*/nullptr) {}
    444 
    445 std::atomic<int> AudioProcessingImpl::instance_count_(0);
    446 
    447 AudioProcessingImpl::AudioProcessingImpl(
    448    const Environment& env,
    449    const AudioProcessing::Config& config,
    450    std::optional<EchoCanceller3Config> echo_canceller_config,
    451    std::optional<EchoCanceller3Config> echo_canceller_multichannel_config,
    452    std::unique_ptr<CustomProcessing> capture_post_processor,
    453    std::unique_ptr<CustomProcessing> render_pre_processor,
    454    std::unique_ptr<EchoControlFactory> echo_control_factory,
    455    scoped_refptr<EchoDetector> echo_detector,
    456    std::unique_ptr<CustomAudioAnalyzer> capture_analyzer,
    457    std::unique_ptr<NeuralResidualEchoEstimator> neural_residual_echo_estimator)
    458    : env_(env),
    459      data_dumper_(new ApmDataDumper(instance_count_.fetch_add(1) + 1)),
    460      capture_runtime_settings_(RuntimeSettingQueueSize()),
    461      render_runtime_settings_(RuntimeSettingQueueSize()),
    462      capture_runtime_settings_enqueuer_(&capture_runtime_settings_),
    463      render_runtime_settings_enqueuer_(&render_runtime_settings_),
    464      echo_control_factory_(std::move(echo_control_factory)),
    465      config_(config),
    466      echo_canceller_config_(echo_canceller_config),
    467      echo_canceller_multichannel_config_(echo_canceller_multichannel_config),
    468      submodule_states_(!!capture_post_processor,
    469                        !!render_pre_processor,
    470                        !!capture_analyzer),
    471      submodules_(std::move(capture_post_processor),
    472                  std::move(render_pre_processor),
    473                  std::move(echo_detector),
    474                  std::move(capture_analyzer),
    475                  std::move(neural_residual_echo_estimator)),
    476      constants_(!env.field_trials().IsEnabled(
    477                     "WebRTC-ApmExperimentalMultiChannelRenderKillSwitch"),
    478                 !env.field_trials().IsEnabled(
    479                     "WebRTC-ApmExperimentalMultiChannelCaptureKillSwitch"),
    480                 EnforceSplitBandHpf(env.field_trials()),
    481                 MinimizeProcessingForUnusedOutput(env.field_trials())),
    482      capture_(),
    483      capture_nonlocked_(),
    484      applied_input_volume_stats_reporter_(
    485          InputVolumeStatsReporter::InputVolumeType::kApplied),
    486      recommended_input_volume_stats_reporter_(
    487          InputVolumeStatsReporter::InputVolumeType::kRecommended) {
    488  RTC_LOG(LS_INFO) << "Injected APM submodules:"
    489                      "\nEcho control factory: "
    490                   << !!echo_control_factory_
    491                   << "\nEcho detector: " << !!submodules_.echo_detector
    492                   << "\nCapture analyzer: " << !!submodules_.capture_analyzer
    493                   << "\nCapture post processor: "
    494                   << !!submodules_.capture_post_processor
    495                   << "\nRender pre processor: "
    496                   << !!submodules_.render_pre_processor
    497                   << "\nNeural residual echo estimator "
    498                   << !!submodules_.neural_residual_echo_estimator;
    499  if (!DenormalDisabler::IsSupported()) {
    500    RTC_LOG(LS_INFO) << "Denormal disabler unsupported";
    501  }
    502 
    503  RTC_LOG(LS_INFO) << "AudioProcessing: " << config_.ToString();
    504 
    505  // Mark Echo Controller enabled if a factory is injected.
    506  capture_nonlocked_.echo_controller_enabled =
    507      static_cast<bool>(echo_control_factory_);
    508 
    509  Initialize();
    510 }
    511 
    512 AudioProcessingImpl::~AudioProcessingImpl() = default;
    513 
    514 int AudioProcessingImpl::Initialize() {
    515  // Run in a single-threaded manner during initialization.
    516  MutexLock lock_render(&mutex_render_);
    517  MutexLock lock_capture(&mutex_capture_);
    518  InitializeLocked();
    519  return kNoError;
    520 }
    521 
    522 int AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) {
    523  // Run in a single-threaded manner during initialization.
    524  MutexLock lock_render(&mutex_render_);
    525  MutexLock lock_capture(&mutex_capture_);
    526  InitializeLocked(processing_config);
    527  return kNoError;
    528 }
    529 
    530 void AudioProcessingImpl::MaybeInitializeRender(
    531    const StreamConfig& input_config,
    532    const StreamConfig& output_config) {
    533  ProcessingConfig processing_config = formats_.api_format;
    534  processing_config.reverse_input_stream() = input_config;
    535  processing_config.reverse_output_stream() = output_config;
    536 
    537  if (processing_config == formats_.api_format) {
    538    return;
    539  }
    540 
    541  MutexLock lock_capture(&mutex_capture_);
    542  InitializeLocked(processing_config);
    543 }
    544 
    545 void AudioProcessingImpl::InitializeLocked() {
    546  UpdateActiveSubmoduleStates();
    547 
    548  const int render_audiobuffer_sample_rate_hz =
    549      formats_.api_format.reverse_output_stream().num_frames() == 0
    550          ? formats_.render_processing_format.sample_rate_hz()
    551          : formats_.api_format.reverse_output_stream().sample_rate_hz();
    552  if (formats_.api_format.reverse_input_stream().num_channels() > 0) {
    553    render_.render_audio.reset(new AudioBuffer(
    554        formats_.api_format.reverse_input_stream().sample_rate_hz(),
    555        formats_.api_format.reverse_input_stream().num_channels(),
    556        formats_.render_processing_format.sample_rate_hz(),
    557        formats_.render_processing_format.num_channels(),
    558        render_audiobuffer_sample_rate_hz,
    559        formats_.render_processing_format.num_channels()));
    560    if (formats_.api_format.reverse_input_stream() !=
    561        formats_.api_format.reverse_output_stream()) {
    562      render_.render_converter = AudioConverter::Create(
    563          formats_.api_format.reverse_input_stream().num_channels(),
    564          formats_.api_format.reverse_input_stream().num_frames(),
    565          formats_.api_format.reverse_output_stream().num_channels(),
    566          formats_.api_format.reverse_output_stream().num_frames());
    567    } else {
    568      render_.render_converter.reset(nullptr);
    569    }
    570  } else {
    571    render_.render_audio.reset(nullptr);
    572    render_.render_converter.reset(nullptr);
    573  }
    574 
    575  capture_.capture_audio.reset(new AudioBuffer(
    576      formats_.api_format.input_stream().sample_rate_hz(),
    577      formats_.api_format.input_stream().num_channels(),
    578      capture_nonlocked_.capture_processing_format.sample_rate_hz(),
    579      formats_.api_format.output_stream().num_channels(),
    580      formats_.api_format.output_stream().sample_rate_hz(),
    581      formats_.api_format.output_stream().num_channels()));
    582  SetDownmixMethod(*capture_.capture_audio,
    583                   config_.pipeline.capture_downmix_method);
    584 
    585  if (capture_nonlocked_.capture_processing_format.sample_rate_hz() <
    586          formats_.api_format.output_stream().sample_rate_hz() &&
    587      formats_.api_format.output_stream().sample_rate_hz() == 48000) {
    588    capture_.capture_fullband_audio.reset(
    589        new AudioBuffer(formats_.api_format.input_stream().sample_rate_hz(),
    590                        formats_.api_format.input_stream().num_channels(),
    591                        formats_.api_format.output_stream().sample_rate_hz(),
    592                        formats_.api_format.output_stream().num_channels(),
    593                        formats_.api_format.output_stream().sample_rate_hz(),
    594                        formats_.api_format.output_stream().num_channels()));
    595    SetDownmixMethod(*capture_.capture_fullband_audio,
    596                     config_.pipeline.capture_downmix_method);
    597  } else {
    598    capture_.capture_fullband_audio.reset();
    599  }
    600 
    601  AllocateRenderQueue();
    602 
    603  InitializeGainController1();
    604  InitializeHighPassFilter(true);
    605  InitializeResidualEchoDetector();
    606  InitializeEchoController();
    607  InitializeGainController2();
    608  InitializeNoiseSuppressor();
    609  InitializeAnalyzer();
    610  InitializePostProcessor();
    611  InitializePreProcessor();
    612  InitializeCaptureLevelsAdjuster();
    613 
    614  if (aec_dump_) {
    615    aec_dump_->WriteInitMessage(formats_.api_format, TimeUTCMillis());
    616  }
    617 }
    618 
    619 void AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) {
    620  UpdateActiveSubmoduleStates();
    621 
    622  formats_.api_format = config;
    623 
    624  // Choose maximum rate to use for the split filtering.
    625  RTC_DCHECK(config_.pipeline.maximum_internal_processing_rate == 48000 ||
    626             config_.pipeline.maximum_internal_processing_rate == 32000);
    627  int max_splitting_rate = 48000;
    628  if (config_.pipeline.maximum_internal_processing_rate == 32000) {
    629    max_splitting_rate = config_.pipeline.maximum_internal_processing_rate;
    630  }
    631 
    632  int capture_processing_rate = SuitableProcessRate(
    633      std::min(formats_.api_format.input_stream().sample_rate_hz(),
    634               formats_.api_format.output_stream().sample_rate_hz()),
    635      max_splitting_rate,
    636      submodule_states_.CaptureMultiBandSubModulesActive() ||
    637          submodule_states_.RenderMultiBandSubModulesActive());
    638  RTC_DCHECK_NE(8000, capture_processing_rate);
    639 
    640  capture_nonlocked_.capture_processing_format =
    641      StreamConfig(capture_processing_rate);
    642 
    643  int render_processing_rate;
    644  if (!capture_nonlocked_.echo_controller_enabled) {
    645    render_processing_rate = SuitableProcessRate(
    646        std::min(formats_.api_format.reverse_input_stream().sample_rate_hz(),
    647                 formats_.api_format.reverse_output_stream().sample_rate_hz()),
    648        max_splitting_rate,
    649        submodule_states_.CaptureMultiBandSubModulesActive() ||
    650            submodule_states_.RenderMultiBandSubModulesActive());
    651  } else {
    652    render_processing_rate = capture_processing_rate;
    653  }
    654 
    655  // If the forward sample rate is 8 kHz, the render stream is also processed
    656  // at this rate.
    657  if (capture_nonlocked_.capture_processing_format.sample_rate_hz() ==
    658      kSampleRate8kHz) {
    659    render_processing_rate = kSampleRate8kHz;
    660  } else {
    661    render_processing_rate =
    662        std::max(render_processing_rate, static_cast<int>(kSampleRate16kHz));
    663  }
    664 
    665  RTC_DCHECK_NE(8000, render_processing_rate);
    666 
    667  if (submodule_states_.RenderMultiBandSubModulesActive()) {
    668    // By default, downmix the render stream to mono for analysis. This has been
    669    // demonstrated to work well for AEC in most practical scenarios.
    670    const bool multi_channel_render = config_.pipeline.multi_channel_render &&
    671                                      constants_.multi_channel_render_support;
    672    int render_processing_num_channels =
    673        multi_channel_render
    674            ? formats_.api_format.reverse_input_stream().num_channels()
    675            : 1;
    676    formats_.render_processing_format =
    677        StreamConfig(render_processing_rate, render_processing_num_channels);
    678  } else {
    679    formats_.render_processing_format = StreamConfig(
    680        formats_.api_format.reverse_input_stream().sample_rate_hz(),
    681        formats_.api_format.reverse_input_stream().num_channels());
    682  }
    683 
    684  if (capture_nonlocked_.capture_processing_format.sample_rate_hz() ==
    685          kSampleRate32kHz ||
    686      capture_nonlocked_.capture_processing_format.sample_rate_hz() ==
    687          kSampleRate48kHz) {
    688    capture_nonlocked_.split_rate = kSampleRate16kHz;
    689  } else {
    690    capture_nonlocked_.split_rate =
    691        capture_nonlocked_.capture_processing_format.sample_rate_hz();
    692  }
    693 
    694  InitializeLocked();
    695 }
    696 
    697 void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
    698  // Run in a single-threaded manner when applying the settings.
    699  MutexLock lock_render(&mutex_render_);
    700  MutexLock lock_capture(&mutex_capture_);
    701 
    702  RTC_LOG(LS_INFO) << "AudioProcessing::ApplyConfig: " << config.ToString();
    703 
    704  const bool pipeline_config_changed =
    705      config_.pipeline.multi_channel_render !=
    706          config.pipeline.multi_channel_render ||
    707      config_.pipeline.multi_channel_capture !=
    708          config.pipeline.multi_channel_capture ||
    709      config_.pipeline.maximum_internal_processing_rate !=
    710          config.pipeline.maximum_internal_processing_rate ||
    711      config_.pipeline.capture_downmix_method !=
    712          config.pipeline.capture_downmix_method;
    713 
    714  const bool aec_config_changed =
    715      config_.echo_canceller.enabled != config.echo_canceller.enabled ||
    716      config_.echo_canceller.mobile_mode != config.echo_canceller.mobile_mode;
    717 
    718  const bool agc1_config_changed =
    719      config_.gain_controller1 != config.gain_controller1;
    720 
    721  const bool agc2_config_changed =
    722      config_.gain_controller2 != config.gain_controller2;
    723 
    724  const bool ns_config_changed =
    725      config_.noise_suppression.enabled != config.noise_suppression.enabled ||
    726      config_.noise_suppression.level != config.noise_suppression.level;
    727 
    728  const bool pre_amplifier_config_changed =
    729      config_.pre_amplifier.enabled != config.pre_amplifier.enabled ||
    730      config_.pre_amplifier.fixed_gain_factor !=
    731          config.pre_amplifier.fixed_gain_factor;
    732 
    733  const bool gain_adjustment_config_changed =
    734      config_.capture_level_adjustment != config.capture_level_adjustment;
    735 
    736  config_ = config;
    737 
    738  if (aec_config_changed) {
    739    InitializeEchoController();
    740  }
    741 
    742  if (ns_config_changed) {
    743    InitializeNoiseSuppressor();
    744  }
    745 
    746  InitializeHighPassFilter(false);
    747 
    748  if (agc1_config_changed) {
    749    InitializeGainController1();
    750  }
    751 
    752  const bool config_ok = GainController2::Validate(config_.gain_controller2);
    753  if (!config_ok) {
    754    RTC_LOG(LS_ERROR)
    755        << "Invalid Gain Controller 2 config; using the default config.";
    756    config_.gain_controller2 = AudioProcessing::Config::GainController2();
    757  }
    758 
    759  if (agc2_config_changed) {
    760    InitializeGainController2();
    761  }
    762 
    763  if (pre_amplifier_config_changed || gain_adjustment_config_changed) {
    764    InitializeCaptureLevelsAdjuster();
    765  }
    766 
    767  // Reinitialization must happen after all submodule configuration to avoid
    768  // additional reinitializations on the next capture / render processing call.
    769  if (pipeline_config_changed) {
    770    InitializeLocked(formats_.api_format);
    771  }
    772 }
    773 
    774 int AudioProcessingImpl::proc_sample_rate_hz() const {
    775  // Used as callback from submodules, hence locking is not allowed.
    776  return capture_nonlocked_.capture_processing_format.sample_rate_hz();
    777 }
    778 
    779 int AudioProcessingImpl::proc_fullband_sample_rate_hz() const {
    780  return capture_.capture_fullband_audio
    781             ? capture_.capture_fullband_audio->num_frames() * 100
    782             : capture_nonlocked_.capture_processing_format.sample_rate_hz();
    783 }
    784 
    785 int AudioProcessingImpl::proc_split_sample_rate_hz() const {
    786  // Used as callback from submodules, hence locking is not allowed.
    787  return capture_nonlocked_.split_rate;
    788 }
    789 
    790 size_t AudioProcessingImpl::num_reverse_channels() const {
    791  // Used as callback from submodules, hence locking is not allowed.
    792  return formats_.render_processing_format.num_channels();
    793 }
    794 
    795 size_t AudioProcessingImpl::num_input_channels() const {
    796  // Used as callback from submodules, hence locking is not allowed.
    797  return formats_.api_format.input_stream().num_channels();
    798 }
    799 
    800 size_t AudioProcessingImpl::num_proc_channels() const {
    801  // Used as callback from submodules, hence locking is not allowed.
    802  const bool multi_channel_capture = config_.pipeline.multi_channel_capture &&
    803                                     constants_.multi_channel_capture_support;
    804  if (capture_nonlocked_.echo_controller_enabled && !multi_channel_capture) {
    805    return 1;
    806  }
    807  return num_output_channels();
    808 }
    809 
    810 size_t AudioProcessingImpl::num_output_channels() const {
    811  // Used as callback from submodules, hence locking is not allowed.
    812  return formats_.api_format.output_stream().num_channels();
    813 }
    814 
    815 void AudioProcessingImpl::set_output_will_be_muted(bool muted) {
    816  MutexLock lock(&mutex_capture_);
    817  HandleCaptureOutputUsedSetting(!muted);
    818 }
    819 
    820 void AudioProcessingImpl::HandleCaptureOutputUsedSetting(
    821    bool capture_output_used) {
    822  capture_.capture_output_used =
    823      capture_output_used || !constants_.minimize_processing_for_unused_output;
    824 
    825  if (submodules_.agc_manager) {
    826    submodules_.agc_manager->HandleCaptureOutputUsedChange(
    827        capture_.capture_output_used);
    828  }
    829  if (submodules_.echo_controller) {
    830    submodules_.echo_controller->SetCaptureOutputUsage(
    831        capture_.capture_output_used);
    832  }
    833  if (submodules_.noise_suppressor) {
    834    submodules_.noise_suppressor->SetCaptureOutputUsage(
    835        capture_.capture_output_used);
    836  }
    837  if (submodules_.gain_controller2) {
    838    submodules_.gain_controller2->SetCaptureOutputUsed(
    839        capture_.capture_output_used);
    840  }
    841 }
    842 
    843 void AudioProcessingImpl::SetRuntimeSetting(RuntimeSetting setting) {
    844  PostRuntimeSetting(setting);
    845 }
    846 
    847 bool AudioProcessingImpl::PostRuntimeSetting(RuntimeSetting setting) {
    848  switch (setting.type()) {
    849    case RuntimeSetting::Type::kCustomRenderProcessingRuntimeSetting:
    850    case RuntimeSetting::Type::kPlayoutAudioDeviceChange:
    851      return render_runtime_settings_enqueuer_.Enqueue(setting);
    852    case RuntimeSetting::Type::kCapturePreGain:
    853    case RuntimeSetting::Type::kCapturePostGain:
    854    case RuntimeSetting::Type::kCaptureCompressionGain:
    855    case RuntimeSetting::Type::kCaptureFixedPostGain:
    856    case RuntimeSetting::Type::kCaptureOutputUsed:
    857      return capture_runtime_settings_enqueuer_.Enqueue(setting);
    858    case RuntimeSetting::Type::kPlayoutVolumeChange: {
    859      bool enqueueing_successful;
    860      enqueueing_successful =
    861          capture_runtime_settings_enqueuer_.Enqueue(setting);
    862      enqueueing_successful =
    863          render_runtime_settings_enqueuer_.Enqueue(setting) &&
    864          enqueueing_successful;
    865      return enqueueing_successful;
    866    }
    867    case RuntimeSetting::Type::kNotSpecified:
    868      RTC_DCHECK_NOTREACHED();
    869      return true;
    870  }
    871  // The language allows the enum to have a non-enumerator
    872  // value. Check that this doesn't happen.
    873  RTC_DCHECK_NOTREACHED();
    874  return true;
    875 }
    876 
    877 AudioProcessingImpl::RuntimeSettingEnqueuer::RuntimeSettingEnqueuer(
    878    SwapQueue<RuntimeSetting>* runtime_settings)
    879    : runtime_settings_(*runtime_settings) {
    880  RTC_DCHECK(runtime_settings);
    881 }
    882 
    883 AudioProcessingImpl::RuntimeSettingEnqueuer::~RuntimeSettingEnqueuer() =
    884    default;
    885 
    886 bool AudioProcessingImpl::RuntimeSettingEnqueuer::Enqueue(
    887    RuntimeSetting setting) {
    888  const bool successful_insert = runtime_settings_.Insert(&setting);
    889 
    890  if (!successful_insert) {
    891    RTC_LOG(LS_ERROR) << "Cannot enqueue a new runtime setting.";
    892  }
    893  return successful_insert;
    894 }
    895 
    896 void AudioProcessingImpl::MaybeInitializeCapture(
    897    const StreamConfig& input_config,
    898    const StreamConfig& output_config) {
    899  ProcessingConfig processing_config;
    900  bool reinitialization_required = false;
    901  {
    902    // Acquire the capture lock in order to access api_format. The lock is
    903    // released immediately, as we may need to acquire the render lock as part
    904    // of the conditional reinitialization.
    905    MutexLock lock_capture(&mutex_capture_);
    906    processing_config = formats_.api_format;
    907    reinitialization_required = UpdateActiveSubmoduleStates();
    908  }
    909 
    910  if (processing_config.input_stream() != input_config) {
    911    reinitialization_required = true;
    912  }
    913 
    914  if (processing_config.output_stream() != output_config) {
    915    reinitialization_required = true;
    916  }
    917 
    918  if (reinitialization_required) {
    919    MutexLock lock_render(&mutex_render_);
    920    MutexLock lock_capture(&mutex_capture_);
    921    // Reread the API format since the render format may have changed.
    922    processing_config = formats_.api_format;
    923    processing_config.input_stream() = input_config;
    924    processing_config.output_stream() = output_config;
    925    InitializeLocked(processing_config);
    926  }
    927 }
    928 
    929 int AudioProcessingImpl::ProcessStream(const float* const* src,
    930                                       const StreamConfig& input_config,
    931                                       const StreamConfig& output_config,
    932                                       float* const* dest) {
    933  TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_StreamConfig");
    934  DenormalDisabler denormal_disabler;
    935  RETURN_ON_ERR(
    936      HandleUnsupportedAudioFormats(src, input_config, output_config, dest));
    937  MaybeInitializeCapture(input_config, output_config);
    938 
    939  MutexLock lock_capture(&mutex_capture_);
    940 
    941  if (aec_dump_) {
    942    RecordUnprocessedCaptureStream(src);
    943  }
    944 
    945  capture_.capture_audio->CopyFrom(src, formats_.api_format.input_stream());
    946  if (capture_.capture_fullband_audio) {
    947    capture_.capture_fullband_audio->CopyFrom(
    948        src, formats_.api_format.input_stream());
    949  }
    950  RETURN_ON_ERR(ProcessCaptureStreamLocked());
    951  if (capture_.capture_fullband_audio) {
    952    capture_.capture_fullband_audio->CopyTo(formats_.api_format.output_stream(),
    953                                            dest);
    954  } else {
    955    capture_.capture_audio->CopyTo(formats_.api_format.output_stream(), dest);
    956  }
    957 
    958  if (aec_dump_) {
    959    RecordProcessedCaptureStream(dest);
    960  }
    961  return kNoError;
    962 }
    963 
    964 void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
    965  RuntimeSetting setting;
    966  int num_settings_processed = 0;
    967  while (capture_runtime_settings_.Remove(&setting)) {
    968    if (aec_dump_) {
    969      aec_dump_->WriteRuntimeSetting(setting);
    970    }
    971    switch (setting.type()) {
    972      case RuntimeSetting::Type::kCapturePreGain:
    973        if (config_.pre_amplifier.enabled ||
    974            config_.capture_level_adjustment.enabled) {
    975          float value;
    976          setting.GetFloat(&value);
    977          // If the pre-amplifier is used, apply the new gain to the
    978          // pre-amplifier regardless if the capture level adjustment is
    979          // activated. This approach allows both functionalities to coexist
    980          // until they have been properly merged.
    981          if (config_.pre_amplifier.enabled) {
    982            config_.pre_amplifier.fixed_gain_factor = value;
    983          } else {
    984            config_.capture_level_adjustment.pre_gain_factor = value;
    985          }
    986 
    987          // Use both the pre-amplifier and the capture level adjustment gains
    988          // as pre-gains.
    989          float gain = 1.f;
    990          if (config_.pre_amplifier.enabled) {
    991            gain *= config_.pre_amplifier.fixed_gain_factor;
    992          }
    993          if (config_.capture_level_adjustment.enabled) {
    994            gain *= config_.capture_level_adjustment.pre_gain_factor;
    995          }
    996 
    997          submodules_.capture_levels_adjuster->SetPreGain(gain);
    998        }
    999        // TODO(bugs.chromium.org/9138): Log setting handling by Aec Dump.
   1000        break;
   1001      case RuntimeSetting::Type::kCapturePostGain:
   1002        if (config_.capture_level_adjustment.enabled) {
   1003          float value;
   1004          setting.GetFloat(&value);
   1005          config_.capture_level_adjustment.post_gain_factor = value;
   1006          submodules_.capture_levels_adjuster->SetPostGain(
   1007              config_.capture_level_adjustment.post_gain_factor);
   1008        }
   1009        // TODO(bugs.chromium.org/9138): Log setting handling by Aec Dump.
   1010        break;
   1011      case RuntimeSetting::Type::kCaptureCompressionGain: {
   1012        if (!submodules_.agc_manager &&
   1013            !(submodules_.gain_controller2 &&
   1014              config_.gain_controller2.input_volume_controller.enabled)) {
   1015          float value;
   1016          setting.GetFloat(&value);
   1017          int int_value = static_cast<int>(value + .5f);
   1018          config_.gain_controller1.compression_gain_db = int_value;
   1019          if (submodules_.gain_control) {
   1020            int error =
   1021                submodules_.gain_control->set_compression_gain_db(int_value);
   1022            RTC_DCHECK_EQ(kNoError, error);
   1023          }
   1024        }
   1025        break;
   1026      }
   1027      case RuntimeSetting::Type::kCaptureFixedPostGain: {
   1028        if (submodules_.gain_controller2) {
   1029          float value;
   1030          setting.GetFloat(&value);
   1031          config_.gain_controller2.fixed_digital.gain_db = value;
   1032          submodules_.gain_controller2->SetFixedGainDb(value);
   1033        }
   1034        break;
   1035      }
   1036      case RuntimeSetting::Type::kPlayoutVolumeChange: {
   1037        int value;
   1038        setting.GetInt(&value);
   1039        capture_.playout_volume = value;
   1040        break;
   1041      }
   1042      case RuntimeSetting::Type::kPlayoutAudioDeviceChange:
   1043        RTC_DCHECK_NOTREACHED();
   1044        break;
   1045      case RuntimeSetting::Type::kCustomRenderProcessingRuntimeSetting:
   1046        RTC_DCHECK_NOTREACHED();
   1047        break;
   1048      case RuntimeSetting::Type::kNotSpecified:
   1049        RTC_DCHECK_NOTREACHED();
   1050        break;
   1051      case RuntimeSetting::Type::kCaptureOutputUsed:
   1052        bool value;
   1053        setting.GetBool(&value);
   1054        HandleCaptureOutputUsedSetting(value);
   1055        break;
   1056    }
   1057    ++num_settings_processed;
   1058  }
   1059 
   1060  if (num_settings_processed >= RuntimeSettingQueueSize()) {
   1061    // Handle overrun of the runtime settings queue, which likely will has
   1062    // caused settings to be discarded.
   1063    HandleOverrunInCaptureRuntimeSettingsQueue();
   1064  }
   1065 }
   1066 
   1067 void AudioProcessingImpl::HandleOverrunInCaptureRuntimeSettingsQueue() {
   1068  // Fall back to a safe state for the case when a setting for capture output
   1069  // usage setting has been missed.
   1070  HandleCaptureOutputUsedSetting(/*capture_output_used=*/true);
   1071 }
   1072 
   1073 void AudioProcessingImpl::HandleRenderRuntimeSettings() {
   1074  RuntimeSetting setting;
   1075  while (render_runtime_settings_.Remove(&setting)) {
   1076    if (aec_dump_) {
   1077      aec_dump_->WriteRuntimeSetting(setting);
   1078    }
   1079    switch (setting.type()) {
   1080      case RuntimeSetting::Type::kPlayoutAudioDeviceChange:  // fall-through
   1081      case RuntimeSetting::Type::kPlayoutVolumeChange:       // fall-through
   1082      case RuntimeSetting::Type::kCustomRenderProcessingRuntimeSetting:
   1083        if (submodules_.render_pre_processor) {
   1084          submodules_.render_pre_processor->SetRuntimeSetting(setting);
   1085        }
   1086        break;
   1087      case RuntimeSetting::Type::kCapturePreGain:          // fall-through
   1088      case RuntimeSetting::Type::kCapturePostGain:         // fall-through
   1089      case RuntimeSetting::Type::kCaptureCompressionGain:  // fall-through
   1090      case RuntimeSetting::Type::kCaptureFixedPostGain:    // fall-through
   1091      case RuntimeSetting::Type::kCaptureOutputUsed:       // fall-through
   1092      case RuntimeSetting::Type::kNotSpecified:
   1093        RTC_DCHECK_NOTREACHED();
   1094        break;
   1095    }
   1096  }
   1097 }
   1098 
   1099 void AudioProcessingImpl::QueueBandedRenderAudio(AudioBuffer* audio) {
   1100  RTC_DCHECK_GE(160, audio->num_frames_per_band());
   1101 
   1102  if (submodules_.echo_control_mobile) {
   1103    EchoControlMobileImpl::PackRenderAudioBuffer(audio, num_output_channels(),
   1104                                                 num_reverse_channels(),
   1105                                                 &aecm_render_queue_buffer_);
   1106    RTC_DCHECK(aecm_render_signal_queue_);
   1107    // Insert the samples into the queue.
   1108    if (!aecm_render_signal_queue_->Insert(&aecm_render_queue_buffer_)) {
   1109      // The data queue is full and needs to be emptied.
   1110      EmptyQueuedRenderAudio();
   1111 
   1112      // Retry the insert (should always work).
   1113      bool result =
   1114          aecm_render_signal_queue_->Insert(&aecm_render_queue_buffer_);
   1115      RTC_DCHECK(result);
   1116    }
   1117  }
   1118 
   1119  if (!submodules_.agc_manager && submodules_.gain_control) {
   1120    GainControlImpl::PackRenderAudioBuffer(*audio, &agc_render_queue_buffer_);
   1121    // Insert the samples into the queue.
   1122    if (!agc_render_signal_queue_->Insert(&agc_render_queue_buffer_)) {
   1123      // The data queue is full and needs to be emptied.
   1124      EmptyQueuedRenderAudio();
   1125 
   1126      // Retry the insert (should always work).
   1127      bool result = agc_render_signal_queue_->Insert(&agc_render_queue_buffer_);
   1128      RTC_DCHECK(result);
   1129    }
   1130  }
   1131 }
   1132 
   1133 void AudioProcessingImpl::QueueNonbandedRenderAudio(AudioBuffer* audio) {
   1134  if (submodules_.echo_detector) {
   1135    PackRenderAudioBufferForEchoDetector(*audio, red_render_queue_buffer_);
   1136    RTC_DCHECK(red_render_signal_queue_);
   1137    // Insert the samples into the queue.
   1138    if (!red_render_signal_queue_->Insert(&red_render_queue_buffer_)) {
   1139      // The data queue is full and needs to be emptied.
   1140      EmptyQueuedRenderAudio();
   1141 
   1142      // Retry the insert (should always work).
   1143      bool result = red_render_signal_queue_->Insert(&red_render_queue_buffer_);
   1144      RTC_DCHECK(result);
   1145    }
   1146  }
   1147 }
   1148 
   1149 void AudioProcessingImpl::AllocateRenderQueue() {
   1150  const size_t new_agc_render_queue_element_max_size =
   1151      std::max(static_cast<size_t>(1), kMaxAllowedValuesOfSamplesPerBand);
   1152 
   1153  const size_t new_red_render_queue_element_max_size =
   1154      std::max(static_cast<size_t>(1), kMaxAllowedValuesOfSamplesPerFrame);
   1155 
   1156  // Reallocate the queues if the queue item sizes are too small to fit the
   1157  // data to put in the queues.
   1158 
   1159  if (agc_render_queue_element_max_size_ <
   1160      new_agc_render_queue_element_max_size) {
   1161    agc_render_queue_element_max_size_ = new_agc_render_queue_element_max_size;
   1162 
   1163    std::vector<int16_t> template_queue_element(
   1164        agc_render_queue_element_max_size_);
   1165 
   1166    agc_render_signal_queue_.reset(
   1167        new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>(
   1168            kMaxNumFramesToBuffer, template_queue_element,
   1169            RenderQueueItemVerifier<int16_t>(
   1170                agc_render_queue_element_max_size_)));
   1171 
   1172    agc_render_queue_buffer_.resize(agc_render_queue_element_max_size_);
   1173    agc_capture_queue_buffer_.resize(agc_render_queue_element_max_size_);
   1174  } else {
   1175    agc_render_signal_queue_->Clear();
   1176  }
   1177 
   1178  if (submodules_.echo_detector) {
   1179    if (red_render_queue_element_max_size_ <
   1180        new_red_render_queue_element_max_size) {
   1181      red_render_queue_element_max_size_ =
   1182          new_red_render_queue_element_max_size;
   1183 
   1184      std::vector<float> template_queue_element(
   1185          red_render_queue_element_max_size_);
   1186 
   1187      red_render_signal_queue_.reset(
   1188          new SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>(
   1189              kMaxNumFramesToBuffer, template_queue_element,
   1190              RenderQueueItemVerifier<float>(
   1191                  red_render_queue_element_max_size_)));
   1192 
   1193      red_render_queue_buffer_.resize(red_render_queue_element_max_size_);
   1194      red_capture_queue_buffer_.resize(red_render_queue_element_max_size_);
   1195    } else {
   1196      red_render_signal_queue_->Clear();
   1197    }
   1198  }
   1199 }
   1200 
   1201 void AudioProcessingImpl::EmptyQueuedRenderAudio() {
   1202  MutexLock lock_capture(&mutex_capture_);
   1203  EmptyQueuedRenderAudioLocked();
   1204 }
   1205 
   1206 void AudioProcessingImpl::EmptyQueuedRenderAudioLocked() {
   1207  if (submodules_.echo_control_mobile) {
   1208    RTC_DCHECK(aecm_render_signal_queue_);
   1209    while (aecm_render_signal_queue_->Remove(&aecm_capture_queue_buffer_)) {
   1210      submodules_.echo_control_mobile->ProcessRenderAudio(
   1211          aecm_capture_queue_buffer_);
   1212    }
   1213  }
   1214 
   1215  if (submodules_.gain_control) {
   1216    while (agc_render_signal_queue_->Remove(&agc_capture_queue_buffer_)) {
   1217      submodules_.gain_control->ProcessRenderAudio(agc_capture_queue_buffer_);
   1218    }
   1219  }
   1220 
   1221  if (submodules_.echo_detector) {
   1222    while (red_render_signal_queue_->Remove(&red_capture_queue_buffer_)) {
   1223      submodules_.echo_detector->AnalyzeRenderAudio(red_capture_queue_buffer_);
   1224    }
   1225  }
   1226 }
   1227 
   1228 int AudioProcessingImpl::ProcessStream(const int16_t* const src,
   1229                                       const StreamConfig& input_config,
   1230                                       const StreamConfig& output_config,
   1231                                       int16_t* const dest) {
   1232  TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_AudioFrame");
   1233 
   1234  RETURN_ON_ERR(
   1235      HandleUnsupportedAudioFormats(src, input_config, output_config, dest));
   1236  MaybeInitializeCapture(input_config, output_config);
   1237 
   1238  MutexLock lock_capture(&mutex_capture_);
   1239  DenormalDisabler denormal_disabler;
   1240 
   1241  if (aec_dump_) {
   1242    RecordUnprocessedCaptureStream(src, input_config);
   1243  }
   1244 
   1245  capture_.capture_audio->CopyFrom(src, input_config);
   1246  if (capture_.capture_fullband_audio) {
   1247    capture_.capture_fullband_audio->CopyFrom(src, input_config);
   1248  }
   1249  RETURN_ON_ERR(ProcessCaptureStreamLocked());
   1250  if (submodule_states_.CaptureMultiBandProcessingPresent() ||
   1251      submodule_states_.CaptureFullBandProcessingActive()) {
   1252    if (capture_.capture_fullband_audio) {
   1253      capture_.capture_fullband_audio->CopyTo(output_config, dest);
   1254    } else {
   1255      capture_.capture_audio->CopyTo(output_config, dest);
   1256    }
   1257  }
   1258 
   1259  if (aec_dump_) {
   1260    RecordProcessedCaptureStream(dest, output_config);
   1261  }
   1262  return kNoError;
   1263 }
   1264 
   1265 int AudioProcessingImpl::ProcessCaptureStreamLocked() {
   1266  EmptyQueuedRenderAudioLocked();
   1267  HandleCaptureRuntimeSettings();
   1268  DenormalDisabler denormal_disabler;
   1269 
   1270  // Ensure that not both the AEC and AECM are active at the same time.
   1271  // TODO(peah): Simplify once the public API Enable functions for these
   1272  // are moved to APM.
   1273  RTC_DCHECK_LE(
   1274      !!submodules_.echo_controller + !!submodules_.echo_control_mobile, 1);
   1275 
   1276  data_dumper_->DumpRaw(
   1277      "applied_input_volume",
   1278      capture_.applied_input_volume.value_or(kUnspecifiedDataDumpInputVolume));
   1279 
   1280  AudioBuffer* capture_buffer = capture_.capture_audio.get();  // For brevity.
   1281  AudioBuffer* linear_aec_buffer = capture_.linear_aec_output.get();
   1282 
   1283  if (submodules_.high_pass_filter &&
   1284      config_.high_pass_filter.apply_in_full_band &&
   1285      !constants_.enforce_split_band_hpf) {
   1286    submodules_.high_pass_filter->Process(capture_buffer,
   1287                                          /*use_split_band_data=*/false);
   1288  }
   1289 
   1290  if (submodules_.capture_levels_adjuster) {
   1291    if (config_.capture_level_adjustment.analog_mic_gain_emulation.enabled) {
   1292      // When the input volume is emulated, retrieve the volume applied to the
   1293      // input audio and notify that to APM so that the volume is passed to the
   1294      // active AGC.
   1295      set_stream_analog_level_locked(
   1296          submodules_.capture_levels_adjuster->GetAnalogMicGainLevel());
   1297    }
   1298    submodules_.capture_levels_adjuster->ApplyPreLevelAdjustment(
   1299        *capture_buffer);
   1300  }
   1301 
   1302  capture_input_rms_.Analyze(ArrayView<const float>(
   1303      capture_buffer->channels_const()[0],
   1304      capture_nonlocked_.capture_processing_format.num_frames()));
   1305  const bool log_rms = ++capture_rms_interval_counter_ >= 1000;
   1306  if (log_rms) {
   1307    capture_rms_interval_counter_ = 0;
   1308    RmsLevel::Levels levels = capture_input_rms_.AverageAndPeak();
   1309    RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureInputLevelAverageRms",
   1310                                levels.average, 1, RmsLevel::kMinLevelDb, 64);
   1311    RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureInputLevelPeakRms",
   1312                                levels.peak, 1, RmsLevel::kMinLevelDb, 64);
   1313  }
   1314 
   1315  if (capture_.applied_input_volume.has_value()) {
   1316    applied_input_volume_stats_reporter_.UpdateStatistics(
   1317        *capture_.applied_input_volume);
   1318  }
   1319 
   1320  if (submodules_.echo_controller) {
   1321    // Determine if the echo path gain has changed by checking all the gains
   1322    // applied before AEC.
   1323    capture_.echo_path_gain_change = capture_.applied_input_volume_changed;
   1324 
   1325    // Detect and flag any change in the capture level adjustment pre-gain.
   1326    if (submodules_.capture_levels_adjuster) {
   1327      float pre_adjustment_gain =
   1328          submodules_.capture_levels_adjuster->GetPreAdjustmentGain();
   1329      capture_.echo_path_gain_change =
   1330          capture_.echo_path_gain_change ||
   1331          (capture_.prev_pre_adjustment_gain != pre_adjustment_gain &&
   1332           capture_.prev_pre_adjustment_gain >= 0.0f);
   1333      capture_.prev_pre_adjustment_gain = pre_adjustment_gain;
   1334    }
   1335 
   1336    // Detect volume change.
   1337    capture_.echo_path_gain_change =
   1338        capture_.echo_path_gain_change ||
   1339        (capture_.prev_playout_volume != capture_.playout_volume &&
   1340         capture_.prev_playout_volume >= 0);
   1341    capture_.prev_playout_volume = capture_.playout_volume;
   1342 
   1343    submodules_.echo_controller->AnalyzeCapture(capture_buffer);
   1344  }
   1345 
   1346  if (submodules_.agc_manager) {
   1347    submodules_.agc_manager->AnalyzePreProcess(*capture_buffer);
   1348  }
   1349 
   1350  if (submodules_.gain_controller2 &&
   1351      config_.gain_controller2.input_volume_controller.enabled) {
   1352    // Expect the volume to be available if the input controller is enabled.
   1353    RTC_DCHECK(capture_.applied_input_volume.has_value());
   1354    if (capture_.applied_input_volume.has_value()) {
   1355      submodules_.gain_controller2->Analyze(*capture_.applied_input_volume,
   1356                                            *capture_buffer);
   1357    }
   1358  }
   1359 
   1360  if (submodule_states_.CaptureMultiBandSubModulesActive() &&
   1361      SampleRateSupportsMultiBand(
   1362          capture_nonlocked_.capture_processing_format.sample_rate_hz())) {
   1363    capture_buffer->SplitIntoFrequencyBands();
   1364  }
   1365 
   1366  const bool multi_channel_capture = config_.pipeline.multi_channel_capture &&
   1367                                     constants_.multi_channel_capture_support;
   1368  if (submodules_.echo_controller && !multi_channel_capture) {
   1369    // Force down-mixing of the number of channels after the detection of
   1370    // capture signal saturation.
   1371    // TODO(peah): Look into ensuring that this kind of tampering with the
   1372    // AudioBuffer functionality should not be needed.
   1373    capture_buffer->set_num_channels(1);
   1374  }
   1375 
   1376  if (submodules_.high_pass_filter &&
   1377      (!config_.high_pass_filter.apply_in_full_band ||
   1378       constants_.enforce_split_band_hpf)) {
   1379    submodules_.high_pass_filter->Process(capture_buffer,
   1380                                          /*use_split_band_data=*/true);
   1381  }
   1382 
   1383  if (submodules_.gain_control) {
   1384    RETURN_ON_ERR(
   1385        submodules_.gain_control->AnalyzeCaptureAudio(*capture_buffer));
   1386  }
   1387 
   1388  if ((!config_.noise_suppression.analyze_linear_aec_output_when_available ||
   1389       !linear_aec_buffer || submodules_.echo_control_mobile) &&
   1390      submodules_.noise_suppressor) {
   1391    submodules_.noise_suppressor->Analyze(*capture_buffer);
   1392  }
   1393 
   1394  if (submodules_.echo_control_mobile) {
   1395    // Ensure that the stream delay was set before the call to the
   1396    // AECM ProcessCaptureAudio function.
   1397    if (!capture_.was_stream_delay_set) {
   1398      return AudioProcessing::kStreamParameterNotSetError;
   1399    }
   1400 
   1401    if (submodules_.noise_suppressor) {
   1402      submodules_.noise_suppressor->Process(capture_buffer);
   1403    }
   1404 
   1405    RETURN_ON_ERR(submodules_.echo_control_mobile->ProcessCaptureAudio(
   1406        capture_buffer, stream_delay_ms()));
   1407  } else {
   1408    if (submodules_.echo_controller) {
   1409      data_dumper_->DumpRaw("stream_delay", stream_delay_ms());
   1410 
   1411      if (capture_.was_stream_delay_set) {
   1412        submodules_.echo_controller->SetAudioBufferDelay(stream_delay_ms());
   1413      }
   1414 
   1415      submodules_.echo_controller->ProcessCapture(
   1416          capture_buffer, linear_aec_buffer, capture_.echo_path_gain_change);
   1417    }
   1418 
   1419    if (config_.noise_suppression.analyze_linear_aec_output_when_available &&
   1420        linear_aec_buffer && submodules_.noise_suppressor) {
   1421      submodules_.noise_suppressor->Analyze(*linear_aec_buffer);
   1422    }
   1423 
   1424    if (submodules_.noise_suppressor) {
   1425      submodules_.noise_suppressor->Process(capture_buffer);
   1426    }
   1427  }
   1428 
   1429  if (submodules_.agc_manager) {
   1430    submodules_.agc_manager->Process(*capture_buffer);
   1431 
   1432    std::optional<int> new_digital_gain =
   1433        submodules_.agc_manager->GetDigitalComressionGain();
   1434    if (new_digital_gain && submodules_.gain_control) {
   1435      submodules_.gain_control->set_compression_gain_db(*new_digital_gain);
   1436    }
   1437  }
   1438 
   1439  if (submodules_.gain_control) {
   1440    // TODO(peah): Add reporting from AEC3 whether there is echo.
   1441    RETURN_ON_ERR(submodules_.gain_control->ProcessCaptureAudio(
   1442        capture_buffer, /*stream_has_echo*/ false));
   1443  }
   1444 
   1445  if (submodule_states_.CaptureMultiBandProcessingPresent() &&
   1446      SampleRateSupportsMultiBand(
   1447          capture_nonlocked_.capture_processing_format.sample_rate_hz())) {
   1448    capture_buffer->MergeFrequencyBands();
   1449  }
   1450 
   1451  if (capture_.capture_output_used) {
   1452    if (capture_.capture_fullband_audio) {
   1453      const auto& ec = submodules_.echo_controller;
   1454      bool ec_active = ec ? ec->ActiveProcessing() : false;
   1455      // Only update the fullband buffer if the multiband processing has changed
   1456      // the signal. Keep the original signal otherwise.
   1457      if (submodule_states_.CaptureMultiBandProcessingActive(ec_active)) {
   1458        capture_buffer->CopyTo(capture_.capture_fullband_audio.get());
   1459      }
   1460      capture_buffer = capture_.capture_fullband_audio.get();
   1461    }
   1462 
   1463    if (submodules_.echo_detector) {
   1464      submodules_.echo_detector->AnalyzeCaptureAudio(ArrayView<const float>(
   1465          capture_buffer->channels()[0], capture_buffer->num_frames()));
   1466    }
   1467 
   1468    // Experimental APM sub-module that analyzes `capture_buffer`.
   1469    if (submodules_.capture_analyzer) {
   1470      submodules_.capture_analyzer->Analyze(capture_buffer);
   1471    }
   1472 
   1473    if (submodules_.gain_controller2) {
   1474      // TODO(bugs.webrtc.org/7494): Let AGC2 detect applied input volume
   1475      // changes.
   1476      submodules_.gain_controller2->Process(
   1477          /*speech_probability=*/std::nullopt,
   1478          capture_.applied_input_volume_changed, capture_buffer);
   1479    }
   1480 
   1481    if (submodules_.post_filter) {
   1482      submodules_.post_filter->Process(*capture_buffer);
   1483    }
   1484 
   1485    if (submodules_.capture_post_processor) {
   1486      submodules_.capture_post_processor->Process(capture_buffer);
   1487    }
   1488 
   1489    capture_output_rms_.Analyze(ArrayView<const float>(
   1490        capture_buffer->channels_const()[0],
   1491        capture_nonlocked_.capture_processing_format.num_frames()));
   1492    if (log_rms) {
   1493      RmsLevel::Levels levels = capture_output_rms_.AverageAndPeak();
   1494      RTC_HISTOGRAM_COUNTS_LINEAR(
   1495          "WebRTC.Audio.ApmCaptureOutputLevelAverageRms", levels.average, 1,
   1496          RmsLevel::kMinLevelDb, 64);
   1497      RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.ApmCaptureOutputLevelPeakRms",
   1498                                  levels.peak, 1, RmsLevel::kMinLevelDb, 64);
   1499    }
   1500 
   1501    // Compute echo-detector stats.
   1502    if (submodules_.echo_detector) {
   1503      auto ed_metrics = submodules_.echo_detector->GetMetrics();
   1504      capture_.stats.residual_echo_likelihood = ed_metrics.echo_likelihood;
   1505      capture_.stats.residual_echo_likelihood_recent_max =
   1506          ed_metrics.echo_likelihood_recent_max;
   1507    }
   1508  }
   1509 
   1510  // Compute echo-controller stats.
   1511  if (submodules_.echo_controller) {
   1512    auto ec_metrics = submodules_.echo_controller->GetMetrics();
   1513    capture_.stats.echo_return_loss = ec_metrics.echo_return_loss;
   1514    capture_.stats.echo_return_loss_enhancement =
   1515        ec_metrics.echo_return_loss_enhancement;
   1516    capture_.stats.delay_ms = ec_metrics.delay_ms;
   1517  }
   1518 
   1519  // Pass stats for reporting.
   1520  stats_reporter_.UpdateStatistics(capture_.stats);
   1521 
   1522  UpdateRecommendedInputVolumeLocked();
   1523  if (capture_.recommended_input_volume.has_value()) {
   1524    recommended_input_volume_stats_reporter_.UpdateStatistics(
   1525        *capture_.recommended_input_volume);
   1526  }
   1527 
   1528  if (submodules_.capture_levels_adjuster) {
   1529    submodules_.capture_levels_adjuster->ApplyPostLevelAdjustment(
   1530        *capture_buffer);
   1531 
   1532    if (config_.capture_level_adjustment.analog_mic_gain_emulation.enabled) {
   1533      // If the input volume emulation is used, retrieve the recommended input
   1534      // volume and set that to emulate the input volume on the next processed
   1535      // audio frame.
   1536      RTC_DCHECK(capture_.recommended_input_volume.has_value());
   1537      submodules_.capture_levels_adjuster->SetAnalogMicGainLevel(
   1538          *capture_.recommended_input_volume);
   1539    }
   1540  }
   1541 
   1542  // Temporarily set the output to zero after the stream has been unmuted
   1543  // (capture output is again used). The purpose of this is to avoid clicks and
   1544  // artefacts in the audio that results when the processing again is
   1545  // reactivated after unmuting.
   1546  if (!capture_.capture_output_used_last_frame &&
   1547      capture_.capture_output_used) {
   1548    for (size_t ch = 0; ch < capture_buffer->num_channels(); ++ch) {
   1549      ArrayView<float> channel_view(capture_buffer->channels()[ch],
   1550                                    capture_buffer->num_frames());
   1551      std::fill(channel_view.begin(), channel_view.end(), 0.f);
   1552    }
   1553  }
   1554  capture_.capture_output_used_last_frame = capture_.capture_output_used;
   1555 
   1556  capture_.was_stream_delay_set = false;
   1557 
   1558  data_dumper_->DumpRaw("recommended_input_volume",
   1559                        capture_.recommended_input_volume.value_or(
   1560                            kUnspecifiedDataDumpInputVolume));
   1561 
   1562  return kNoError;
   1563 }
   1564 
   1565 int AudioProcessingImpl::AnalyzeReverseStream(
   1566    const float* const* data,
   1567    const StreamConfig& reverse_config) {
   1568  TRACE_EVENT0("webrtc", "AudioProcessing::AnalyzeReverseStream_StreamConfig");
   1569  MutexLock lock(&mutex_render_);
   1570  DenormalDisabler denormal_disabler;
   1571  RTC_DCHECK(data);
   1572  for (size_t i = 0; i < reverse_config.num_channels(); ++i) {
   1573    RTC_DCHECK(data[i]);
   1574  }
   1575  RETURN_ON_ERR(
   1576      AudioFormatValidityToErrorCode(ValidateAudioFormat(reverse_config)));
   1577 
   1578  MaybeInitializeRender(reverse_config, reverse_config);
   1579  return AnalyzeReverseStreamLocked(data, reverse_config, reverse_config);
   1580 }
   1581 
   1582 int AudioProcessingImpl::ProcessReverseStream(const float* const* src,
   1583                                              const StreamConfig& input_config,
   1584                                              const StreamConfig& output_config,
   1585                                              float* const* dest) {
   1586  TRACE_EVENT0("webrtc", "AudioProcessing::ProcessReverseStream_StreamConfig");
   1587  MutexLock lock(&mutex_render_);
   1588  DenormalDisabler denormal_disabler;
   1589  RETURN_ON_ERR(
   1590      HandleUnsupportedAudioFormats(src, input_config, output_config, dest));
   1591 
   1592  MaybeInitializeRender(input_config, output_config);
   1593 
   1594  RETURN_ON_ERR(AnalyzeReverseStreamLocked(src, input_config, output_config));
   1595 
   1596  if (submodule_states_.RenderMultiBandProcessingActive() ||
   1597      submodule_states_.RenderFullBandProcessingActive()) {
   1598    render_.render_audio->CopyTo(formats_.api_format.reverse_output_stream(),
   1599                                 dest);
   1600  } else if (formats_.api_format.reverse_input_stream() !=
   1601             formats_.api_format.reverse_output_stream()) {
   1602    render_.render_converter->Convert(src, input_config.num_samples(), dest,
   1603                                      output_config.num_samples());
   1604  } else {
   1605    CopyAudioIfNeeded(src, input_config.num_frames(),
   1606                      input_config.num_channels(), dest);
   1607  }
   1608 
   1609  return kNoError;
   1610 }
   1611 
   1612 int AudioProcessingImpl::AnalyzeReverseStreamLocked(
   1613    const float* const* src,
   1614    const StreamConfig& /* input_config */,
   1615    const StreamConfig& /* output_config */) {
   1616  if (aec_dump_) {
   1617    const size_t channel_size =
   1618        formats_.api_format.reverse_input_stream().num_frames();
   1619    const size_t num_channels =
   1620        formats_.api_format.reverse_input_stream().num_channels();
   1621    aec_dump_->WriteRenderStreamMessage(src, num_channels, channel_size);
   1622  }
   1623  render_.render_audio->CopyFrom(src,
   1624                                 formats_.api_format.reverse_input_stream());
   1625  return ProcessRenderStreamLocked();
   1626 }
   1627 
   1628 int AudioProcessingImpl::ProcessReverseStream(const int16_t* const src,
   1629                                              const StreamConfig& input_config,
   1630                                              const StreamConfig& output_config,
   1631                                              int16_t* const dest) {
   1632  TRACE_EVENT0("webrtc", "AudioProcessing::ProcessReverseStream_AudioFrame");
   1633 
   1634  MutexLock lock(&mutex_render_);
   1635  DenormalDisabler denormal_disabler;
   1636 
   1637  RETURN_ON_ERR(
   1638      HandleUnsupportedAudioFormats(src, input_config, output_config, dest));
   1639  MaybeInitializeRender(input_config, output_config);
   1640 
   1641  if (aec_dump_) {
   1642    aec_dump_->WriteRenderStreamMessage(src, input_config.num_frames(),
   1643                                        input_config.num_channels());
   1644  }
   1645 
   1646  render_.render_audio->CopyFrom(src, input_config);
   1647  RETURN_ON_ERR(ProcessRenderStreamLocked());
   1648  if (submodule_states_.RenderMultiBandProcessingActive() ||
   1649      submodule_states_.RenderFullBandProcessingActive()) {
   1650    render_.render_audio->CopyTo(output_config, dest);
   1651  }
   1652  return kNoError;
   1653 }
   1654 
   1655 int AudioProcessingImpl::ProcessRenderStreamLocked() {
   1656  AudioBuffer* render_buffer = render_.render_audio.get();  // For brevity.
   1657 
   1658  HandleRenderRuntimeSettings();
   1659  DenormalDisabler denormal_disabler;
   1660 
   1661  if (submodules_.render_pre_processor) {
   1662    submodules_.render_pre_processor->Process(render_buffer);
   1663  }
   1664 
   1665  QueueNonbandedRenderAudio(render_buffer);
   1666 
   1667  if (submodule_states_.RenderMultiBandSubModulesActive() &&
   1668      SampleRateSupportsMultiBand(
   1669          formats_.render_processing_format.sample_rate_hz())) {
   1670    render_buffer->SplitIntoFrequencyBands();
   1671  }
   1672 
   1673  if (submodule_states_.RenderMultiBandSubModulesActive()) {
   1674    QueueBandedRenderAudio(render_buffer);
   1675  }
   1676 
   1677  // TODO(peah): Perform the queuing inside QueueRenderAudiuo().
   1678  if (submodules_.echo_controller) {
   1679    submodules_.echo_controller->AnalyzeRender(render_buffer);
   1680  }
   1681 
   1682  if (submodule_states_.RenderMultiBandProcessingActive() &&
   1683      SampleRateSupportsMultiBand(
   1684          formats_.render_processing_format.sample_rate_hz())) {
   1685    render_buffer->MergeFrequencyBands();
   1686  }
   1687 
   1688  return kNoError;
   1689 }
   1690 
   1691 int AudioProcessingImpl::set_stream_delay_ms(int delay) {
   1692  MutexLock lock(&mutex_capture_);
   1693  Error retval = kNoError;
   1694  capture_.was_stream_delay_set = true;
   1695 
   1696  if (delay < 0) {
   1697    delay = 0;
   1698    retval = kBadStreamParameterWarning;
   1699  }
   1700 
   1701  // TODO(ajm): the max is rather arbitrarily chosen; investigate.
   1702  if (delay > 500) {
   1703    delay = 500;
   1704    retval = kBadStreamParameterWarning;
   1705  }
   1706 
   1707  capture_nonlocked_.stream_delay_ms = delay;
   1708  return retval;
   1709 }
   1710 
   1711 bool AudioProcessingImpl::GetLinearAecOutput(
   1712    ArrayView<std::array<float, 160>> linear_output) const {
   1713  MutexLock lock(&mutex_capture_);
   1714  AudioBuffer* linear_aec_buffer = capture_.linear_aec_output.get();
   1715 
   1716  RTC_DCHECK(linear_aec_buffer);
   1717  if (linear_aec_buffer) {
   1718    RTC_DCHECK_EQ(1, linear_aec_buffer->num_bands());
   1719    RTC_DCHECK_EQ(linear_output.size(), linear_aec_buffer->num_channels());
   1720 
   1721    for (size_t ch = 0; ch < linear_aec_buffer->num_channels(); ++ch) {
   1722      RTC_DCHECK_EQ(linear_output[ch].size(), linear_aec_buffer->num_frames());
   1723      ArrayView<const float> channel_view =
   1724          ArrayView<const float>(linear_aec_buffer->channels_const()[ch],
   1725                                 linear_aec_buffer->num_frames());
   1726      FloatS16ToFloat(channel_view.data(), channel_view.size(),
   1727                      linear_output[ch].data());
   1728    }
   1729    return true;
   1730  }
   1731  RTC_LOG(LS_ERROR) << "No linear AEC output available";
   1732  RTC_DCHECK_NOTREACHED();
   1733  return false;
   1734 }
   1735 
   1736 int AudioProcessingImpl::stream_delay_ms() const {
   1737  // Used as callback from submodules, hence locking is not allowed.
   1738  return capture_nonlocked_.stream_delay_ms;
   1739 }
   1740 
   1741 void AudioProcessingImpl::set_stream_key_pressed(bool key_pressed) {
   1742  MutexLock lock(&mutex_capture_);
   1743  capture_.key_pressed = key_pressed;
   1744 }
   1745 
   1746 void AudioProcessingImpl::set_stream_analog_level(int level) {
   1747  MutexLock lock_capture(&mutex_capture_);
   1748  set_stream_analog_level_locked(level);
   1749 }
   1750 
   1751 void AudioProcessingImpl::set_stream_analog_level_locked(int level) {
   1752  capture_.applied_input_volume_changed =
   1753      capture_.applied_input_volume.has_value() &&
   1754      *capture_.applied_input_volume != level;
   1755  capture_.applied_input_volume = level;
   1756 
   1757  // Invalidate any previously recommended input volume which will be updated by
   1758  // `ProcessStream()`.
   1759  capture_.recommended_input_volume = std::nullopt;
   1760 
   1761  if (submodules_.agc_manager) {
   1762    submodules_.agc_manager->set_stream_analog_level(level);
   1763    return;
   1764  }
   1765 
   1766  if (submodules_.gain_control) {
   1767    int error = submodules_.gain_control->set_stream_analog_level(level);
   1768    RTC_DCHECK_EQ(kNoError, error);
   1769    return;
   1770  }
   1771 }
   1772 
   1773 int AudioProcessingImpl::recommended_stream_analog_level() const {
   1774  MutexLock lock_capture(&mutex_capture_);
   1775  if (!capture_.applied_input_volume.has_value()) {
   1776    RTC_LOG(LS_ERROR) << "set_stream_analog_level has not been called";
   1777  }
   1778  // Input volume to recommend when `set_stream_analog_level()` is not called.
   1779  constexpr int kFallBackInputVolume = 255;
   1780  // When APM has no input volume to recommend, return the latest applied input
   1781  // volume that has been observed in order to possibly produce no input volume
   1782  // change. If no applied input volume has been observed, return a fall-back
   1783  // value.
   1784  return capture_.recommended_input_volume.value_or(
   1785      capture_.applied_input_volume.value_or(kFallBackInputVolume));
   1786 }
   1787 
   1788 void AudioProcessingImpl::UpdateRecommendedInputVolumeLocked() {
   1789  if (!capture_.applied_input_volume.has_value()) {
   1790    // When `set_stream_analog_level()` is not called, no input level can be
   1791    // recommended.
   1792    capture_.recommended_input_volume = std::nullopt;
   1793    return;
   1794  }
   1795 
   1796  if (submodules_.agc_manager) {
   1797    capture_.recommended_input_volume =
   1798        submodules_.agc_manager->recommended_analog_level();
   1799    return;
   1800  }
   1801 
   1802  if (submodules_.gain_control) {
   1803    capture_.recommended_input_volume =
   1804        submodules_.gain_control->stream_analog_level();
   1805    return;
   1806  }
   1807 
   1808  if (submodules_.gain_controller2 &&
   1809      config_.gain_controller2.input_volume_controller.enabled) {
   1810    capture_.recommended_input_volume =
   1811        submodules_.gain_controller2->recommended_input_volume();
   1812    return;
   1813  }
   1814 
   1815  capture_.recommended_input_volume = capture_.applied_input_volume;
   1816 }
   1817 
   1818 bool AudioProcessingImpl::CreateAndAttachAecDump(absl::string_view file_name,
   1819                                                 int64_t max_log_size_bytes,
   1820                                                 TaskQueueBase* absl_nonnull
   1821                                                     worker_queue) {
   1822  std::unique_ptr<AecDump> aec_dump =
   1823      AecDumpFactory::Create(file_name, max_log_size_bytes, worker_queue);
   1824  if (!aec_dump) {
   1825    return false;
   1826  }
   1827 
   1828  AttachAecDump(std::move(aec_dump));
   1829  return true;
   1830 }
   1831 
   1832 bool AudioProcessingImpl::CreateAndAttachAecDump(FILE* handle,
   1833                                                 int64_t max_log_size_bytes,
   1834                                                 TaskQueueBase* absl_nonnull
   1835                                                     worker_queue) {
   1836  std::unique_ptr<AecDump> aec_dump =
   1837      AecDumpFactory::Create(handle, max_log_size_bytes, worker_queue);
   1838  if (!aec_dump) {
   1839    return false;
   1840  }
   1841 
   1842  AttachAecDump(std::move(aec_dump));
   1843  return true;
   1844 }
   1845 
   1846 void AudioProcessingImpl::AttachAecDump(std::unique_ptr<AecDump> aec_dump) {
   1847  RTC_DCHECK(aec_dump);
   1848  MutexLock lock_render(&mutex_render_);
   1849  MutexLock lock_capture(&mutex_capture_);
   1850 
   1851  // The previously attached AecDump will be destroyed with the
   1852  // 'aec_dump' parameter, which is after locks are released.
   1853  aec_dump_.swap(aec_dump);
   1854  WriteAecDumpConfigMessage(true);
   1855  aec_dump_->WriteInitMessage(formats_.api_format, TimeUTCMillis());
   1856 }
   1857 
   1858 void AudioProcessingImpl::DetachAecDump() {
   1859  // The d-tor of a task-queue based AecDump blocks until all pending
   1860  // tasks are done. This construction avoids blocking while holding
   1861  // the render and capture locks.
   1862  std::unique_ptr<AecDump> aec_dump = nullptr;
   1863  {
   1864    MutexLock lock_render(&mutex_render_);
   1865    MutexLock lock_capture(&mutex_capture_);
   1866    aec_dump = std::move(aec_dump_);
   1867  }
   1868 }
   1869 
   1870 AudioProcessing::Config AudioProcessingImpl::GetConfig() const {
   1871  MutexLock lock_render(&mutex_render_);
   1872  MutexLock lock_capture(&mutex_capture_);
   1873  return config_;
   1874 }
   1875 
   1876 bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
   1877  return submodule_states_.Update(
   1878      config_.high_pass_filter.enabled, !!submodules_.echo_control_mobile,
   1879      !!submodules_.noise_suppressor, !!submodules_.gain_control,
   1880      !!submodules_.gain_controller2,
   1881      config_.pre_amplifier.enabled || config_.capture_level_adjustment.enabled,
   1882      capture_nonlocked_.echo_controller_enabled);
   1883 }
   1884 
   1885 void AudioProcessingImpl::InitializeHighPassFilter(bool forced_reset) {
   1886  bool high_pass_filter_needed_by_aec =
   1887      config_.echo_canceller.enabled &&
   1888      config_.echo_canceller.enforce_high_pass_filtering &&
   1889      !config_.echo_canceller.mobile_mode;
   1890  if (submodule_states_.HighPassFilteringRequired() ||
   1891      high_pass_filter_needed_by_aec) {
   1892    bool use_full_band = config_.high_pass_filter.apply_in_full_band &&
   1893                         !constants_.enforce_split_band_hpf;
   1894    int rate = use_full_band ? proc_fullband_sample_rate_hz()
   1895                             : proc_split_sample_rate_hz();
   1896    size_t num_channels =
   1897        use_full_band ? num_output_channels() : num_proc_channels();
   1898 
   1899    if (!submodules_.high_pass_filter ||
   1900        rate != submodules_.high_pass_filter->sample_rate_hz() ||
   1901        forced_reset ||
   1902        num_channels != submodules_.high_pass_filter->num_channels()) {
   1903      submodules_.high_pass_filter.reset(
   1904          new HighPassFilter(rate, num_channels));
   1905    }
   1906  } else {
   1907    submodules_.high_pass_filter.reset();
   1908  }
   1909 }
   1910 
   1911 void AudioProcessingImpl::InitializeEchoController() {
   1912  bool use_echo_controller =
   1913      echo_control_factory_ ||
   1914      (config_.echo_canceller.enabled && !config_.echo_canceller.mobile_mode);
   1915 
   1916  if (use_echo_controller) {
   1917    // Create and activate the echo controller.
   1918    if (echo_control_factory_) {
   1919      submodules_.echo_controller = echo_control_factory_->Create(
   1920          env_, proc_sample_rate_hz(), num_reverse_channels(),
   1921          num_proc_channels(),
   1922          submodules_.neural_residual_echo_estimator.get());
   1923      RTC_DCHECK(submodules_.echo_controller);
   1924    } else {
   1925      EchoCanceller3Config config_to_use =
   1926          echo_canceller_config_.value_or(EchoCanceller3Config());
   1927      std::optional<EchoCanceller3Config> multichannel_config_to_use =
   1928          echo_canceller_multichannel_config_;
   1929      if (!echo_canceller_config_.has_value() &&
   1930          !multichannel_config_to_use.has_value()) {
   1931        // We create a default multichannel config only if the user has set no
   1932        // config: If the user only provides a non-multichannel config, that
   1933        // config is used for both mono and multichannel AEC.
   1934        multichannel_config_to_use =
   1935            EchoCanceller3Config::CreateDefaultMultichannelConfig();
   1936      }
   1937      submodules_.echo_controller = std::make_unique<EchoCanceller3>(
   1938          env_, config_to_use, multichannel_config_to_use,
   1939          submodules_.neural_residual_echo_estimator.get(),
   1940          proc_sample_rate_hz(), num_reverse_channels(), num_proc_channels());
   1941    }
   1942 
   1943    // Setup the storage for returning the linear AEC output.
   1944    if (config_.echo_canceller.export_linear_aec_output) {
   1945      constexpr int kLinearOutputRateHz = 16000;
   1946      capture_.linear_aec_output = std::make_unique<AudioBuffer>(
   1947          kLinearOutputRateHz, num_proc_channels(), kLinearOutputRateHz,
   1948          num_proc_channels(), kLinearOutputRateHz, num_proc_channels());
   1949    } else {
   1950      capture_.linear_aec_output.reset();
   1951    }
   1952 
   1953    capture_nonlocked_.echo_controller_enabled = true;
   1954 
   1955    if (!env_.field_trials().IsEnabled("WebRTC-PostFilterKillSwitch")) {
   1956      // Only creates a PostFilter if current sample-rate is high enough to
   1957      // require a filter.
   1958      submodules_.post_filter = PostFilter::CreateIfNeeded(
   1959          proc_sample_rate_hz(), num_proc_channels());
   1960    }
   1961 
   1962    submodules_.echo_control_mobile.reset();
   1963    aecm_render_signal_queue_.reset();
   1964    return;
   1965  }
   1966 
   1967  submodules_.echo_controller.reset();
   1968  capture_nonlocked_.echo_controller_enabled = false;
   1969  capture_.linear_aec_output.reset();
   1970 
   1971  if (!config_.echo_canceller.enabled) {
   1972    submodules_.echo_control_mobile.reset();
   1973    aecm_render_signal_queue_.reset();
   1974    return;
   1975  }
   1976 
   1977  if (config_.echo_canceller.mobile_mode) {
   1978    // Create and activate AECM.
   1979    size_t max_element_size =
   1980        std::max(static_cast<size_t>(1),
   1981                 kMaxAllowedValuesOfSamplesPerBand *
   1982                     EchoControlMobileImpl::NumCancellersRequired(
   1983                         num_output_channels(), num_reverse_channels()));
   1984 
   1985    std::vector<int16_t> template_queue_element(max_element_size);
   1986 
   1987    aecm_render_signal_queue_.reset(
   1988        new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>(
   1989            kMaxNumFramesToBuffer, template_queue_element,
   1990            RenderQueueItemVerifier<int16_t>(max_element_size)));
   1991 
   1992    aecm_render_queue_buffer_.resize(max_element_size);
   1993    aecm_capture_queue_buffer_.resize(max_element_size);
   1994 
   1995    submodules_.echo_control_mobile.reset(new EchoControlMobileImpl());
   1996 
   1997    submodules_.echo_control_mobile->Initialize(proc_split_sample_rate_hz(),
   1998                                                num_reverse_channels(),
   1999                                                num_output_channels());
   2000    return;
   2001  }
   2002 
   2003  submodules_.echo_control_mobile.reset();
   2004  aecm_render_signal_queue_.reset();
   2005 }
   2006 
   2007 void AudioProcessingImpl::InitializeGainController1() {
   2008  if (config_.gain_controller2.enabled &&
   2009      config_.gain_controller2.input_volume_controller.enabled &&
   2010      config_.gain_controller1.enabled &&
   2011      (config_.gain_controller1.mode ==
   2012           AudioProcessing::Config::GainController1::kAdaptiveAnalog ||
   2013       config_.gain_controller1.analog_gain_controller.enabled)) {
   2014    RTC_LOG(LS_ERROR) << "APM configuration not valid: "
   2015                      << "Multiple input volume controllers enabled.";
   2016  }
   2017 
   2018  if (!config_.gain_controller1.enabled) {
   2019    submodules_.agc_manager.reset();
   2020    submodules_.gain_control.reset();
   2021    return;
   2022  }
   2023 
   2024  RTC_HISTOGRAM_BOOLEAN(
   2025      "WebRTC.Audio.GainController.Analog.Enabled",
   2026      config_.gain_controller1.analog_gain_controller.enabled);
   2027 
   2028  if (!submodules_.gain_control) {
   2029    submodules_.gain_control.reset(new GainControlImpl());
   2030  }
   2031 
   2032  submodules_.gain_control->Initialize(num_proc_channels(),
   2033                                       proc_sample_rate_hz());
   2034  if (!config_.gain_controller1.analog_gain_controller.enabled) {
   2035    int error = submodules_.gain_control->set_mode(
   2036        Agc1ConfigModeToInterfaceMode(config_.gain_controller1.mode));
   2037    RTC_DCHECK_EQ(kNoError, error);
   2038    error = submodules_.gain_control->set_target_level_dbfs(
   2039        config_.gain_controller1.target_level_dbfs);
   2040    RTC_DCHECK_EQ(kNoError, error);
   2041    error = submodules_.gain_control->set_compression_gain_db(
   2042        config_.gain_controller1.compression_gain_db);
   2043    RTC_DCHECK_EQ(kNoError, error);
   2044    error = submodules_.gain_control->enable_limiter(
   2045        config_.gain_controller1.enable_limiter);
   2046    RTC_DCHECK_EQ(kNoError, error);
   2047    constexpr int kAnalogLevelMinimum = 0;
   2048    constexpr int kAnalogLevelMaximum = 255;
   2049    error = submodules_.gain_control->set_analog_level_limits(
   2050        kAnalogLevelMinimum, kAnalogLevelMaximum);
   2051    RTC_DCHECK_EQ(kNoError, error);
   2052 
   2053    submodules_.agc_manager.reset();
   2054    return;
   2055  }
   2056 
   2057  if (!submodules_.agc_manager || submodules_.agc_manager->num_channels() !=
   2058                                      static_cast<int>(num_proc_channels())) {
   2059    int stream_analog_level = -1;
   2060    const bool re_creation = !!submodules_.agc_manager;
   2061    if (re_creation) {
   2062      stream_analog_level = submodules_.agc_manager->recommended_analog_level();
   2063    }
   2064    submodules_.agc_manager = std::make_unique<AgcManagerDirect>(
   2065        env_, num_proc_channels(),
   2066        config_.gain_controller1.analog_gain_controller);
   2067    if (re_creation) {
   2068      submodules_.agc_manager->set_stream_analog_level(stream_analog_level);
   2069    }
   2070  }
   2071  submodules_.agc_manager->Initialize();
   2072  submodules_.agc_manager->SetupDigitalGainControl(*submodules_.gain_control);
   2073  submodules_.agc_manager->HandleCaptureOutputUsedChange(
   2074      capture_.capture_output_used);
   2075 }
   2076 
   2077 void AudioProcessingImpl::InitializeGainController2() {
   2078  if (!config_.gain_controller2.enabled) {
   2079    submodules_.gain_controller2.reset();
   2080    return;
   2081  }
   2082  // Input volume controller configuration if the AGC2 is running
   2083  // and its parameters require to fully switch the gain control to
   2084  // AGC2.
   2085  const InputVolumeController::Config input_volume_controller_config =
   2086      InputVolumeController::Config{};
   2087  submodules_.gain_controller2 = std::make_unique<GainController2>(
   2088      env_, config_.gain_controller2, input_volume_controller_config,
   2089      proc_fullband_sample_rate_hz(), num_output_channels(),
   2090      /*use_internal_vad=*/true);
   2091  submodules_.gain_controller2->SetCaptureOutputUsed(
   2092      capture_.capture_output_used);
   2093 }
   2094 
   2095 void AudioProcessingImpl::InitializeNoiseSuppressor() {
   2096  submodules_.noise_suppressor.reset();
   2097 
   2098  if (config_.noise_suppression.enabled) {
   2099    auto map_level =
   2100        [](AudioProcessing::Config::NoiseSuppression::Level level) {
   2101          using NoiseSuppresionConfig =
   2102              AudioProcessing::Config::NoiseSuppression;
   2103          switch (level) {
   2104            case NoiseSuppresionConfig::kLow:
   2105              return NsConfig::SuppressionLevel::k6dB;
   2106            case NoiseSuppresionConfig::kModerate:
   2107              return NsConfig::SuppressionLevel::k12dB;
   2108            case NoiseSuppresionConfig::kHigh:
   2109              return NsConfig::SuppressionLevel::k18dB;
   2110            case NoiseSuppresionConfig::kVeryHigh:
   2111              return NsConfig::SuppressionLevel::k21dB;
   2112          }
   2113          RTC_CHECK_NOTREACHED();
   2114        };
   2115 
   2116    NsConfig cfg;
   2117    cfg.target_level = map_level(config_.noise_suppression.level);
   2118    submodules_.noise_suppressor = std::make_unique<NoiseSuppressor>(
   2119        cfg, proc_sample_rate_hz(), num_proc_channels());
   2120  }
   2121 }
   2122 
   2123 void AudioProcessingImpl::InitializeCaptureLevelsAdjuster() {
   2124  if (config_.pre_amplifier.enabled ||
   2125      config_.capture_level_adjustment.enabled) {
   2126    // Use both the pre-amplifier and the capture level adjustment gains as
   2127    // pre-gains.
   2128    float pre_gain = 1.f;
   2129    if (config_.pre_amplifier.enabled) {
   2130      pre_gain *= config_.pre_amplifier.fixed_gain_factor;
   2131    }
   2132    if (config_.capture_level_adjustment.enabled) {
   2133      pre_gain *= config_.capture_level_adjustment.pre_gain_factor;
   2134    }
   2135 
   2136    submodules_.capture_levels_adjuster =
   2137        std::make_unique<CaptureLevelsAdjuster>(
   2138            config_.capture_level_adjustment.analog_mic_gain_emulation.enabled,
   2139            config_.capture_level_adjustment.analog_mic_gain_emulation
   2140                .initial_level,
   2141            pre_gain, config_.capture_level_adjustment.post_gain_factor);
   2142  } else {
   2143    submodules_.capture_levels_adjuster.reset();
   2144  }
   2145 }
   2146 
   2147 void AudioProcessingImpl::InitializeResidualEchoDetector() {
   2148  if (submodules_.echo_detector) {
   2149    submodules_.echo_detector->Initialize(
   2150        proc_fullband_sample_rate_hz(), 1,
   2151        formats_.render_processing_format.sample_rate_hz(), 1);
   2152  }
   2153 }
   2154 
   2155 void AudioProcessingImpl::InitializeAnalyzer() {
   2156  if (submodules_.capture_analyzer) {
   2157    submodules_.capture_analyzer->Initialize(proc_fullband_sample_rate_hz(),
   2158                                             num_proc_channels());
   2159  }
   2160 }
   2161 
   2162 void AudioProcessingImpl::InitializePostProcessor() {
   2163  if (submodules_.capture_post_processor) {
   2164    submodules_.capture_post_processor->Initialize(
   2165        proc_fullband_sample_rate_hz(), num_proc_channels());
   2166  }
   2167 }
   2168 
   2169 void AudioProcessingImpl::InitializePreProcessor() {
   2170  if (submodules_.render_pre_processor) {
   2171    submodules_.render_pre_processor->Initialize(
   2172        formats_.render_processing_format.sample_rate_hz(),
   2173        formats_.render_processing_format.num_channels());
   2174  }
   2175 }
   2176 
   2177 void AudioProcessingImpl::WriteAecDumpConfigMessage(bool forced) {
   2178  if (!aec_dump_) {
   2179    return;
   2180  }
   2181 
   2182  std::string experiments_description = "";
   2183  // TODO(peah): Add semicolon-separated concatenations of experiment
   2184  // descriptions for other submodules.
   2185  if (!!submodules_.capture_post_processor) {
   2186    experiments_description += "CapturePostProcessor;";
   2187  }
   2188  if (!!submodules_.render_pre_processor) {
   2189    experiments_description += "RenderPreProcessor;";
   2190  }
   2191  if (capture_nonlocked_.echo_controller_enabled) {
   2192    experiments_description += "EchoController;";
   2193  }
   2194  if (config_.gain_controller2.enabled) {
   2195    experiments_description += "GainController2;";
   2196  }
   2197  if (submodules_.neural_residual_echo_estimator) {
   2198    experiments_description += "NeuralResidualEchoEstimator;";
   2199  }
   2200 
   2201  InternalAPMConfig apm_config;
   2202 
   2203  apm_config.aec_enabled = config_.echo_canceller.enabled;
   2204  apm_config.aec_delay_agnostic_enabled = false;
   2205  apm_config.aec_extended_filter_enabled = false;
   2206  apm_config.aec_suppression_level = 0;
   2207 
   2208  apm_config.aecm_enabled = !!submodules_.echo_control_mobile;
   2209  apm_config.aecm_comfort_noise_enabled =
   2210      submodules_.echo_control_mobile &&
   2211      submodules_.echo_control_mobile->is_comfort_noise_enabled();
   2212  apm_config.aecm_routing_mode =
   2213      submodules_.echo_control_mobile
   2214          ? static_cast<int>(submodules_.echo_control_mobile->routing_mode())
   2215          : 0;
   2216 
   2217  apm_config.agc_enabled = !!submodules_.gain_control;
   2218 
   2219  apm_config.agc_mode = submodules_.gain_control
   2220                            ? static_cast<int>(submodules_.gain_control->mode())
   2221                            : GainControl::kAdaptiveAnalog;
   2222  apm_config.agc_limiter_enabled =
   2223      submodules_.gain_control ? submodules_.gain_control->is_limiter_enabled()
   2224                               : false;
   2225  apm_config.noise_robust_agc_enabled = !!submodules_.agc_manager;
   2226 
   2227  apm_config.hpf_enabled = config_.high_pass_filter.enabled;
   2228 
   2229  apm_config.ns_enabled = config_.noise_suppression.enabled;
   2230  apm_config.ns_level = static_cast<int>(config_.noise_suppression.level);
   2231 
   2232  apm_config.experiments_description = experiments_description;
   2233  apm_config.pre_amplifier_enabled = config_.pre_amplifier.enabled;
   2234  apm_config.pre_amplifier_fixed_gain_factor =
   2235      config_.pre_amplifier.fixed_gain_factor;
   2236 
   2237  if (!forced && apm_config == apm_config_for_aec_dump_) {
   2238    return;
   2239  }
   2240  aec_dump_->WriteConfig(apm_config);
   2241  apm_config_for_aec_dump_ = apm_config;
   2242 }
   2243 
   2244 void AudioProcessingImpl::RecordUnprocessedCaptureStream(
   2245    const float* const* src) {
   2246  RTC_DCHECK(aec_dump_);
   2247  WriteAecDumpConfigMessage(false);
   2248 
   2249  const size_t channel_size = formats_.api_format.input_stream().num_frames();
   2250  const size_t num_channels = formats_.api_format.input_stream().num_channels();
   2251  for (size_t ch = 0u; ch < num_channels; ++ch) {
   2252    aec_dump_->AddCaptureStreamInput(
   2253        MonoView<const float>(src[ch], channel_size));
   2254  }
   2255  RecordAudioProcessingState();
   2256 }
   2257 
   2258 void AudioProcessingImpl::RecordUnprocessedCaptureStream(
   2259    const int16_t* const data,
   2260    const StreamConfig& config) {
   2261  RTC_DCHECK(aec_dump_);
   2262  WriteAecDumpConfigMessage(false);
   2263 
   2264  aec_dump_->AddCaptureStreamInput(data, config.num_channels(),
   2265                                   config.num_frames());
   2266  RecordAudioProcessingState();
   2267 }
   2268 
   2269 void AudioProcessingImpl::RecordProcessedCaptureStream(
   2270    const float* const* processed_capture_stream) {
   2271  RTC_DCHECK(aec_dump_);
   2272 
   2273  const size_t channel_size = formats_.api_format.output_stream().num_frames();
   2274  const size_t num_channels =
   2275      formats_.api_format.output_stream().num_channels();
   2276  for (size_t ch = 0u; ch < num_channels; ++ch) {
   2277    aec_dump_->AddCaptureStreamOutput(
   2278        MonoView<const float>(processed_capture_stream[ch], channel_size));
   2279  }
   2280 
   2281  aec_dump_->WriteCaptureStreamMessage();
   2282 }
   2283 
   2284 void AudioProcessingImpl::RecordProcessedCaptureStream(
   2285    const int16_t* const data,
   2286    const StreamConfig& config) {
   2287  RTC_DCHECK(aec_dump_);
   2288 
   2289  aec_dump_->AddCaptureStreamOutput(data, config.num_channels(),
   2290                                    config.num_frames());
   2291  aec_dump_->WriteCaptureStreamMessage();
   2292 }
   2293 
   2294 void AudioProcessingImpl::RecordAudioProcessingState() {
   2295  RTC_DCHECK(aec_dump_);
   2296  AecDump::AudioProcessingState audio_proc_state;
   2297  audio_proc_state.delay = capture_nonlocked_.stream_delay_ms;
   2298  audio_proc_state.drift = 0;
   2299  audio_proc_state.applied_input_volume = capture_.applied_input_volume;
   2300  audio_proc_state.keypress = capture_.key_pressed;
   2301  aec_dump_->AddAudioProcessingState(audio_proc_state);
   2302 }
   2303 
   2304 AudioProcessingImpl::ApmCaptureState::ApmCaptureState()
   2305    : was_stream_delay_set(false),
   2306      capture_output_used(true),
   2307      capture_output_used_last_frame(true),
   2308      key_pressed(false),
   2309      capture_processing_format(kSampleRate16kHz),
   2310      split_rate(kSampleRate16kHz),
   2311      echo_path_gain_change(false),
   2312      prev_pre_adjustment_gain(-1.0f),
   2313      playout_volume(-1),
   2314      prev_playout_volume(-1),
   2315      applied_input_volume_changed(false) {}
   2316 
   2317 AudioProcessingImpl::ApmCaptureState::~ApmCaptureState() = default;
   2318 
   2319 AudioProcessingImpl::ApmRenderState::ApmRenderState() = default;
   2320 
   2321 AudioProcessingImpl::ApmRenderState::~ApmRenderState() = default;
   2322 
   2323 AudioProcessingImpl::ApmStatsReporter::ApmStatsReporter()
   2324    : stats_message_queue_(1) {}
   2325 
   2326 AudioProcessingImpl::ApmStatsReporter::~ApmStatsReporter() = default;
   2327 
   2328 AudioProcessingStats AudioProcessingImpl::ApmStatsReporter::GetStatistics() {
   2329  MutexLock lock_stats(&mutex_stats_);
   2330  bool new_stats_available = stats_message_queue_.Remove(&cached_stats_);
   2331  // If the message queue is full, return the cached stats.
   2332  static_cast<void>(new_stats_available);
   2333 
   2334  return cached_stats_;
   2335 }
   2336 
   2337 void AudioProcessingImpl::ApmStatsReporter::UpdateStatistics(
   2338    const AudioProcessingStats& new_stats) {
   2339  AudioProcessingStats stats_to_queue = new_stats;
   2340  bool stats_message_passed = stats_message_queue_.Insert(&stats_to_queue);
   2341  // If the message queue is full, discard the new stats.
   2342  static_cast<void>(stats_message_passed);
   2343 }
   2344 
   2345 }  // namespace webrtc