mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

To focus on the ability to predict clipping, the clipping predictor evaluator doesn't increment the true positive count anymore when a prediction is simultaneously observed with a detection. Note that `WebRTC.Audio.Agc.ClippingPredictor.F1Score` is still used to log the F1 score - i.e., the histogram hasn't been renamed. Bug: webrtc:12774 Change-Id: Ia987e568a6df2a3ddba7fa1b5697d6feda22d20c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231233 Commit-Queue: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Hanna Silen <silen@webrtc.org> Cr-Commit-Position: refs/heads/main@{#34942}
122 lines
5 KiB
C++
122 lines
5 KiB
C++
/*
|
|
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_EVALUATOR_H_
|
|
#define MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_EVALUATOR_H_
|
|
|
|
#include <vector>
|
|
|
|
#include "absl/types/optional.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// Clipping prediction counters.
|
|
struct ClippingPredictionCounters {
|
|
int true_positives; // TP.
|
|
int true_negatives; // TN.
|
|
int false_positives; // FP.
|
|
int false_negatives; // FN.
|
|
};
|
|
|
|
// Counts true/false positives/negatives while observing sequences of flag pairs
|
|
// that indicate whether clipping has been detected and/or if clipping is
|
|
// predicted. When a true positive is found measures the time interval between
|
|
// prediction and detection events.
|
|
// After a prediction is observed and for a period equal to
|
|
// `history_size` calls to `Observe()`, one or more detections are expected. If
|
|
// the expectation is met, a true positive is added and the time interval
|
|
// between the earliest prediction and the detection is recorded; otherwise,
|
|
// when the deadline is reached, a false positive is added. Note that one
|
|
// detection matches all the expected detections that have not expired - i.e.,
|
|
// one detection counts as multiple true positives.
|
|
// If a detection is observed, but no prediction has been observed over the past
|
|
// `history_size` calls to `Observe()`, then a false negative is added;
|
|
// otherwise, a true negative is added.
|
|
class ClippingPredictorEvaluator {
|
|
public:
|
|
// Ctor. `history_size` indicates how long to wait for a call to `Observe()`
|
|
// having `clipping_detected` set to true from the time clipping is predicted.
|
|
explicit ClippingPredictorEvaluator(int history_size);
|
|
ClippingPredictorEvaluator(const ClippingPredictorEvaluator&) = delete;
|
|
ClippingPredictorEvaluator& operator=(const ClippingPredictorEvaluator&) =
|
|
delete;
|
|
~ClippingPredictorEvaluator();
|
|
|
|
// Observes whether clipping has been detected and/or if clipping is
|
|
// predicted. When predicted one or more detections are expected in the next
|
|
// `history_size_` calls of `Observe()`. When true positives are found returns
|
|
// the prediction interval between the earliest prediction and the detection.
|
|
absl::optional<int> Observe(bool clipping_detected, bool clipping_predicted);
|
|
|
|
// Removes any expectation recently set after a call to `Observe()` having
|
|
// `clipping_predicted` set to true. Counters won't be reset.
|
|
void RemoveExpectations();
|
|
|
|
// Resets counters and removes any expectation (see `RemoveExpectations()`).
|
|
void Reset();
|
|
|
|
ClippingPredictionCounters counters() const { return counters_; }
|
|
|
|
private:
|
|
const int history_size_;
|
|
|
|
// State of a detection expected to be observed after a prediction.
|
|
struct ExpectedDetection {
|
|
// Time to live (TTL); remaining number of `Observe()` calls to match a call
|
|
// having `clipping_detected` set to true.
|
|
int ttl;
|
|
// True if an `Observe()` call having `clipping_detected` set to true has
|
|
// been observed.
|
|
bool detected;
|
|
};
|
|
// Ring buffer of expected detections.
|
|
const int ring_buffer_capacity_;
|
|
std::vector<ExpectedDetection> ring_buffer_;
|
|
int ring_buffer_tail_;
|
|
int ring_buffer_size_;
|
|
|
|
// Pushes `expected_detection` into `expected_matches_ring_buffer_`.
|
|
void Push(ExpectedDetection expected_detection);
|
|
// Decreased the TTLs in `expected_matches_ring_buffer_` and removes expired
|
|
// items.
|
|
void DecreaseTimesToLive();
|
|
// Returns the prediction interval for the earliest unexpired expected
|
|
// detection if any.
|
|
absl::optional<int> FindEarliestPredictionInterval() const;
|
|
// Marks all the items in `expected_matches_ring_buffer_` as `detected` and
|
|
// returns the number of updated items.
|
|
int MarkExpectedDetectionAsDetected();
|
|
// Returns true if `expected_matches_ring_buffer_` has an item having `ttl`
|
|
// equal to 0 (expired) and `detected` equal to false (unmatched).
|
|
bool HasExpiredUnmatchedExpectedDetection() const;
|
|
|
|
// Counters.
|
|
ClippingPredictionCounters counters_;
|
|
};
|
|
|
|
// Clipping prediction metrics derived from the clipping prediction counters.
|
|
struct ClippingPredictionMetrics {
|
|
// Precision (P) is defined as TP / (TP + FP).
|
|
float precision;
|
|
// Recall (R) is defined as TP / (TP + FN).
|
|
float recall;
|
|
// The F1 score is defined as 2 * P * R / (P + R).
|
|
float f1_score;
|
|
};
|
|
|
|
// Derives clipping prediction metrics from the true/false positives/negatives
|
|
// `counters`. Returns an unspecified value if one or more metrics are not
|
|
// defined.
|
|
absl::optional<ClippingPredictionMetrics> ComputeClippingPredictionMetrics(
|
|
const ClippingPredictionCounters& counters);
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_EVALUATOR_H_
|