tor-browser

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

quantile_noise_estimator.cc (3029B)


      1 /*
      2 *  Copyright (c) 2019 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/ns/quantile_noise_estimator.h"
     12 
     13 #include <algorithm>
     14 #include <array>
     15 #include <cmath>
     16 #include <cstddef>
     17 
     18 #include "api/array_view.h"
     19 #include "modules/audio_processing/ns/fast_math.h"
     20 #include "modules/audio_processing/ns/ns_common.h"
     21 
     22 namespace webrtc {
     23 
     24 QuantileNoiseEstimator::QuantileNoiseEstimator() {
     25  quantile_.fill(0.f);
     26  density_.fill(0.3f);
     27  log_quantile_.fill(8.f);
     28 
     29  constexpr float kOneBySimult = 1.f / kSimult;
     30  for (size_t i = 0; i < kSimult; ++i) {
     31    counter_[i] = floor(kLongStartupPhaseBlocks * (i + 1.f) * kOneBySimult);
     32  }
     33 }
     34 
     35 void QuantileNoiseEstimator::Estimate(
     36    ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
     37    ArrayView<float, kFftSizeBy2Plus1> noise_spectrum) {
     38  std::array<float, kFftSizeBy2Plus1> log_spectrum;
     39  LogApproximation(signal_spectrum, log_spectrum);
     40 
     41  int quantile_index_to_return = -1;
     42  // Loop over simultaneous estimates.
     43  for (int s = 0, k = 0; s < kSimult;
     44       ++s, k += static_cast<int>(kFftSizeBy2Plus1)) {
     45    const float one_by_counter_plus_1 = 1.f / (counter_[s] + 1.f);
     46    for (int i = 0, j = k; i < static_cast<int>(kFftSizeBy2Plus1); ++i, ++j) {
     47      // Update log quantile estimate.
     48      const float delta = density_[j] > 1.f ? 40.f / density_[j] : 40.f;
     49 
     50      const float multiplier = delta * one_by_counter_plus_1;
     51      if (log_spectrum[i] > log_quantile_[j]) {
     52        log_quantile_[j] += 0.25f * multiplier;
     53      } else {
     54        log_quantile_[j] -= 0.75f * multiplier;
     55      }
     56 
     57      // Update density estimate.
     58      constexpr float kWidth = 0.01f;
     59      constexpr float kOneByWidthPlus2 = 1.f / (2.f * kWidth);
     60      if (fabs(log_spectrum[i] - log_quantile_[j]) < kWidth) {
     61        density_[j] = (counter_[s] * density_[j] + kOneByWidthPlus2) *
     62                      one_by_counter_plus_1;
     63      }
     64    }
     65 
     66    if (counter_[s] >= kLongStartupPhaseBlocks) {
     67      counter_[s] = 0;
     68      if (num_updates_ >= kLongStartupPhaseBlocks) {
     69        quantile_index_to_return = k;
     70      }
     71    }
     72 
     73    ++counter_[s];
     74  }
     75 
     76  // Sequentially update the noise during startup.
     77  if (num_updates_ < kLongStartupPhaseBlocks) {
     78    // Use the last "s" to get noise during startup that differ from zero.
     79    quantile_index_to_return = kFftSizeBy2Plus1 * (kSimult - 1);
     80    ++num_updates_;
     81  }
     82 
     83  if (quantile_index_to_return >= 0) {
     84    ExpApproximation(
     85        ArrayView<const float>(&log_quantile_[quantile_index_to_return],
     86                               kFftSizeBy2Plus1),
     87        quantile_);
     88  }
     89 
     90  std::copy(quantile_.begin(), quantile_.end(), noise_spectrum.begin());
     91 }
     92 
     93 }  // namespace webrtc