subband_nearend_detector.cc (3056B)
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/subband_nearend_detector.h" 12 13 #include <array> 14 #include <cstddef> 15 #include <numeric> 16 17 #include "api/array_view.h" 18 #include "api/audio/echo_canceller3_config.h" 19 #include "modules/audio_processing/aec3/aec3_common.h" 20 #include "modules/audio_processing/aec3/moving_average.h" 21 22 namespace webrtc { 23 SubbandNearendDetector::SubbandNearendDetector( 24 const EchoCanceller3Config::Suppressor::SubbandNearendDetection& config, 25 size_t num_capture_channels) 26 : config_(config), 27 num_capture_channels_(num_capture_channels), 28 nearend_smoothers_(num_capture_channels_, 29 aec3::MovingAverage(kFftLengthBy2Plus1, 30 config_.nearend_average_blocks)), 31 one_over_subband_length1_( 32 1.f / (config_.subband1.high - config_.subband1.low + 1)), 33 one_over_subband_length2_( 34 1.f / (config_.subband2.high - config_.subband2.low + 1)) {} 35 36 void SubbandNearendDetector::Update( 37 ArrayView<const std::array<float, kFftLengthBy2Plus1>> nearend_spectrum, 38 ArrayView<const std::array<float, kFftLengthBy2Plus1>> 39 /* residual_echo_spectrum */, 40 ArrayView<const std::array<float, kFftLengthBy2Plus1>> 41 comfort_noise_spectrum, 42 bool /* initial_state */) { 43 nearend_state_ = false; 44 for (size_t ch = 0; ch < num_capture_channels_; ++ch) { 45 const std::array<float, kFftLengthBy2Plus1>& noise = 46 comfort_noise_spectrum[ch]; 47 std::array<float, kFftLengthBy2Plus1> nearend; 48 nearend_smoothers_[ch].Average(nearend_spectrum[ch], nearend); 49 50 // Noise power of the first region. 51 float noise_power = 52 std::accumulate(noise.begin() + config_.subband1.low, 53 noise.begin() + config_.subband1.high + 1, 0.f) * 54 one_over_subband_length1_; 55 56 // Nearend power of the first region. 57 float nearend_power_subband1 = 58 std::accumulate(nearend.begin() + config_.subband1.low, 59 nearend.begin() + config_.subband1.high + 1, 0.f) * 60 one_over_subband_length1_; 61 62 // Nearend power of the second region. 63 float nearend_power_subband2 = 64 std::accumulate(nearend.begin() + config_.subband2.low, 65 nearend.begin() + config_.subband2.high + 1, 0.f) * 66 one_over_subband_length2_; 67 68 // One channel is sufficient to trigger nearend state. 69 nearend_state_ = 70 nearend_state_ || 71 (nearend_power_subband1 < 72 config_.nearend_threshold * nearend_power_subband2 && 73 (nearend_power_subband1 > config_.snr_threshold * noise_power)); 74 } 75 } 76 } // namespace webrtc