tor-browser

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

echo_remover_metrics.cc (6222B)


      1 /*
      2 *  Copyright (c) 2017 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/aec3/echo_remover_metrics.h"
     12 
     13 #include <algorithm>
     14 #include <array>
     15 #include <cmath>
     16 #include <cstddef>
     17 #include <numeric>
     18 
     19 #include "modules/audio_processing/aec3/aec3_common.h"
     20 #include "modules/audio_processing/aec3/aec_state.h"
     21 #include "rtc_base/checks.h"
     22 #include "rtc_base/numerics/safe_minmax.h"
     23 #include "system_wrappers/include/metrics.h"
     24 
     25 namespace webrtc {
     26 
     27 EchoRemoverMetrics::DbMetric::DbMetric() : DbMetric(0.f, 0.f, 0.f) {}
     28 EchoRemoverMetrics::DbMetric::DbMetric(float sum_value,
     29                                       float floor_value,
     30                                       float ceil_value)
     31    : sum_value(sum_value), floor_value(floor_value), ceil_value(ceil_value) {}
     32 
     33 void EchoRemoverMetrics::DbMetric::Update(float value) {
     34  sum_value += value;
     35  floor_value = std::min(floor_value, value);
     36  ceil_value = std::max(ceil_value, value);
     37 }
     38 
     39 void EchoRemoverMetrics::DbMetric::UpdateInstant(float value) {
     40  sum_value = value;
     41  floor_value = std::min(floor_value, value);
     42  ceil_value = std::max(ceil_value, value);
     43 }
     44 
     45 EchoRemoverMetrics::EchoRemoverMetrics() {
     46  ResetMetrics();
     47 }
     48 
     49 void EchoRemoverMetrics::ResetMetrics() {
     50  erl_time_domain_ = DbMetric(0.f, 10000.f, 0.000f);
     51  erle_time_domain_ = DbMetric(0.f, 0.f, 1000.f);
     52  saturated_capture_ = false;
     53 }
     54 
     55 void EchoRemoverMetrics::Update(
     56    const AecState& aec_state,
     57    const std::array<float, kFftLengthBy2Plus1>& /* comfort_noise_spectrum */,
     58    const std::array<float, kFftLengthBy2Plus1>& /* suppressor_gain */) {
     59  metrics_reported_ = false;
     60  if (++block_counter_ <= kMetricsCollectionBlocks) {
     61    erl_time_domain_.UpdateInstant(aec_state.ErlTimeDomain());
     62    erle_time_domain_.UpdateInstant(aec_state.FullBandErleLog2());
     63    saturated_capture_ = saturated_capture_ || aec_state.SaturatedCapture();
     64  } else {
     65    // Report the metrics over several frames in order to lower the impact of
     66    // the logarithms involved on the computational complexity.
     67    switch (block_counter_) {
     68      case kMetricsCollectionBlocks + 1:
     69        RTC_HISTOGRAM_BOOLEAN(
     70            "WebRTC.Audio.EchoCanceller.UsableLinearEstimate",
     71            static_cast<int>(aec_state.UsableLinearEstimate() ? 1 : 0));
     72        RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.FilterDelay",
     73                                    aec_state.MinDirectPathFilterDelay(), 0, 30,
     74                                    31);
     75        RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.EchoCanceller.CaptureSaturation",
     76                              static_cast<int>(saturated_capture_ ? 1 : 0));
     77        break;
     78      case kMetricsCollectionBlocks + 2:
     79        RTC_HISTOGRAM_COUNTS_LINEAR(
     80            "WebRTC.Audio.EchoCanceller.Erl.Value",
     81            aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f,
     82                                                erl_time_domain_.sum_value),
     83            0, 59, 30);
     84        RTC_HISTOGRAM_COUNTS_LINEAR(
     85            "WebRTC.Audio.EchoCanceller.Erl.Max",
     86            aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f,
     87                                                erl_time_domain_.ceil_value),
     88            0, 59, 30);
     89        RTC_HISTOGRAM_COUNTS_LINEAR(
     90            "WebRTC.Audio.EchoCanceller.Erl.Min",
     91            aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f,
     92                                                erl_time_domain_.floor_value),
     93            0, 59, 30);
     94        break;
     95      case kMetricsCollectionBlocks + 3:
     96        RTC_HISTOGRAM_COUNTS_LINEAR(
     97            "WebRTC.Audio.EchoCanceller.Erle.Value",
     98            aec3::TransformDbMetricForReporting(false, 0.f, 19.f, 0.f, 1.f,
     99                                                erle_time_domain_.sum_value),
    100            0, 19, 20);
    101        RTC_HISTOGRAM_COUNTS_LINEAR(
    102            "WebRTC.Audio.EchoCanceller.Erle.Max",
    103            aec3::TransformDbMetricForReporting(false, 0.f, 19.f, 0.f, 1.f,
    104                                                erle_time_domain_.ceil_value),
    105            0, 19, 20);
    106        RTC_HISTOGRAM_COUNTS_LINEAR(
    107            "WebRTC.Audio.EchoCanceller.Erle.Min",
    108            aec3::TransformDbMetricForReporting(false, 0.f, 19.f, 0.f, 1.f,
    109                                                erle_time_domain_.floor_value),
    110            0, 19, 20);
    111        metrics_reported_ = true;
    112        RTC_DCHECK_EQ(kMetricsReportingIntervalBlocks, block_counter_);
    113        block_counter_ = 0;
    114        ResetMetrics();
    115        break;
    116      default:
    117        RTC_DCHECK_NOTREACHED();
    118        break;
    119    }
    120  }
    121 }
    122 
    123 namespace aec3 {
    124 
    125 void UpdateDbMetric(const std::array<float, kFftLengthBy2Plus1>& value,
    126                    std::array<EchoRemoverMetrics::DbMetric, 2>* statistic) {
    127  RTC_DCHECK(statistic);
    128  // Truncation is intended in the band width computation.
    129  constexpr int kNumBands = 2;
    130  constexpr int kBandWidth = 65 / kNumBands;
    131  constexpr float kOneByBandWidth = 1.f / kBandWidth;
    132  RTC_DCHECK_EQ(kNumBands, statistic->size());
    133  RTC_DCHECK_EQ(65, value.size());
    134  for (size_t k = 0; k < statistic->size(); ++k) {
    135    float average_band =
    136        std::accumulate(value.begin() + kBandWidth * k,
    137                        value.begin() + kBandWidth * (k + 1), 0.f) *
    138        kOneByBandWidth;
    139    (*statistic)[k].Update(average_band);
    140  }
    141 }
    142 
    143 int TransformDbMetricForReporting(bool negate,
    144                                  float min_value,
    145                                  float max_value,
    146                                  float offset,
    147                                  float scaling,
    148                                  float value) {
    149  float new_value = 10.f * std::log10(value * scaling + 1e-10f) + offset;
    150  if (negate) {
    151    new_value = -new_value;
    152  }
    153  return static_cast<int>(SafeClamp(new_value, min_value, max_value));
    154 }
    155 
    156 }  // namespace aec3
    157 
    158 }  // namespace webrtc