tor-browser

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

dominant_nearend_detector.cc (3245B)


      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/aec3/dominant_nearend_detector.h"
     12 
     13 #include <algorithm>
     14 #include <array>
     15 #include <cstddef>
     16 #include <numeric>
     17 
     18 #include "api/array_view.h"
     19 #include "api/audio/echo_canceller3_config.h"
     20 #include "modules/audio_processing/aec3/aec3_common.h"
     21 #include "rtc_base/checks.h"
     22 
     23 namespace webrtc {
     24 DominantNearendDetector::DominantNearendDetector(
     25    const EchoCanceller3Config::Suppressor::DominantNearendDetection& config,
     26    size_t num_capture_channels)
     27    : enr_threshold_(config.enr_threshold),
     28      enr_exit_threshold_(config.enr_exit_threshold),
     29      snr_threshold_(config.snr_threshold),
     30      hold_duration_(config.hold_duration),
     31      trigger_threshold_(config.trigger_threshold),
     32      use_during_initial_phase_(config.use_during_initial_phase),
     33      num_capture_channels_(num_capture_channels),
     34      trigger_counters_(num_capture_channels_),
     35      hold_counters_(num_capture_channels_) {}
     36 
     37 void DominantNearendDetector::Update(
     38    ArrayView<const std::array<float, kFftLengthBy2Plus1>> nearend_spectrum,
     39    ArrayView<const std::array<float, kFftLengthBy2Plus1>>
     40        residual_echo_spectrum,
     41    ArrayView<const std::array<float, kFftLengthBy2Plus1>>
     42        comfort_noise_spectrum,
     43    bool initial_state) {
     44  nearend_state_ = false;
     45 
     46  auto low_frequency_energy = [](ArrayView<const float> spectrum) {
     47    RTC_DCHECK_LE(16, spectrum.size());
     48    return std::accumulate(spectrum.begin() + 1, spectrum.begin() + 16, 0.f);
     49  };
     50 
     51  for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
     52    const float ne_sum = low_frequency_energy(nearend_spectrum[ch]);
     53    const float echo_sum = low_frequency_energy(residual_echo_spectrum[ch]);
     54    const float noise_sum = low_frequency_energy(comfort_noise_spectrum[ch]);
     55 
     56    // Detect strong active nearend if the nearend is sufficiently stronger than
     57    // the echo and the nearend noise.
     58    if ((!initial_state || use_during_initial_phase_) &&
     59        echo_sum < enr_threshold_ * ne_sum &&
     60        ne_sum > snr_threshold_ * noise_sum) {
     61      if (++trigger_counters_[ch] >= trigger_threshold_) {
     62        // After a period of strong active nearend activity, flag nearend mode.
     63        hold_counters_[ch] = hold_duration_;
     64        trigger_counters_[ch] = trigger_threshold_;
     65      }
     66    } else {
     67      // Forget previously detected strong active nearend activity.
     68      trigger_counters_[ch] = std::max(0, trigger_counters_[ch] - 1);
     69    }
     70 
     71    // Exit nearend-state early at strong echo.
     72    if (echo_sum > enr_exit_threshold_ * ne_sum &&
     73        echo_sum > snr_threshold_ * noise_sum) {
     74      hold_counters_[ch] = 0;
     75    }
     76 
     77    // Remain in any nearend mode for a certain duration.
     78    hold_counters_[ch] = std::max(0, hold_counters_[ch] - 1);
     79    nearend_state_ = nearend_state_ || hold_counters_[ch] > 0;
     80  }
     81 }
     82 }  // namespace webrtc