tor-browser

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

echo_audibility.cc (4551B)


      1 /*
      2 *  Copyright (c) 2018 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_audibility.h"
     12 
     13 #include <algorithm>
     14 #include <cmath>
     15 #include <optional>
     16 #include <utility>
     17 #include <vector>
     18 
     19 #include "api/array_view.h"
     20 #include "modules/audio_processing/aec3/aec3_common.h"
     21 #include "modules/audio_processing/aec3/block_buffer.h"
     22 #include "modules/audio_processing/aec3/render_buffer.h"
     23 #include "modules/audio_processing/aec3/spectrum_buffer.h"
     24 #include "modules/audio_processing/aec3/stationarity_estimator.h"
     25 
     26 namespace webrtc {
     27 
     28 EchoAudibility::EchoAudibility(bool use_render_stationarity_at_init)
     29    : use_render_stationarity_at_init_(use_render_stationarity_at_init) {
     30  Reset();
     31 }
     32 
     33 EchoAudibility::~EchoAudibility() = default;
     34 
     35 void EchoAudibility::Update(const RenderBuffer& render_buffer,
     36                            ArrayView<const float> average_reverb,
     37                            int delay_blocks,
     38                            bool external_delay_seen) {
     39  UpdateRenderNoiseEstimator(render_buffer.GetSpectrumBuffer(),
     40                             render_buffer.GetBlockBuffer(),
     41                             external_delay_seen);
     42 
     43  if (external_delay_seen || use_render_stationarity_at_init_) {
     44    UpdateRenderStationarityFlags(render_buffer, average_reverb, delay_blocks);
     45  }
     46 }
     47 
     48 void EchoAudibility::Reset() {
     49  render_stationarity_.Reset();
     50  non_zero_render_seen_ = false;
     51  render_spectrum_write_prev_ = std::nullopt;
     52 }
     53 
     54 void EchoAudibility::UpdateRenderStationarityFlags(
     55    const RenderBuffer& render_buffer,
     56    ArrayView<const float> average_reverb,
     57    int min_channel_delay_blocks) {
     58  const SpectrumBuffer& spectrum_buffer = render_buffer.GetSpectrumBuffer();
     59  int idx_at_delay = spectrum_buffer.OffsetIndex(spectrum_buffer.read,
     60                                                 min_channel_delay_blocks);
     61 
     62  int num_lookahead = render_buffer.Headroom() - min_channel_delay_blocks + 1;
     63  num_lookahead = std::max(0, num_lookahead);
     64 
     65  render_stationarity_.UpdateStationarityFlags(spectrum_buffer, average_reverb,
     66                                               idx_at_delay, num_lookahead);
     67 }
     68 
     69 void EchoAudibility::UpdateRenderNoiseEstimator(
     70    const SpectrumBuffer& spectrum_buffer,
     71    const BlockBuffer& block_buffer,
     72    bool external_delay_seen) {
     73  if (!render_spectrum_write_prev_) {
     74    render_spectrum_write_prev_ = spectrum_buffer.write;
     75    render_block_write_prev_ = block_buffer.write;
     76    return;
     77  }
     78  int render_spectrum_write_current = spectrum_buffer.write;
     79  if (!non_zero_render_seen_ && !external_delay_seen) {
     80    non_zero_render_seen_ = !IsRenderTooLow(block_buffer);
     81  }
     82  if (non_zero_render_seen_) {
     83    for (int idx = render_spectrum_write_prev_.value();
     84         idx != render_spectrum_write_current;
     85         idx = spectrum_buffer.DecIndex(idx)) {
     86      render_stationarity_.UpdateNoiseEstimator(spectrum_buffer.buffer[idx]);
     87    }
     88  }
     89  render_spectrum_write_prev_ = render_spectrum_write_current;
     90 }
     91 
     92 bool EchoAudibility::IsRenderTooLow(const BlockBuffer& block_buffer) {
     93  const int num_render_channels =
     94      static_cast<int>(block_buffer.buffer[0].NumChannels());
     95  bool too_low = false;
     96  const int render_block_write_current = block_buffer.write;
     97  if (render_block_write_current == render_block_write_prev_) {
     98    too_low = true;
     99  } else {
    100    for (int idx = render_block_write_prev_; idx != render_block_write_current;
    101         idx = block_buffer.IncIndex(idx)) {
    102      float max_abs_over_channels = 0.f;
    103      for (int ch = 0; ch < num_render_channels; ++ch) {
    104        ArrayView<const float, kBlockSize> block =
    105            block_buffer.buffer[idx].View(/*band=*/0, /*channel=*/ch);
    106        auto r = std::minmax_element(block.cbegin(), block.cend());
    107        float max_abs_channel =
    108            std::max(std::fabs(*r.first), std::fabs(*r.second));
    109        max_abs_over_channels =
    110            std::max(max_abs_over_channels, max_abs_channel);
    111      }
    112      if (max_abs_over_channels < 10.f) {
    113        too_low = true;  // Discards all blocks if one of them is too low.
    114        break;
    115      }
    116    }
    117  }
    118  render_block_write_prev_ = render_block_write_current;
    119  return too_low;
    120 }
    121 
    122 }  // namespace webrtc