1 /* 2 * Copyright (c) 2022 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_AEC3_MULTI_CHANNEL_CONTENT_DETECTOR_H_ 12 #define MODULES_AUDIO_PROCESSING_AEC3_MULTI_CHANNEL_CONTENT_DETECTOR_H_ 13 14 #include <stddef.h> 15 16 #include <memory> 17 #include <vector> 18 19 #include "absl/types/optional.h" 20 21 namespace webrtc { 22 23 // Analyzes audio content to determine whether the contained audio is proper 24 // multichannel, or only upmixed mono. To allow for differences introduced by 25 // hardware drivers, a threshold `detection_threshold` is used for the 26 // detection. 27 // Logs metrics continously and upon destruction. 28 class MultiChannelContentDetector { 29 public: 30 // If |stereo_detection_timeout_threshold_seconds| <= 0, no timeout is 31 // applied: Once multichannel is detected, the detector remains in that state 32 // for its lifetime. 33 MultiChannelContentDetector(bool detect_stereo_content, 34 int num_render_input_channels, 35 float detection_threshold, 36 int stereo_detection_timeout_threshold_seconds, 37 float stereo_detection_hysteresis_seconds); 38 39 // Compares the left and right channels in the render `frame` to determine 40 // whether the signal is a proper multichannel signal. Returns a bool 41 // indicating whether a change in the proper multichannel content was 42 // detected. 43 bool UpdateDetection( 44 const std::vector<std::vector<std::vector<float>>>& frame); 45 IsProperMultiChannelContentDetected()46 bool IsProperMultiChannelContentDetected() const { 47 return persistent_multichannel_content_detected_; 48 } 49 IsTemporaryMultiChannelContentDetected()50 bool IsTemporaryMultiChannelContentDetected() const { 51 return temporary_multichannel_content_detected_; 52 } 53 54 private: 55 // Tracks and logs metrics for the amount of multichannel content detected. 56 class MetricsLogger { 57 public: 58 MetricsLogger(); 59 60 // The destructor logs call summary statistics. 61 ~MetricsLogger(); 62 63 // Updates and logs metrics. 64 void Update(bool persistent_multichannel_content_detected); 65 66 private: 67 int frame_counter_ = 0; 68 69 // Counts the number of frames of persistent multichannel audio observed 70 // during the current metrics collection interval. 71 int persistent_multichannel_frame_counter_ = 0; 72 73 // Indicates whether persistent multichannel content has ever been detected. 74 bool any_multichannel_content_detected_ = false; 75 }; 76 77 const bool detect_stereo_content_; 78 const float detection_threshold_; 79 const absl::optional<int> detection_timeout_threshold_frames_; 80 const int stereo_detection_hysteresis_frames_; 81 82 // Collects and reports metrics on the amount of multichannel content 83 // detected. Only created if |num_render_input_channels| > 1 and 84 // |detect_stereo_content_| is true. 85 const std::unique_ptr<MetricsLogger> metrics_logger_; 86 87 bool persistent_multichannel_content_detected_; 88 bool temporary_multichannel_content_detected_ = false; 89 int64_t frames_since_stereo_detected_last_ = 0; 90 int64_t consecutive_frames_with_stereo_ = 0; 91 }; 92 93 } // namespace webrtc 94 95 #endif // MODULES_AUDIO_PROCESSING_AEC3_MULTI_CHANNEL_CONTENT_DETECTOR_H_ 96