stationarity_estimator.h (4048B)
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 #ifndef MODULES_AUDIO_PROCESSING_AEC3_STATIONARITY_ESTIMATOR_H_ 12 #define MODULES_AUDIO_PROCESSING_AEC3_STATIONARITY_ESTIMATOR_H_ 13 14 #include <array> 15 #include <atomic> 16 #include <cstddef> 17 #include <memory> 18 19 #include "api/array_view.h" 20 #include "modules/audio_processing/aec3/aec3_common.h" // kFftLengthBy2Plus1... 21 #include "rtc_base/checks.h" 22 23 namespace webrtc { 24 25 class ApmDataDumper; 26 struct SpectrumBuffer; 27 28 class StationarityEstimator { 29 public: 30 StationarityEstimator(); 31 ~StationarityEstimator(); 32 33 // Reset the stationarity estimator. 34 void Reset(); 35 36 // Update just the noise estimator. Usefull until the delay is known 37 void UpdateNoiseEstimator( 38 ArrayView<const std::array<float, kFftLengthBy2Plus1>> spectrum); 39 40 // Update the flag indicating whether this current frame is stationary. For 41 // getting a more robust estimation, it looks at future and/or past frames. 42 void UpdateStationarityFlags( 43 const SpectrumBuffer& spectrum_buffer, 44 ArrayView<const float> render_reverb_contribution_spectrum, 45 int idx_current, 46 int num_lookahead); 47 48 // Returns true if the current band is stationary. 49 bool IsBandStationary(size_t band) const { 50 return stationarity_flags_[band] && (hangovers_[band] == 0); 51 } 52 53 // Returns true if the current block is estimated as stationary. 54 bool IsBlockStationary() const; 55 56 private: 57 static constexpr int kWindowLength = 13; 58 // Returns the power of the stationary noise spectrum at a band. 59 float GetStationarityPowerBand(size_t k) const { return noise_.Power(k); } 60 61 // Get an estimation of the stationarity for the current band by looking 62 // at the past/present/future available data. 63 bool EstimateBandStationarity(const SpectrumBuffer& spectrum_buffer, 64 ArrayView<const float> average_reverb, 65 const std::array<int, kWindowLength>& indexes, 66 size_t band) const; 67 68 // True if all bands at the current point are stationary. 69 bool AreAllBandsStationary(); 70 71 // Update the hangover depending on the stationary status of the current 72 // frame. 73 void UpdateHangover(); 74 75 // Smooth the stationarity detection by looking at neighbouring frequency 76 // bands. 77 void SmoothStationaryPerFreq(); 78 79 class NoiseSpectrum { 80 public: 81 NoiseSpectrum(); 82 ~NoiseSpectrum(); 83 84 // Reset the noise power spectrum estimate state. 85 void Reset(); 86 87 // Update the noise power spectrum with a new frame. 88 void Update( 89 ArrayView<const std::array<float, kFftLengthBy2Plus1>> spectrum); 90 91 // Get the noise estimation power spectrum. 92 ArrayView<const float> Spectrum() const { return noise_spectrum_; } 93 94 // Get the noise power spectrum at a certain band. 95 float Power(size_t band) const { 96 RTC_DCHECK_LT(band, noise_spectrum_.size()); 97 return noise_spectrum_[band]; 98 } 99 100 private: 101 // Get the update coefficient to be used for the current frame. 102 float GetAlpha() const; 103 104 // Update the noise power spectrum at a certain band with a new frame. 105 float UpdateBandBySmoothing(float power_band, 106 float power_band_noise, 107 float alpha) const; 108 std::array<float, kFftLengthBy2Plus1> noise_spectrum_; 109 size_t block_counter_; 110 }; 111 112 static std::atomic<int> instance_count_; 113 std::unique_ptr<ApmDataDumper> data_dumper_; 114 NoiseSpectrum noise_; 115 std::array<int, kFftLengthBy2Plus1> hangovers_; 116 std::array<bool, kFftLengthBy2Plus1> stationarity_flags_; 117 }; 118 119 } // namespace webrtc 120 121 #endif // MODULES_AUDIO_PROCESSING_AEC3_STATIONARITY_ESTIMATOR_H_