tor-browser

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

audio_processing_impl.h (23989B)


      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 #ifndef MODULES_AUDIO_PROCESSING_AUDIO_PROCESSING_IMPL_H_
     12 #define MODULES_AUDIO_PROCESSING_AUDIO_PROCESSING_IMPL_H_
     13 
     14 #include <array>
     15 #include <atomic>
     16 #include <cstdint>
     17 #include <cstdio>
     18 #include <memory>
     19 #include <optional>
     20 #include <utility>
     21 #include <vector>
     22 
     23 #include "absl/base/nullability.h"
     24 #include "absl/strings/string_view.h"
     25 #include "api/array_view.h"
     26 #include "api/audio/audio_processing.h"
     27 #include "api/audio/audio_processing_statistics.h"
     28 #include "api/audio/echo_canceller3_config.h"
     29 #include "api/audio/echo_control.h"
     30 #include "api/audio/neural_residual_echo_estimator.h"
     31 #include "api/environment/environment.h"
     32 #include "api/scoped_refptr.h"
     33 #include "api/task_queue/task_queue_base.h"
     34 #include "modules/audio_processing/agc/agc_manager_direct.h"
     35 #include "modules/audio_processing/agc2/input_volume_stats_reporter.h"
     36 #include "modules/audio_processing/audio_buffer.h"
     37 #include "modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.h"
     38 #include "modules/audio_processing/echo_control_mobile_impl.h"
     39 #include "modules/audio_processing/gain_control_impl.h"
     40 #include "modules/audio_processing/gain_controller2.h"
     41 #include "modules/audio_processing/high_pass_filter.h"
     42 #include "modules/audio_processing/include/aec_dump.h"
     43 #include "modules/audio_processing/include/audio_frame_proxies.h"
     44 #include "modules/audio_processing/ns/noise_suppressor.h"
     45 #include "modules/audio_processing/post_filter.h"
     46 #include "modules/audio_processing/render_queue_item_verifier.h"
     47 #include "modules/audio_processing/rms_level.h"
     48 #include "rtc_base/gtest_prod_util.h"
     49 #include "rtc_base/swap_queue.h"
     50 #include "rtc_base/synchronization/mutex.h"
     51 #include "rtc_base/thread_annotations.h"
     52 
     53 namespace webrtc {
     54 
     55 class ApmDataDumper;
     56 class AudioConverter;
     57 
     58 constexpr int RuntimeSettingQueueSize() {
     59  return 100;
     60 }
     61 
     62 class AudioProcessingImpl : public AudioProcessing {
     63 public:
     64  // Methods forcing APM to run in a single-threaded manner.
     65  // Acquires both the render and capture locks.
     66  explicit AudioProcessingImpl(const Environment& env);
     67  AudioProcessingImpl(
     68      const Environment& env,
     69      const AudioProcessing::Config& config,
     70      std::optional<EchoCanceller3Config> echo_canceller_config,
     71      std::optional<EchoCanceller3Config> echo_canceller_multichannel_config,
     72      std::unique_ptr<CustomProcessing> capture_post_processor,
     73      std::unique_ptr<CustomProcessing> render_pre_processor,
     74      std::unique_ptr<EchoControlFactory> echo_control_factory,
     75      scoped_refptr<EchoDetector> echo_detector,
     76      std::unique_ptr<CustomAudioAnalyzer> capture_analyzer,
     77      std::unique_ptr<NeuralResidualEchoEstimator>
     78          neural_residual_echo_estimator);
     79  ~AudioProcessingImpl() override;
     80  int Initialize() override;
     81  int Initialize(const ProcessingConfig& processing_config) override;
     82  void ApplyConfig(const AudioProcessing::Config& config) override;
     83  bool CreateAndAttachAecDump(absl::string_view file_name,
     84                              int64_t max_log_size_bytes,
     85                              TaskQueueBase* absl_nonnull
     86                                  worker_queue) override;
     87  bool CreateAndAttachAecDump(FILE* handle,
     88                              int64_t max_log_size_bytes,
     89                              TaskQueueBase* absl_nonnull
     90                                  worker_queue) override;
     91  // TODO(webrtc:5298) Deprecated variant.
     92  void AttachAecDump(std::unique_ptr<AecDump> aec_dump) override;
     93  void DetachAecDump() override;
     94  void SetRuntimeSetting(RuntimeSetting setting) override;
     95  bool PostRuntimeSetting(RuntimeSetting setting) override;
     96 
     97  // Capture-side exclusive methods possibly running APM in a
     98  // multi-threaded manner. Acquire the capture lock.
     99  int ProcessStream(const int16_t* const src,
    100                    const StreamConfig& input_config,
    101                    const StreamConfig& output_config,
    102                    int16_t* const dest) override;
    103  int ProcessStream(const float* const* src,
    104                    const StreamConfig& input_config,
    105                    const StreamConfig& output_config,
    106                    float* const* dest) override;
    107  bool GetLinearAecOutput(
    108      ArrayView<std::array<float, 160>> linear_output) const override;
    109  void set_output_will_be_muted(bool muted) override;
    110  void HandleCaptureOutputUsedSetting(bool capture_output_used)
    111      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    112  int set_stream_delay_ms(int delay) override;
    113  void set_stream_key_pressed(bool key_pressed) override;
    114  void set_stream_analog_level(int level) override;
    115  int recommended_stream_analog_level() const
    116      RTC_LOCKS_EXCLUDED(mutex_capture_) override;
    117 
    118  // Render-side exclusive methods possibly running APM in a
    119  // multi-threaded manner. Acquire the render lock.
    120  int ProcessReverseStream(const int16_t* const src,
    121                           const StreamConfig& input_config,
    122                           const StreamConfig& output_config,
    123                           int16_t* const dest) override;
    124  int AnalyzeReverseStream(const float* const* data,
    125                           const StreamConfig& reverse_config) override;
    126  int ProcessReverseStream(const float* const* src,
    127                           const StreamConfig& input_config,
    128                           const StreamConfig& output_config,
    129                           float* const* dest) override;
    130 
    131  // Methods only accessed from APM submodules or
    132  // from AudioProcessing tests in a single-threaded manner.
    133  // Hence there is no need for locks in these.
    134  int proc_sample_rate_hz() const override;
    135  int proc_split_sample_rate_hz() const override;
    136  size_t num_input_channels() const override;
    137  size_t num_proc_channels() const override;
    138  size_t num_output_channels() const override;
    139  size_t num_reverse_channels() const override;
    140  int stream_delay_ms() const override;
    141 
    142  AudioProcessingStats GetStatistics(bool /* has_remote_tracks */) override {
    143    return GetStatistics();
    144  }
    145  AudioProcessingStats GetStatistics() override {
    146    return stats_reporter_.GetStatistics();
    147  }
    148 
    149  AudioProcessing::Config GetConfig() const override;
    150 
    151 protected:
    152  // Overridden in a mock.
    153  virtual void InitializeLocked()
    154      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_);
    155  void AssertLockedForTest()
    156      RTC_ASSERT_EXCLUSIVE_LOCK(mutex_render_, mutex_capture_) {
    157    mutex_render_.AssertHeld();
    158    mutex_capture_.AssertHeld();
    159  }
    160 
    161 private:
    162  // TODO(peah): These friend classes should be removed as soon as the new
    163  // parameter setting scheme allows.
    164  FRIEND_TEST_ALL_PREFIXES(ApmConfiguration, DefaultBehavior);
    165  FRIEND_TEST_ALL_PREFIXES(ApmConfiguration, ValidConfigBehavior);
    166  FRIEND_TEST_ALL_PREFIXES(ApmConfiguration, InValidConfigBehavior);
    167 
    168  void set_stream_analog_level_locked(int level)
    169      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    170  void UpdateRecommendedInputVolumeLocked()
    171      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    172 
    173  // Class providing thread-safe message pipe functionality for
    174  // `runtime_settings_`.
    175  class RuntimeSettingEnqueuer {
    176   public:
    177    explicit RuntimeSettingEnqueuer(
    178        SwapQueue<RuntimeSetting>* runtime_settings);
    179    ~RuntimeSettingEnqueuer();
    180 
    181    // Enqueue setting and return whether the setting was successfully enqueued.
    182    bool Enqueue(RuntimeSetting setting);
    183 
    184   private:
    185    SwapQueue<RuntimeSetting>& runtime_settings_;
    186  };
    187 
    188  const Environment env_;
    189  const std::unique_ptr<ApmDataDumper> data_dumper_;
    190  static std::atomic<int> instance_count_;
    191 
    192  SwapQueue<RuntimeSetting> capture_runtime_settings_;
    193  SwapQueue<RuntimeSetting> render_runtime_settings_;
    194 
    195  RuntimeSettingEnqueuer capture_runtime_settings_enqueuer_;
    196  RuntimeSettingEnqueuer render_runtime_settings_enqueuer_;
    197 
    198  // EchoControl factory.
    199  const std::unique_ptr<EchoControlFactory> echo_control_factory_;
    200 
    201  class SubmoduleStates {
    202   public:
    203    SubmoduleStates(bool capture_post_processor_enabled,
    204                    bool render_pre_processor_enabled,
    205                    bool capture_analyzer_enabled);
    206    // Updates the submodule state and returns true if it has changed.
    207    bool Update(bool high_pass_filter_enabled,
    208                bool mobile_echo_controller_enabled,
    209                bool noise_suppressor_enabled,
    210                bool adaptive_gain_controller_enabled,
    211                bool gain_controller2_enabled,
    212                bool gain_adjustment_enabled,
    213                bool echo_controller_enabled);
    214    bool CaptureMultiBandSubModulesActive() const;
    215    bool CaptureMultiBandProcessingPresent() const;
    216    bool CaptureMultiBandProcessingActive(bool ec_processing_active) const;
    217    bool CaptureFullBandProcessingActive() const;
    218    bool CaptureAnalyzerActive() const;
    219    bool RenderMultiBandSubModulesActive() const;
    220    bool RenderFullBandProcessingActive() const;
    221    bool RenderMultiBandProcessingActive() const;
    222    bool HighPassFilteringRequired() const;
    223 
    224   private:
    225    const bool capture_post_processor_enabled_ = false;
    226    const bool render_pre_processor_enabled_ = false;
    227    const bool capture_analyzer_enabled_ = false;
    228    bool high_pass_filter_enabled_ = false;
    229    bool mobile_echo_controller_enabled_ = false;
    230    bool noise_suppressor_enabled_ = false;
    231    bool adaptive_gain_controller_enabled_ = false;
    232    bool gain_controller2_enabled_ = false;
    233    bool gain_adjustment_enabled_ = false;
    234    bool echo_controller_enabled_ = false;
    235    bool first_update_ = true;
    236  };
    237 
    238  // Methods for modifying the formats struct that is used by both
    239  // the render and capture threads. The check for whether modifications are
    240  // needed is done while holding a single lock only, thereby avoiding that the
    241  // capture thread blocks the render thread.
    242  // Called by render: Holds the render lock when reading the format struct and
    243  // acquires both locks if reinitialization is required.
    244  void MaybeInitializeRender(const StreamConfig& input_config,
    245                             const StreamConfig& output_config)
    246      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    247  // Called by capture: Acquires and releases the capture lock to read the
    248  // format struct and acquires both locks if reinitialization is needed.
    249  void MaybeInitializeCapture(const StreamConfig& input_config,
    250                              const StreamConfig& output_config);
    251 
    252  // Method for updating the state keeping track of the active submodules.
    253  // Returns a bool indicating whether the state has changed.
    254  bool UpdateActiveSubmoduleStates()
    255      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    256 
    257  // Methods requiring APM running in a single-threaded manner, requiring both
    258  // the render and capture lock to be acquired.
    259  void InitializeLocked(const ProcessingConfig& config)
    260      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_);
    261  void InitializeResidualEchoDetector()
    262      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_);
    263  void InitializeEchoController()
    264      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_);
    265 
    266  // Initializations of capture-only sub-modules, requiring the capture lock
    267  // already acquired.
    268  void InitializeHighPassFilter(bool forced_reset)
    269      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    270  void InitializeGainController1() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    271  // Initializes the `GainController2` sub-module. If the sub-module is enabled,
    272  // recreates it.
    273  void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    274  void InitializeNoiseSuppressor() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    275  void InitializeCaptureLevelsAdjuster()
    276      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    277  void InitializePostProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    278  void InitializeAnalyzer() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    279 
    280  // Initializations of render-only submodules, requiring the render lock
    281  // already acquired.
    282  void InitializePreProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    283 
    284  // Sample rate used for the fullband processing.
    285  int proc_fullband_sample_rate_hz() const
    286      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    287 
    288  // Empties and handles the respective RuntimeSetting queues.
    289  void HandleCaptureRuntimeSettings()
    290      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    291  void HandleRenderRuntimeSettings()
    292      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    293 
    294  void EmptyQueuedRenderAudio() RTC_LOCKS_EXCLUDED(mutex_capture_);
    295  void EmptyQueuedRenderAudioLocked()
    296      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    297  void AllocateRenderQueue()
    298      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_);
    299  void QueueBandedRenderAudio(AudioBuffer* audio)
    300      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    301  void QueueNonbandedRenderAudio(AudioBuffer* audio)
    302      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    303 
    304  // Capture-side exclusive methods possibly running APM in a multi-threaded
    305  // manner that are called with the render lock already acquired.
    306  int ProcessCaptureStreamLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    307 
    308  // Render-side exclusive methods possibly running APM in a multi-threaded
    309  // manner that are called with the render lock already acquired.
    310  int AnalyzeReverseStreamLocked(const float* const* src,
    311                                 const StreamConfig& input_config,
    312                                 const StreamConfig& output_config)
    313      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    314  int ProcessRenderStreamLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_);
    315 
    316  // Collects configuration settings from public and private
    317  // submodules to be saved as an audioproc::Config message on the
    318  // AecDump if it is attached.  If not `forced`, only writes the current
    319  // config if it is different from the last saved one; if `forced`,
    320  // writes the config regardless of the last saved.
    321  void WriteAecDumpConfigMessage(bool forced)
    322      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    323 
    324  // Notifies attached AecDump of current configuration and capture data.
    325  void RecordUnprocessedCaptureStream(const float* const* capture_stream)
    326      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    327 
    328  void RecordUnprocessedCaptureStream(const int16_t* const data,
    329                                      const StreamConfig& config)
    330      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    331 
    332  // Notifies attached AecDump of current configuration and
    333  // processed capture data and issues a capture stream recording
    334  // request.
    335  void RecordProcessedCaptureStream(
    336      const float* const* processed_capture_stream)
    337      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    338 
    339  void RecordProcessedCaptureStream(const int16_t* const data,
    340                                    const StreamConfig& config)
    341      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    342 
    343  // Notifies attached AecDump about current state (delay, drift, etc).
    344  void RecordAudioProcessingState()
    345      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    346 
    347  // Ensures that overruns in the capture runtime settings queue is properly
    348  // handled by the code, providing safe-fallbacks to mitigate the implications
    349  // of any settings being missed.
    350  void HandleOverrunInCaptureRuntimeSettingsQueue()
    351      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_capture_);
    352 
    353  // AecDump instance used for optionally logging APM config, input
    354  // and output to file in the AEC-dump format defined in debug.proto.
    355  std::unique_ptr<AecDump> aec_dump_;
    356 
    357  // Hold the last config written with AecDump for avoiding writing
    358  // the same config twice.
    359  InternalAPMConfig apm_config_for_aec_dump_ RTC_GUARDED_BY(mutex_capture_);
    360 
    361  // Critical sections.
    362  mutable Mutex mutex_render_ RTC_ACQUIRED_BEFORE(mutex_capture_);
    363  mutable Mutex mutex_capture_;
    364 
    365  // Struct containing the Config specifying the behavior of APM.
    366  AudioProcessing::Config config_;
    367 
    368  // AEC3 settings used when an EchoControlFactory is not present.
    369  const std::optional<EchoCanceller3Config> echo_canceller_config_;
    370  const std::optional<EchoCanceller3Config> echo_canceller_multichannel_config_;
    371 
    372  // Class containing information about what submodules are active.
    373  SubmoduleStates submodule_states_;
    374 
    375  // Struct containing the pointers to the submodules.
    376  struct Submodules {
    377    Submodules(std::unique_ptr<CustomProcessing> capture_post_processor,
    378               std::unique_ptr<CustomProcessing> render_pre_processor,
    379               scoped_refptr<EchoDetector> echo_detector,
    380               std::unique_ptr<CustomAudioAnalyzer> capture_analyzer,
    381               std::unique_ptr<NeuralResidualEchoEstimator>
    382                   neural_residual_echo_estimator)
    383        : echo_detector(std::move(echo_detector)),
    384          capture_post_processor(std::move(capture_post_processor)),
    385          render_pre_processor(std::move(render_pre_processor)),
    386          capture_analyzer(std::move(capture_analyzer)),
    387          neural_residual_echo_estimator(
    388              std::move(neural_residual_echo_estimator)) {}
    389    // Accessed internally from capture or during initialization.
    390    const scoped_refptr<EchoDetector> echo_detector;
    391    const std::unique_ptr<CustomProcessing> capture_post_processor;
    392    const std::unique_ptr<CustomProcessing> render_pre_processor;
    393    const std::unique_ptr<CustomAudioAnalyzer> capture_analyzer;
    394    std::unique_ptr<AgcManagerDirect> agc_manager;
    395    std::unique_ptr<GainControlImpl> gain_control;
    396    std::unique_ptr<GainController2> gain_controller2;
    397    std::unique_ptr<HighPassFilter> high_pass_filter;
    398    std::unique_ptr<EchoControl> echo_controller;
    399    std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
    400    std::unique_ptr<NoiseSuppressor> noise_suppressor;
    401    std::unique_ptr<PostFilter> post_filter;
    402    std::unique_ptr<CaptureLevelsAdjuster> capture_levels_adjuster;
    403    std::unique_ptr<NeuralResidualEchoEstimator> neural_residual_echo_estimator;
    404  } submodules_;
    405 
    406  // State that is written to while holding both the render and capture locks
    407  // but can be read without any lock being held.
    408  // As this is only accessed internally of APM, and all internal methods in APM
    409  // either are holding the render or capture locks, this construct is safe as
    410  // it is not possible to read the variables while writing them.
    411  struct ApmFormatState {
    412    ApmFormatState()
    413        :  // Format of processing streams at input/output call sites.
    414          api_format({{{kSampleRate16kHz, 1},
    415                       {kSampleRate16kHz, 1},
    416                       {kSampleRate16kHz, 1},
    417                       {kSampleRate16kHz, 1}}}),
    418          render_processing_format(kSampleRate16kHz, 1) {}
    419    ProcessingConfig api_format;
    420    StreamConfig render_processing_format;
    421  } formats_;
    422 
    423  // APM constants.
    424  const struct ApmConstants {
    425    ApmConstants(bool multi_channel_render_support,
    426                 bool multi_channel_capture_support,
    427                 bool enforce_split_band_hpf,
    428                 bool minimize_processing_for_unused_output)
    429        : multi_channel_render_support(multi_channel_render_support),
    430          multi_channel_capture_support(multi_channel_capture_support),
    431          enforce_split_band_hpf(enforce_split_band_hpf),
    432          minimize_processing_for_unused_output(
    433              minimize_processing_for_unused_output) {}
    434    bool multi_channel_render_support;
    435    bool multi_channel_capture_support;
    436    bool enforce_split_band_hpf;
    437    bool minimize_processing_for_unused_output;
    438  } constants_;
    439 
    440  struct ApmCaptureState {
    441    ApmCaptureState();
    442    ~ApmCaptureState();
    443    bool was_stream_delay_set;
    444    bool capture_output_used;
    445    bool capture_output_used_last_frame;
    446    bool key_pressed;
    447    std::unique_ptr<AudioBuffer> capture_audio;
    448    std::unique_ptr<AudioBuffer> capture_fullband_audio;
    449    std::unique_ptr<AudioBuffer> linear_aec_output;
    450    // Only the rate and samples fields of capture_processing_format_ are used
    451    // because the capture processing number of channels is mutable and is
    452    // tracked by the capture_audio_.
    453    StreamConfig capture_processing_format;
    454    int split_rate;
    455    bool echo_path_gain_change;
    456    float prev_pre_adjustment_gain;
    457    int playout_volume;
    458    int prev_playout_volume;
    459    AudioProcessingStats stats;
    460    // Input volume applied on the audio input device when the audio is
    461    // acquired. Unspecified when unknown.
    462    std::optional<int> applied_input_volume;
    463    bool applied_input_volume_changed;
    464    // Recommended input volume to apply on the audio input device the next time
    465    // that audio is acquired. Unspecified when no input volume can be
    466    // recommended.
    467    std::optional<int> recommended_input_volume;
    468  } capture_ RTC_GUARDED_BY(mutex_capture_);
    469 
    470  struct ApmCaptureNonLockedState {
    471    ApmCaptureNonLockedState()
    472        : capture_processing_format(kSampleRate16kHz),
    473          split_rate(kSampleRate16kHz),
    474          stream_delay_ms(0) {}
    475    // Only the rate and samples fields of capture_processing_format_ are used
    476    // because the forward processing number of channels is mutable and is
    477    // tracked by the capture_audio_.
    478    StreamConfig capture_processing_format;
    479    int split_rate;
    480    int stream_delay_ms;
    481    bool echo_controller_enabled = false;
    482  } capture_nonlocked_;
    483 
    484  struct ApmRenderState {
    485    ApmRenderState();
    486    ~ApmRenderState();
    487    std::unique_ptr<AudioConverter> render_converter;
    488    std::unique_ptr<AudioBuffer> render_audio;
    489  } render_ RTC_GUARDED_BY(mutex_render_);
    490 
    491  // Class for statistics reporting. The class is thread-safe and no lock is
    492  // needed when accessing it.
    493  class ApmStatsReporter {
    494   public:
    495    ApmStatsReporter();
    496    ~ApmStatsReporter();
    497 
    498    // Returns the most recently reported statistics.
    499    AudioProcessingStats GetStatistics();
    500 
    501    // Update the cached statistics.
    502    void UpdateStatistics(const AudioProcessingStats& new_stats);
    503 
    504   private:
    505    Mutex mutex_stats_;
    506    AudioProcessingStats cached_stats_ RTC_GUARDED_BY(mutex_stats_);
    507    SwapQueue<AudioProcessingStats> stats_message_queue_;
    508  } stats_reporter_;
    509 
    510  std::vector<int16_t> aecm_render_queue_buffer_ RTC_GUARDED_BY(mutex_render_);
    511  std::vector<int16_t> aecm_capture_queue_buffer_
    512      RTC_GUARDED_BY(mutex_capture_);
    513 
    514  size_t agc_render_queue_element_max_size_ RTC_GUARDED_BY(mutex_render_)
    515      RTC_GUARDED_BY(mutex_capture_) = 0;
    516  std::vector<int16_t> agc_render_queue_buffer_ RTC_GUARDED_BY(mutex_render_);
    517  std::vector<int16_t> agc_capture_queue_buffer_ RTC_GUARDED_BY(mutex_capture_);
    518 
    519  size_t red_render_queue_element_max_size_ RTC_GUARDED_BY(mutex_render_)
    520      RTC_GUARDED_BY(mutex_capture_) = 0;
    521  std::vector<float> red_render_queue_buffer_ RTC_GUARDED_BY(mutex_render_);
    522  std::vector<float> red_capture_queue_buffer_ RTC_GUARDED_BY(mutex_capture_);
    523 
    524  RmsLevel capture_input_rms_ RTC_GUARDED_BY(mutex_capture_);
    525  RmsLevel capture_output_rms_ RTC_GUARDED_BY(mutex_capture_);
    526  int capture_rms_interval_counter_ RTC_GUARDED_BY(mutex_capture_) = 0;
    527 
    528  InputVolumeStatsReporter applied_input_volume_stats_reporter_
    529      RTC_GUARDED_BY(mutex_capture_);
    530  InputVolumeStatsReporter recommended_input_volume_stats_reporter_
    531      RTC_GUARDED_BY(mutex_capture_);
    532 
    533  // Lock protection not needed.
    534  std::unique_ptr<
    535      SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>>
    536      aecm_render_signal_queue_;
    537  std::unique_ptr<
    538      SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>>
    539      agc_render_signal_queue_;
    540  std::unique_ptr<SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>>
    541      red_render_signal_queue_;
    542 };
    543 
    544 }  // namespace webrtc
    545 
    546 #endif  // MODULES_AUDIO_PROCESSING_AUDIO_PROCESSING_IMPL_H_