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