Update to current webrtc library
This is from the upstream library commit id 3326535126e435f1ba647885ce43a8f0f3d317eb, corresponding to Chromium 88.0.4290.1.
This commit is contained in:
102
webrtc/modules/audio_processing/ns/BUILD.gn
Normal file
102
webrtc/modules/audio_processing/ns/BUILD.gn
Normal file
@ -0,0 +1,102 @@
|
||||
# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("../../../webrtc.gni")
|
||||
|
||||
rtc_static_library("ns") {
|
||||
visibility = [ "*" ]
|
||||
configs += [ "..:apm_debug_dump" ]
|
||||
sources = [
|
||||
"fast_math.cc",
|
||||
"fast_math.h",
|
||||
"histograms.cc",
|
||||
"histograms.h",
|
||||
"noise_estimator.cc",
|
||||
"noise_estimator.h",
|
||||
"noise_suppressor.cc",
|
||||
"noise_suppressor.h",
|
||||
"ns_common.h",
|
||||
"ns_config.h",
|
||||
"ns_fft.cc",
|
||||
"ns_fft.h",
|
||||
"prior_signal_model.cc",
|
||||
"prior_signal_model.h",
|
||||
"prior_signal_model_estimator.cc",
|
||||
"prior_signal_model_estimator.h",
|
||||
"quantile_noise_estimator.cc",
|
||||
"quantile_noise_estimator.h",
|
||||
"signal_model.cc",
|
||||
"signal_model.h",
|
||||
"signal_model_estimator.cc",
|
||||
"signal_model_estimator.h",
|
||||
"speech_probability_estimator.cc",
|
||||
"speech_probability_estimator.h",
|
||||
"suppression_params.cc",
|
||||
"suppression_params.h",
|
||||
"wiener_filter.cc",
|
||||
"wiener_filter.h",
|
||||
]
|
||||
|
||||
defines = []
|
||||
if (rtc_build_with_neon && current_cpu != "arm64") {
|
||||
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
|
||||
cflags = [ "-mfpu=neon" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"..:apm_logging",
|
||||
"..:audio_buffer",
|
||||
"..:high_pass_filter",
|
||||
"../../../api:array_view",
|
||||
"../../../common_audio:common_audio_c",
|
||||
"../../../common_audio/third_party/ooura:fft_size_128",
|
||||
"../../../common_audio/third_party/ooura:fft_size_256",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base/system:arch",
|
||||
"../../../system_wrappers",
|
||||
"../../../system_wrappers:field_trial",
|
||||
"../../../system_wrappers:metrics",
|
||||
"../utility:cascaded_biquad_filter",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_source_set("ns_unittests") {
|
||||
testonly = true
|
||||
|
||||
configs += [ "..:apm_debug_dump" ]
|
||||
sources = [ "noise_suppressor_unittest.cc" ]
|
||||
|
||||
deps = [
|
||||
":ns",
|
||||
"..:apm_logging",
|
||||
"..:audio_buffer",
|
||||
"..:audio_processing",
|
||||
"..:audio_processing_unittests",
|
||||
"..:high_pass_filter",
|
||||
"../../../api:array_view",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base/system:arch",
|
||||
"../../../system_wrappers",
|
||||
"../../../test:test_support",
|
||||
"../utility:cascaded_biquad_filter",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
|
||||
defines = []
|
||||
|
||||
if (rtc_enable_protobuf) {
|
||||
sources += []
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_
|
||||
|
||||
#define BLOCKL_MAX 160 // max processing block length: 160
|
||||
#define ANAL_BLOCKL_MAX 256 // max analysis block length: 256
|
||||
#define HALF_ANAL_BLOCKL 129 // half max analysis block length + 1
|
||||
#define NUM_HIGH_BANDS_MAX 2 // max number of high bands: 2
|
||||
|
||||
#define QUANTILE (float)0.25
|
||||
|
||||
#define SIMULT 3
|
||||
#define END_STARTUP_LONG 200
|
||||
#define END_STARTUP_SHORT 50
|
||||
#define FACTOR (float)40.0
|
||||
#define WIDTH (float)0.01
|
||||
|
||||
// Length of fft work arrays.
|
||||
#define IP_LENGTH (ANAL_BLOCKL_MAX >> 1) // must be at least ceil(2 + sqrt(ANAL_BLOCKL_MAX/2))
|
||||
#define W_LENGTH (ANAL_BLOCKL_MAX >> 1)
|
||||
|
||||
//PARAMETERS FOR NEW METHOD
|
||||
#define DD_PR_SNR (float)0.98 // DD update of prior SNR
|
||||
#define LRT_TAVG (float)0.50 // tavg parameter for LRT (previously 0.90)
|
||||
#define SPECT_FL_TAVG (float)0.30 // tavg parameter for spectral flatness measure
|
||||
#define SPECT_DIFF_TAVG (float)0.30 // tavg parameter for spectral difference measure
|
||||
#define PRIOR_UPDATE (float)0.10 // update parameter of prior model
|
||||
#define NOISE_UPDATE (float)0.90 // update parameter for noise
|
||||
#define SPEECH_UPDATE (float)0.99 // update parameter when likely speech
|
||||
#define WIDTH_PR_MAP (float)4.0 // width parameter in sigmoid map for prior model
|
||||
#define LRT_FEATURE_THR (float)0.5 // default threshold for LRT feature
|
||||
#define SF_FEATURE_THR (float)0.5 // default threshold for Spectral Flatness feature
|
||||
#define SD_FEATURE_THR (float)0.5 // default threshold for Spectral Difference feature
|
||||
#define PROB_RANGE (float)0.20 // probability threshold for noise state in
|
||||
// speech/noise likelihood
|
||||
#define HIST_PAR_EST 1000 // histogram size for estimation of parameters
|
||||
#define GAMMA_PAUSE (float)0.05 // update for conservative noise estimate
|
||||
//
|
||||
#define B_LIM (float)0.5 // threshold in final energy gain factor calculation
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_
|
84
webrtc/modules/audio_processing/ns/fast_math.cc
Normal file
84
webrtc/modules/audio_processing/ns/fast_math.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
float FastLog2f(float in) {
|
||||
RTC_DCHECK_GT(in, .0f);
|
||||
// Read and interpret float as uint32_t and then cast to float.
|
||||
// This is done to extract the exponent (bits 30 - 23).
|
||||
// "Right shift" of the exponent is then performed by multiplying
|
||||
// with the constant (1/2^23). Finally, we subtract a constant to
|
||||
// remove the bias (https://en.wikipedia.org/wiki/Exponent_bias).
|
||||
union {
|
||||
float dummy;
|
||||
uint32_t a;
|
||||
} x = {in};
|
||||
float out = x.a;
|
||||
out *= 1.1920929e-7f; // 1/2^23
|
||||
out -= 126.942695f; // Remove bias.
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
float SqrtFastApproximation(float f) {
|
||||
// TODO(peah): Add fast approximate implementation.
|
||||
return sqrtf(f);
|
||||
}
|
||||
|
||||
float Pow2Approximation(float p) {
|
||||
// TODO(peah): Add fast approximate implementation.
|
||||
return powf(2.f, p);
|
||||
}
|
||||
|
||||
float PowApproximation(float x, float p) {
|
||||
return Pow2Approximation(p * FastLog2f(x));
|
||||
}
|
||||
|
||||
float LogApproximation(float x) {
|
||||
constexpr float kLogOf2 = 0.69314718056f;
|
||||
return FastLog2f(x) * kLogOf2;
|
||||
}
|
||||
|
||||
void LogApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y) {
|
||||
for (size_t k = 0; k < x.size(); ++k) {
|
||||
y[k] = LogApproximation(x[k]);
|
||||
}
|
||||
}
|
||||
|
||||
float ExpApproximation(float x) {
|
||||
constexpr float kLog10Ofe = 0.4342944819f;
|
||||
return PowApproximation(10.f, x * kLog10Ofe);
|
||||
}
|
||||
|
||||
void ExpApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y) {
|
||||
for (size_t k = 0; k < x.size(); ++k) {
|
||||
y[k] = ExpApproximation(x[k]);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpApproximationSignFlip(rtc::ArrayView<const float> x,
|
||||
rtc::ArrayView<float> y) {
|
||||
for (size_t k = 0; k < x.size(); ++k) {
|
||||
y[k] = ExpApproximation(-x[k]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
38
webrtc/modules/audio_processing/ns/fast_math.h
Normal file
38
webrtc/modules/audio_processing/ns/fast_math.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_FAST_MATH_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_FAST_MATH_H_
|
||||
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Sqrt approximation.
|
||||
float SqrtFastApproximation(float f);
|
||||
|
||||
// Log base conversion log(x) = log2(x)/log2(e).
|
||||
float LogApproximation(float x);
|
||||
void LogApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y);
|
||||
|
||||
// 2^x approximation.
|
||||
float Pow2Approximation(float p);
|
||||
|
||||
// x^p approximation.
|
||||
float PowApproximation(float x, float p);
|
||||
|
||||
// e^x approximation.
|
||||
float ExpApproximation(float x);
|
||||
void ExpApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y);
|
||||
void ExpApproximationSignFlip(rtc::ArrayView<const float> x,
|
||||
rtc::ArrayView<float> y);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_FAST_MATH_H_
|
47
webrtc/modules/audio_processing/ns/histograms.cc
Normal file
47
webrtc/modules/audio_processing/ns/histograms.cc
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/histograms.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
Histograms::Histograms() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Histograms::Clear() {
|
||||
lrt_.fill(0);
|
||||
spectral_flatness_.fill(0);
|
||||
spectral_diff_.fill(0);
|
||||
}
|
||||
|
||||
void Histograms::Update(const SignalModel& features_) {
|
||||
// Update the histogram for the LRT.
|
||||
constexpr float kOneByBinSizeLrt = 1.f / kBinSizeLrt;
|
||||
if (features_.lrt < kHistogramSize * kBinSizeLrt && features_.lrt >= 0.f) {
|
||||
++lrt_[kOneByBinSizeLrt * features_.lrt];
|
||||
}
|
||||
|
||||
// Update histogram for the spectral flatness.
|
||||
constexpr float kOneByBinSizeSpecFlat = 1.f / kBinSizeSpecFlat;
|
||||
if (features_.spectral_flatness < kHistogramSize * kBinSizeSpecFlat &&
|
||||
features_.spectral_flatness >= 0.f) {
|
||||
++spectral_flatness_[features_.spectral_flatness * kOneByBinSizeSpecFlat];
|
||||
}
|
||||
|
||||
// Update histogram for the spectral difference.
|
||||
constexpr float kOneByBinSizeSpecDiff = 1.f / kBinSizeSpecDiff;
|
||||
if (features_.spectral_diff < kHistogramSize * kBinSizeSpecDiff &&
|
||||
features_.spectral_diff >= 0.f) {
|
||||
++spectral_diff_[features_.spectral_diff * kOneByBinSizeSpecDiff];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
55
webrtc/modules/audio_processing/ns/histograms.h
Normal file
55
webrtc/modules/audio_processing/ns/histograms.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_HISTOGRAMS_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_HISTOGRAMS_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/signal_model.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr int kHistogramSize = 1000;
|
||||
|
||||
// Class for handling the updating of histograms.
|
||||
class Histograms {
|
||||
public:
|
||||
Histograms();
|
||||
Histograms(const Histograms&) = delete;
|
||||
Histograms& operator=(const Histograms&) = delete;
|
||||
|
||||
// Clears the histograms.
|
||||
void Clear();
|
||||
|
||||
// Extracts thresholds for feature parameters and updates the corresponding
|
||||
// histogram.
|
||||
void Update(const SignalModel& features_);
|
||||
|
||||
// Methods for accessing the histograms.
|
||||
rtc::ArrayView<const int, kHistogramSize> get_lrt() const { return lrt_; }
|
||||
rtc::ArrayView<const int, kHistogramSize> get_spectral_flatness() const {
|
||||
return spectral_flatness_;
|
||||
}
|
||||
rtc::ArrayView<const int, kHistogramSize> get_spectral_diff() const {
|
||||
return spectral_diff_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<int, kHistogramSize> lrt_;
|
||||
std::array<int, kHistogramSize> spectral_flatness_;
|
||||
std::array<int, kHistogramSize> spectral_diff_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_HISTOGRAMS_H_
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
typedef struct NsHandleT NsHandle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function creates an instance of the floating point Noise Suppression.
|
||||
*/
|
||||
NsHandle* WebRtcNs_Create();
|
||||
|
||||
/*
|
||||
* This function frees the dynamic memory of a specified noise suppression
|
||||
* instance.
|
||||
*
|
||||
* Input:
|
||||
* - NS_inst : Pointer to NS instance that should be freed
|
||||
*/
|
||||
void WebRtcNs_Free(NsHandle* NS_inst);
|
||||
|
||||
/*
|
||||
* This function initializes a NS instance and has to be called before any other
|
||||
* processing is made.
|
||||
*
|
||||
* Input:
|
||||
* - NS_inst : Instance that should be initialized
|
||||
* - fs : sampling frequency
|
||||
*
|
||||
* Output:
|
||||
* - NS_inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNs_Init(NsHandle* NS_inst, uint32_t fs);
|
||||
|
||||
/*
|
||||
* This changes the aggressiveness of the noise suppression method.
|
||||
*
|
||||
* Input:
|
||||
* - NS_inst : Noise suppression instance.
|
||||
* - mode : 0: Mild, 1: Medium , 2: Aggressive
|
||||
*
|
||||
* Output:
|
||||
* - NS_inst : Updated instance.
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNs_set_policy(NsHandle* NS_inst, int mode);
|
||||
|
||||
/*
|
||||
* This functions estimates the background noise for the inserted speech frame.
|
||||
* The input and output signals should always be 10ms (80 or 160 samples).
|
||||
*
|
||||
* Input
|
||||
* - NS_inst : Noise suppression instance.
|
||||
* - spframe : Pointer to speech frame buffer for L band
|
||||
*
|
||||
* Output:
|
||||
* - NS_inst : Updated NS instance
|
||||
*/
|
||||
void WebRtcNs_Analyze(NsHandle* NS_inst, const float* spframe);
|
||||
|
||||
/*
|
||||
* This functions does Noise Suppression for the inserted speech frame. The
|
||||
* input and output signals should always be 10ms (80 or 160 samples).
|
||||
*
|
||||
* Input
|
||||
* - NS_inst : Noise suppression instance.
|
||||
* - spframe : Pointer to speech frame buffer for each band
|
||||
* - num_bands : Number of bands
|
||||
*
|
||||
* Output:
|
||||
* - NS_inst : Updated NS instance
|
||||
* - outframe : Pointer to output frame for each band
|
||||
*/
|
||||
void WebRtcNs_Process(NsHandle* NS_inst,
|
||||
const float* const* spframe,
|
||||
size_t num_bands,
|
||||
float* const* outframe);
|
||||
|
||||
/* Returns the internally used prior speech probability of the current frame.
|
||||
* There is a frequency bin based one as well, with which this should not be
|
||||
* confused.
|
||||
*
|
||||
* Input
|
||||
* - handle : Noise suppression instance.
|
||||
*
|
||||
* Return value : Prior speech probability in interval [0.0, 1.0].
|
||||
* -1 - NULL pointer or uninitialized instance.
|
||||
*/
|
||||
float WebRtcNs_prior_speech_probability(NsHandle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_H_
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_X_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_X_H_
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
typedef struct NsxHandleT NsxHandle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function creates an instance of the fixed point Noise Suppression.
|
||||
*/
|
||||
NsxHandle* WebRtcNsx_Create();
|
||||
|
||||
/*
|
||||
* This function frees the dynamic memory of a specified Noise Suppression
|
||||
* instance.
|
||||
*
|
||||
* Input:
|
||||
* - nsxInst : Pointer to NS instance that should be freed
|
||||
*/
|
||||
void WebRtcNsx_Free(NsxHandle* nsxInst);
|
||||
|
||||
/*
|
||||
* This function initializes a NS instance
|
||||
*
|
||||
* Input:
|
||||
* - nsxInst : Instance that should be initialized
|
||||
* - fs : sampling frequency
|
||||
*
|
||||
* Output:
|
||||
* - nsxInst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNsx_Init(NsxHandle* nsxInst, uint32_t fs);
|
||||
|
||||
/*
|
||||
* This changes the aggressiveness of the noise suppression method.
|
||||
*
|
||||
* Input:
|
||||
* - nsxInst : Instance that should be initialized
|
||||
* - mode : 0: Mild, 1: Medium , 2: Aggressive
|
||||
*
|
||||
* Output:
|
||||
* - nsxInst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode);
|
||||
|
||||
/*
|
||||
* This functions does noise suppression for the inserted speech frame. The
|
||||
* input and output signals should always be 10ms (80 or 160 samples).
|
||||
*
|
||||
* Input
|
||||
* - nsxInst : NSx instance. Needs to be initiated before call.
|
||||
* - speechFrame : Pointer to speech frame buffer for each band
|
||||
* - num_bands : Number of bands
|
||||
*
|
||||
* Output:
|
||||
* - nsxInst : Updated NSx instance
|
||||
* - outFrame : Pointer to output frame for each band
|
||||
*/
|
||||
void WebRtcNsx_Process(NsxHandle* nsxInst,
|
||||
const short* const* speechFrame,
|
||||
int num_bands,
|
||||
short* const* outFrame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_INCLUDE_NOISE_SUPPRESSION_X_H_
|
195
webrtc/modules/audio_processing/ns/noise_estimator.cc
Normal file
195
webrtc/modules/audio_processing/ns/noise_estimator.cc
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/noise_estimator.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Log(i).
|
||||
constexpr std::array<float, 129> log_table = {
|
||||
0.f, 0.f, 0.f, 0.f, 0.f, 1.609438f, 1.791759f,
|
||||
1.945910f, 2.079442f, 2.197225f, 2.302585f, 2.397895f, 2.484907f, 2.564949f,
|
||||
2.639057f, 2.708050f, 2.772589f, 2.833213f, 2.890372f, 2.944439f, 2.995732f,
|
||||
3.044522f, 3.091043f, 3.135494f, 3.178054f, 3.218876f, 3.258097f, 3.295837f,
|
||||
3.332205f, 3.367296f, 3.401197f, 3.433987f, 3.465736f, 3.496507f, 3.526361f,
|
||||
3.555348f, 3.583519f, 3.610918f, 3.637586f, 3.663562f, 3.688879f, 3.713572f,
|
||||
3.737669f, 3.761200f, 3.784190f, 3.806663f, 3.828641f, 3.850147f, 3.871201f,
|
||||
3.891820f, 3.912023f, 3.931826f, 3.951244f, 3.970292f, 3.988984f, 4.007333f,
|
||||
4.025352f, 4.043051f, 4.060443f, 4.077538f, 4.094345f, 4.110874f, 4.127134f,
|
||||
4.143135f, 4.158883f, 4.174387f, 4.189655f, 4.204693f, 4.219508f, 4.234107f,
|
||||
4.248495f, 4.262680f, 4.276666f, 4.290460f, 4.304065f, 4.317488f, 4.330733f,
|
||||
4.343805f, 4.356709f, 4.369448f, 4.382027f, 4.394449f, 4.406719f, 4.418841f,
|
||||
4.430817f, 4.442651f, 4.454347f, 4.465908f, 4.477337f, 4.488636f, 4.499810f,
|
||||
4.510859f, 4.521789f, 4.532599f, 4.543295f, 4.553877f, 4.564348f, 4.574711f,
|
||||
4.584968f, 4.595119f, 4.605170f, 4.615121f, 4.624973f, 4.634729f, 4.644391f,
|
||||
4.653960f, 4.663439f, 4.672829f, 4.682131f, 4.691348f, 4.700480f, 4.709530f,
|
||||
4.718499f, 4.727388f, 4.736198f, 4.744932f, 4.753591f, 4.762174f, 4.770685f,
|
||||
4.779124f, 4.787492f, 4.795791f, 4.804021f, 4.812184f, 4.820282f, 4.828314f,
|
||||
4.836282f, 4.844187f, 4.852030f};
|
||||
|
||||
} // namespace
|
||||
|
||||
NoiseEstimator::NoiseEstimator(const SuppressionParams& suppression_params)
|
||||
: suppression_params_(suppression_params) {
|
||||
noise_spectrum_.fill(0.f);
|
||||
prev_noise_spectrum_.fill(0.f);
|
||||
conservative_noise_spectrum_.fill(0.f);
|
||||
parametric_noise_spectrum_.fill(0.f);
|
||||
}
|
||||
|
||||
void NoiseEstimator::PrepareAnalysis() {
|
||||
std::copy(noise_spectrum_.begin(), noise_spectrum_.end(),
|
||||
prev_noise_spectrum_.begin());
|
||||
}
|
||||
|
||||
void NoiseEstimator::PreUpdate(
|
||||
int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum) {
|
||||
quantile_noise_estimator_.Estimate(signal_spectrum, noise_spectrum_);
|
||||
|
||||
if (num_analyzed_frames < kShortStartupPhaseBlocks) {
|
||||
// Compute simplified noise model during startup.
|
||||
const size_t kStartBand = 5;
|
||||
float sum_log_i_log_magn = 0.f;
|
||||
float sum_log_i = 0.f;
|
||||
float sum_log_i_square = 0.f;
|
||||
float sum_log_magn = 0.f;
|
||||
for (size_t i = kStartBand; i < kFftSizeBy2Plus1; ++i) {
|
||||
float log_i = log_table[i];
|
||||
sum_log_i += log_i;
|
||||
sum_log_i_square += log_i * log_i;
|
||||
float log_signal = LogApproximation(signal_spectrum[i]);
|
||||
sum_log_magn += log_signal;
|
||||
sum_log_i_log_magn += log_i * log_signal;
|
||||
}
|
||||
|
||||
// Estimate the parameter for the level of the white noise.
|
||||
constexpr float kOneByFftSizeBy2Plus1 = 1.f / kFftSizeBy2Plus1;
|
||||
white_noise_level_ += signal_spectral_sum * kOneByFftSizeBy2Plus1 *
|
||||
suppression_params_.over_subtraction_factor;
|
||||
|
||||
// Estimate pink noise parameters.
|
||||
float denom = sum_log_i_square * (kFftSizeBy2Plus1 - kStartBand) -
|
||||
sum_log_i * sum_log_i;
|
||||
float num =
|
||||
sum_log_i_square * sum_log_magn - sum_log_i * sum_log_i_log_magn;
|
||||
RTC_DCHECK_NE(denom, 0.f);
|
||||
float pink_noise_adjustment = num / denom;
|
||||
|
||||
// Constrain the estimated spectrum to be positive.
|
||||
pink_noise_adjustment = std::max(pink_noise_adjustment, 0.f);
|
||||
pink_noise_numerator_ += pink_noise_adjustment;
|
||||
num = sum_log_i * sum_log_magn -
|
||||
(kFftSizeBy2Plus1 - kStartBand) * sum_log_i_log_magn;
|
||||
RTC_DCHECK_NE(denom, 0.f);
|
||||
pink_noise_adjustment = num / denom;
|
||||
|
||||
// Constrain the pink noise power to be in the interval [0, 1].
|
||||
pink_noise_adjustment = std::max(std::min(pink_noise_adjustment, 1.f), 0.f);
|
||||
|
||||
pink_noise_exp_ += pink_noise_adjustment;
|
||||
|
||||
const float one_by_num_analyzed_frames_plus_1 =
|
||||
1.f / (num_analyzed_frames + 1.f);
|
||||
|
||||
// Calculate the frequency-independent parts of parametric noise estimate.
|
||||
float parametric_exp = 0.f;
|
||||
float parametric_num = 0.f;
|
||||
if (pink_noise_exp_ > 0.f) {
|
||||
// Use pink noise estimate.
|
||||
parametric_num = ExpApproximation(pink_noise_numerator_ *
|
||||
one_by_num_analyzed_frames_plus_1);
|
||||
parametric_num *= num_analyzed_frames + 1.f;
|
||||
parametric_exp = pink_noise_exp_ * one_by_num_analyzed_frames_plus_1;
|
||||
}
|
||||
|
||||
constexpr float kOneByShortStartupPhaseBlocks =
|
||||
1.f / kShortStartupPhaseBlocks;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
// Estimate the background noise using the white and pink noise
|
||||
// parameters.
|
||||
if (pink_noise_exp_ == 0.f) {
|
||||
// Use white noise estimate.
|
||||
parametric_noise_spectrum_[i] = white_noise_level_;
|
||||
} else {
|
||||
// Use pink noise estimate.
|
||||
float use_band = i < kStartBand ? kStartBand : i;
|
||||
float denom = PowApproximation(use_band, parametric_exp);
|
||||
RTC_DCHECK_NE(denom, 0.f);
|
||||
parametric_noise_spectrum_[i] = parametric_num / denom;
|
||||
}
|
||||
}
|
||||
|
||||
// Weight quantile noise with modeled noise.
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
noise_spectrum_[i] *= num_analyzed_frames;
|
||||
float tmp = parametric_noise_spectrum_[i] *
|
||||
(kShortStartupPhaseBlocks - num_analyzed_frames);
|
||||
noise_spectrum_[i] += tmp * one_by_num_analyzed_frames_plus_1;
|
||||
noise_spectrum_[i] *= kOneByShortStartupPhaseBlocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseEstimator::PostUpdate(
|
||||
rtc::ArrayView<const float> speech_probability,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum) {
|
||||
// Time-avg parameter for noise_spectrum update.
|
||||
constexpr float kNoiseUpdate = 0.9f;
|
||||
|
||||
float gamma = kNoiseUpdate;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
const float prob_speech = speech_probability[i];
|
||||
const float prob_non_speech = 1.f - prob_speech;
|
||||
|
||||
// Temporary noise update used for speech frames if update value is less
|
||||
// than previous.
|
||||
float noise_update_tmp =
|
||||
gamma * prev_noise_spectrum_[i] +
|
||||
(1.f - gamma) * (prob_non_speech * signal_spectrum[i] +
|
||||
prob_speech * prev_noise_spectrum_[i]);
|
||||
|
||||
// Time-constant based on speech/noise_spectrum state.
|
||||
float gamma_old = gamma;
|
||||
|
||||
// Increase gamma for frame likely to be seech.
|
||||
constexpr float kProbRange = .2f;
|
||||
gamma = prob_speech > kProbRange ? .99f : kNoiseUpdate;
|
||||
|
||||
// Conservative noise_spectrum update.
|
||||
if (prob_speech < kProbRange) {
|
||||
conservative_noise_spectrum_[i] +=
|
||||
0.05f * (signal_spectrum[i] - conservative_noise_spectrum_[i]);
|
||||
}
|
||||
|
||||
// Noise_spectrum update.
|
||||
if (gamma == gamma_old) {
|
||||
noise_spectrum_[i] = noise_update_tmp;
|
||||
} else {
|
||||
noise_spectrum_[i] =
|
||||
gamma * prev_noise_spectrum_[i] +
|
||||
(1.f - gamma) * (prob_non_speech * signal_spectrum[i] +
|
||||
prob_speech * prev_noise_spectrum_[i]);
|
||||
// Allow for noise_spectrum update downwards: If noise_spectrum update
|
||||
// decreases the noise_spectrum, it is safe, so allow it to happen.
|
||||
noise_spectrum_[i] = std::min(noise_spectrum_[i], noise_update_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
77
webrtc/modules/audio_processing/ns/noise_estimator.h
Normal file
77
webrtc/modules/audio_processing/ns/noise_estimator.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_ESTIMATOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_NOISE_ESTIMATOR_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/quantile_noise_estimator.h"
|
||||
#include "modules/audio_processing/ns/suppression_params.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class for estimating the spectral characteristics of the noise in an incoming
|
||||
// signal.
|
||||
class NoiseEstimator {
|
||||
public:
|
||||
explicit NoiseEstimator(const SuppressionParams& suppression_params);
|
||||
|
||||
// Prepare the estimator for analysis of a new frame.
|
||||
void PrepareAnalysis();
|
||||
|
||||
// Performs the first step of the estimator update.
|
||||
void PreUpdate(int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum);
|
||||
|
||||
// Performs the second step of the estimator update.
|
||||
void PostUpdate(
|
||||
rtc::ArrayView<const float> speech_probability,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum);
|
||||
|
||||
// Returns the noise spectral estimate.
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> get_noise_spectrum() const {
|
||||
return noise_spectrum_;
|
||||
}
|
||||
|
||||
// Returns the noise from the previous frame.
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> get_prev_noise_spectrum()
|
||||
const {
|
||||
return prev_noise_spectrum_;
|
||||
}
|
||||
|
||||
// Returns a noise spectral estimate based on white and pink noise parameters.
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> get_parametric_noise_spectrum()
|
||||
const {
|
||||
return parametric_noise_spectrum_;
|
||||
}
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1>
|
||||
get_conservative_noise_spectrum() const {
|
||||
return conservative_noise_spectrum_;
|
||||
}
|
||||
|
||||
private:
|
||||
const SuppressionParams& suppression_params_;
|
||||
float white_noise_level_ = 0.f;
|
||||
float pink_noise_numerator_ = 0.f;
|
||||
float pink_noise_exp_ = 0.f;
|
||||
std::array<float, kFftSizeBy2Plus1> prev_noise_spectrum_;
|
||||
std::array<float, kFftSizeBy2Plus1> conservative_noise_spectrum_;
|
||||
std::array<float, kFftSizeBy2Plus1> parametric_noise_spectrum_;
|
||||
std::array<float, kFftSizeBy2Plus1> noise_spectrum_;
|
||||
QuantileNoiseEstimator quantile_noise_estimator_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_ESTIMATOR_H_
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_processing/ns/include/noise_suppression.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "webrtc/modules/audio_processing/ns/defines.h"
|
||||
#include "webrtc/modules/audio_processing/ns/ns_core.h"
|
||||
|
||||
NsHandle* WebRtcNs_Create() {
|
||||
NoiseSuppressionC* self = malloc(sizeof(NoiseSuppressionC));
|
||||
self->initFlag = 0;
|
||||
return (NsHandle*)self;
|
||||
}
|
||||
|
||||
void WebRtcNs_Free(NsHandle* NS_inst) {
|
||||
free(NS_inst);
|
||||
}
|
||||
|
||||
int WebRtcNs_Init(NsHandle* NS_inst, uint32_t fs) {
|
||||
return WebRtcNs_InitCore((NoiseSuppressionC*)NS_inst, fs);
|
||||
}
|
||||
|
||||
int WebRtcNs_set_policy(NsHandle* NS_inst, int mode) {
|
||||
return WebRtcNs_set_policy_core((NoiseSuppressionC*)NS_inst, mode);
|
||||
}
|
||||
|
||||
void WebRtcNs_Analyze(NsHandle* NS_inst, const float* spframe) {
|
||||
WebRtcNs_AnalyzeCore((NoiseSuppressionC*)NS_inst, spframe);
|
||||
}
|
||||
|
||||
void WebRtcNs_Process(NsHandle* NS_inst,
|
||||
const float* const* spframe,
|
||||
size_t num_bands,
|
||||
float* const* outframe) {
|
||||
WebRtcNs_ProcessCore((NoiseSuppressionC*)NS_inst, spframe, num_bands,
|
||||
outframe);
|
||||
}
|
||||
|
||||
float WebRtcNs_prior_speech_probability(NsHandle* handle) {
|
||||
NoiseSuppressionC* self = (NoiseSuppressionC*)handle;
|
||||
if (handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (self->initFlag == 0) {
|
||||
return -1;
|
||||
}
|
||||
return self->priorSpeechProb;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/real_fft.h"
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_core.h"
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_defines.h"
|
||||
|
||||
NsxHandle* WebRtcNsx_Create() {
|
||||
NoiseSuppressionFixedC* self = malloc(sizeof(NoiseSuppressionFixedC));
|
||||
WebRtcSpl_Init();
|
||||
self->real_fft = NULL;
|
||||
self->initFlag = 0;
|
||||
return (NsxHandle*)self;
|
||||
}
|
||||
|
||||
void WebRtcNsx_Free(NsxHandle* nsxInst) {
|
||||
WebRtcSpl_FreeRealFFT(((NoiseSuppressionFixedC*)nsxInst)->real_fft);
|
||||
free(nsxInst);
|
||||
}
|
||||
|
||||
int WebRtcNsx_Init(NsxHandle* nsxInst, uint32_t fs) {
|
||||
return WebRtcNsx_InitCore((NoiseSuppressionFixedC*)nsxInst, fs);
|
||||
}
|
||||
|
||||
int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode) {
|
||||
return WebRtcNsx_set_policy_core((NoiseSuppressionFixedC*)nsxInst, mode);
|
||||
}
|
||||
|
||||
void WebRtcNsx_Process(NsxHandle* nsxInst,
|
||||
const short* const* speechFrame,
|
||||
int num_bands,
|
||||
short* const* outFrame) {
|
||||
WebRtcNsx_ProcessCore((NoiseSuppressionFixedC*)nsxInst, speechFrame,
|
||||
num_bands, outFrame);
|
||||
}
|
549
webrtc/modules/audio_processing/ns/noise_suppressor.cc
Normal file
549
webrtc/modules/audio_processing/ns/noise_suppressor.cc
Normal file
@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/noise_suppressor.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Maps sample rate to number of bands.
|
||||
size_t NumBandsForRate(size_t sample_rate_hz) {
|
||||
RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 32000 ||
|
||||
sample_rate_hz == 48000);
|
||||
return sample_rate_hz / 16000;
|
||||
}
|
||||
|
||||
// Maximum number of channels for which the channel data is stored on
|
||||
// the stack. If the number of channels are larger than this, they are stored
|
||||
// using scratch memory that is pre-allocated on the heap. The reason for this
|
||||
// partitioning is not to waste heap space for handling the more common numbers
|
||||
// of channels, while at the same time not limiting the support for higher
|
||||
// numbers of channels by enforcing the channel data to be stored on the
|
||||
// stack using a fixed maximum value.
|
||||
constexpr size_t kMaxNumChannelsOnStack = 2;
|
||||
|
||||
// Chooses the number of channels to store on the heap when that is required due
|
||||
// to the number of channels being larger than the pre-defined number
|
||||
// of channels to store on the stack.
|
||||
size_t NumChannelsOnHeap(size_t num_channels) {
|
||||
return num_channels > kMaxNumChannelsOnStack ? num_channels : 0;
|
||||
}
|
||||
|
||||
// Hybrib Hanning and flat window for the filterbank.
|
||||
constexpr std::array<float, 96> kBlocks160w256FirstHalf = {
|
||||
0.00000000f, 0.01636173f, 0.03271908f, 0.04906767f, 0.06540313f,
|
||||
0.08172107f, 0.09801714f, 0.11428696f, 0.13052619f, 0.14673047f,
|
||||
0.16289547f, 0.17901686f, 0.19509032f, 0.21111155f, 0.22707626f,
|
||||
0.24298018f, 0.25881905f, 0.27458862f, 0.29028468f, 0.30590302f,
|
||||
0.32143947f, 0.33688985f, 0.35225005f, 0.36751594f, 0.38268343f,
|
||||
0.39774847f, 0.41270703f, 0.42755509f, 0.44228869f, 0.45690388f,
|
||||
0.47139674f, 0.48576339f, 0.50000000f, 0.51410274f, 0.52806785f,
|
||||
0.54189158f, 0.55557023f, 0.56910015f, 0.58247770f, 0.59569930f,
|
||||
0.60876143f, 0.62166057f, 0.63439328f, 0.64695615f, 0.65934582f,
|
||||
0.67155895f, 0.68359230f, 0.69544264f, 0.70710678f, 0.71858162f,
|
||||
0.72986407f, 0.74095113f, 0.75183981f, 0.76252720f, 0.77301045f,
|
||||
0.78328675f, 0.79335334f, 0.80320753f, 0.81284668f, 0.82226822f,
|
||||
0.83146961f, 0.84044840f, 0.84920218f, 0.85772861f, 0.86602540f,
|
||||
0.87409034f, 0.88192126f, 0.88951608f, 0.89687274f, 0.90398929f,
|
||||
0.91086382f, 0.91749450f, 0.92387953f, 0.93001722f, 0.93590593f,
|
||||
0.94154407f, 0.94693013f, 0.95206268f, 0.95694034f, 0.96156180f,
|
||||
0.96592583f, 0.97003125f, 0.97387698f, 0.97746197f, 0.98078528f,
|
||||
0.98384601f, 0.98664333f, 0.98917651f, 0.99144486f, 0.99344778f,
|
||||
0.99518473f, 0.99665524f, 0.99785892f, 0.99879546f, 0.99946459f,
|
||||
0.99986614f};
|
||||
|
||||
// Applies the filterbank window to a buffer.
|
||||
void ApplyFilterBankWindow(rtc::ArrayView<float, kFftSize> x) {
|
||||
for (size_t i = 0; i < 96; ++i) {
|
||||
x[i] = kBlocks160w256FirstHalf[i] * x[i];
|
||||
}
|
||||
|
||||
for (size_t i = 161, k = 95; i < kFftSize; ++i, --k) {
|
||||
RTC_DCHECK_NE(0, k);
|
||||
x[i] = kBlocks160w256FirstHalf[k] * x[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Extends a frame with previous data.
|
||||
void FormExtendedFrame(rtc::ArrayView<const float, kNsFrameSize> frame,
|
||||
rtc::ArrayView<float, kFftSize - kNsFrameSize> old_data,
|
||||
rtc::ArrayView<float, kFftSize> extended_frame) {
|
||||
std::copy(old_data.begin(), old_data.end(), extended_frame.begin());
|
||||
std::copy(frame.begin(), frame.end(),
|
||||
extended_frame.begin() + old_data.size());
|
||||
std::copy(extended_frame.end() - old_data.size(), extended_frame.end(),
|
||||
old_data.begin());
|
||||
}
|
||||
|
||||
// Uses overlap-and-add to produce an output frame.
|
||||
void OverlapAndAdd(rtc::ArrayView<const float, kFftSize> extended_frame,
|
||||
rtc::ArrayView<float, kOverlapSize> overlap_memory,
|
||||
rtc::ArrayView<float, kNsFrameSize> output_frame) {
|
||||
for (size_t i = 0; i < kOverlapSize; ++i) {
|
||||
output_frame[i] = overlap_memory[i] + extended_frame[i];
|
||||
}
|
||||
std::copy(extended_frame.begin() + kOverlapSize,
|
||||
extended_frame.begin() + kNsFrameSize,
|
||||
output_frame.begin() + kOverlapSize);
|
||||
std::copy(extended_frame.begin() + kNsFrameSize, extended_frame.end(),
|
||||
overlap_memory.begin());
|
||||
}
|
||||
|
||||
// Produces a delayed frame.
|
||||
void DelaySignal(rtc::ArrayView<const float, kNsFrameSize> frame,
|
||||
rtc::ArrayView<float, kFftSize - kNsFrameSize> delay_buffer,
|
||||
rtc::ArrayView<float, kNsFrameSize> delayed_frame) {
|
||||
constexpr size_t kSamplesFromFrame = kNsFrameSize - (kFftSize - kNsFrameSize);
|
||||
std::copy(delay_buffer.begin(), delay_buffer.end(), delayed_frame.begin());
|
||||
std::copy(frame.begin(), frame.begin() + kSamplesFromFrame,
|
||||
delayed_frame.begin() + delay_buffer.size());
|
||||
|
||||
std::copy(frame.begin() + kSamplesFromFrame, frame.end(),
|
||||
delay_buffer.begin());
|
||||
}
|
||||
|
||||
// Computes the energy of an extended frame.
|
||||
float ComputeEnergyOfExtendedFrame(rtc::ArrayView<const float, kFftSize> x) {
|
||||
float energy = 0.f;
|
||||
for (float x_k : x) {
|
||||
energy += x_k * x_k;
|
||||
}
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
// Computes the energy of an extended frame based on its subcomponents.
|
||||
float ComputeEnergyOfExtendedFrame(
|
||||
rtc::ArrayView<const float, kNsFrameSize> frame,
|
||||
rtc::ArrayView<float, kFftSize - kNsFrameSize> old_data) {
|
||||
float energy = 0.f;
|
||||
for (float v : old_data) {
|
||||
energy += v * v;
|
||||
}
|
||||
for (float v : frame) {
|
||||
energy += v * v;
|
||||
}
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
// Computes the magnitude spectrum based on an FFT output.
|
||||
void ComputeMagnitudeSpectrum(
|
||||
rtc::ArrayView<const float, kFftSize> real,
|
||||
rtc::ArrayView<const float, kFftSize> imag,
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> signal_spectrum) {
|
||||
signal_spectrum[0] = fabsf(real[0]) + 1.f;
|
||||
signal_spectrum[kFftSizeBy2Plus1 - 1] =
|
||||
fabsf(real[kFftSizeBy2Plus1 - 1]) + 1.f;
|
||||
|
||||
for (size_t i = 1; i < kFftSizeBy2Plus1 - 1; ++i) {
|
||||
signal_spectrum[i] =
|
||||
SqrtFastApproximation(real[i] * real[i] + imag[i] * imag[i]) + 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute prior and post SNR.
|
||||
void ComputeSnr(rtc::ArrayView<const float, kFftSizeBy2Plus1> filter,
|
||||
rtc::ArrayView<const float> prev_signal_spectrum,
|
||||
rtc::ArrayView<const float> signal_spectrum,
|
||||
rtc::ArrayView<const float> prev_noise_spectrum,
|
||||
rtc::ArrayView<const float> noise_spectrum,
|
||||
rtc::ArrayView<float> prior_snr,
|
||||
rtc::ArrayView<float> post_snr) {
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
// Previous post SNR.
|
||||
// Previous estimate: based on previous frame with gain filter.
|
||||
float prev_estimate = prev_signal_spectrum[i] /
|
||||
(prev_noise_spectrum[i] + 0.0001f) * filter[i];
|
||||
// Post SNR.
|
||||
if (signal_spectrum[i] > noise_spectrum[i]) {
|
||||
post_snr[i] = signal_spectrum[i] / (noise_spectrum[i] + 0.0001f) - 1.f;
|
||||
} else {
|
||||
post_snr[i] = 0.f;
|
||||
}
|
||||
// The directed decision estimate of the prior SNR is a sum the current and
|
||||
// previous estimates.
|
||||
prior_snr[i] = 0.98f * prev_estimate + (1.f - 0.98f) * post_snr[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Computes the attenuating gain for the noise suppression of the upper bands.
|
||||
float ComputeUpperBandsGain(
|
||||
float minimum_attenuating_gain,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> filter,
|
||||
rtc::ArrayView<const float> speech_probability,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prev_analysis_signal_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum) {
|
||||
// Average speech prob and filter gain for the end of the lowest band.
|
||||
constexpr int kNumAvgBins = 32;
|
||||
constexpr float kOneByNumAvgBins = 1.f / kNumAvgBins;
|
||||
|
||||
float avg_prob_speech = 0.f;
|
||||
float avg_filter_gain = 0.f;
|
||||
for (size_t i = kFftSizeBy2Plus1 - kNumAvgBins - 1; i < kFftSizeBy2Plus1 - 1;
|
||||
i++) {
|
||||
avg_prob_speech += speech_probability[i];
|
||||
avg_filter_gain += filter[i];
|
||||
}
|
||||
avg_prob_speech = avg_prob_speech * kOneByNumAvgBins;
|
||||
avg_filter_gain = avg_filter_gain * kOneByNumAvgBins;
|
||||
|
||||
// If the speech was suppressed by a component between Analyze and Process, an
|
||||
// example being by an AEC, it should not be considered speech for the purpose
|
||||
// of high band suppression. To that end, the speech probability is scaled
|
||||
// accordingly.
|
||||
float sum_analysis_spectrum = 0.f;
|
||||
float sum_processing_spectrum = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
sum_analysis_spectrum += prev_analysis_signal_spectrum[i];
|
||||
sum_processing_spectrum += signal_spectrum[i];
|
||||
}
|
||||
|
||||
// The magnitude spectrum computation enforces the spectrum to be strictly
|
||||
// positive.
|
||||
RTC_DCHECK_GT(sum_analysis_spectrum, 0.f);
|
||||
avg_prob_speech *= sum_processing_spectrum / sum_analysis_spectrum;
|
||||
|
||||
// Compute gain based on speech probability.
|
||||
float gain =
|
||||
0.5f * (1.f + static_cast<float>(tanh(2.f * avg_prob_speech - 1.f)));
|
||||
|
||||
// Combine gain with low band gain.
|
||||
if (avg_prob_speech >= 0.5f) {
|
||||
gain = 0.25f * gain + 0.75f * avg_filter_gain;
|
||||
} else {
|
||||
gain = 0.5f * gain + 0.5f * avg_filter_gain;
|
||||
}
|
||||
|
||||
// Make sure gain is within flooring range.
|
||||
return std::min(std::max(gain, minimum_attenuating_gain), 1.f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NoiseSuppressor::ChannelState::ChannelState(
|
||||
const SuppressionParams& suppression_params,
|
||||
size_t num_bands)
|
||||
: wiener_filter(suppression_params),
|
||||
noise_estimator(suppression_params),
|
||||
process_delay_memory(num_bands > 1 ? num_bands - 1 : 0) {
|
||||
analyze_analysis_memory.fill(0.f);
|
||||
prev_analysis_signal_spectrum.fill(1.f);
|
||||
process_analysis_memory.fill(0.f);
|
||||
process_synthesis_memory.fill(0.f);
|
||||
for (auto& d : process_delay_memory) {
|
||||
d.fill(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
NoiseSuppressor::NoiseSuppressor(const NsConfig& config,
|
||||
size_t sample_rate_hz,
|
||||
size_t num_channels)
|
||||
: num_bands_(NumBandsForRate(sample_rate_hz)),
|
||||
num_channels_(num_channels),
|
||||
suppression_params_(config.target_level),
|
||||
filter_bank_states_heap_(NumChannelsOnHeap(num_channels_)),
|
||||
upper_band_gains_heap_(NumChannelsOnHeap(num_channels_)),
|
||||
energies_before_filtering_heap_(NumChannelsOnHeap(num_channels_)),
|
||||
gain_adjustments_heap_(NumChannelsOnHeap(num_channels_)),
|
||||
channels_(num_channels_) {
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
channels_[ch] =
|
||||
std::make_unique<ChannelState>(suppression_params_, num_bands_);
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseSuppressor::AggregateWienerFilters(
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> filter) const {
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> filter0 =
|
||||
channels_[0]->wiener_filter.get_filter();
|
||||
std::copy(filter0.begin(), filter0.end(), filter.begin());
|
||||
|
||||
for (size_t ch = 1; ch < num_channels_; ++ch) {
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> filter_ch =
|
||||
channels_[ch]->wiener_filter.get_filter();
|
||||
|
||||
for (size_t k = 0; k < kFftSizeBy2Plus1; ++k) {
|
||||
filter[k] = std::min(filter[k], filter_ch[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseSuppressor::Analyze(const AudioBuffer& audio) {
|
||||
// Prepare the noise estimator for the analysis stage.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
channels_[ch]->noise_estimator.PrepareAnalysis();
|
||||
}
|
||||
|
||||
// Check for zero frames.
|
||||
bool zero_frame = true;
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
rtc::ArrayView<const float, kNsFrameSize> y_band0(
|
||||
&audio.split_bands_const(ch)[0][0], kNsFrameSize);
|
||||
float energy = ComputeEnergyOfExtendedFrame(
|
||||
y_band0, channels_[ch]->analyze_analysis_memory);
|
||||
if (energy > 0.f) {
|
||||
zero_frame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (zero_frame) {
|
||||
// We want to avoid updating statistics in this case:
|
||||
// Updating feature statistics when we have zeros only will cause
|
||||
// thresholds to move towards zero signal situations. This in turn has the
|
||||
// effect that once the signal is "turned on" (non-zero values) everything
|
||||
// will be treated as speech and there is no noise suppression effect.
|
||||
// Depending on the duration of the inactive signal it takes a
|
||||
// considerable amount of time for the system to learn what is noise and
|
||||
// what is speech.
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update analysis counter for frames that are properly analyzed.
|
||||
if (++num_analyzed_frames_ < 0) {
|
||||
num_analyzed_frames_ = 0;
|
||||
}
|
||||
|
||||
// Analyze all channels.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
std::unique_ptr<ChannelState>& ch_p = channels_[ch];
|
||||
rtc::ArrayView<const float, kNsFrameSize> y_band0(
|
||||
&audio.split_bands_const(ch)[0][0], kNsFrameSize);
|
||||
|
||||
// Form an extended frame and apply analysis filter bank windowing.
|
||||
std::array<float, kFftSize> extended_frame;
|
||||
FormExtendedFrame(y_band0, ch_p->analyze_analysis_memory, extended_frame);
|
||||
ApplyFilterBankWindow(extended_frame);
|
||||
|
||||
// Compute the magnitude spectrum.
|
||||
std::array<float, kFftSize> real;
|
||||
std::array<float, kFftSize> imag;
|
||||
fft_.Fft(extended_frame, real, imag);
|
||||
|
||||
std::array<float, kFftSizeBy2Plus1> signal_spectrum;
|
||||
ComputeMagnitudeSpectrum(real, imag, signal_spectrum);
|
||||
|
||||
// Compute energies.
|
||||
float signal_energy = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
signal_energy += real[i] * real[i] + imag[i] * imag[i];
|
||||
}
|
||||
signal_energy /= kFftSizeBy2Plus1;
|
||||
|
||||
float signal_spectral_sum = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
signal_spectral_sum += signal_spectrum[i];
|
||||
}
|
||||
|
||||
// Estimate the noise spectra and the probability estimates of speech
|
||||
// presence.
|
||||
ch_p->noise_estimator.PreUpdate(num_analyzed_frames_, signal_spectrum,
|
||||
signal_spectral_sum);
|
||||
|
||||
std::array<float, kFftSizeBy2Plus1> post_snr;
|
||||
std::array<float, kFftSizeBy2Plus1> prior_snr;
|
||||
ComputeSnr(ch_p->wiener_filter.get_filter(),
|
||||
ch_p->prev_analysis_signal_spectrum, signal_spectrum,
|
||||
ch_p->noise_estimator.get_prev_noise_spectrum(),
|
||||
ch_p->noise_estimator.get_noise_spectrum(), prior_snr, post_snr);
|
||||
|
||||
ch_p->speech_probability_estimator.Update(
|
||||
num_analyzed_frames_, prior_snr, post_snr,
|
||||
ch_p->noise_estimator.get_conservative_noise_spectrum(),
|
||||
signal_spectrum, signal_spectral_sum, signal_energy);
|
||||
|
||||
ch_p->noise_estimator.PostUpdate(
|
||||
ch_p->speech_probability_estimator.get_probability(), signal_spectrum);
|
||||
|
||||
// Store the magnitude spectrum to make it avalilable for the process
|
||||
// method.
|
||||
std::copy(signal_spectrum.begin(), signal_spectrum.end(),
|
||||
ch_p->prev_analysis_signal_spectrum.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseSuppressor::Process(AudioBuffer* audio) {
|
||||
// Select the space for storing data during the processing.
|
||||
std::array<FilterBankState, kMaxNumChannelsOnStack> filter_bank_states_stack;
|
||||
rtc::ArrayView<FilterBankState> filter_bank_states(
|
||||
filter_bank_states_stack.data(), num_channels_);
|
||||
std::array<float, kMaxNumChannelsOnStack> upper_band_gains_stack;
|
||||
rtc::ArrayView<float> upper_band_gains(upper_band_gains_stack.data(),
|
||||
num_channels_);
|
||||
std::array<float, kMaxNumChannelsOnStack> energies_before_filtering_stack;
|
||||
rtc::ArrayView<float> energies_before_filtering(
|
||||
energies_before_filtering_stack.data(), num_channels_);
|
||||
std::array<float, kMaxNumChannelsOnStack> gain_adjustments_stack;
|
||||
rtc::ArrayView<float> gain_adjustments(gain_adjustments_stack.data(),
|
||||
num_channels_);
|
||||
if (NumChannelsOnHeap(num_channels_) > 0) {
|
||||
// If the stack-allocated space is too small, use the heap for storing the
|
||||
// data.
|
||||
filter_bank_states = rtc::ArrayView<FilterBankState>(
|
||||
filter_bank_states_heap_.data(), num_channels_);
|
||||
upper_band_gains =
|
||||
rtc::ArrayView<float>(upper_band_gains_heap_.data(), num_channels_);
|
||||
energies_before_filtering = rtc::ArrayView<float>(
|
||||
energies_before_filtering_heap_.data(), num_channels_);
|
||||
gain_adjustments =
|
||||
rtc::ArrayView<float>(gain_adjustments_heap_.data(), num_channels_);
|
||||
}
|
||||
|
||||
// Compute the suppression filters for all channels.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
// Form an extended frame and apply analysis filter bank windowing.
|
||||
rtc::ArrayView<float, kNsFrameSize> y_band0(&audio->split_bands(ch)[0][0],
|
||||
kNsFrameSize);
|
||||
|
||||
FormExtendedFrame(y_band0, channels_[ch]->process_analysis_memory,
|
||||
filter_bank_states[ch].extended_frame);
|
||||
|
||||
ApplyFilterBankWindow(filter_bank_states[ch].extended_frame);
|
||||
|
||||
energies_before_filtering[ch] =
|
||||
ComputeEnergyOfExtendedFrame(filter_bank_states[ch].extended_frame);
|
||||
|
||||
// Perform filter bank analysis and compute the magnitude spectrum.
|
||||
fft_.Fft(filter_bank_states[ch].extended_frame, filter_bank_states[ch].real,
|
||||
filter_bank_states[ch].imag);
|
||||
|
||||
std::array<float, kFftSizeBy2Plus1> signal_spectrum;
|
||||
ComputeMagnitudeSpectrum(filter_bank_states[ch].real,
|
||||
filter_bank_states[ch].imag, signal_spectrum);
|
||||
|
||||
// Compute the frequency domain gain filter for noise attenuation.
|
||||
channels_[ch]->wiener_filter.Update(
|
||||
num_analyzed_frames_,
|
||||
channels_[ch]->noise_estimator.get_noise_spectrum(),
|
||||
channels_[ch]->noise_estimator.get_prev_noise_spectrum(),
|
||||
channels_[ch]->noise_estimator.get_parametric_noise_spectrum(),
|
||||
signal_spectrum);
|
||||
|
||||
if (num_bands_ > 1) {
|
||||
// Compute the time-domain gain for attenuating the noise in the upper
|
||||
// bands.
|
||||
|
||||
upper_band_gains[ch] = ComputeUpperBandsGain(
|
||||
suppression_params_.minimum_attenuating_gain,
|
||||
channels_[ch]->wiener_filter.get_filter(),
|
||||
channels_[ch]->speech_probability_estimator.get_probability(),
|
||||
channels_[ch]->prev_analysis_signal_spectrum, signal_spectrum);
|
||||
}
|
||||
}
|
||||
|
||||
// Aggregate the Wiener filters for all channels.
|
||||
std::array<float, kFftSizeBy2Plus1> filter_data;
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> filter = filter_data;
|
||||
if (num_channels_ == 1) {
|
||||
filter = channels_[0]->wiener_filter.get_filter();
|
||||
} else {
|
||||
AggregateWienerFilters(filter_data);
|
||||
}
|
||||
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
// Apply the filter to the lower band.
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
filter_bank_states[ch].real[i] *= filter[i];
|
||||
filter_bank_states[ch].imag[i] *= filter[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Perform filter bank synthesis
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
fft_.Ifft(filter_bank_states[ch].real, filter_bank_states[ch].imag,
|
||||
filter_bank_states[ch].extended_frame);
|
||||
}
|
||||
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
const float energy_after_filtering =
|
||||
ComputeEnergyOfExtendedFrame(filter_bank_states[ch].extended_frame);
|
||||
|
||||
// Apply synthesis window.
|
||||
ApplyFilterBankWindow(filter_bank_states[ch].extended_frame);
|
||||
|
||||
// Compute the adjustment of the noise attenuation filter based on the
|
||||
// effect of the attenuation.
|
||||
gain_adjustments[ch] =
|
||||
channels_[ch]->wiener_filter.ComputeOverallScalingFactor(
|
||||
num_analyzed_frames_,
|
||||
channels_[ch]->speech_probability_estimator.get_prior_probability(),
|
||||
energies_before_filtering[ch], energy_after_filtering);
|
||||
}
|
||||
|
||||
// Select and apply adjustment of the noise attenuation filter based on the
|
||||
// effect of the attenuation.
|
||||
float gain_adjustment = gain_adjustments[0];
|
||||
for (size_t ch = 1; ch < num_channels_; ++ch) {
|
||||
gain_adjustment = std::min(gain_adjustment, gain_adjustments[ch]);
|
||||
}
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
for (size_t i = 0; i < kFftSize; ++i) {
|
||||
filter_bank_states[ch].extended_frame[i] =
|
||||
gain_adjustment * filter_bank_states[ch].extended_frame[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Use overlap-and-add to form the output frame of the lowest band.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
rtc::ArrayView<float, kNsFrameSize> y_band0(&audio->split_bands(ch)[0][0],
|
||||
kNsFrameSize);
|
||||
OverlapAndAdd(filter_bank_states[ch].extended_frame,
|
||||
channels_[ch]->process_synthesis_memory, y_band0);
|
||||
}
|
||||
|
||||
if (num_bands_ > 1) {
|
||||
// Select the noise attenuating gain to apply to the upper band.
|
||||
float upper_band_gain = upper_band_gains[0];
|
||||
for (size_t ch = 1; ch < num_channels_; ++ch) {
|
||||
upper_band_gain = std::min(upper_band_gain, upper_band_gains[ch]);
|
||||
}
|
||||
|
||||
// Process the upper bands.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
for (size_t b = 1; b < num_bands_; ++b) {
|
||||
// Delay the upper bands to match the delay of the filterbank applied to
|
||||
// the lowest band.
|
||||
rtc::ArrayView<float, kNsFrameSize> y_band(
|
||||
&audio->split_bands(ch)[b][0], kNsFrameSize);
|
||||
std::array<float, kNsFrameSize> delayed_frame;
|
||||
DelaySignal(y_band, channels_[ch]->process_delay_memory[b - 1],
|
||||
delayed_frame);
|
||||
|
||||
// Apply the time-domain noise-attenuating gain.
|
||||
for (size_t j = 0; j < kNsFrameSize; j++) {
|
||||
y_band[j] = upper_band_gain * delayed_frame[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the output the allowed range.
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
for (size_t b = 0; b < num_bands_; ++b) {
|
||||
rtc::ArrayView<float, kNsFrameSize> y_band(&audio->split_bands(ch)[b][0],
|
||||
kNsFrameSize);
|
||||
for (size_t j = 0; j < kNsFrameSize; j++) {
|
||||
y_band[j] = std::min(std::max(y_band[j], -32768.f), 32767.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
83
webrtc/modules/audio_processing/ns/noise_suppressor.h
Normal file
83
webrtc/modules/audio_processing/ns/noise_suppressor.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/audio_buffer.h"
|
||||
#include "modules/audio_processing/ns/noise_estimator.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/ns_config.h"
|
||||
#include "modules/audio_processing/ns/ns_fft.h"
|
||||
#include "modules/audio_processing/ns/speech_probability_estimator.h"
|
||||
#include "modules/audio_processing/ns/wiener_filter.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class for suppressing noise in a signal.
|
||||
class NoiseSuppressor {
|
||||
public:
|
||||
NoiseSuppressor(const NsConfig& config,
|
||||
size_t sample_rate_hz,
|
||||
size_t num_channels);
|
||||
NoiseSuppressor(const NoiseSuppressor&) = delete;
|
||||
NoiseSuppressor& operator=(const NoiseSuppressor&) = delete;
|
||||
|
||||
// Analyses the signal (typically applied before the AEC to avoid analyzing
|
||||
// any comfort noise signal).
|
||||
void Analyze(const AudioBuffer& audio);
|
||||
|
||||
// Applies noise suppression.
|
||||
void Process(AudioBuffer* audio);
|
||||
|
||||
private:
|
||||
const size_t num_bands_;
|
||||
const size_t num_channels_;
|
||||
const SuppressionParams suppression_params_;
|
||||
int32_t num_analyzed_frames_ = -1;
|
||||
NrFft fft_;
|
||||
|
||||
struct ChannelState {
|
||||
ChannelState(const SuppressionParams& suppression_params, size_t num_bands);
|
||||
|
||||
SpeechProbabilityEstimator speech_probability_estimator;
|
||||
WienerFilter wiener_filter;
|
||||
NoiseEstimator noise_estimator;
|
||||
std::array<float, kFftSizeBy2Plus1> prev_analysis_signal_spectrum;
|
||||
std::array<float, kFftSize - kNsFrameSize> analyze_analysis_memory;
|
||||
std::array<float, kOverlapSize> process_analysis_memory;
|
||||
std::array<float, kOverlapSize> process_synthesis_memory;
|
||||
std::vector<std::array<float, kOverlapSize>> process_delay_memory;
|
||||
};
|
||||
|
||||
struct FilterBankState {
|
||||
std::array<float, kFftSize> real;
|
||||
std::array<float, kFftSize> imag;
|
||||
std::array<float, kFftSize> extended_frame;
|
||||
};
|
||||
|
||||
std::vector<FilterBankState> filter_bank_states_heap_;
|
||||
std::vector<float> upper_band_gains_heap_;
|
||||
std::vector<float> energies_before_filtering_heap_;
|
||||
std::vector<float> gain_adjustments_heap_;
|
||||
std::vector<std::unique_ptr<ChannelState>> channels_;
|
||||
|
||||
// Aggregates the Wiener filters into a single filter to use.
|
||||
void AggregateWienerFilters(
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> filter) const;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSOR_H_
|
34
webrtc/modules/audio_processing/ns/ns_common.h
Normal file
34
webrtc/modules/audio_processing/ns/ns_common.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_NS_COMMON_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_NS_COMMON_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr size_t kFftSize = 256;
|
||||
constexpr size_t kFftSizeBy2Plus1 = kFftSize / 2 + 1;
|
||||
constexpr size_t kNsFrameSize = 160;
|
||||
constexpr size_t kOverlapSize = kFftSize - kNsFrameSize;
|
||||
|
||||
constexpr int kShortStartupPhaseBlocks = 50;
|
||||
constexpr int kLongStartupPhaseBlocks = 200;
|
||||
constexpr int kFeatureUpdateWindowSize = 500;
|
||||
|
||||
constexpr float kLtrFeatureThr = 0.5f;
|
||||
constexpr float kBinSizeLrt = 0.1f;
|
||||
constexpr float kBinSizeSpecFlat = 0.05f;
|
||||
constexpr float kBinSizeSpecDiff = 0.1f;
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_NS_COMMON_H_
|
24
webrtc/modules/audio_processing/ns/ns_config.h
Normal file
24
webrtc/modules/audio_processing/ns/ns_config.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_NS_CONFIG_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_NS_CONFIG_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Config struct for the noise suppressor
|
||||
struct NsConfig {
|
||||
enum class SuppressionLevel { k6dB, k12dB, k18dB, k21dB };
|
||||
SuppressionLevel target_level = SuppressionLevel::k12dB;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_NS_CONFIG_H_
|
File diff suppressed because it is too large
Load Diff
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_
|
||||
|
||||
#include "webrtc/modules/audio_processing/ns/defines.h"
|
||||
|
||||
typedef struct NSParaExtract_ {
|
||||
// Bin size of histogram.
|
||||
float binSizeLrt;
|
||||
float binSizeSpecFlat;
|
||||
float binSizeSpecDiff;
|
||||
// Range of histogram over which LRT threshold is computed.
|
||||
float rangeAvgHistLrt;
|
||||
// Scale parameters: multiply dominant peaks of the histograms by scale factor
|
||||
// to obtain thresholds for prior model.
|
||||
float factor1ModelPars; // For LRT and spectral difference.
|
||||
float factor2ModelPars; // For spectral_flatness: used when noise is flatter
|
||||
// than speech.
|
||||
// Peak limit for spectral flatness (varies between 0 and 1).
|
||||
float thresPosSpecFlat;
|
||||
// Limit on spacing of two highest peaks in histogram: spacing determined by
|
||||
// bin size.
|
||||
float limitPeakSpacingSpecFlat;
|
||||
float limitPeakSpacingSpecDiff;
|
||||
// Limit on relevance of second peak.
|
||||
float limitPeakWeightsSpecFlat;
|
||||
float limitPeakWeightsSpecDiff;
|
||||
// Limit on fluctuation of LRT feature.
|
||||
float thresFluctLrt;
|
||||
// Limit on the max and min values for the feature thresholds.
|
||||
float maxLrt;
|
||||
float minLrt;
|
||||
float maxSpecFlat;
|
||||
float minSpecFlat;
|
||||
float maxSpecDiff;
|
||||
float minSpecDiff;
|
||||
// Criteria of weight of histogram peak to accept/reject feature.
|
||||
int thresWeightSpecFlat;
|
||||
int thresWeightSpecDiff;
|
||||
|
||||
} NSParaExtract;
|
||||
|
||||
typedef struct NoiseSuppressionC_ {
|
||||
uint32_t fs;
|
||||
size_t blockLen;
|
||||
size_t windShift;
|
||||
size_t anaLen;
|
||||
size_t magnLen;
|
||||
int aggrMode;
|
||||
const float* window;
|
||||
float analyzeBuf[ANAL_BLOCKL_MAX];
|
||||
float dataBuf[ANAL_BLOCKL_MAX];
|
||||
float syntBuf[ANAL_BLOCKL_MAX];
|
||||
|
||||
int initFlag;
|
||||
// Parameters for quantile noise estimation.
|
||||
float density[SIMULT * HALF_ANAL_BLOCKL];
|
||||
float lquantile[SIMULT * HALF_ANAL_BLOCKL];
|
||||
float quantile[HALF_ANAL_BLOCKL];
|
||||
int counter[SIMULT];
|
||||
int updates;
|
||||
// Parameters for Wiener filter.
|
||||
float smooth[HALF_ANAL_BLOCKL];
|
||||
float overdrive;
|
||||
float denoiseBound;
|
||||
int gainmap;
|
||||
// FFT work arrays.
|
||||
size_t ip[IP_LENGTH];
|
||||
float wfft[W_LENGTH];
|
||||
|
||||
// Parameters for new method: some not needed, will reduce/cleanup later.
|
||||
int32_t blockInd; // Frame index counter.
|
||||
int modelUpdatePars[4]; // Parameters for updating or estimating.
|
||||
// Thresholds/weights for prior model.
|
||||
float priorModelPars[7]; // Parameters for prior model.
|
||||
float noise[HALF_ANAL_BLOCKL]; // Noise spectrum from current frame.
|
||||
float noisePrev[HALF_ANAL_BLOCKL]; // Noise spectrum from previous frame.
|
||||
// Magnitude spectrum of previous analyze frame.
|
||||
float magnPrevAnalyze[HALF_ANAL_BLOCKL];
|
||||
// Magnitude spectrum of previous process frame.
|
||||
float magnPrevProcess[HALF_ANAL_BLOCKL];
|
||||
float logLrtTimeAvg[HALF_ANAL_BLOCKL]; // Log LRT factor with time-smoothing.
|
||||
float priorSpeechProb; // Prior speech/noise probability.
|
||||
float featureData[7];
|
||||
// Conservative noise spectrum estimate.
|
||||
float magnAvgPause[HALF_ANAL_BLOCKL];
|
||||
float signalEnergy; // Energy of |magn|.
|
||||
float sumMagn;
|
||||
float whiteNoiseLevel; // Initial noise estimate.
|
||||
float initMagnEst[HALF_ANAL_BLOCKL]; // Initial magnitude spectrum estimate.
|
||||
float pinkNoiseNumerator; // Pink noise parameter: numerator.
|
||||
float pinkNoiseExp; // Pink noise parameter: power of frequencies.
|
||||
float parametricNoise[HALF_ANAL_BLOCKL];
|
||||
// Parameters for feature extraction.
|
||||
NSParaExtract featureExtractionParams;
|
||||
// Histograms for parameter estimation.
|
||||
int histLrt[HIST_PAR_EST];
|
||||
int histSpecFlat[HIST_PAR_EST];
|
||||
int histSpecDiff[HIST_PAR_EST];
|
||||
// Quantities for high band estimate.
|
||||
float speechProb[HALF_ANAL_BLOCKL]; // Final speech/noise prob: prior + LRT.
|
||||
// Buffering data for HB.
|
||||
float dataBufHB[NUM_HIGH_BANDS_MAX][ANAL_BLOCKL_MAX];
|
||||
|
||||
} NoiseSuppressionC;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNs_InitCore(...)
|
||||
*
|
||||
* This function initializes a noise suppression instance
|
||||
*
|
||||
* Input:
|
||||
* - self : Instance that should be initialized
|
||||
* - fs : Sampling frequency
|
||||
*
|
||||
* Output:
|
||||
* - self : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNs_InitCore(NoiseSuppressionC* self, uint32_t fs);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNs_set_policy_core(...)
|
||||
*
|
||||
* This changes the aggressiveness of the noise suppression method.
|
||||
*
|
||||
* Input:
|
||||
* - self : Instance that should be initialized
|
||||
* - mode : 0: Mild (6dB), 1: Medium (10dB), 2: Aggressive (15dB)
|
||||
*
|
||||
* Output:
|
||||
* - self : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNs_set_policy_core(NoiseSuppressionC* self, int mode);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNs_AnalyzeCore
|
||||
*
|
||||
* Estimate the background noise.
|
||||
*
|
||||
* Input:
|
||||
* - self : Instance that should be initialized
|
||||
* - speechFrame : Input speech frame for lower band
|
||||
*
|
||||
* Output:
|
||||
* - self : Updated instance
|
||||
*/
|
||||
void WebRtcNs_AnalyzeCore(NoiseSuppressionC* self, const float* speechFrame);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNs_ProcessCore
|
||||
*
|
||||
* Do noise suppression.
|
||||
*
|
||||
* Input:
|
||||
* - self : Instance that should be initialized
|
||||
* - inFrame : Input speech frame for each band
|
||||
* - num_bands : Number of bands
|
||||
*
|
||||
* Output:
|
||||
* - self : Updated instance
|
||||
* - outFrame : Output speech frame for each band
|
||||
*/
|
||||
void WebRtcNs_ProcessCore(NoiseSuppressionC* self,
|
||||
const float* const* inFrame,
|
||||
size_t num_bands,
|
||||
float* const* outFrame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_
|
64
webrtc/modules/audio_processing/ns/ns_fft.cc
Normal file
64
webrtc/modules/audio_processing/ns/ns_fft.cc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/ns_fft.h"
|
||||
|
||||
#include "common_audio/third_party/ooura/fft_size_256/fft4g.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
NrFft::NrFft() : bit_reversal_state_(kFftSize / 2), tables_(kFftSize / 2) {
|
||||
// Initialize WebRtc_rdt (setting (bit_reversal_state_[0] to 0 triggers
|
||||
// initialization)
|
||||
bit_reversal_state_[0] = 0.f;
|
||||
std::array<float, kFftSize> tmp_buffer;
|
||||
tmp_buffer.fill(0.f);
|
||||
WebRtc_rdft(kFftSize, 1, tmp_buffer.data(), bit_reversal_state_.data(),
|
||||
tables_.data());
|
||||
}
|
||||
|
||||
void NrFft::Fft(rtc::ArrayView<float, kFftSize> time_data,
|
||||
rtc::ArrayView<float, kFftSize> real,
|
||||
rtc::ArrayView<float, kFftSize> imag) {
|
||||
WebRtc_rdft(kFftSize, 1, time_data.data(), bit_reversal_state_.data(),
|
||||
tables_.data());
|
||||
|
||||
imag[0] = 0;
|
||||
real[0] = time_data[0];
|
||||
|
||||
imag[kFftSizeBy2Plus1 - 1] = 0;
|
||||
real[kFftSizeBy2Plus1 - 1] = time_data[1];
|
||||
|
||||
for (size_t i = 1; i < kFftSizeBy2Plus1 - 1; ++i) {
|
||||
real[i] = time_data[2 * i];
|
||||
imag[i] = time_data[2 * i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
void NrFft::Ifft(rtc::ArrayView<const float> real,
|
||||
rtc::ArrayView<const float> imag,
|
||||
rtc::ArrayView<float> time_data) {
|
||||
time_data[0] = real[0];
|
||||
time_data[1] = real[kFftSizeBy2Plus1 - 1];
|
||||
for (size_t i = 1; i < kFftSizeBy2Plus1 - 1; ++i) {
|
||||
time_data[2 * i] = real[i];
|
||||
time_data[2 * i + 1] = imag[i];
|
||||
}
|
||||
WebRtc_rdft(kFftSize, -1, time_data.data(), bit_reversal_state_.data(),
|
||||
tables_.data());
|
||||
|
||||
// Scale the output
|
||||
constexpr float kScaling = 2.f / kFftSize;
|
||||
for (float& d : time_data) {
|
||||
d *= kScaling;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
45
webrtc/modules/audio_processing/ns/ns_fft.h
Normal file
45
webrtc/modules/audio_processing/ns/ns_fft.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_NS_FFT_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_NS_FFT_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Wrapper class providing 256 point FFT functionality.
|
||||
class NrFft {
|
||||
public:
|
||||
NrFft();
|
||||
NrFft(const NrFft&) = delete;
|
||||
NrFft& operator=(const NrFft&) = delete;
|
||||
|
||||
// Transforms the signal from time to frequency domain.
|
||||
void Fft(rtc::ArrayView<float, kFftSize> time_data,
|
||||
rtc::ArrayView<float, kFftSize> real,
|
||||
rtc::ArrayView<float, kFftSize> imag);
|
||||
|
||||
// Transforms the signal from frequency to time domain.
|
||||
void Ifft(rtc::ArrayView<const float> real,
|
||||
rtc::ArrayView<const float> imag,
|
||||
rtc::ArrayView<float> time_data);
|
||||
|
||||
private:
|
||||
std::vector<size_t> bit_reversal_state_;
|
||||
std::vector<float> tables_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_NS_FFT_H_
|
File diff suppressed because it is too large
Load Diff
@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_
|
||||
|
||||
#ifdef NS_FILEDEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_defines.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
typedef struct NoiseSuppressionFixedC_ {
|
||||
uint32_t fs;
|
||||
|
||||
const int16_t* window;
|
||||
int16_t analysisBuffer[ANAL_BLOCKL_MAX];
|
||||
int16_t synthesisBuffer[ANAL_BLOCKL_MAX];
|
||||
uint16_t noiseSupFilter[HALF_ANAL_BLOCKL];
|
||||
uint16_t overdrive; /* Q8 */
|
||||
uint16_t denoiseBound; /* Q14 */
|
||||
const int16_t* factor2Table;
|
||||
int16_t noiseEstLogQuantile[SIMULT* HALF_ANAL_BLOCKL];
|
||||
int16_t noiseEstDensity[SIMULT* HALF_ANAL_BLOCKL];
|
||||
int16_t noiseEstCounter[SIMULT];
|
||||
int16_t noiseEstQuantile[HALF_ANAL_BLOCKL];
|
||||
|
||||
size_t anaLen;
|
||||
size_t anaLen2;
|
||||
size_t magnLen;
|
||||
int aggrMode;
|
||||
int stages;
|
||||
int initFlag;
|
||||
int gainMap;
|
||||
|
||||
int32_t maxLrt;
|
||||
int32_t minLrt;
|
||||
// Log LRT factor with time-smoothing in Q8.
|
||||
int32_t logLrtTimeAvgW32[HALF_ANAL_BLOCKL];
|
||||
int32_t featureLogLrt;
|
||||
int32_t thresholdLogLrt;
|
||||
int16_t weightLogLrt;
|
||||
|
||||
uint32_t featureSpecDiff;
|
||||
uint32_t thresholdSpecDiff;
|
||||
int16_t weightSpecDiff;
|
||||
|
||||
uint32_t featureSpecFlat;
|
||||
uint32_t thresholdSpecFlat;
|
||||
int16_t weightSpecFlat;
|
||||
|
||||
// Conservative estimate of noise spectrum.
|
||||
int32_t avgMagnPause[HALF_ANAL_BLOCKL];
|
||||
uint32_t magnEnergy;
|
||||
uint32_t sumMagn;
|
||||
uint32_t curAvgMagnEnergy;
|
||||
uint32_t timeAvgMagnEnergy;
|
||||
uint32_t timeAvgMagnEnergyTmp;
|
||||
|
||||
uint32_t whiteNoiseLevel; // Initial noise estimate.
|
||||
// Initial magnitude spectrum estimate.
|
||||
uint32_t initMagnEst[HALF_ANAL_BLOCKL];
|
||||
// Pink noise parameters:
|
||||
int32_t pinkNoiseNumerator; // Numerator.
|
||||
int32_t pinkNoiseExp; // Power of freq.
|
||||
int minNorm; // Smallest normalization factor.
|
||||
int zeroInputSignal; // Zero input signal flag.
|
||||
|
||||
// Noise spectrum from previous frame.
|
||||
uint32_t prevNoiseU32[HALF_ANAL_BLOCKL];
|
||||
// Magnitude spectrum from previous frame.
|
||||
uint16_t prevMagnU16[HALF_ANAL_BLOCKL];
|
||||
// Prior speech/noise probability in Q14.
|
||||
int16_t priorNonSpeechProb;
|
||||
|
||||
int blockIndex; // Frame index counter.
|
||||
// Parameter for updating or estimating thresholds/weights for prior model.
|
||||
int modelUpdate;
|
||||
int cntThresUpdate;
|
||||
|
||||
// Histograms for parameter estimation.
|
||||
int16_t histLrt[HIST_PAR_EST];
|
||||
int16_t histSpecFlat[HIST_PAR_EST];
|
||||
int16_t histSpecDiff[HIST_PAR_EST];
|
||||
|
||||
// Quantities for high band estimate.
|
||||
int16_t dataBufHBFX[NUM_HIGH_BANDS_MAX][ANAL_BLOCKL_MAX];
|
||||
|
||||
int qNoise;
|
||||
int prevQNoise;
|
||||
int prevQMagn;
|
||||
size_t blockLen10ms;
|
||||
|
||||
int16_t real[ANAL_BLOCKL_MAX];
|
||||
int16_t imag[ANAL_BLOCKL_MAX];
|
||||
int32_t energyIn;
|
||||
int scaleEnergyIn;
|
||||
int normData;
|
||||
|
||||
struct RealFFT* real_fft;
|
||||
} NoiseSuppressionFixedC;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNsx_InitCore(...)
|
||||
*
|
||||
* This function initializes a noise suppression instance
|
||||
*
|
||||
* Input:
|
||||
* - inst : Instance that should be initialized
|
||||
* - fs : Sampling frequency
|
||||
*
|
||||
* Output:
|
||||
* - inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNsx_set_policy_core(...)
|
||||
*
|
||||
* This changes the aggressiveness of the noise suppression method.
|
||||
*
|
||||
* Input:
|
||||
* - inst : Instance that should be initialized
|
||||
* - mode : 0: Mild (6 dB), 1: Medium (10 dB), 2: Aggressive (15 dB)
|
||||
*
|
||||
* Output:
|
||||
* - inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcNsx_set_policy_core(NoiseSuppressionFixedC* inst, int mode);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNsx_ProcessCore
|
||||
*
|
||||
* Do noise suppression.
|
||||
*
|
||||
* Input:
|
||||
* - inst : Instance that should be initialized
|
||||
* - inFrame : Input speech frame for each band
|
||||
* - num_bands : Number of bands
|
||||
*
|
||||
* Output:
|
||||
* - inst : Updated instance
|
||||
* - outFrame : Output speech frame for each band
|
||||
*/
|
||||
void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst,
|
||||
const short* const* inFrame,
|
||||
int num_bands,
|
||||
short* const* outFrame);
|
||||
|
||||
/****************************************************************************
|
||||
* Some function pointers, for internal functions shared by ARM NEON and
|
||||
* generic C code.
|
||||
*/
|
||||
// Noise Estimation.
|
||||
typedef void (*NoiseEstimation)(NoiseSuppressionFixedC* inst,
|
||||
uint16_t* magn,
|
||||
uint32_t* noise,
|
||||
int16_t* q_noise);
|
||||
extern NoiseEstimation WebRtcNsx_NoiseEstimation;
|
||||
|
||||
// Filter the data in the frequency domain, and create spectrum.
|
||||
typedef void (*PrepareSpectrum)(NoiseSuppressionFixedC* inst,
|
||||
int16_t* freq_buff);
|
||||
extern PrepareSpectrum WebRtcNsx_PrepareSpectrum;
|
||||
|
||||
// For the noise supression process, synthesis, read out fully processed
|
||||
// segment, and update synthesis buffer.
|
||||
typedef void (*SynthesisUpdate)(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out_frame,
|
||||
int16_t gain_factor);
|
||||
extern SynthesisUpdate WebRtcNsx_SynthesisUpdate;
|
||||
|
||||
// Update analysis buffer for lower band, and window data before FFT.
|
||||
typedef void (*AnalysisUpdate)(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out,
|
||||
int16_t* new_speech);
|
||||
extern AnalysisUpdate WebRtcNsx_AnalysisUpdate;
|
||||
|
||||
// Denormalize the real-valued signal |in|, the output from inverse FFT.
|
||||
typedef void (*Denormalize)(NoiseSuppressionFixedC* inst,
|
||||
int16_t* in,
|
||||
int factor);
|
||||
extern Denormalize WebRtcNsx_Denormalize;
|
||||
|
||||
// Normalize the real-valued signal |in|, the input to forward FFT.
|
||||
typedef void (*NormalizeRealBuffer)(NoiseSuppressionFixedC* inst,
|
||||
const int16_t* in,
|
||||
int16_t* out);
|
||||
extern NormalizeRealBuffer WebRtcNsx_NormalizeRealBuffer;
|
||||
|
||||
// Compute speech/noise probability.
|
||||
// Intended to be private.
|
||||
void WebRtcNsx_SpeechNoiseProb(NoiseSuppressionFixedC* inst,
|
||||
uint16_t* nonSpeechProbFinal,
|
||||
uint32_t* priorLocSnr,
|
||||
uint32_t* postLocSnr);
|
||||
|
||||
#if (defined WEBRTC_DETECT_NEON || defined WEBRTC_HAS_NEON)
|
||||
// For the above function pointers, functions for generic platforms are declared
|
||||
// and defined as static in file nsx_core.c, while those for ARM Neon platforms
|
||||
// are declared below and defined in file nsx_core_neon.c.
|
||||
void WebRtcNsx_NoiseEstimationNeon(NoiseSuppressionFixedC* inst,
|
||||
uint16_t* magn,
|
||||
uint32_t* noise,
|
||||
int16_t* q_noise);
|
||||
void WebRtcNsx_SynthesisUpdateNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out_frame,
|
||||
int16_t gain_factor);
|
||||
void WebRtcNsx_AnalysisUpdateNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out,
|
||||
int16_t* new_speech);
|
||||
void WebRtcNsx_PrepareSpectrumNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* freq_buff);
|
||||
#endif
|
||||
|
||||
#if defined(MIPS32_LE)
|
||||
// For the above function pointers, functions for generic platforms are declared
|
||||
// and defined as static in file nsx_core.c, while those for MIPS platforms
|
||||
// are declared below and defined in file nsx_core_mips.c.
|
||||
void WebRtcNsx_SynthesisUpdate_mips(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out_frame,
|
||||
int16_t gain_factor);
|
||||
void WebRtcNsx_AnalysisUpdate_mips(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out,
|
||||
int16_t* new_speech);
|
||||
void WebRtcNsx_PrepareSpectrum_mips(NoiseSuppressionFixedC* inst,
|
||||
int16_t* freq_buff);
|
||||
void WebRtcNsx_NormalizeRealBuffer_mips(NoiseSuppressionFixedC* inst,
|
||||
const int16_t* in,
|
||||
int16_t* out);
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
void WebRtcNsx_Denormalize_mips(NoiseSuppressionFixedC* inst,
|
||||
int16_t* in,
|
||||
int factor);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_
|
@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "webrtc/modules/audio_processing/ns/include/noise_suppression_x.h"
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_core.h"
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_defines.h"
|
||||
|
||||
static const int16_t kIndicatorTable[17] = {
|
||||
0, 2017, 3809, 5227, 6258, 6963, 7424, 7718,
|
||||
7901, 8014, 8084, 8126, 8152, 8168, 8177, 8183, 8187
|
||||
};
|
||||
|
||||
// Compute speech/noise probability
|
||||
// speech/noise probability is returned in: probSpeechFinal
|
||||
//snrLocPrior is the prior SNR for each frequency (in Q11)
|
||||
//snrLocPost is the post SNR for each frequency (in Q11)
|
||||
void WebRtcNsx_SpeechNoiseProb(NoiseSuppressionFixedC* inst,
|
||||
uint16_t* nonSpeechProbFinal,
|
||||
uint32_t* priorLocSnr,
|
||||
uint32_t* postLocSnr) {
|
||||
uint32_t zeros, num, den, tmpU32no1, tmpU32no2, tmpU32no3;
|
||||
int32_t invLrtFX, indPriorFX, tmp32, tmp32no1, tmp32no2, besselTmpFX32;
|
||||
int32_t frac32, logTmp;
|
||||
int32_t logLrtTimeAvgKsumFX;
|
||||
int16_t indPriorFX16;
|
||||
int16_t tmp16, tmp16no1, tmp16no2, tmpIndFX, tableIndex, frac, intPart;
|
||||
size_t i;
|
||||
int normTmp, normTmp2, nShifts;
|
||||
|
||||
// compute feature based on average LR factor
|
||||
// this is the average over all frequencies of the smooth log LRT
|
||||
logLrtTimeAvgKsumFX = 0;
|
||||
for (i = 0; i < inst->magnLen; i++) {
|
||||
besselTmpFX32 = (int32_t)postLocSnr[i]; // Q11
|
||||
normTmp = WebRtcSpl_NormU32(postLocSnr[i]);
|
||||
num = postLocSnr[i] << normTmp; // Q(11+normTmp)
|
||||
if (normTmp > 10) {
|
||||
den = priorLocSnr[i] << (normTmp - 11); // Q(normTmp)
|
||||
} else {
|
||||
den = priorLocSnr[i] >> (11 - normTmp); // Q(normTmp)
|
||||
}
|
||||
if (den > 0) {
|
||||
besselTmpFX32 -= num / den; // Q11
|
||||
} else {
|
||||
besselTmpFX32 = 0;
|
||||
}
|
||||
|
||||
// inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - log(snrLocPrior)
|
||||
// - inst->logLrtTimeAvg[i]);
|
||||
// Here, LRT_TAVG = 0.5
|
||||
zeros = WebRtcSpl_NormU32(priorLocSnr[i]);
|
||||
frac32 = (int32_t)(((priorLocSnr[i] << zeros) & 0x7FFFFFFF) >> 19);
|
||||
tmp32 = (frac32 * frac32 * -43) >> 19;
|
||||
tmp32 += ((int16_t)frac32 * 5412) >> 12;
|
||||
frac32 = tmp32 + 37;
|
||||
// tmp32 = log2(priorLocSnr[i])
|
||||
tmp32 = (int32_t)(((31 - zeros) << 12) + frac32) - (11 << 12); // Q12
|
||||
logTmp = (tmp32 * 178) >> 8; // log2(priorLocSnr[i])*log(2)
|
||||
// tmp32no1 = LRT_TAVG * (log(snrLocPrior) + inst->logLrtTimeAvg[i]) in Q12.
|
||||
tmp32no1 = (logTmp + inst->logLrtTimeAvgW32[i]) / 2;
|
||||
inst->logLrtTimeAvgW32[i] += (besselTmpFX32 - tmp32no1); // Q12
|
||||
|
||||
logLrtTimeAvgKsumFX += inst->logLrtTimeAvgW32[i]; // Q12
|
||||
}
|
||||
inst->featureLogLrt = (logLrtTimeAvgKsumFX * BIN_SIZE_LRT) >>
|
||||
(inst->stages + 11);
|
||||
|
||||
// done with computation of LR factor
|
||||
|
||||
//
|
||||
//compute the indicator functions
|
||||
//
|
||||
|
||||
// average LRT feature
|
||||
// FLOAT code
|
||||
// indicator0 = 0.5 * (tanh(widthPrior *
|
||||
// (logLrtTimeAvgKsum - threshPrior0)) + 1.0);
|
||||
tmpIndFX = 16384; // Q14(1.0)
|
||||
tmp32no1 = logLrtTimeAvgKsumFX - inst->thresholdLogLrt; // Q12
|
||||
nShifts = 7 - inst->stages; // WIDTH_PR_MAP_SHIFT - inst->stages + 5;
|
||||
//use larger width in tanh map for pause regions
|
||||
if (tmp32no1 < 0) {
|
||||
tmpIndFX = 0;
|
||||
tmp32no1 = -tmp32no1;
|
||||
//widthPrior = widthPrior * 2.0;
|
||||
nShifts++;
|
||||
}
|
||||
tmp32no1 = WEBRTC_SPL_SHIFT_W32(tmp32no1, nShifts); // Q14
|
||||
// compute indicator function: sigmoid map
|
||||
tableIndex = (int16_t)(tmp32no1 >> 14);
|
||||
if ((tableIndex < 16) && (tableIndex >= 0)) {
|
||||
tmp16no2 = kIndicatorTable[tableIndex];
|
||||
tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];
|
||||
frac = (int16_t)(tmp32no1 & 0x00003fff); // Q14
|
||||
tmp16no2 += (int16_t)((tmp16no1 * frac) >> 14);
|
||||
if (tmpIndFX == 0) {
|
||||
tmpIndFX = 8192 - tmp16no2; // Q14
|
||||
} else {
|
||||
tmpIndFX = 8192 + tmp16no2; // Q14
|
||||
}
|
||||
}
|
||||
indPriorFX = inst->weightLogLrt * tmpIndFX; // 6*Q14
|
||||
|
||||
//spectral flatness feature
|
||||
if (inst->weightSpecFlat) {
|
||||
tmpU32no1 = WEBRTC_SPL_UMUL(inst->featureSpecFlat, 400); // Q10
|
||||
tmpIndFX = 16384; // Q14(1.0)
|
||||
//use larger width in tanh map for pause regions
|
||||
tmpU32no2 = inst->thresholdSpecFlat - tmpU32no1; //Q10
|
||||
nShifts = 4;
|
||||
if (inst->thresholdSpecFlat < tmpU32no1) {
|
||||
tmpIndFX = 0;
|
||||
tmpU32no2 = tmpU32no1 - inst->thresholdSpecFlat;
|
||||
//widthPrior = widthPrior * 2.0;
|
||||
nShifts++;
|
||||
}
|
||||
tmpU32no1 = WebRtcSpl_DivU32U16(tmpU32no2 << nShifts, 25); // Q14
|
||||
// compute indicator function: sigmoid map
|
||||
// FLOAT code
|
||||
// indicator1 = 0.5 * (tanh(sgnMap * widthPrior *
|
||||
// (threshPrior1 - tmpFloat1)) + 1.0);
|
||||
tableIndex = (int16_t)(tmpU32no1 >> 14);
|
||||
if (tableIndex < 16) {
|
||||
tmp16no2 = kIndicatorTable[tableIndex];
|
||||
tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];
|
||||
frac = (int16_t)(tmpU32no1 & 0x00003fff); // Q14
|
||||
tmp16no2 += (int16_t)((tmp16no1 * frac) >> 14);
|
||||
if (tmpIndFX) {
|
||||
tmpIndFX = 8192 + tmp16no2; // Q14
|
||||
} else {
|
||||
tmpIndFX = 8192 - tmp16no2; // Q14
|
||||
}
|
||||
}
|
||||
indPriorFX += inst->weightSpecFlat * tmpIndFX; // 6*Q14
|
||||
}
|
||||
|
||||
//for template spectral-difference
|
||||
if (inst->weightSpecDiff) {
|
||||
tmpU32no1 = 0;
|
||||
if (inst->featureSpecDiff) {
|
||||
normTmp = WEBRTC_SPL_MIN(20 - inst->stages,
|
||||
WebRtcSpl_NormU32(inst->featureSpecDiff));
|
||||
assert(normTmp >= 0);
|
||||
tmpU32no1 = inst->featureSpecDiff << normTmp; // Q(normTmp-2*stages)
|
||||
tmpU32no2 = inst->timeAvgMagnEnergy >> (20 - inst->stages - normTmp);
|
||||
if (tmpU32no2 > 0) {
|
||||
// Q(20 - inst->stages)
|
||||
tmpU32no1 /= tmpU32no2;
|
||||
} else {
|
||||
tmpU32no1 = (uint32_t)(0x7fffffff);
|
||||
}
|
||||
}
|
||||
tmpU32no3 = (inst->thresholdSpecDiff << 17) / 25;
|
||||
tmpU32no2 = tmpU32no1 - tmpU32no3;
|
||||
nShifts = 1;
|
||||
tmpIndFX = 16384; // Q14(1.0)
|
||||
//use larger width in tanh map for pause regions
|
||||
if (tmpU32no2 & 0x80000000) {
|
||||
tmpIndFX = 0;
|
||||
tmpU32no2 = tmpU32no3 - tmpU32no1;
|
||||
//widthPrior = widthPrior * 2.0;
|
||||
nShifts--;
|
||||
}
|
||||
tmpU32no1 = tmpU32no2 >> nShifts;
|
||||
// compute indicator function: sigmoid map
|
||||
/* FLOAT code
|
||||
indicator2 = 0.5 * (tanh(widthPrior * (tmpFloat1 - threshPrior2)) + 1.0);
|
||||
*/
|
||||
tableIndex = (int16_t)(tmpU32no1 >> 14);
|
||||
if (tableIndex < 16) {
|
||||
tmp16no2 = kIndicatorTable[tableIndex];
|
||||
tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex];
|
||||
frac = (int16_t)(tmpU32no1 & 0x00003fff); // Q14
|
||||
tmp16no2 += (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
tmp16no1, frac, 14);
|
||||
if (tmpIndFX) {
|
||||
tmpIndFX = 8192 + tmp16no2;
|
||||
} else {
|
||||
tmpIndFX = 8192 - tmp16no2;
|
||||
}
|
||||
}
|
||||
indPriorFX += inst->weightSpecDiff * tmpIndFX; // 6*Q14
|
||||
}
|
||||
|
||||
//combine the indicator function with the feature weights
|
||||
// FLOAT code
|
||||
// indPrior = 1 - (weightIndPrior0 * indicator0 + weightIndPrior1 *
|
||||
// indicator1 + weightIndPrior2 * indicator2);
|
||||
indPriorFX16 = WebRtcSpl_DivW32W16ResW16(98307 - indPriorFX, 6); // Q14
|
||||
// done with computing indicator function
|
||||
|
||||
//compute the prior probability
|
||||
// FLOAT code
|
||||
// inst->priorNonSpeechProb += PRIOR_UPDATE *
|
||||
// (indPriorNonSpeech - inst->priorNonSpeechProb);
|
||||
tmp16 = indPriorFX16 - inst->priorNonSpeechProb; // Q14
|
||||
inst->priorNonSpeechProb += (int16_t)((PRIOR_UPDATE_Q14 * tmp16) >> 14);
|
||||
|
||||
//final speech probability: combine prior model with LR factor:
|
||||
|
||||
memset(nonSpeechProbFinal, 0, sizeof(uint16_t) * inst->magnLen);
|
||||
|
||||
if (inst->priorNonSpeechProb > 0) {
|
||||
for (i = 0; i < inst->magnLen; i++) {
|
||||
// FLOAT code
|
||||
// invLrt = exp(inst->logLrtTimeAvg[i]);
|
||||
// invLrt = inst->priorSpeechProb * invLrt;
|
||||
// nonSpeechProbFinal[i] = (1.0 - inst->priorSpeechProb) /
|
||||
// (1.0 - inst->priorSpeechProb + invLrt);
|
||||
// invLrt = (1.0 - inst->priorNonSpeechProb) * invLrt;
|
||||
// nonSpeechProbFinal[i] = inst->priorNonSpeechProb /
|
||||
// (inst->priorNonSpeechProb + invLrt);
|
||||
if (inst->logLrtTimeAvgW32[i] < 65300) {
|
||||
tmp32no1 = (inst->logLrtTimeAvgW32[i] * 23637) >> 14; // Q12
|
||||
intPart = (int16_t)(tmp32no1 >> 12);
|
||||
if (intPart < -8) {
|
||||
intPart = -8;
|
||||
}
|
||||
frac = (int16_t)(tmp32no1 & 0x00000fff); // Q12
|
||||
|
||||
// Quadratic approximation of 2^frac
|
||||
tmp32no2 = (frac * frac * 44) >> 19; // Q12.
|
||||
tmp32no2 += (frac * 84) >> 7; // Q12
|
||||
invLrtFX = (1 << (8 + intPart)) +
|
||||
WEBRTC_SPL_SHIFT_W32(tmp32no2, intPart - 4); // Q8
|
||||
|
||||
normTmp = WebRtcSpl_NormW32(invLrtFX);
|
||||
normTmp2 = WebRtcSpl_NormW16((16384 - inst->priorNonSpeechProb));
|
||||
if (normTmp + normTmp2 >= 7) {
|
||||
if (normTmp + normTmp2 < 15) {
|
||||
invLrtFX >>= 15 - normTmp2 - normTmp;
|
||||
// Q(normTmp+normTmp2-7)
|
||||
tmp32no1 = invLrtFX * (16384 - inst->priorNonSpeechProb);
|
||||
// Q(normTmp+normTmp2+7)
|
||||
invLrtFX = WEBRTC_SPL_SHIFT_W32(tmp32no1, 7 - normTmp - normTmp2);
|
||||
// Q14
|
||||
} else {
|
||||
tmp32no1 = invLrtFX * (16384 - inst->priorNonSpeechProb);
|
||||
// Q22
|
||||
invLrtFX = tmp32no1 >> 8; // Q14.
|
||||
}
|
||||
|
||||
tmp32no1 = (int32_t)inst->priorNonSpeechProb << 8; // Q22
|
||||
|
||||
nonSpeechProbFinal[i] = tmp32no1 /
|
||||
(inst->priorNonSpeechProb + invLrtFX); // Q8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,598 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_processing/ns/nsx_core.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Constants to compensate for shifting signal log(2^shifts).
|
||||
const int16_t WebRtcNsx_kLogTable[9] = {
|
||||
0, 177, 355, 532, 710, 887, 1065, 1242, 1420
|
||||
};
|
||||
|
||||
const int16_t WebRtcNsx_kCounterDiv[201] = {
|
||||
32767, 16384, 10923, 8192, 6554, 5461, 4681, 4096, 3641, 3277, 2979, 2731,
|
||||
2521, 2341, 2185, 2048, 1928, 1820, 1725, 1638, 1560, 1489, 1425, 1365, 1311,
|
||||
1260, 1214, 1170, 1130, 1092, 1057, 1024, 993, 964, 936, 910, 886, 862, 840,
|
||||
819, 799, 780, 762, 745, 728, 712, 697, 683, 669, 655, 643, 630, 618, 607,
|
||||
596, 585, 575, 565, 555, 546, 537, 529, 520, 512, 504, 496, 489, 482, 475,
|
||||
468, 462, 455, 449, 443, 437, 431, 426, 420, 415, 410, 405, 400, 395, 390,
|
||||
386, 381, 377, 372, 368, 364, 360, 356, 352, 349, 345, 341, 338, 334, 331,
|
||||
328, 324, 321, 318, 315, 312, 309, 306, 303, 301, 298, 295, 293, 290, 287,
|
||||
285, 282, 280, 278, 275, 273, 271, 269, 266, 264, 262, 260, 258, 256, 254,
|
||||
252, 250, 248, 246, 245, 243, 241, 239, 237, 236, 234, 232, 231, 229, 228,
|
||||
226, 224, 223, 221, 220, 218, 217, 216, 214, 213, 211, 210, 209, 207, 206,
|
||||
205, 204, 202, 201, 200, 199, 197, 196, 195, 194, 193, 192, 191, 189, 188,
|
||||
187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173,
|
||||
172, 172, 171, 170, 169, 168, 167, 166, 165, 165, 164, 163
|
||||
};
|
||||
|
||||
const int16_t WebRtcNsx_kLogTableFrac[256] = {
|
||||
0, 1, 3, 4, 6, 7, 9, 10, 11, 13, 14, 16, 17, 18, 20, 21,
|
||||
22, 24, 25, 26, 28, 29, 30, 32, 33, 34, 36, 37, 38, 40, 41, 42,
|
||||
44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 56, 57, 59, 60, 61, 62,
|
||||
63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81,
|
||||
82, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 97, 98, 99,
|
||||
100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116,
|
||||
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
|
||||
132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
|
||||
147, 148, 149, 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 160,
|
||||
161, 162, 163, 164, 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174,
|
||||
175, 176, 177, 178, 178, 179, 180, 181, 182, 183, 184, 185, 185, 186, 187,
|
||||
188, 189, 190, 191, 192, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200,
|
||||
201, 202, 203, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 212,
|
||||
213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
|
||||
225, 226, 227, 228, 228, 229, 230, 231, 231, 232, 233, 234, 234, 235, 236,
|
||||
237, 238, 238, 239, 240, 241, 241, 242, 243, 244, 244, 245, 246, 247, 247,
|
||||
248, 249, 249, 250, 251, 252, 252, 253, 254, 255, 255
|
||||
};
|
||||
|
||||
// Update the noise estimation information.
|
||||
static void UpdateNoiseEstimateNeon(NoiseSuppressionFixedC* inst, int offset) {
|
||||
const int16_t kExp2Const = 11819; // Q13
|
||||
int16_t* ptr_noiseEstLogQuantile = NULL;
|
||||
int16_t* ptr_noiseEstQuantile = NULL;
|
||||
int16x4_t kExp2Const16x4 = vdup_n_s16(kExp2Const);
|
||||
int32x4_t twentyOne32x4 = vdupq_n_s32(21);
|
||||
int32x4_t constA32x4 = vdupq_n_s32(0x1fffff);
|
||||
int32x4_t constB32x4 = vdupq_n_s32(0x200000);
|
||||
|
||||
int16_t tmp16 = WebRtcSpl_MaxValueW16(inst->noiseEstLogQuantile + offset,
|
||||
inst->magnLen);
|
||||
|
||||
// Guarantee a Q-domain as high as possible and still fit in int16
|
||||
inst->qNoise = 14 - (int) WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2Const,
|
||||
tmp16,
|
||||
21);
|
||||
|
||||
int32x4_t qNoise32x4 = vdupq_n_s32(inst->qNoise);
|
||||
|
||||
for (ptr_noiseEstLogQuantile = &inst->noiseEstLogQuantile[offset],
|
||||
ptr_noiseEstQuantile = &inst->noiseEstQuantile[0];
|
||||
ptr_noiseEstQuantile < &inst->noiseEstQuantile[inst->magnLen - 3];
|
||||
ptr_noiseEstQuantile += 4, ptr_noiseEstLogQuantile += 4) {
|
||||
|
||||
// tmp32no2 = kExp2Const * inst->noiseEstLogQuantile[offset + i];
|
||||
int16x4_t v16x4 = vld1_s16(ptr_noiseEstLogQuantile);
|
||||
int32x4_t v32x4B = vmull_s16(v16x4, kExp2Const16x4);
|
||||
|
||||
// tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF)); // 2^21 + frac
|
||||
int32x4_t v32x4A = vandq_s32(v32x4B, constA32x4);
|
||||
v32x4A = vorrq_s32(v32x4A, constB32x4);
|
||||
|
||||
// tmp16 = (int16_t)(tmp32no2 >> 21);
|
||||
v32x4B = vshrq_n_s32(v32x4B, 21);
|
||||
|
||||
// tmp16 -= 21;// shift 21 to get result in Q0
|
||||
v32x4B = vsubq_s32(v32x4B, twentyOne32x4);
|
||||
|
||||
// tmp16 += (int16_t) inst->qNoise;
|
||||
// shift to get result in Q(qNoise)
|
||||
v32x4B = vaddq_s32(v32x4B, qNoise32x4);
|
||||
|
||||
// if (tmp16 < 0) {
|
||||
// tmp32no1 >>= -tmp16;
|
||||
// } else {
|
||||
// tmp32no1 <<= tmp16;
|
||||
// }
|
||||
v32x4B = vshlq_s32(v32x4A, v32x4B);
|
||||
|
||||
// tmp16 = WebRtcSpl_SatW32ToW16(tmp32no1);
|
||||
v16x4 = vqmovn_s32(v32x4B);
|
||||
|
||||
//inst->noiseEstQuantile[i] = tmp16;
|
||||
vst1_s16(ptr_noiseEstQuantile, v16x4);
|
||||
}
|
||||
|
||||
// Last iteration:
|
||||
|
||||
// inst->quantile[i]=exp(inst->lquantile[offset+i]);
|
||||
// in Q21
|
||||
int32_t tmp32no2 = kExp2Const * *ptr_noiseEstLogQuantile;
|
||||
int32_t tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF)); // 2^21 + frac
|
||||
|
||||
tmp16 = (int16_t)(tmp32no2 >> 21);
|
||||
tmp16 -= 21;// shift 21 to get result in Q0
|
||||
tmp16 += (int16_t) inst->qNoise; //shift to get result in Q(qNoise)
|
||||
if (tmp16 < 0) {
|
||||
tmp32no1 >>= -tmp16;
|
||||
} else {
|
||||
tmp32no1 <<= tmp16;
|
||||
}
|
||||
*ptr_noiseEstQuantile = WebRtcSpl_SatW32ToW16(tmp32no1);
|
||||
}
|
||||
|
||||
// Noise Estimation
|
||||
void WebRtcNsx_NoiseEstimationNeon(NoiseSuppressionFixedC* inst,
|
||||
uint16_t* magn,
|
||||
uint32_t* noise,
|
||||
int16_t* q_noise) {
|
||||
int16_t lmagn[HALF_ANAL_BLOCKL], counter, countDiv;
|
||||
int16_t countProd, delta, zeros, frac;
|
||||
int16_t log2, tabind, logval, tmp16, tmp16no1, tmp16no2;
|
||||
const int16_t log2_const = 22713;
|
||||
const int16_t width_factor = 21845;
|
||||
|
||||
size_t i, s, offset;
|
||||
|
||||
tabind = inst->stages - inst->normData;
|
||||
assert(tabind < 9);
|
||||
assert(tabind > -9);
|
||||
if (tabind < 0) {
|
||||
logval = -WebRtcNsx_kLogTable[-tabind];
|
||||
} else {
|
||||
logval = WebRtcNsx_kLogTable[tabind];
|
||||
}
|
||||
|
||||
int16x8_t logval_16x8 = vdupq_n_s16(logval);
|
||||
|
||||
// lmagn(i)=log(magn(i))=log(2)*log2(magn(i))
|
||||
// magn is in Q(-stages), and the real lmagn values are:
|
||||
// real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages)
|
||||
// lmagn in Q8
|
||||
for (i = 0; i < inst->magnLen; i++) {
|
||||
if (magn[i]) {
|
||||
zeros = WebRtcSpl_NormU32((uint32_t)magn[i]);
|
||||
frac = (int16_t)((((uint32_t)magn[i] << zeros)
|
||||
& 0x7FFFFFFF) >> 23);
|
||||
assert(frac < 256);
|
||||
// log2(magn(i))
|
||||
log2 = (int16_t)(((31 - zeros) << 8)
|
||||
+ WebRtcNsx_kLogTableFrac[frac]);
|
||||
// log2(magn(i))*log(2)
|
||||
lmagn[i] = (int16_t)((log2 * log2_const) >> 15);
|
||||
// + log(2^stages)
|
||||
lmagn[i] += logval;
|
||||
} else {
|
||||
lmagn[i] = logval;
|
||||
}
|
||||
}
|
||||
|
||||
int16x4_t Q3_16x4 = vdup_n_s16(3);
|
||||
int16x8_t WIDTHQ8_16x8 = vdupq_n_s16(WIDTH_Q8);
|
||||
int16x8_t WIDTHFACTOR_16x8 = vdupq_n_s16(width_factor);
|
||||
|
||||
int16_t factor = FACTOR_Q7;
|
||||
if (inst->blockIndex < END_STARTUP_LONG)
|
||||
factor = FACTOR_Q7_STARTUP;
|
||||
|
||||
// Loop over simultaneous estimates
|
||||
for (s = 0; s < SIMULT; s++) {
|
||||
offset = s * inst->magnLen;
|
||||
|
||||
// Get counter values from state
|
||||
counter = inst->noiseEstCounter[s];
|
||||
assert(counter < 201);
|
||||
countDiv = WebRtcNsx_kCounterDiv[counter];
|
||||
countProd = (int16_t)(counter * countDiv);
|
||||
|
||||
// quant_est(...)
|
||||
int16_t deltaBuff[8];
|
||||
int16x4_t tmp16x4_0;
|
||||
int16x4_t tmp16x4_1;
|
||||
int16x4_t countDiv_16x4 = vdup_n_s16(countDiv);
|
||||
int16x8_t countProd_16x8 = vdupq_n_s16(countProd);
|
||||
int16x8_t tmp16x8_0 = vdupq_n_s16(countDiv);
|
||||
int16x8_t prod16x8 = vqrdmulhq_s16(WIDTHFACTOR_16x8, tmp16x8_0);
|
||||
int16x8_t tmp16x8_1;
|
||||
int16x8_t tmp16x8_2;
|
||||
int16x8_t tmp16x8_3;
|
||||
uint16x8_t tmp16x8_4;
|
||||
int32x4_t tmp32x4;
|
||||
|
||||
for (i = 0; i + 7 < inst->magnLen; i += 8) {
|
||||
// Compute delta.
|
||||
// Smaller step size during startup. This prevents from using
|
||||
// unrealistic values causing overflow.
|
||||
tmp16x8_0 = vdupq_n_s16(factor);
|
||||
vst1q_s16(deltaBuff, tmp16x8_0);
|
||||
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (inst->noiseEstDensity[offset + i + j] > 512) {
|
||||
// Get values for deltaBuff by shifting intead of dividing.
|
||||
int factor = WebRtcSpl_NormW16(inst->noiseEstDensity[offset + i + j]);
|
||||
deltaBuff[j] = (int16_t)(FACTOR_Q16 >> (14 - factor));
|
||||
}
|
||||
}
|
||||
|
||||
// Update log quantile estimate
|
||||
|
||||
// tmp16 = (int16_t)((delta * countDiv) >> 14);
|
||||
tmp32x4 = vmull_s16(vld1_s16(&deltaBuff[0]), countDiv_16x4);
|
||||
tmp16x4_1 = vshrn_n_s32(tmp32x4, 14);
|
||||
tmp32x4 = vmull_s16(vld1_s16(&deltaBuff[4]), countDiv_16x4);
|
||||
tmp16x4_0 = vshrn_n_s32(tmp32x4, 14);
|
||||
tmp16x8_0 = vcombine_s16(tmp16x4_1, tmp16x4_0); // Keep for several lines.
|
||||
|
||||
// prepare for the "if" branch
|
||||
// tmp16 += 2;
|
||||
// tmp16_1 = (Word16)(tmp16>>2);
|
||||
tmp16x8_1 = vrshrq_n_s16(tmp16x8_0, 2);
|
||||
|
||||
// inst->noiseEstLogQuantile[offset+i] + tmp16_1;
|
||||
tmp16x8_2 = vld1q_s16(&inst->noiseEstLogQuantile[offset + i]); // Keep
|
||||
tmp16x8_1 = vaddq_s16(tmp16x8_2, tmp16x8_1); // Keep for several lines
|
||||
|
||||
// Prepare for the "else" branch
|
||||
// tmp16 += 1;
|
||||
// tmp16_1 = (Word16)(tmp16>>1);
|
||||
tmp16x8_0 = vrshrq_n_s16(tmp16x8_0, 1);
|
||||
|
||||
// tmp16_2 = (int16_t)((tmp16_1 * 3) >> 1);
|
||||
tmp32x4 = vmull_s16(vget_low_s16(tmp16x8_0), Q3_16x4);
|
||||
tmp16x4_1 = vshrn_n_s32(tmp32x4, 1);
|
||||
|
||||
// tmp16_2 = (int16_t)((tmp16_1 * 3) >> 1);
|
||||
tmp32x4 = vmull_s16(vget_high_s16(tmp16x8_0), Q3_16x4);
|
||||
tmp16x4_0 = vshrn_n_s32(tmp32x4, 1);
|
||||
|
||||
// inst->noiseEstLogQuantile[offset + i] - tmp16_2;
|
||||
tmp16x8_0 = vcombine_s16(tmp16x4_1, tmp16x4_0); // keep
|
||||
tmp16x8_0 = vsubq_s16(tmp16x8_2, tmp16x8_0);
|
||||
|
||||
// logval is the smallest fixed point representation we can have. Values
|
||||
// below that will correspond to values in the interval [0, 1], which
|
||||
// can't possibly occur.
|
||||
tmp16x8_0 = vmaxq_s16(tmp16x8_0, logval_16x8);
|
||||
|
||||
// Do the if-else branches:
|
||||
tmp16x8_3 = vld1q_s16(&lmagn[i]); // keep for several lines
|
||||
tmp16x8_4 = vcgtq_s16(tmp16x8_3, tmp16x8_2);
|
||||
tmp16x8_2 = vbslq_s16(tmp16x8_4, tmp16x8_1, tmp16x8_0);
|
||||
vst1q_s16(&inst->noiseEstLogQuantile[offset + i], tmp16x8_2);
|
||||
|
||||
// Update density estimate
|
||||
// tmp16_1 + tmp16_2
|
||||
tmp16x8_1 = vld1q_s16(&inst->noiseEstDensity[offset + i]);
|
||||
tmp16x8_0 = vqrdmulhq_s16(tmp16x8_1, countProd_16x8);
|
||||
tmp16x8_0 = vaddq_s16(tmp16x8_0, prod16x8);
|
||||
|
||||
// lmagn[i] - inst->noiseEstLogQuantile[offset + i]
|
||||
tmp16x8_3 = vsubq_s16(tmp16x8_3, tmp16x8_2);
|
||||
tmp16x8_3 = vabsq_s16(tmp16x8_3);
|
||||
tmp16x8_4 = vcgtq_s16(WIDTHQ8_16x8, tmp16x8_3);
|
||||
tmp16x8_1 = vbslq_s16(tmp16x8_4, tmp16x8_0, tmp16x8_1);
|
||||
vst1q_s16(&inst->noiseEstDensity[offset + i], tmp16x8_1);
|
||||
} // End loop over magnitude spectrum
|
||||
|
||||
// Last iteration over magnitude spectrum:
|
||||
// compute delta
|
||||
if (inst->noiseEstDensity[offset + i] > 512) {
|
||||
// Get values for deltaBuff by shifting intead of dividing.
|
||||
int factor = WebRtcSpl_NormW16(inst->noiseEstDensity[offset + i]);
|
||||
delta = (int16_t)(FACTOR_Q16 >> (14 - factor));
|
||||
} else {
|
||||
delta = FACTOR_Q7;
|
||||
if (inst->blockIndex < END_STARTUP_LONG) {
|
||||
// Smaller step size during startup. This prevents from using
|
||||
// unrealistic values causing overflow.
|
||||
delta = FACTOR_Q7_STARTUP;
|
||||
}
|
||||
}
|
||||
// update log quantile estimate
|
||||
tmp16 = (int16_t)((delta * countDiv) >> 14);
|
||||
if (lmagn[i] > inst->noiseEstLogQuantile[offset + i]) {
|
||||
// +=QUANTILE*delta/(inst->counter[s]+1) QUANTILE=0.25, =1 in Q2
|
||||
// CounterDiv=1/(inst->counter[s]+1) in Q15
|
||||
tmp16 += 2;
|
||||
inst->noiseEstLogQuantile[offset + i] += tmp16 / 4;
|
||||
} else {
|
||||
tmp16 += 1;
|
||||
// *(1-QUANTILE), in Q2 QUANTILE=0.25, 1-0.25=0.75=3 in Q2
|
||||
// TODO(bjornv): investigate why we need to truncate twice.
|
||||
tmp16no2 = (int16_t)((tmp16 / 2) * 3 / 2);
|
||||
inst->noiseEstLogQuantile[offset + i] -= tmp16no2;
|
||||
if (inst->noiseEstLogQuantile[offset + i] < logval) {
|
||||
// logval is the smallest fixed point representation we can have.
|
||||
// Values below that will correspond to values in the interval
|
||||
// [0, 1], which can't possibly occur.
|
||||
inst->noiseEstLogQuantile[offset + i] = logval;
|
||||
}
|
||||
}
|
||||
|
||||
// update density estimate
|
||||
if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i])
|
||||
< WIDTH_Q8) {
|
||||
tmp16no1 = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
inst->noiseEstDensity[offset + i], countProd, 15);
|
||||
tmp16no2 = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
width_factor, countDiv, 15);
|
||||
inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2;
|
||||
}
|
||||
|
||||
|
||||
if (counter >= END_STARTUP_LONG) {
|
||||
inst->noiseEstCounter[s] = 0;
|
||||
if (inst->blockIndex >= END_STARTUP_LONG) {
|
||||
UpdateNoiseEstimateNeon(inst, offset);
|
||||
}
|
||||
}
|
||||
inst->noiseEstCounter[s]++;
|
||||
|
||||
} // end loop over simultaneous estimates
|
||||
|
||||
// Sequentially update the noise during startup
|
||||
if (inst->blockIndex < END_STARTUP_LONG) {
|
||||
UpdateNoiseEstimateNeon(inst, offset);
|
||||
}
|
||||
|
||||
for (i = 0; i < inst->magnLen; i++) {
|
||||
noise[i] = (uint32_t)(inst->noiseEstQuantile[i]); // Q(qNoise)
|
||||
}
|
||||
(*q_noise) = (int16_t)inst->qNoise;
|
||||
}
|
||||
|
||||
// Filter the data in the frequency domain, and create spectrum.
|
||||
void WebRtcNsx_PrepareSpectrumNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* freq_buf) {
|
||||
assert(inst->magnLen % 8 == 1);
|
||||
assert(inst->anaLen2 % 16 == 0);
|
||||
|
||||
// (1) Filtering.
|
||||
|
||||
// Fixed point C code for the next block is as follows:
|
||||
// for (i = 0; i < inst->magnLen; i++) {
|
||||
// inst->real[i] = (int16_t)((inst->real[i] *
|
||||
// (int16_t)(inst->noiseSupFilter[i])) >> 14); // Q(normData-stages)
|
||||
// inst->imag[i] = (int16_t)((inst->imag[i] *
|
||||
// (int16_t)(inst->noiseSupFilter[i])) >> 14); // Q(normData-stages)
|
||||
// }
|
||||
|
||||
int16_t* preal = &inst->real[0];
|
||||
int16_t* pimag = &inst->imag[0];
|
||||
int16_t* pns_filter = (int16_t*)&inst->noiseSupFilter[0];
|
||||
int16_t* pimag_end = pimag + inst->magnLen - 4;
|
||||
|
||||
while (pimag < pimag_end) {
|
||||
int16x8_t real = vld1q_s16(preal);
|
||||
int16x8_t imag = vld1q_s16(pimag);
|
||||
int16x8_t ns_filter = vld1q_s16(pns_filter);
|
||||
|
||||
int32x4_t tmp_r_0 = vmull_s16(vget_low_s16(real), vget_low_s16(ns_filter));
|
||||
int32x4_t tmp_i_0 = vmull_s16(vget_low_s16(imag), vget_low_s16(ns_filter));
|
||||
int32x4_t tmp_r_1 = vmull_s16(vget_high_s16(real),
|
||||
vget_high_s16(ns_filter));
|
||||
int32x4_t tmp_i_1 = vmull_s16(vget_high_s16(imag),
|
||||
vget_high_s16(ns_filter));
|
||||
|
||||
int16x4_t result_r_0 = vshrn_n_s32(tmp_r_0, 14);
|
||||
int16x4_t result_i_0 = vshrn_n_s32(tmp_i_0, 14);
|
||||
int16x4_t result_r_1 = vshrn_n_s32(tmp_r_1, 14);
|
||||
int16x4_t result_i_1 = vshrn_n_s32(tmp_i_1, 14);
|
||||
|
||||
vst1q_s16(preal, vcombine_s16(result_r_0, result_r_1));
|
||||
vst1q_s16(pimag, vcombine_s16(result_i_0, result_i_1));
|
||||
preal += 8;
|
||||
pimag += 8;
|
||||
pns_filter += 8;
|
||||
}
|
||||
|
||||
// Filter the last element
|
||||
*preal = (int16_t)((*preal * *pns_filter) >> 14);
|
||||
*pimag = (int16_t)((*pimag * *pns_filter) >> 14);
|
||||
|
||||
// (2) Create spectrum.
|
||||
|
||||
// Fixed point C code for the rest of the function is as follows:
|
||||
// freq_buf[0] = inst->real[0];
|
||||
// freq_buf[1] = -inst->imag[0];
|
||||
// for (i = 1, j = 2; i < inst->anaLen2; i += 1, j += 2) {
|
||||
// freq_buf[j] = inst->real[i];
|
||||
// freq_buf[j + 1] = -inst->imag[i];
|
||||
// }
|
||||
// freq_buf[inst->anaLen] = inst->real[inst->anaLen2];
|
||||
// freq_buf[inst->anaLen + 1] = -inst->imag[inst->anaLen2];
|
||||
|
||||
preal = &inst->real[0];
|
||||
pimag = &inst->imag[0];
|
||||
pimag_end = pimag + inst->anaLen2;
|
||||
int16_t * freq_buf_start = freq_buf;
|
||||
while (pimag < pimag_end) {
|
||||
// loop unroll
|
||||
int16x8x2_t real_imag_0;
|
||||
int16x8x2_t real_imag_1;
|
||||
real_imag_0.val[1] = vld1q_s16(pimag);
|
||||
real_imag_0.val[0] = vld1q_s16(preal);
|
||||
preal += 8;
|
||||
pimag += 8;
|
||||
real_imag_1.val[1] = vld1q_s16(pimag);
|
||||
real_imag_1.val[0] = vld1q_s16(preal);
|
||||
preal += 8;
|
||||
pimag += 8;
|
||||
|
||||
real_imag_0.val[1] = vnegq_s16(real_imag_0.val[1]);
|
||||
real_imag_1.val[1] = vnegq_s16(real_imag_1.val[1]);
|
||||
vst2q_s16(freq_buf_start, real_imag_0);
|
||||
freq_buf_start += 16;
|
||||
vst2q_s16(freq_buf_start, real_imag_1);
|
||||
freq_buf_start += 16;
|
||||
}
|
||||
freq_buf[inst->anaLen] = inst->real[inst->anaLen2];
|
||||
freq_buf[inst->anaLen + 1] = -inst->imag[inst->anaLen2];
|
||||
}
|
||||
|
||||
// For the noise supress process, synthesis, read out fully processed segment,
|
||||
// and update synthesis buffer.
|
||||
void WebRtcNsx_SynthesisUpdateNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out_frame,
|
||||
int16_t gain_factor) {
|
||||
assert(inst->anaLen % 16 == 0);
|
||||
assert(inst->blockLen10ms % 16 == 0);
|
||||
|
||||
int16_t* preal_start = inst->real;
|
||||
const int16_t* pwindow = inst->window;
|
||||
int16_t* preal_end = preal_start + inst->anaLen;
|
||||
int16_t* psynthesis_buffer = inst->synthesisBuffer;
|
||||
|
||||
while (preal_start < preal_end) {
|
||||
// Loop unroll.
|
||||
int16x8_t window_0 = vld1q_s16(pwindow);
|
||||
int16x8_t real_0 = vld1q_s16(preal_start);
|
||||
int16x8_t synthesis_buffer_0 = vld1q_s16(psynthesis_buffer);
|
||||
|
||||
int16x8_t window_1 = vld1q_s16(pwindow + 8);
|
||||
int16x8_t real_1 = vld1q_s16(preal_start + 8);
|
||||
int16x8_t synthesis_buffer_1 = vld1q_s16(psynthesis_buffer + 8);
|
||||
|
||||
int32x4_t tmp32a_0_low = vmull_s16(vget_low_s16(real_0),
|
||||
vget_low_s16(window_0));
|
||||
int32x4_t tmp32a_0_high = vmull_s16(vget_high_s16(real_0),
|
||||
vget_high_s16(window_0));
|
||||
|
||||
int32x4_t tmp32a_1_low = vmull_s16(vget_low_s16(real_1),
|
||||
vget_low_s16(window_1));
|
||||
int32x4_t tmp32a_1_high = vmull_s16(vget_high_s16(real_1),
|
||||
vget_high_s16(window_1));
|
||||
|
||||
int16x4_t tmp16a_0_low = vqrshrn_n_s32(tmp32a_0_low, 14);
|
||||
int16x4_t tmp16a_0_high = vqrshrn_n_s32(tmp32a_0_high, 14);
|
||||
|
||||
int16x4_t tmp16a_1_low = vqrshrn_n_s32(tmp32a_1_low, 14);
|
||||
int16x4_t tmp16a_1_high = vqrshrn_n_s32(tmp32a_1_high, 14);
|
||||
|
||||
int32x4_t tmp32b_0_low = vmull_n_s16(tmp16a_0_low, gain_factor);
|
||||
int32x4_t tmp32b_0_high = vmull_n_s16(tmp16a_0_high, gain_factor);
|
||||
|
||||
int32x4_t tmp32b_1_low = vmull_n_s16(tmp16a_1_low, gain_factor);
|
||||
int32x4_t tmp32b_1_high = vmull_n_s16(tmp16a_1_high, gain_factor);
|
||||
|
||||
int16x4_t tmp16b_0_low = vqrshrn_n_s32(tmp32b_0_low, 13);
|
||||
int16x4_t tmp16b_0_high = vqrshrn_n_s32(tmp32b_0_high, 13);
|
||||
|
||||
int16x4_t tmp16b_1_low = vqrshrn_n_s32(tmp32b_1_low, 13);
|
||||
int16x4_t tmp16b_1_high = vqrshrn_n_s32(tmp32b_1_high, 13);
|
||||
|
||||
synthesis_buffer_0 = vqaddq_s16(vcombine_s16(tmp16b_0_low, tmp16b_0_high),
|
||||
synthesis_buffer_0);
|
||||
synthesis_buffer_1 = vqaddq_s16(vcombine_s16(tmp16b_1_low, tmp16b_1_high),
|
||||
synthesis_buffer_1);
|
||||
vst1q_s16(psynthesis_buffer, synthesis_buffer_0);
|
||||
vst1q_s16(psynthesis_buffer + 8, synthesis_buffer_1);
|
||||
|
||||
pwindow += 16;
|
||||
preal_start += 16;
|
||||
psynthesis_buffer += 16;
|
||||
}
|
||||
|
||||
// Read out fully processed segment.
|
||||
int16_t * p_start = inst->synthesisBuffer;
|
||||
int16_t * p_end = inst->synthesisBuffer + inst->blockLen10ms;
|
||||
int16_t * p_frame = out_frame;
|
||||
while (p_start < p_end) {
|
||||
int16x8_t frame_0 = vld1q_s16(p_start);
|
||||
vst1q_s16(p_frame, frame_0);
|
||||
p_start += 8;
|
||||
p_frame += 8;
|
||||
}
|
||||
|
||||
// Update synthesis buffer.
|
||||
int16_t* p_start_src = inst->synthesisBuffer + inst->blockLen10ms;
|
||||
int16_t* p_end_src = inst->synthesisBuffer + inst->anaLen;
|
||||
int16_t* p_start_dst = inst->synthesisBuffer;
|
||||
while (p_start_src < p_end_src) {
|
||||
int16x8_t frame = vld1q_s16(p_start_src);
|
||||
vst1q_s16(p_start_dst, frame);
|
||||
p_start_src += 8;
|
||||
p_start_dst += 8;
|
||||
}
|
||||
|
||||
p_start = inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms;
|
||||
p_end = p_start + inst->blockLen10ms;
|
||||
int16x8_t zero = vdupq_n_s16(0);
|
||||
for (;p_start < p_end; p_start += 8) {
|
||||
vst1q_s16(p_start, zero);
|
||||
}
|
||||
}
|
||||
|
||||
// Update analysis buffer for lower band, and window data before FFT.
|
||||
void WebRtcNsx_AnalysisUpdateNeon(NoiseSuppressionFixedC* inst,
|
||||
int16_t* out,
|
||||
int16_t* new_speech) {
|
||||
assert(inst->blockLen10ms % 16 == 0);
|
||||
assert(inst->anaLen % 16 == 0);
|
||||
|
||||
// For lower band update analysis buffer.
|
||||
// memcpy(inst->analysisBuffer, inst->analysisBuffer + inst->blockLen10ms,
|
||||
// (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->analysisBuffer));
|
||||
int16_t* p_start_src = inst->analysisBuffer + inst->blockLen10ms;
|
||||
int16_t* p_end_src = inst->analysisBuffer + inst->anaLen;
|
||||
int16_t* p_start_dst = inst->analysisBuffer;
|
||||
while (p_start_src < p_end_src) {
|
||||
int16x8_t frame = vld1q_s16(p_start_src);
|
||||
vst1q_s16(p_start_dst, frame);
|
||||
|
||||
p_start_src += 8;
|
||||
p_start_dst += 8;
|
||||
}
|
||||
|
||||
// memcpy(inst->analysisBuffer + inst->anaLen - inst->blockLen10ms,
|
||||
// new_speech, inst->blockLen10ms * sizeof(*inst->analysisBuffer));
|
||||
p_start_src = new_speech;
|
||||
p_end_src = new_speech + inst->blockLen10ms;
|
||||
p_start_dst = inst->analysisBuffer + inst->anaLen - inst->blockLen10ms;
|
||||
while (p_start_src < p_end_src) {
|
||||
int16x8_t frame = vld1q_s16(p_start_src);
|
||||
vst1q_s16(p_start_dst, frame);
|
||||
|
||||
p_start_src += 8;
|
||||
p_start_dst += 8;
|
||||
}
|
||||
|
||||
// Window data before FFT.
|
||||
int16_t* p_start_window = (int16_t*) inst->window;
|
||||
int16_t* p_start_buffer = inst->analysisBuffer;
|
||||
int16_t* p_start_out = out;
|
||||
const int16_t* p_end_out = out + inst->anaLen;
|
||||
|
||||
// Load the first element to reduce pipeline bubble.
|
||||
int16x8_t window = vld1q_s16(p_start_window);
|
||||
int16x8_t buffer = vld1q_s16(p_start_buffer);
|
||||
p_start_window += 8;
|
||||
p_start_buffer += 8;
|
||||
|
||||
while (p_start_out < p_end_out) {
|
||||
// Unroll loop.
|
||||
int32x4_t tmp32_low = vmull_s16(vget_low_s16(window), vget_low_s16(buffer));
|
||||
int32x4_t tmp32_high = vmull_s16(vget_high_s16(window),
|
||||
vget_high_s16(buffer));
|
||||
window = vld1q_s16(p_start_window);
|
||||
buffer = vld1q_s16(p_start_buffer);
|
||||
|
||||
int16x4_t result_low = vrshrn_n_s32(tmp32_low, 14);
|
||||
int16x4_t result_high = vrshrn_n_s32(tmp32_high, 14);
|
||||
vst1q_s16(p_start_out, vcombine_s16(result_low, result_high));
|
||||
|
||||
p_start_buffer += 8;
|
||||
p_start_window += 8;
|
||||
p_start_out += 8;
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_
|
||||
|
||||
#define ANAL_BLOCKL_MAX 256 /* Max analysis block length */
|
||||
#define HALF_ANAL_BLOCKL 129 /* Half max analysis block length + 1 */
|
||||
#define NUM_HIGH_BANDS_MAX 2 /* Max number of high bands */
|
||||
#define SIMULT 3
|
||||
#define END_STARTUP_LONG 200
|
||||
#define END_STARTUP_SHORT 50
|
||||
#define FACTOR_Q16 2621440 /* 40 in Q16 */
|
||||
#define FACTOR_Q7 5120 /* 40 in Q7 */
|
||||
#define FACTOR_Q7_STARTUP 1024 /* 8 in Q7 */
|
||||
#define WIDTH_Q8 3 /* 0.01 in Q8 (or 25 ) */
|
||||
|
||||
/* PARAMETERS FOR NEW METHOD */
|
||||
#define DD_PR_SNR_Q11 2007 /* ~= Q11(0.98) DD update of prior SNR */
|
||||
#define ONE_MINUS_DD_PR_SNR_Q11 41 /* DD update of prior SNR */
|
||||
#define SPECT_FLAT_TAVG_Q14 4915 /* (0.30) tavg parameter for spectral flatness measure */
|
||||
#define SPECT_DIFF_TAVG_Q8 77 /* (0.30) tavg parameter for spectral flatness measure */
|
||||
#define PRIOR_UPDATE_Q14 1638 /* Q14(0.1) Update parameter of prior model */
|
||||
#define NOISE_UPDATE_Q8 26 /* 26 ~= Q8(0.1) Update parameter for noise */
|
||||
|
||||
/* Probability threshold for noise state in speech/noise likelihood. */
|
||||
#define ONE_MINUS_PROB_RANGE_Q8 205 /* 205 ~= Q8(0.8) */
|
||||
#define HIST_PAR_EST 1000 /* Histogram size for estimation of parameters */
|
||||
|
||||
/* FEATURE EXTRACTION CONFIG */
|
||||
/* Bin size of histogram */
|
||||
#define BIN_SIZE_LRT 10
|
||||
/* Scale parameters: multiply dominant peaks of the histograms by scale factor to obtain. */
|
||||
/* Thresholds for prior model */
|
||||
#define FACTOR_1_LRT_DIFF 6 /* For LRT and spectral difference (5 times bigger) */
|
||||
/* For spectral_flatness: used when noise is flatter than speech (10 times bigger). */
|
||||
#define FACTOR_2_FLAT_Q10 922
|
||||
/* Peak limit for spectral flatness (varies between 0 and 1) */
|
||||
#define THRES_PEAK_FLAT 24 /* * 2 * BIN_SIZE_FLAT_FX */
|
||||
/* Limit on spacing of two highest peaks in histogram: spacing determined by bin size. */
|
||||
#define LIM_PEAK_SPACE_FLAT_DIFF 4 /* * 2 * BIN_SIZE_DIFF_FX */
|
||||
/* Limit on relevance of second peak */
|
||||
#define LIM_PEAK_WEIGHT_FLAT_DIFF 2
|
||||
#define THRES_FLUCT_LRT 10240 /* = 20 * inst->modelUpdate; fluctuation limit of LRT feat. */
|
||||
/* Limit on the max and min values for the feature thresholds */
|
||||
#define MAX_FLAT_Q10 38912 /* * 2 * BIN_SIZE_FLAT_FX */
|
||||
#define MIN_FLAT_Q10 4096 /* * 2 * BIN_SIZE_FLAT_FX */
|
||||
#define MAX_DIFF 100 /* * 2 * BIN_SIZE_DIFF_FX */
|
||||
#define MIN_DIFF 16 /* * 2 * BIN_SIZE_DIFF_FX */
|
||||
/* Criteria of weight of histogram peak to accept/reject feature */
|
||||
#define THRES_WEIGHT_FLAT_DIFF 154 /*(int)(0.3*(inst->modelUpdate)) for flatness and difference */
|
||||
|
||||
#define STAT_UPDATES 9 /* Update every 512 = 1 << 9 block */
|
||||
#define ONE_MINUS_GAMMA_PAUSE_Q8 13 /* ~= Q8(0.05) Update for conservative noise estimate */
|
||||
#define GAMMA_NOISE_TRANS_AND_SPEECH_Q8 3 /* ~= Q8(0.01) Update for transition and noise region */
|
||||
|
||||
#endif /* WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ */
|
18
webrtc/modules/audio_processing/ns/prior_signal_model.cc
Normal file
18
webrtc/modules/audio_processing/ns/prior_signal_model.cc
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/prior_signal_model.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
PriorSignalModel::PriorSignalModel(float lrt_initial_value)
|
||||
: lrt(lrt_initial_value) {}
|
||||
|
||||
} // namespace webrtc
|
32
webrtc/modules/audio_processing/ns/prior_signal_model.h
Normal file
32
webrtc/modules/audio_processing/ns/prior_signal_model.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Struct for storing the prior signal model parameters.
|
||||
struct PriorSignalModel {
|
||||
explicit PriorSignalModel(float lrt_initial_value);
|
||||
PriorSignalModel(const PriorSignalModel&) = delete;
|
||||
PriorSignalModel& operator=(const PriorSignalModel&) = delete;
|
||||
|
||||
float lrt;
|
||||
float flatness_threshold = .5f;
|
||||
float template_diff_threshold = .5f;
|
||||
float lrt_weighting = 1.f;
|
||||
float flatness_weighting = 0.f;
|
||||
float difference_weighting = 0.f;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_H_
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/prior_signal_model_estimator.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Identifies the first of the two largest peaks in the histogram.
|
||||
void FindFirstOfTwoLargestPeaks(
|
||||
float bin_size,
|
||||
rtc::ArrayView<const int, kHistogramSize> spectral_flatness,
|
||||
float* peak_position,
|
||||
int* peak_weight) {
|
||||
RTC_DCHECK(peak_position);
|
||||
RTC_DCHECK(peak_weight);
|
||||
|
||||
int peak_value = 0;
|
||||
int secondary_peak_value = 0;
|
||||
*peak_position = 0.f;
|
||||
float secondary_peak_position = 0.f;
|
||||
*peak_weight = 0;
|
||||
int secondary_peak_weight = 0;
|
||||
|
||||
// Identify the two largest peaks.
|
||||
for (int i = 0; i < kHistogramSize; ++i) {
|
||||
const float bin_mid = (i + 0.5f) * bin_size;
|
||||
if (spectral_flatness[i] > peak_value) {
|
||||
// Found new "first" peak candidate.
|
||||
secondary_peak_value = peak_value;
|
||||
secondary_peak_weight = *peak_weight;
|
||||
secondary_peak_position = *peak_position;
|
||||
|
||||
peak_value = spectral_flatness[i];
|
||||
*peak_weight = spectral_flatness[i];
|
||||
*peak_position = bin_mid;
|
||||
} else if (spectral_flatness[i] > secondary_peak_value) {
|
||||
// Found new "second" peak candidate.
|
||||
secondary_peak_value = spectral_flatness[i];
|
||||
secondary_peak_weight = spectral_flatness[i];
|
||||
secondary_peak_position = bin_mid;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the peaks if they are close.
|
||||
if ((fabs(secondary_peak_position - *peak_position) < 2 * bin_size) &&
|
||||
(secondary_peak_weight > 0.5f * (*peak_weight))) {
|
||||
*peak_weight += secondary_peak_weight;
|
||||
*peak_position = 0.5f * (*peak_position + secondary_peak_position);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateLrt(rtc::ArrayView<const int, kHistogramSize> lrt_histogram,
|
||||
float* prior_model_lrt,
|
||||
bool* low_lrt_fluctuations) {
|
||||
RTC_DCHECK(prior_model_lrt);
|
||||
RTC_DCHECK(low_lrt_fluctuations);
|
||||
|
||||
float average = 0.f;
|
||||
float average_compl = 0.f;
|
||||
float average_squared = 0.f;
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
float bin_mid = (i + 0.5f) * kBinSizeLrt;
|
||||
average += lrt_histogram[i] * bin_mid;
|
||||
count += lrt_histogram[i];
|
||||
}
|
||||
if (count > 0) {
|
||||
average = average / count;
|
||||
}
|
||||
|
||||
for (int i = 0; i < kHistogramSize; ++i) {
|
||||
float bin_mid = (i + 0.5f) * kBinSizeLrt;
|
||||
average_squared += lrt_histogram[i] * bin_mid * bin_mid;
|
||||
average_compl += lrt_histogram[i] * bin_mid;
|
||||
}
|
||||
constexpr float kOneFeatureUpdateWindowSize = 1.f / kFeatureUpdateWindowSize;
|
||||
average_squared = average_squared * kOneFeatureUpdateWindowSize;
|
||||
average_compl = average_compl * kOneFeatureUpdateWindowSize;
|
||||
|
||||
// Fluctuation limit of LRT feature.
|
||||
*low_lrt_fluctuations = average_squared - average * average_compl < 0.05f;
|
||||
|
||||
// Get threshold for LRT feature.
|
||||
constexpr float kMaxLrt = 1.f;
|
||||
constexpr float kMinLrt = .2f;
|
||||
if (*low_lrt_fluctuations) {
|
||||
// Very low fluctuation, so likely noise.
|
||||
*prior_model_lrt = kMaxLrt;
|
||||
} else {
|
||||
*prior_model_lrt = std::min(kMaxLrt, std::max(kMinLrt, 1.2f * average));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PriorSignalModelEstimator::PriorSignalModelEstimator(float lrt_initial_value)
|
||||
: prior_model_(lrt_initial_value) {}
|
||||
|
||||
// Extract thresholds for feature parameters and computes the threshold/weights.
|
||||
void PriorSignalModelEstimator::Update(const Histograms& histograms) {
|
||||
bool low_lrt_fluctuations;
|
||||
UpdateLrt(histograms.get_lrt(), &prior_model_.lrt, &low_lrt_fluctuations);
|
||||
|
||||
// For spectral flatness and spectral difference: compute the main peaks of
|
||||
// the histograms.
|
||||
float spectral_flatness_peak_position;
|
||||
int spectral_flatness_peak_weight;
|
||||
FindFirstOfTwoLargestPeaks(
|
||||
kBinSizeSpecFlat, histograms.get_spectral_flatness(),
|
||||
&spectral_flatness_peak_position, &spectral_flatness_peak_weight);
|
||||
|
||||
float spectral_diff_peak_position = 0.f;
|
||||
int spectral_diff_peak_weight = 0;
|
||||
FindFirstOfTwoLargestPeaks(kBinSizeSpecDiff, histograms.get_spectral_diff(),
|
||||
&spectral_diff_peak_position,
|
||||
&spectral_diff_peak_weight);
|
||||
|
||||
// Reject if weight of peaks is not large enough, or peak value too small.
|
||||
// Peak limit for spectral flatness (varies between 0 and 1).
|
||||
const int use_spec_flat = spectral_flatness_peak_weight < 0.3f * 500 ||
|
||||
spectral_flatness_peak_position < 0.6f
|
||||
? 0
|
||||
: 1;
|
||||
|
||||
// Reject if weight of peaks is not large enough or if fluctuation of the LRT
|
||||
// feature are very low, indicating a noise state.
|
||||
const int use_spec_diff =
|
||||
spectral_diff_peak_weight < 0.3f * 500 || low_lrt_fluctuations ? 0 : 1;
|
||||
|
||||
// Update the model.
|
||||
prior_model_.template_diff_threshold = 1.2f * spectral_diff_peak_position;
|
||||
prior_model_.template_diff_threshold =
|
||||
std::min(1.f, std::max(0.16f, prior_model_.template_diff_threshold));
|
||||
|
||||
float one_by_feature_sum = 1.f / (1.f + use_spec_flat + use_spec_diff);
|
||||
prior_model_.lrt_weighting = one_by_feature_sum;
|
||||
|
||||
if (use_spec_flat == 1) {
|
||||
prior_model_.flatness_threshold = 0.9f * spectral_flatness_peak_position;
|
||||
prior_model_.flatness_threshold =
|
||||
std::min(.95f, std::max(0.1f, prior_model_.flatness_threshold));
|
||||
prior_model_.flatness_weighting = one_by_feature_sum;
|
||||
} else {
|
||||
prior_model_.flatness_weighting = 0.f;
|
||||
}
|
||||
|
||||
if (use_spec_diff == 1) {
|
||||
prior_model_.difference_weighting = one_by_feature_sum;
|
||||
} else {
|
||||
prior_model_.difference_weighting = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_ESTIMATOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_ESTIMATOR_H_
|
||||
|
||||
#include "modules/audio_processing/ns/histograms.h"
|
||||
#include "modules/audio_processing/ns/prior_signal_model.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Estimator of the prior signal model parameters.
|
||||
class PriorSignalModelEstimator {
|
||||
public:
|
||||
explicit PriorSignalModelEstimator(float lrt_initial_value);
|
||||
PriorSignalModelEstimator(const PriorSignalModelEstimator&) = delete;
|
||||
PriorSignalModelEstimator& operator=(const PriorSignalModelEstimator&) =
|
||||
delete;
|
||||
|
||||
// Updates the model estimate.
|
||||
void Update(const Histograms& h);
|
||||
|
||||
// Returns the estimated model.
|
||||
const PriorSignalModel& get_prior_model() const { return prior_model_; }
|
||||
|
||||
private:
|
||||
PriorSignalModel prior_model_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_PRIOR_SIGNAL_MODEL_ESTIMATOR_H_
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/quantile_noise_estimator.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
QuantileNoiseEstimator::QuantileNoiseEstimator() {
|
||||
quantile_.fill(0.f);
|
||||
density_.fill(0.3f);
|
||||
log_quantile_.fill(8.f);
|
||||
|
||||
constexpr float kOneBySimult = 1.f / kSimult;
|
||||
for (size_t i = 0; i < kSimult; ++i) {
|
||||
counter_[i] = floor(kLongStartupPhaseBlocks * (i + 1.f) * kOneBySimult);
|
||||
}
|
||||
}
|
||||
|
||||
void QuantileNoiseEstimator::Estimate(
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> noise_spectrum) {
|
||||
std::array<float, kFftSizeBy2Plus1> log_spectrum;
|
||||
LogApproximation(signal_spectrum, log_spectrum);
|
||||
|
||||
int quantile_index_to_return = -1;
|
||||
// Loop over simultaneous estimates.
|
||||
for (int s = 0, k = 0; s < kSimult;
|
||||
++s, k += static_cast<int>(kFftSizeBy2Plus1)) {
|
||||
const float one_by_counter_plus_1 = 1.f / (counter_[s] + 1.f);
|
||||
for (int i = 0, j = k; i < static_cast<int>(kFftSizeBy2Plus1); ++i, ++j) {
|
||||
// Update log quantile estimate.
|
||||
const float delta = density_[j] > 1.f ? 40.f / density_[j] : 40.f;
|
||||
|
||||
const float multiplier = delta * one_by_counter_plus_1;
|
||||
if (log_spectrum[i] > log_quantile_[j]) {
|
||||
log_quantile_[j] += 0.25f * multiplier;
|
||||
} else {
|
||||
log_quantile_[j] -= 0.75f * multiplier;
|
||||
}
|
||||
|
||||
// Update density estimate.
|
||||
constexpr float kWidth = 0.01f;
|
||||
constexpr float kOneByWidthPlus2 = 1.f / (2.f * kWidth);
|
||||
if (fabs(log_spectrum[i] - log_quantile_[j]) < kWidth) {
|
||||
density_[j] = (counter_[s] * density_[j] + kOneByWidthPlus2) *
|
||||
one_by_counter_plus_1;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter_[s] >= kLongStartupPhaseBlocks) {
|
||||
counter_[s] = 0;
|
||||
if (num_updates_ >= kLongStartupPhaseBlocks) {
|
||||
quantile_index_to_return = k;
|
||||
}
|
||||
}
|
||||
|
||||
++counter_[s];
|
||||
}
|
||||
|
||||
// Sequentially update the noise during startup.
|
||||
if (num_updates_ < kLongStartupPhaseBlocks) {
|
||||
// Use the last "s" to get noise during startup that differ from zero.
|
||||
quantile_index_to_return = kFftSizeBy2Plus1 * (kSimult - 1);
|
||||
++num_updates_;
|
||||
}
|
||||
|
||||
if (quantile_index_to_return >= 0) {
|
||||
ExpApproximation(
|
||||
rtc::ArrayView<const float>(&log_quantile_[quantile_index_to_return],
|
||||
kFftSizeBy2Plus1),
|
||||
quantile_);
|
||||
}
|
||||
|
||||
std::copy(quantile_.begin(), quantile_.end(), noise_spectrum.begin());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_QUANTILE_NOISE_ESTIMATOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_QUANTILE_NOISE_ESTIMATOR_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr int kSimult = 3;
|
||||
|
||||
// For quantile noise estimation.
|
||||
class QuantileNoiseEstimator {
|
||||
public:
|
||||
QuantileNoiseEstimator();
|
||||
QuantileNoiseEstimator(const QuantileNoiseEstimator&) = delete;
|
||||
QuantileNoiseEstimator& operator=(const QuantileNoiseEstimator&) = delete;
|
||||
|
||||
// Estimate noise.
|
||||
void Estimate(rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> noise_spectrum);
|
||||
|
||||
private:
|
||||
std::array<float, kSimult * kFftSizeBy2Plus1> density_;
|
||||
std::array<float, kSimult * kFftSizeBy2Plus1> log_quantile_;
|
||||
std::array<float, kFftSizeBy2Plus1> quantile_;
|
||||
std::array<int, kSimult> counter_;
|
||||
int num_updates_ = 1;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_QUANTILE_NOISE_ESTIMATOR_H_
|
24
webrtc/modules/audio_processing/ns/signal_model.cc
Normal file
24
webrtc/modules/audio_processing/ns/signal_model.cc
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/signal_model.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SignalModel::SignalModel() {
|
||||
constexpr float kSfFeatureThr = 0.5f;
|
||||
|
||||
lrt = kLtrFeatureThr;
|
||||
spectral_flatness = kSfFeatureThr;
|
||||
spectral_diff = kSfFeatureThr;
|
||||
avg_log_lrt.fill(kLtrFeatureThr);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
34
webrtc/modules/audio_processing/ns/signal_model.h
Normal file
34
webrtc/modules/audio_processing/ns/signal_model.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct SignalModel {
|
||||
SignalModel();
|
||||
SignalModel(const SignalModel&) = delete;
|
||||
SignalModel& operator=(const SignalModel&) = delete;
|
||||
|
||||
float lrt;
|
||||
float spectral_diff;
|
||||
float spectral_flatness;
|
||||
// Log LRT factor with time-smoothing.
|
||||
std::array<float, kFftSizeBy2Plus1> avg_log_lrt;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_H_
|
175
webrtc/modules/audio_processing/ns/signal_model_estimator.cc
Normal file
175
webrtc/modules/audio_processing/ns/signal_model_estimator.cc
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/signal_model_estimator.h"
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float kOneByFftSizeBy2Plus1 = 1.f / kFftSizeBy2Plus1;
|
||||
|
||||
// Computes the difference measure between input spectrum and a template/learned
|
||||
// noise spectrum.
|
||||
float ComputeSpectralDiff(
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> conservative_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float diff_normalization) {
|
||||
// spectral_diff = var(signal_spectrum) - cov(signal_spectrum, magnAvgPause)^2
|
||||
// / var(magnAvgPause)
|
||||
|
||||
// Compute average quantities.
|
||||
float noise_average = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
// Conservative smooth noise spectrum from pause frames.
|
||||
noise_average += conservative_noise_spectrum[i];
|
||||
}
|
||||
noise_average = noise_average * kOneByFftSizeBy2Plus1;
|
||||
float signal_average = signal_spectral_sum * kOneByFftSizeBy2Plus1;
|
||||
|
||||
// Compute variance and covariance quantities.
|
||||
float covariance = 0.f;
|
||||
float noise_variance = 0.f;
|
||||
float signal_variance = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
float signal_diff = signal_spectrum[i] - signal_average;
|
||||
float noise_diff = conservative_noise_spectrum[i] - noise_average;
|
||||
covariance += signal_diff * noise_diff;
|
||||
noise_variance += noise_diff * noise_diff;
|
||||
signal_variance += signal_diff * signal_diff;
|
||||
}
|
||||
covariance *= kOneByFftSizeBy2Plus1;
|
||||
noise_variance *= kOneByFftSizeBy2Plus1;
|
||||
signal_variance *= kOneByFftSizeBy2Plus1;
|
||||
|
||||
// Update of average magnitude spectrum.
|
||||
float spectral_diff =
|
||||
signal_variance - (covariance * covariance) / (noise_variance + 0.0001f);
|
||||
// Normalize.
|
||||
return spectral_diff / (diff_normalization + 0.0001f);
|
||||
}
|
||||
|
||||
// Updates the spectral flatness based on the input spectrum.
|
||||
void UpdateSpectralFlatness(
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float* spectral_flatness) {
|
||||
RTC_DCHECK(spectral_flatness);
|
||||
|
||||
// Compute log of ratio of the geometric to arithmetic mean (handle the log(0)
|
||||
// separately).
|
||||
constexpr float kAveraging = 0.3f;
|
||||
float avg_spect_flatness_num = 0.f;
|
||||
for (size_t i = 1; i < kFftSizeBy2Plus1; ++i) {
|
||||
if (signal_spectrum[i] == 0.f) {
|
||||
*spectral_flatness -= kAveraging * (*spectral_flatness);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < kFftSizeBy2Plus1; ++i) {
|
||||
avg_spect_flatness_num += LogApproximation(signal_spectrum[i]);
|
||||
}
|
||||
|
||||
float avg_spect_flatness_denom = signal_spectral_sum - signal_spectrum[0];
|
||||
|
||||
avg_spect_flatness_denom = avg_spect_flatness_denom * kOneByFftSizeBy2Plus1;
|
||||
avg_spect_flatness_num = avg_spect_flatness_num * kOneByFftSizeBy2Plus1;
|
||||
|
||||
float spectral_tmp =
|
||||
ExpApproximation(avg_spect_flatness_num) / avg_spect_flatness_denom;
|
||||
|
||||
// Time-avg update of spectral flatness feature.
|
||||
*spectral_flatness += kAveraging * (spectral_tmp - *spectral_flatness);
|
||||
}
|
||||
|
||||
// Updates the log LRT measures.
|
||||
void UpdateSpectralLrt(rtc::ArrayView<const float, kFftSizeBy2Plus1> prior_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> post_snr,
|
||||
rtc::ArrayView<float, kFftSizeBy2Plus1> avg_log_lrt,
|
||||
float* lrt) {
|
||||
RTC_DCHECK(lrt);
|
||||
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
float tmp1 = 1.f + 2.f * prior_snr[i];
|
||||
float tmp2 = 2.f * prior_snr[i] / (tmp1 + 0.0001f);
|
||||
float bessel_tmp = (post_snr[i] + 1.f) * tmp2;
|
||||
avg_log_lrt[i] +=
|
||||
.5f * (bessel_tmp - LogApproximation(tmp1) - avg_log_lrt[i]);
|
||||
}
|
||||
|
||||
float log_lrt_time_avg_k_sum = 0.f;
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
log_lrt_time_avg_k_sum += avg_log_lrt[i];
|
||||
}
|
||||
*lrt = log_lrt_time_avg_k_sum * kOneByFftSizeBy2Plus1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SignalModelEstimator::SignalModelEstimator()
|
||||
: prior_model_estimator_(kLtrFeatureThr) {}
|
||||
|
||||
void SignalModelEstimator::AdjustNormalization(int32_t num_analyzed_frames,
|
||||
float signal_energy) {
|
||||
diff_normalization_ *= num_analyzed_frames;
|
||||
diff_normalization_ += signal_energy;
|
||||
diff_normalization_ /= (num_analyzed_frames + 1);
|
||||
}
|
||||
|
||||
// Update the noise features.
|
||||
void SignalModelEstimator::Update(
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prior_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> post_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> conservative_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float signal_energy) {
|
||||
// Compute spectral flatness on input spectrum.
|
||||
UpdateSpectralFlatness(signal_spectrum, signal_spectral_sum,
|
||||
&features_.spectral_flatness);
|
||||
|
||||
// Compute difference of input spectrum with learned/estimated noise spectrum.
|
||||
float spectral_diff =
|
||||
ComputeSpectralDiff(conservative_noise_spectrum, signal_spectrum,
|
||||
signal_spectral_sum, diff_normalization_);
|
||||
// Compute time-avg update of difference feature.
|
||||
features_.spectral_diff += 0.3f * (spectral_diff - features_.spectral_diff);
|
||||
|
||||
signal_energy_sum_ += signal_energy;
|
||||
|
||||
// Compute histograms for parameter decisions (thresholds and weights for
|
||||
// features). Parameters are extracted periodically.
|
||||
if (--histogram_analysis_counter_ > 0) {
|
||||
histograms_.Update(features_);
|
||||
} else {
|
||||
// Compute model parameters.
|
||||
prior_model_estimator_.Update(histograms_);
|
||||
|
||||
// Clear histograms for next update.
|
||||
histograms_.Clear();
|
||||
|
||||
histogram_analysis_counter_ = kFeatureUpdateWindowSize;
|
||||
|
||||
// Update every window:
|
||||
// Compute normalization for the spectral difference for next estimation.
|
||||
signal_energy_sum_ = signal_energy_sum_ / kFeatureUpdateWindowSize;
|
||||
diff_normalization_ = 0.5f * (signal_energy_sum_ + diff_normalization_);
|
||||
signal_energy_sum_ = 0.f;
|
||||
}
|
||||
|
||||
// Compute the LRT.
|
||||
UpdateSpectralLrt(prior_snr, post_snr, features_.avg_log_lrt, &features_.lrt);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
58
webrtc/modules/audio_processing/ns/signal_model_estimator.h
Normal file
58
webrtc/modules/audio_processing/ns/signal_model_estimator.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_ESTIMATOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_ESTIMATOR_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/histograms.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/prior_signal_model.h"
|
||||
#include "modules/audio_processing/ns/prior_signal_model_estimator.h"
|
||||
#include "modules/audio_processing/ns/signal_model.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class SignalModelEstimator {
|
||||
public:
|
||||
SignalModelEstimator();
|
||||
SignalModelEstimator(const SignalModelEstimator&) = delete;
|
||||
SignalModelEstimator& operator=(const SignalModelEstimator&) = delete;
|
||||
|
||||
// Compute signal normalization during the initial startup phase.
|
||||
void AdjustNormalization(int32_t num_analyzed_frames, float signal_energy);
|
||||
|
||||
void Update(
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prior_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> post_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> conservative_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float signal_energy);
|
||||
|
||||
const PriorSignalModel& get_prior_model() const {
|
||||
return prior_model_estimator_.get_prior_model();
|
||||
}
|
||||
const SignalModel& get_model() { return features_; }
|
||||
|
||||
private:
|
||||
float diff_normalization_ = 0.f;
|
||||
float signal_energy_sum_ = 0.f;
|
||||
Histograms histograms_;
|
||||
int histogram_analysis_counter_ = 500;
|
||||
PriorSignalModelEstimator prior_model_estimator_;
|
||||
SignalModel features_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_ESTIMATOR_H_
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/speech_probability_estimator.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SpeechProbabilityEstimator::SpeechProbabilityEstimator() {
|
||||
speech_probability_.fill(0.f);
|
||||
}
|
||||
|
||||
void SpeechProbabilityEstimator::Update(
|
||||
int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prior_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> post_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> conservative_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float signal_energy) {
|
||||
// Update models.
|
||||
if (num_analyzed_frames < kLongStartupPhaseBlocks) {
|
||||
signal_model_estimator_.AdjustNormalization(num_analyzed_frames,
|
||||
signal_energy);
|
||||
}
|
||||
signal_model_estimator_.Update(prior_snr, post_snr,
|
||||
conservative_noise_spectrum, signal_spectrum,
|
||||
signal_spectral_sum, signal_energy);
|
||||
|
||||
const SignalModel& model = signal_model_estimator_.get_model();
|
||||
const PriorSignalModel& prior_model =
|
||||
signal_model_estimator_.get_prior_model();
|
||||
|
||||
// Width parameter in sigmoid map for prior model.
|
||||
constexpr float kWidthPrior0 = 4.f;
|
||||
// Width for pause region: lower range, so increase width in tanh map.
|
||||
constexpr float kWidthPrior1 = 2.f * kWidthPrior0;
|
||||
|
||||
// Average LRT feature: use larger width in tanh map for pause regions.
|
||||
float width_prior = model.lrt < prior_model.lrt ? kWidthPrior1 : kWidthPrior0;
|
||||
|
||||
// Compute indicator function: sigmoid map.
|
||||
float indicator0 =
|
||||
0.5f * (tanh(width_prior * (model.lrt - prior_model.lrt)) + 1.f);
|
||||
|
||||
// Spectral flatness feature: use larger width in tanh map for pause regions.
|
||||
width_prior = model.spectral_flatness > prior_model.flatness_threshold
|
||||
? kWidthPrior1
|
||||
: kWidthPrior0;
|
||||
|
||||
// Compute indicator function: sigmoid map.
|
||||
float indicator1 =
|
||||
0.5f * (tanh(1.f * width_prior *
|
||||
(prior_model.flatness_threshold - model.spectral_flatness)) +
|
||||
1.f);
|
||||
|
||||
// For template spectrum-difference : use larger width in tanh map for pause
|
||||
// regions.
|
||||
width_prior = model.spectral_diff < prior_model.template_diff_threshold
|
||||
? kWidthPrior1
|
||||
: kWidthPrior0;
|
||||
|
||||
// Compute indicator function: sigmoid map.
|
||||
float indicator2 =
|
||||
0.5f * (tanh(width_prior * (model.spectral_diff -
|
||||
prior_model.template_diff_threshold)) +
|
||||
1.f);
|
||||
|
||||
// Combine the indicator function with the feature weights.
|
||||
float ind_prior = prior_model.lrt_weighting * indicator0 +
|
||||
prior_model.flatness_weighting * indicator1 +
|
||||
prior_model.difference_weighting * indicator2;
|
||||
|
||||
// Compute the prior probability.
|
||||
prior_speech_prob_ += 0.1f * (ind_prior - prior_speech_prob_);
|
||||
|
||||
// Make sure probabilities are within range: keep floor to 0.01.
|
||||
prior_speech_prob_ = std::max(std::min(prior_speech_prob_, 1.f), 0.01f);
|
||||
|
||||
// Final speech probability: combine prior model with LR factor:.
|
||||
float gain_prior =
|
||||
(1.f - prior_speech_prob_) / (prior_speech_prob_ + 0.0001f);
|
||||
|
||||
std::array<float, kFftSizeBy2Plus1> inv_lrt;
|
||||
ExpApproximationSignFlip(model.avg_log_lrt, inv_lrt);
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
speech_probability_[i] = 1.f / (1.f + gain_prior * inv_lrt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_SPEECH_PROBABILITY_ESTIMATOR_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_SPEECH_PROBABILITY_ESTIMATOR_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/signal_model_estimator.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class for estimating the probability of speech.
|
||||
class SpeechProbabilityEstimator {
|
||||
public:
|
||||
SpeechProbabilityEstimator();
|
||||
SpeechProbabilityEstimator(const SpeechProbabilityEstimator&) = delete;
|
||||
SpeechProbabilityEstimator& operator=(const SpeechProbabilityEstimator&) =
|
||||
delete;
|
||||
|
||||
// Compute speech probability.
|
||||
void Update(
|
||||
int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prior_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> post_snr,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> conservative_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum,
|
||||
float signal_spectral_sum,
|
||||
float signal_energy);
|
||||
|
||||
float get_prior_probability() const { return prior_speech_prob_; }
|
||||
rtc::ArrayView<const float> get_probability() { return speech_probability_; }
|
||||
|
||||
private:
|
||||
SignalModelEstimator signal_model_estimator_;
|
||||
float prior_speech_prob_ = .5f;
|
||||
std::array<float, kFftSizeBy2Plus1> speech_probability_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_SPEECH_PROBABILITY_ESTIMATOR_H_
|
49
webrtc/modules/audio_processing/ns/suppression_params.cc
Normal file
49
webrtc/modules/audio_processing/ns/suppression_params.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/suppression_params.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SuppressionParams::SuppressionParams(
|
||||
NsConfig::SuppressionLevel suppression_level) {
|
||||
switch (suppression_level) {
|
||||
case NsConfig::SuppressionLevel::k6dB:
|
||||
over_subtraction_factor = 1.f;
|
||||
// 6 dB attenuation.
|
||||
minimum_attenuating_gain = 0.5f;
|
||||
use_attenuation_adjustment = false;
|
||||
break;
|
||||
case NsConfig::SuppressionLevel::k12dB:
|
||||
over_subtraction_factor = 1.f;
|
||||
// 12 dB attenuation.
|
||||
minimum_attenuating_gain = 0.25f;
|
||||
use_attenuation_adjustment = true;
|
||||
break;
|
||||
case NsConfig::SuppressionLevel::k18dB:
|
||||
over_subtraction_factor = 1.1f;
|
||||
// 18 dB attenuation.
|
||||
minimum_attenuating_gain = 0.125f;
|
||||
use_attenuation_adjustment = true;
|
||||
break;
|
||||
case NsConfig::SuppressionLevel::k21dB:
|
||||
over_subtraction_factor = 1.25f;
|
||||
// 20.9 dB attenuation.
|
||||
minimum_attenuating_gain = 0.09f;
|
||||
use_attenuation_adjustment = true;
|
||||
break;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
30
webrtc/modules/audio_processing/ns/suppression_params.h
Normal file
30
webrtc/modules/audio_processing/ns/suppression_params.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_SUPPRESSION_PARAMS_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_SUPPRESSION_PARAMS_H_
|
||||
|
||||
#include "modules/audio_processing/ns/ns_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct SuppressionParams {
|
||||
explicit SuppressionParams(NsConfig::SuppressionLevel suppression_level);
|
||||
SuppressionParams(const SuppressionParams&) = delete;
|
||||
SuppressionParams& operator=(const SuppressionParams&) = delete;
|
||||
|
||||
float over_subtraction_factor;
|
||||
float minimum_attenuating_gain;
|
||||
bool use_attenuation_adjustment;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_SUPPRESSION_PARAMS_H_
|
120
webrtc/modules/audio_processing/ns/wiener_filter.cc
Normal file
120
webrtc/modules/audio_processing/ns/wiener_filter.cc
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_processing/ns/wiener_filter.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_processing/ns/fast_math.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
WienerFilter::WienerFilter(const SuppressionParams& suppression_params)
|
||||
: suppression_params_(suppression_params) {
|
||||
filter_.fill(1.f);
|
||||
initial_spectral_estimate_.fill(0.f);
|
||||
spectrum_prev_process_.fill(0.f);
|
||||
}
|
||||
|
||||
void WienerFilter::Update(
|
||||
int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prev_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> parametric_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum) {
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
// Previous estimate based on previous frame with gain filter.
|
||||
float prev_tsa = spectrum_prev_process_[i] /
|
||||
(prev_noise_spectrum[i] + 0.0001f) * filter_[i];
|
||||
|
||||
// Current estimate.
|
||||
float current_tsa;
|
||||
if (signal_spectrum[i] > noise_spectrum[i]) {
|
||||
current_tsa = signal_spectrum[i] / (noise_spectrum[i] + 0.0001f) - 1.f;
|
||||
} else {
|
||||
current_tsa = 0.f;
|
||||
}
|
||||
|
||||
// Directed decision estimate is sum of two terms: current estimate and
|
||||
// previous estimate.
|
||||
float snr_prior = 0.98f * prev_tsa + (1.f - 0.98f) * current_tsa;
|
||||
filter_[i] =
|
||||
snr_prior / (suppression_params_.over_subtraction_factor + snr_prior);
|
||||
filter_[i] = std::max(std::min(filter_[i], 1.f),
|
||||
suppression_params_.minimum_attenuating_gain);
|
||||
}
|
||||
|
||||
if (num_analyzed_frames < kShortStartupPhaseBlocks) {
|
||||
for (size_t i = 0; i < kFftSizeBy2Plus1; ++i) {
|
||||
initial_spectral_estimate_[i] += signal_spectrum[i];
|
||||
float filter_initial = initial_spectral_estimate_[i] -
|
||||
suppression_params_.over_subtraction_factor *
|
||||
parametric_noise_spectrum[i];
|
||||
filter_initial /= initial_spectral_estimate_[i] + 0.0001f;
|
||||
|
||||
filter_initial = std::max(std::min(filter_initial, 1.f),
|
||||
suppression_params_.minimum_attenuating_gain);
|
||||
|
||||
// Weight the two suppression filters.
|
||||
constexpr float kOnyByShortStartupPhaseBlocks =
|
||||
1.f / kShortStartupPhaseBlocks;
|
||||
filter_initial *= kShortStartupPhaseBlocks - num_analyzed_frames;
|
||||
filter_[i] *= num_analyzed_frames;
|
||||
filter_[i] += filter_initial;
|
||||
filter_[i] *= kOnyByShortStartupPhaseBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
std::copy(signal_spectrum.begin(), signal_spectrum.end(),
|
||||
spectrum_prev_process_.begin());
|
||||
}
|
||||
|
||||
float WienerFilter::ComputeOverallScalingFactor(
|
||||
int32_t num_analyzed_frames,
|
||||
float prior_speech_probability,
|
||||
float energy_before_filtering,
|
||||
float energy_after_filtering) const {
|
||||
if (!suppression_params_.use_attenuation_adjustment ||
|
||||
num_analyzed_frames <= kLongStartupPhaseBlocks) {
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
float gain = SqrtFastApproximation(energy_after_filtering /
|
||||
(energy_before_filtering + 1.f));
|
||||
|
||||
// Scaling for new version. Threshold in final energy gain factor calculation.
|
||||
constexpr float kBLim = 0.5f;
|
||||
float scale_factor1 = 1.f;
|
||||
if (gain > kBLim) {
|
||||
scale_factor1 = 1.f + 1.3f * (gain - kBLim);
|
||||
if (gain * scale_factor1 > 1.f) {
|
||||
scale_factor1 = 1.f / gain;
|
||||
}
|
||||
}
|
||||
|
||||
float scale_factor2 = 1.f;
|
||||
if (gain < kBLim) {
|
||||
// Do not reduce scale too much for pause regions: attenuation here should
|
||||
// be controlled by flooring.
|
||||
gain = std::max(gain, suppression_params_.minimum_attenuating_gain);
|
||||
scale_factor2 = 1.f - 0.3f * (kBLim - gain);
|
||||
}
|
||||
|
||||
// Combine both scales with speech/noise prob: note prior
|
||||
// (prior_speech_probability) is not frequency dependent.
|
||||
return prior_speech_probability * scale_factor1 +
|
||||
(1.f - prior_speech_probability) * scale_factor2;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
57
webrtc/modules/audio_processing/ns/wiener_filter.h
Normal file
57
webrtc/modules/audio_processing/ns/wiener_filter.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_PROCESSING_NS_WIENER_FILTER_H_
|
||||
#define MODULES_AUDIO_PROCESSING_NS_WIENER_FILTER_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_processing/ns/ns_common.h"
|
||||
#include "modules/audio_processing/ns/suppression_params.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Estimates a Wiener-filter based frequency domain noise reduction filter.
|
||||
class WienerFilter {
|
||||
public:
|
||||
explicit WienerFilter(const SuppressionParams& suppression_params);
|
||||
WienerFilter(const WienerFilter&) = delete;
|
||||
WienerFilter& operator=(const WienerFilter&) = delete;
|
||||
|
||||
// Updates the filter estimate.
|
||||
void Update(
|
||||
int32_t num_analyzed_frames,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> prev_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> parametric_noise_spectrum,
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> signal_spectrum);
|
||||
|
||||
// Compute an overall gain scaling factor.
|
||||
float ComputeOverallScalingFactor(int32_t num_analyzed_frames,
|
||||
float prior_speech_probability,
|
||||
float energy_before_filtering,
|
||||
float energy_after_filtering) const;
|
||||
|
||||
// Returns the filter.
|
||||
rtc::ArrayView<const float, kFftSizeBy2Plus1> get_filter() const {
|
||||
return filter_;
|
||||
}
|
||||
|
||||
private:
|
||||
const SuppressionParams& suppression_params_;
|
||||
std::array<float, kFftSizeBy2Plus1> spectrum_prev_process_;
|
||||
std::array<float, kFftSizeBy2Plus1> initial_spectral_estimate_;
|
||||
std::array<float, kFftSizeBy2Plus1> filter_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_PROCESSING_NS_WIENER_FILTER_H_
|
@ -1,574 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_
|
||||
|
||||
// Hanning window for 4ms 16kHz
|
||||
static const float kHanning64w128[128] = {
|
||||
0.00000000000000f, 0.02454122852291f, 0.04906767432742f,
|
||||
0.07356456359967f, 0.09801714032956f, 0.12241067519922f,
|
||||
0.14673047445536f, 0.17096188876030f, 0.19509032201613f,
|
||||
0.21910124015687f, 0.24298017990326f, 0.26671275747490f,
|
||||
0.29028467725446f, 0.31368174039889f, 0.33688985339222f,
|
||||
0.35989503653499f, 0.38268343236509f, 0.40524131400499f,
|
||||
0.42755509343028f, 0.44961132965461f, 0.47139673682600f,
|
||||
0.49289819222978f, 0.51410274419322f, 0.53499761988710f,
|
||||
0.55557023301960f, 0.57580819141785f, 0.59569930449243f,
|
||||
0.61523159058063f, 0.63439328416365f, 0.65317284295378f,
|
||||
0.67155895484702f, 0.68954054473707f, 0.70710678118655f,
|
||||
0.72424708295147f, 0.74095112535496f, 0.75720884650648f,
|
||||
0.77301045336274f, 0.78834642762661f, 0.80320753148064f,
|
||||
0.81758481315158f, 0.83146961230255f, 0.84485356524971f,
|
||||
0.85772861000027f, 0.87008699110871f, 0.88192126434835f,
|
||||
0.89322430119552f, 0.90398929312344f, 0.91420975570353f,
|
||||
0.92387953251129f, 0.93299279883474f, 0.94154406518302f,
|
||||
0.94952818059304f, 0.95694033573221f, 0.96377606579544f,
|
||||
0.97003125319454f, 0.97570213003853f, 0.98078528040323f,
|
||||
0.98527764238894f, 0.98917650996478f, 0.99247953459871f,
|
||||
0.99518472667220f, 0.99729045667869f, 0.99879545620517f,
|
||||
0.99969881869620f, 1.00000000000000f,
|
||||
0.99969881869620f, 0.99879545620517f, 0.99729045667869f,
|
||||
0.99518472667220f, 0.99247953459871f, 0.98917650996478f,
|
||||
0.98527764238894f, 0.98078528040323f, 0.97570213003853f,
|
||||
0.97003125319454f, 0.96377606579544f, 0.95694033573221f,
|
||||
0.94952818059304f, 0.94154406518302f, 0.93299279883474f,
|
||||
0.92387953251129f, 0.91420975570353f, 0.90398929312344f,
|
||||
0.89322430119552f, 0.88192126434835f, 0.87008699110871f,
|
||||
0.85772861000027f, 0.84485356524971f, 0.83146961230255f,
|
||||
0.81758481315158f, 0.80320753148064f, 0.78834642762661f,
|
||||
0.77301045336274f, 0.75720884650648f, 0.74095112535496f,
|
||||
0.72424708295147f, 0.70710678118655f, 0.68954054473707f,
|
||||
0.67155895484702f, 0.65317284295378f, 0.63439328416365f,
|
||||
0.61523159058063f, 0.59569930449243f, 0.57580819141785f,
|
||||
0.55557023301960f, 0.53499761988710f, 0.51410274419322f,
|
||||
0.49289819222978f, 0.47139673682600f, 0.44961132965461f,
|
||||
0.42755509343028f, 0.40524131400499f, 0.38268343236509f,
|
||||
0.35989503653499f, 0.33688985339222f, 0.31368174039889f,
|
||||
0.29028467725446f, 0.26671275747490f, 0.24298017990326f,
|
||||
0.21910124015687f, 0.19509032201613f, 0.17096188876030f,
|
||||
0.14673047445536f, 0.12241067519922f, 0.09801714032956f,
|
||||
0.07356456359967f, 0.04906767432742f, 0.02454122852291f
|
||||
};
|
||||
|
||||
|
||||
|
||||
// hybrib Hanning & flat window
|
||||
static const float kBlocks80w128[128] = {
|
||||
(float)0.00000000, (float)0.03271908, (float)0.06540313, (float)0.09801714, (float)0.13052619,
|
||||
(float)0.16289547, (float)0.19509032, (float)0.22707626, (float)0.25881905, (float)0.29028468,
|
||||
(float)0.32143947, (float)0.35225005, (float)0.38268343, (float)0.41270703, (float)0.44228869,
|
||||
(float)0.47139674, (float)0.50000000, (float)0.52806785, (float)0.55557023, (float)0.58247770,
|
||||
(float)0.60876143, (float)0.63439328, (float)0.65934582, (float)0.68359230, (float)0.70710678,
|
||||
(float)0.72986407, (float)0.75183981, (float)0.77301045, (float)0.79335334, (float)0.81284668,
|
||||
(float)0.83146961, (float)0.84920218, (float)0.86602540, (float)0.88192126, (float)0.89687274,
|
||||
(float)0.91086382, (float)0.92387953, (float)0.93590593, (float)0.94693013, (float)0.95694034,
|
||||
(float)0.96592583, (float)0.97387698, (float)0.98078528, (float)0.98664333, (float)0.99144486,
|
||||
(float)0.99518473, (float)0.99785892, (float)0.99946459, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)0.99946459, (float)0.99785892, (float)0.99518473, (float)0.99144486,
|
||||
(float)0.98664333, (float)0.98078528, (float)0.97387698, (float)0.96592583, (float)0.95694034,
|
||||
(float)0.94693013, (float)0.93590593, (float)0.92387953, (float)0.91086382, (float)0.89687274,
|
||||
(float)0.88192126, (float)0.86602540, (float)0.84920218, (float)0.83146961, (float)0.81284668,
|
||||
(float)0.79335334, (float)0.77301045, (float)0.75183981, (float)0.72986407, (float)0.70710678,
|
||||
(float)0.68359230, (float)0.65934582, (float)0.63439328, (float)0.60876143, (float)0.58247770,
|
||||
(float)0.55557023, (float)0.52806785, (float)0.50000000, (float)0.47139674, (float)0.44228869,
|
||||
(float)0.41270703, (float)0.38268343, (float)0.35225005, (float)0.32143947, (float)0.29028468,
|
||||
(float)0.25881905, (float)0.22707626, (float)0.19509032, (float)0.16289547, (float)0.13052619,
|
||||
(float)0.09801714, (float)0.06540313, (float)0.03271908
|
||||
};
|
||||
|
||||
// hybrib Hanning & flat window
|
||||
static const float kBlocks160w256[256] = {
|
||||
(float)0.00000000, (float)0.01636173, (float)0.03271908, (float)0.04906767, (float)0.06540313,
|
||||
(float)0.08172107, (float)0.09801714, (float)0.11428696, (float)0.13052619, (float)0.14673047,
|
||||
(float)0.16289547, (float)0.17901686, (float)0.19509032, (float)0.21111155, (float)0.22707626,
|
||||
(float)0.24298018, (float)0.25881905, (float)0.27458862, (float)0.29028468, (float)0.30590302,
|
||||
(float)0.32143947, (float)0.33688985, (float)0.35225005, (float)0.36751594, (float)0.38268343,
|
||||
(float)0.39774847, (float)0.41270703, (float)0.42755509, (float)0.44228869, (float)0.45690388,
|
||||
(float)0.47139674, (float)0.48576339, (float)0.50000000, (float)0.51410274, (float)0.52806785,
|
||||
(float)0.54189158, (float)0.55557023, (float)0.56910015, (float)0.58247770, (float)0.59569930,
|
||||
(float)0.60876143, (float)0.62166057, (float)0.63439328, (float)0.64695615, (float)0.65934582,
|
||||
(float)0.67155895, (float)0.68359230, (float)0.69544264, (float)0.70710678, (float)0.71858162,
|
||||
(float)0.72986407, (float)0.74095113, (float)0.75183981, (float)0.76252720, (float)0.77301045,
|
||||
(float)0.78328675, (float)0.79335334, (float)0.80320753, (float)0.81284668, (float)0.82226822,
|
||||
(float)0.83146961, (float)0.84044840, (float)0.84920218, (float)0.85772861, (float)0.86602540,
|
||||
(float)0.87409034, (float)0.88192126, (float)0.88951608, (float)0.89687274, (float)0.90398929,
|
||||
(float)0.91086382, (float)0.91749450, (float)0.92387953, (float)0.93001722, (float)0.93590593,
|
||||
(float)0.94154407, (float)0.94693013, (float)0.95206268, (float)0.95694034, (float)0.96156180,
|
||||
(float)0.96592583, (float)0.97003125, (float)0.97387698, (float)0.97746197, (float)0.98078528,
|
||||
(float)0.98384601, (float)0.98664333, (float)0.98917651, (float)0.99144486, (float)0.99344778,
|
||||
(float)0.99518473, (float)0.99665524, (float)0.99785892, (float)0.99879546, (float)0.99946459,
|
||||
(float)0.99986614, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)0.99986614, (float)0.99946459, (float)0.99879546, (float)0.99785892,
|
||||
(float)0.99665524, (float)0.99518473, (float)0.99344778, (float)0.99144486, (float)0.98917651,
|
||||
(float)0.98664333, (float)0.98384601, (float)0.98078528, (float)0.97746197, (float)0.97387698,
|
||||
(float)0.97003125, (float)0.96592583, (float)0.96156180, (float)0.95694034, (float)0.95206268,
|
||||
(float)0.94693013, (float)0.94154407, (float)0.93590593, (float)0.93001722, (float)0.92387953,
|
||||
(float)0.91749450, (float)0.91086382, (float)0.90398929, (float)0.89687274, (float)0.88951608,
|
||||
(float)0.88192126, (float)0.87409034, (float)0.86602540, (float)0.85772861, (float)0.84920218,
|
||||
(float)0.84044840, (float)0.83146961, (float)0.82226822, (float)0.81284668, (float)0.80320753,
|
||||
(float)0.79335334, (float)0.78328675, (float)0.77301045, (float)0.76252720, (float)0.75183981,
|
||||
(float)0.74095113, (float)0.72986407, (float)0.71858162, (float)0.70710678, (float)0.69544264,
|
||||
(float)0.68359230, (float)0.67155895, (float)0.65934582, (float)0.64695615, (float)0.63439328,
|
||||
(float)0.62166057, (float)0.60876143, (float)0.59569930, (float)0.58247770, (float)0.56910015,
|
||||
(float)0.55557023, (float)0.54189158, (float)0.52806785, (float)0.51410274, (float)0.50000000,
|
||||
(float)0.48576339, (float)0.47139674, (float)0.45690388, (float)0.44228869, (float)0.42755509,
|
||||
(float)0.41270703, (float)0.39774847, (float)0.38268343, (float)0.36751594, (float)0.35225005,
|
||||
(float)0.33688985, (float)0.32143947, (float)0.30590302, (float)0.29028468, (float)0.27458862,
|
||||
(float)0.25881905, (float)0.24298018, (float)0.22707626, (float)0.21111155, (float)0.19509032,
|
||||
(float)0.17901686, (float)0.16289547, (float)0.14673047, (float)0.13052619, (float)0.11428696,
|
||||
(float)0.09801714, (float)0.08172107, (float)0.06540313, (float)0.04906767, (float)0.03271908,
|
||||
(float)0.01636173
|
||||
};
|
||||
|
||||
// hybrib Hanning & flat window: for 20ms
|
||||
static const float kBlocks320w512[512] = {
|
||||
(float)0.00000000, (float)0.00818114, (float)0.01636173, (float)0.02454123, (float)0.03271908,
|
||||
(float)0.04089475, (float)0.04906767, (float)0.05723732, (float)0.06540313, (float)0.07356456,
|
||||
(float)0.08172107, (float)0.08987211, (float)0.09801714, (float)0.10615561, (float)0.11428696,
|
||||
(float)0.12241068, (float)0.13052619, (float)0.13863297, (float)0.14673047, (float)0.15481816,
|
||||
(float)0.16289547, (float)0.17096189, (float)0.17901686, (float)0.18705985, (float)0.19509032,
|
||||
(float)0.20310773, (float)0.21111155, (float)0.21910124, (float)0.22707626, (float)0.23503609,
|
||||
(float)0.24298018, (float)0.25090801, (float)0.25881905, (float)0.26671276, (float)0.27458862,
|
||||
(float)0.28244610, (float)0.29028468, (float)0.29810383, (float)0.30590302, (float)0.31368174,
|
||||
(float)0.32143947, (float)0.32917568, (float)0.33688985, (float)0.34458148, (float)0.35225005,
|
||||
(float)0.35989504, (float)0.36751594, (float)0.37511224, (float)0.38268343, (float)0.39022901,
|
||||
(float)0.39774847, (float)0.40524131, (float)0.41270703, (float)0.42014512, (float)0.42755509,
|
||||
(float)0.43493645, (float)0.44228869, (float)0.44961133, (float)0.45690388, (float)0.46416584,
|
||||
(float)0.47139674, (float)0.47859608, (float)0.48576339, (float)0.49289819, (float)0.50000000,
|
||||
(float)0.50706834, (float)0.51410274, (float)0.52110274, (float)0.52806785, (float)0.53499762,
|
||||
(float)0.54189158, (float)0.54874927, (float)0.55557023, (float)0.56235401, (float)0.56910015,
|
||||
(float)0.57580819, (float)0.58247770, (float)0.58910822, (float)0.59569930, (float)0.60225052,
|
||||
(float)0.60876143, (float)0.61523159, (float)0.62166057, (float)0.62804795, (float)0.63439328,
|
||||
(float)0.64069616, (float)0.64695615, (float)0.65317284, (float)0.65934582, (float)0.66547466,
|
||||
(float)0.67155895, (float)0.67759830, (float)0.68359230, (float)0.68954054, (float)0.69544264,
|
||||
(float)0.70129818, (float)0.70710678, (float)0.71286806, (float)0.71858162, (float)0.72424708,
|
||||
(float)0.72986407, (float)0.73543221, (float)0.74095113, (float)0.74642045, (float)0.75183981,
|
||||
(float)0.75720885, (float)0.76252720, (float)0.76779452, (float)0.77301045, (float)0.77817464,
|
||||
(float)0.78328675, (float)0.78834643, (float)0.79335334, (float)0.79830715, (float)0.80320753,
|
||||
(float)0.80805415, (float)0.81284668, (float)0.81758481, (float)0.82226822, (float)0.82689659,
|
||||
(float)0.83146961, (float)0.83598698, (float)0.84044840, (float)0.84485357, (float)0.84920218,
|
||||
(float)0.85349396, (float)0.85772861, (float)0.86190585, (float)0.86602540, (float)0.87008699,
|
||||
(float)0.87409034, (float)0.87803519, (float)0.88192126, (float)0.88574831, (float)0.88951608,
|
||||
(float)0.89322430, (float)0.89687274, (float)0.90046115, (float)0.90398929, (float)0.90745693,
|
||||
(float)0.91086382, (float)0.91420976, (float)0.91749450, (float)0.92071783, (float)0.92387953,
|
||||
(float)0.92697940, (float)0.93001722, (float)0.93299280, (float)0.93590593, (float)0.93875641,
|
||||
(float)0.94154407, (float)0.94426870, (float)0.94693013, (float)0.94952818, (float)0.95206268,
|
||||
(float)0.95453345, (float)0.95694034, (float)0.95928317, (float)0.96156180, (float)0.96377607,
|
||||
(float)0.96592583, (float)0.96801094, (float)0.97003125, (float)0.97198664, (float)0.97387698,
|
||||
(float)0.97570213, (float)0.97746197, (float)0.97915640, (float)0.98078528, (float)0.98234852,
|
||||
(float)0.98384601, (float)0.98527764, (float)0.98664333, (float)0.98794298, (float)0.98917651,
|
||||
(float)0.99034383, (float)0.99144486, (float)0.99247953, (float)0.99344778, (float)0.99434953,
|
||||
(float)0.99518473, (float)0.99595331, (float)0.99665524, (float)0.99729046, (float)0.99785892,
|
||||
(float)0.99836060, (float)0.99879546, (float)0.99916346, (float)0.99946459, (float)0.99969882,
|
||||
(float)0.99986614, (float)0.99996653, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000,
|
||||
(float)1.00000000, (float)0.99996653, (float)0.99986614, (float)0.99969882, (float)0.99946459,
|
||||
(float)0.99916346, (float)0.99879546, (float)0.99836060, (float)0.99785892, (float)0.99729046,
|
||||
(float)0.99665524, (float)0.99595331, (float)0.99518473, (float)0.99434953, (float)0.99344778,
|
||||
(float)0.99247953, (float)0.99144486, (float)0.99034383, (float)0.98917651, (float)0.98794298,
|
||||
(float)0.98664333, (float)0.98527764, (float)0.98384601, (float)0.98234852, (float)0.98078528,
|
||||
(float)0.97915640, (float)0.97746197, (float)0.97570213, (float)0.97387698, (float)0.97198664,
|
||||
(float)0.97003125, (float)0.96801094, (float)0.96592583, (float)0.96377607, (float)0.96156180,
|
||||
(float)0.95928317, (float)0.95694034, (float)0.95453345, (float)0.95206268, (float)0.94952818,
|
||||
(float)0.94693013, (float)0.94426870, (float)0.94154407, (float)0.93875641, (float)0.93590593,
|
||||
(float)0.93299280, (float)0.93001722, (float)0.92697940, (float)0.92387953, (float)0.92071783,
|
||||
(float)0.91749450, (float)0.91420976, (float)0.91086382, (float)0.90745693, (float)0.90398929,
|
||||
(float)0.90046115, (float)0.89687274, (float)0.89322430, (float)0.88951608, (float)0.88574831,
|
||||
(float)0.88192126, (float)0.87803519, (float)0.87409034, (float)0.87008699, (float)0.86602540,
|
||||
(float)0.86190585, (float)0.85772861, (float)0.85349396, (float)0.84920218, (float)0.84485357,
|
||||
(float)0.84044840, (float)0.83598698, (float)0.83146961, (float)0.82689659, (float)0.82226822,
|
||||
(float)0.81758481, (float)0.81284668, (float)0.80805415, (float)0.80320753, (float)0.79830715,
|
||||
(float)0.79335334, (float)0.78834643, (float)0.78328675, (float)0.77817464, (float)0.77301045,
|
||||
(float)0.76779452, (float)0.76252720, (float)0.75720885, (float)0.75183981, (float)0.74642045,
|
||||
(float)0.74095113, (float)0.73543221, (float)0.72986407, (float)0.72424708, (float)0.71858162,
|
||||
(float)0.71286806, (float)0.70710678, (float)0.70129818, (float)0.69544264, (float)0.68954054,
|
||||
(float)0.68359230, (float)0.67759830, (float)0.67155895, (float)0.66547466, (float)0.65934582,
|
||||
(float)0.65317284, (float)0.64695615, (float)0.64069616, (float)0.63439328, (float)0.62804795,
|
||||
(float)0.62166057, (float)0.61523159, (float)0.60876143, (float)0.60225052, (float)0.59569930,
|
||||
(float)0.58910822, (float)0.58247770, (float)0.57580819, (float)0.56910015, (float)0.56235401,
|
||||
(float)0.55557023, (float)0.54874927, (float)0.54189158, (float)0.53499762, (float)0.52806785,
|
||||
(float)0.52110274, (float)0.51410274, (float)0.50706834, (float)0.50000000, (float)0.49289819,
|
||||
(float)0.48576339, (float)0.47859608, (float)0.47139674, (float)0.46416584, (float)0.45690388,
|
||||
(float)0.44961133, (float)0.44228869, (float)0.43493645, (float)0.42755509, (float)0.42014512,
|
||||
(float)0.41270703, (float)0.40524131, (float)0.39774847, (float)0.39022901, (float)0.38268343,
|
||||
(float)0.37511224, (float)0.36751594, (float)0.35989504, (float)0.35225005, (float)0.34458148,
|
||||
(float)0.33688985, (float)0.32917568, (float)0.32143947, (float)0.31368174, (float)0.30590302,
|
||||
(float)0.29810383, (float)0.29028468, (float)0.28244610, (float)0.27458862, (float)0.26671276,
|
||||
(float)0.25881905, (float)0.25090801, (float)0.24298018, (float)0.23503609, (float)0.22707626,
|
||||
(float)0.21910124, (float)0.21111155, (float)0.20310773, (float)0.19509032, (float)0.18705985,
|
||||
(float)0.17901686, (float)0.17096189, (float)0.16289547, (float)0.15481816, (float)0.14673047,
|
||||
(float)0.13863297, (float)0.13052619, (float)0.12241068, (float)0.11428696, (float)0.10615561,
|
||||
(float)0.09801714, (float)0.08987211, (float)0.08172107, (float)0.07356456, (float)0.06540313,
|
||||
(float)0.05723732, (float)0.04906767, (float)0.04089475, (float)0.03271908, (float)0.02454123,
|
||||
(float)0.01636173, (float)0.00818114
|
||||
};
|
||||
|
||||
|
||||
// Hanning window: for 15ms at 16kHz with symmetric zeros
|
||||
static const float kBlocks240w512[512] = {
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00654494, (float)0.01308960, (float)0.01963369,
|
||||
(float)0.02617695, (float)0.03271908, (float)0.03925982, (float)0.04579887, (float)0.05233596,
|
||||
(float)0.05887080, (float)0.06540313, (float)0.07193266, (float)0.07845910, (float)0.08498218,
|
||||
(float)0.09150162, (float)0.09801714, (float)0.10452846, (float)0.11103531, (float)0.11753740,
|
||||
(float)0.12403446, (float)0.13052620, (float)0.13701233, (float)0.14349262, (float)0.14996676,
|
||||
(float)0.15643448, (float)0.16289547, (float)0.16934951, (float)0.17579629, (float)0.18223552,
|
||||
(float)0.18866697, (float)0.19509032, (float)0.20150533, (float)0.20791170, (float)0.21430916,
|
||||
(float)0.22069745, (float)0.22707628, (float)0.23344538, (float)0.23980446, (float)0.24615330,
|
||||
(float)0.25249159, (float)0.25881904, (float)0.26513544, (float)0.27144045, (float)0.27773386,
|
||||
(float)0.28401536, (float)0.29028466, (float)0.29654160, (float)0.30278578, (float)0.30901700,
|
||||
(float)0.31523499, (float)0.32143945, (float)0.32763019, (float)0.33380687, (float)0.33996925,
|
||||
(float)0.34611708, (float)0.35225007, (float)0.35836795, (float)0.36447051, (float)0.37055743,
|
||||
(float)0.37662852, (float)0.38268346, (float)0.38872197, (float)0.39474389, (float)0.40074885,
|
||||
(float)0.40673664, (float)0.41270703, (float)0.41865975, (float)0.42459452, (float)0.43051112,
|
||||
(float)0.43640924, (float)0.44228873, (float)0.44814920, (float)0.45399052, (float)0.45981237,
|
||||
(float)0.46561453, (float)0.47139674, (float)0.47715878, (float)0.48290035, (float)0.48862126,
|
||||
(float)0.49432120, (float)0.50000000, (float)0.50565743, (float)0.51129311, (float)0.51690692,
|
||||
(float)0.52249855, (float)0.52806789, (float)0.53361452, (float)0.53913832, (float)0.54463905,
|
||||
(float)0.55011642, (float)0.55557024, (float)0.56100029, (float)0.56640625, (float)0.57178795,
|
||||
(float)0.57714522, (float)0.58247769, (float)0.58778524, (float)0.59306765, (float)0.59832460,
|
||||
(float)0.60355598, (float)0.60876143, (float)0.61394083, (float)0.61909395, (float)0.62422055,
|
||||
(float)0.62932038, (float)0.63439333, (float)0.63943899, (float)0.64445734, (float)0.64944810,
|
||||
(float)0.65441096, (float)0.65934587, (float)0.66425246, (float)0.66913062, (float)0.67398012,
|
||||
(float)0.67880076, (float)0.68359232, (float)0.68835455, (float)0.69308740, (float)0.69779050,
|
||||
(float)0.70246369, (float)0.70710677, (float)0.71171963, (float)0.71630198, (float)0.72085363,
|
||||
(float)0.72537440, (float)0.72986406, (float)0.73432255, (float)0.73874950, (float)0.74314487,
|
||||
(float)0.74750835, (float)0.75183982, (float)0.75613910, (float)0.76040596, (float)0.76464027,
|
||||
(float)0.76884186, (float)0.77301043, (float)0.77714598, (float)0.78124821, (float)0.78531694,
|
||||
(float)0.78935206, (float)0.79335338, (float)0.79732066, (float)0.80125386, (float)0.80515265,
|
||||
(float)0.80901700, (float)0.81284672, (float)0.81664157, (float)0.82040149, (float)0.82412618,
|
||||
(float)0.82781565, (float)0.83146966, (float)0.83508795, (float)0.83867061, (float)0.84221727,
|
||||
(float)0.84572780, (float)0.84920216, (float)0.85264021, (float)0.85604161, (float)0.85940641,
|
||||
(float)0.86273444, (float)0.86602545, (float)0.86927933, (float)0.87249607, (float)0.87567532,
|
||||
(float)0.87881714, (float)0.88192129, (float)0.88498765, (float)0.88801610, (float)0.89100653,
|
||||
(float)0.89395881, (float)0.89687276, (float)0.89974827, (float)0.90258533, (float)0.90538365,
|
||||
(float)0.90814316, (float)0.91086388, (float)0.91354549, (float)0.91618794, (float)0.91879123,
|
||||
(float)0.92135513, (float)0.92387950, (float)0.92636442, (float)0.92880958, (float)0.93121493,
|
||||
(float)0.93358046, (float)0.93590593, (float)0.93819135, (float)0.94043654, (float)0.94264150,
|
||||
(float)0.94480604, (float)0.94693011, (float)0.94901365, (float)0.95105654, (float)0.95305866,
|
||||
(float)0.95501995, (float)0.95694035, (float)0.95881975, (float)0.96065807, (float)0.96245527,
|
||||
(float)0.96421117, (float)0.96592581, (float)0.96759909, (float)0.96923089, (float)0.97082120,
|
||||
(float)0.97236991, (float)0.97387701, (float)0.97534233, (float)0.97676587, (float)0.97814763,
|
||||
(float)0.97948742, (float)0.98078531, (float)0.98204112, (float)0.98325491, (float)0.98442656,
|
||||
(float)0.98555607, (float)0.98664331, (float)0.98768836, (float)0.98869103, (float)0.98965138,
|
||||
(float)0.99056935, (float)0.99144489, (float)0.99227792, (float)0.99306846, (float)0.99381649,
|
||||
(float)0.99452192, (float)0.99518472, (float)0.99580491, (float)0.99638247, (float)0.99691731,
|
||||
(float)0.99740952, (float)0.99785894, (float)0.99826562, (float)0.99862951, (float)0.99895066,
|
||||
(float)0.99922901, (float)0.99946457, (float)0.99965733, (float)0.99980724, (float)0.99991435,
|
||||
(float)0.99997860, (float)1.00000000, (float)0.99997860, (float)0.99991435, (float)0.99980724,
|
||||
(float)0.99965733, (float)0.99946457, (float)0.99922901, (float)0.99895066, (float)0.99862951,
|
||||
(float)0.99826562, (float)0.99785894, (float)0.99740946, (float)0.99691731, (float)0.99638247,
|
||||
(float)0.99580491, (float)0.99518472, (float)0.99452192, (float)0.99381644, (float)0.99306846,
|
||||
(float)0.99227792, (float)0.99144489, (float)0.99056935, (float)0.98965138, (float)0.98869103,
|
||||
(float)0.98768836, (float)0.98664331, (float)0.98555607, (float)0.98442656, (float)0.98325491,
|
||||
(float)0.98204112, (float)0.98078525, (float)0.97948742, (float)0.97814757, (float)0.97676587,
|
||||
(float)0.97534227, (float)0.97387695, (float)0.97236991, (float)0.97082120, (float)0.96923089,
|
||||
(float)0.96759909, (float)0.96592581, (float)0.96421117, (float)0.96245521, (float)0.96065807,
|
||||
(float)0.95881969, (float)0.95694029, (float)0.95501995, (float)0.95305860, (float)0.95105648,
|
||||
(float)0.94901365, (float)0.94693011, (float)0.94480604, (float)0.94264150, (float)0.94043654,
|
||||
(float)0.93819129, (float)0.93590593, (float)0.93358046, (float)0.93121493, (float)0.92880952,
|
||||
(float)0.92636436, (float)0.92387950, (float)0.92135507, (float)0.91879123, (float)0.91618794,
|
||||
(float)0.91354543, (float)0.91086382, (float)0.90814310, (float)0.90538365, (float)0.90258527,
|
||||
(float)0.89974827, (float)0.89687276, (float)0.89395875, (float)0.89100647, (float)0.88801610,
|
||||
(float)0.88498759, (float)0.88192123, (float)0.87881714, (float)0.87567532, (float)0.87249595,
|
||||
(float)0.86927933, (float)0.86602539, (float)0.86273432, (float)0.85940641, (float)0.85604161,
|
||||
(float)0.85264009, (float)0.84920216, (float)0.84572780, (float)0.84221715, (float)0.83867055,
|
||||
(float)0.83508795, (float)0.83146954, (float)0.82781565, (float)0.82412612, (float)0.82040137,
|
||||
(float)0.81664157, (float)0.81284660, (float)0.80901700, (float)0.80515265, (float)0.80125374,
|
||||
(float)0.79732066, (float)0.79335332, (float)0.78935200, (float)0.78531694, (float)0.78124815,
|
||||
(float)0.77714586, (float)0.77301049, (float)0.76884180, (float)0.76464021, (float)0.76040596,
|
||||
(float)0.75613904, (float)0.75183970, (float)0.74750835, (float)0.74314481, (float)0.73874938,
|
||||
(float)0.73432249, (float)0.72986400, (float)0.72537428, (float)0.72085363, (float)0.71630186,
|
||||
(float)0.71171951, (float)0.70710677, (float)0.70246363, (float)0.69779032, (float)0.69308734,
|
||||
(float)0.68835449, (float)0.68359220, (float)0.67880070, (float)0.67398006, (float)0.66913044,
|
||||
(float)0.66425240, (float)0.65934575, (float)0.65441096, (float)0.64944804, (float)0.64445722,
|
||||
(float)0.63943905, (float)0.63439327, (float)0.62932026, (float)0.62422055, (float)0.61909389,
|
||||
(float)0.61394072, (float)0.60876143, (float)0.60355592, (float)0.59832448, (float)0.59306765,
|
||||
(float)0.58778518, (float)0.58247757, (float)0.57714522, (float)0.57178789, (float)0.56640613,
|
||||
(float)0.56100023, (float)0.55557019, (float)0.55011630, (float)0.54463905, (float)0.53913826,
|
||||
(float)0.53361434, (float)0.52806783, (float)0.52249849, (float)0.51690674, (float)0.51129305,
|
||||
(float)0.50565726, (float)0.50000006, (float)0.49432117, (float)0.48862115, (float)0.48290038,
|
||||
(float)0.47715873, (float)0.47139663, (float)0.46561456, (float)0.45981231, (float)0.45399037,
|
||||
(float)0.44814920, (float)0.44228864, (float)0.43640912, (float)0.43051112, (float)0.42459446,
|
||||
(float)0.41865960, (float)0.41270703, (float)0.40673658, (float)0.40074870, (float)0.39474386,
|
||||
(float)0.38872188, (float)0.38268328, (float)0.37662849, (float)0.37055734, (float)0.36447033,
|
||||
(float)0.35836792, (float)0.35224995, (float)0.34611690, (float)0.33996922, (float)0.33380675,
|
||||
(float)0.32763001, (float)0.32143945, (float)0.31523487, (float)0.30901679, (float)0.30278572,
|
||||
(float)0.29654145, (float)0.29028472, (float)0.28401530, (float)0.27773371, (float)0.27144048,
|
||||
(float)0.26513538, (float)0.25881892, (float)0.25249159, (float)0.24615324, (float)0.23980433,
|
||||
(float)0.23344538, (float)0.22707619, (float)0.22069728, (float)0.21430916, (float)0.20791161,
|
||||
(float)0.20150517, (float)0.19509031, (float)0.18866688, (float)0.18223536, (float)0.17579627,
|
||||
(float)0.16934940, (float)0.16289529, (float)0.15643445, (float)0.14996666, (float)0.14349243,
|
||||
(float)0.13701232, (float)0.13052608, (float)0.12403426, (float)0.11753736, (float)0.11103519,
|
||||
(float)0.10452849, (float)0.09801710, (float)0.09150149, (float)0.08498220, (float)0.07845904,
|
||||
(float)0.07193252, (float)0.06540315, (float)0.05887074, (float)0.05233581, (float)0.04579888,
|
||||
(float)0.03925974, (float)0.03271893, (float)0.02617695, (float)0.01963361, (float)0.01308943,
|
||||
(float)0.00654493, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000
|
||||
};
|
||||
|
||||
|
||||
// Hanning window: for 30ms with 1024 fft with symmetric zeros at 16kHz
|
||||
static const float kBlocks480w1024[1024] = {
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00327249, (float)0.00654494,
|
||||
(float)0.00981732, (float)0.01308960, (float)0.01636173, (float)0.01963369, (float)0.02290544,
|
||||
(float)0.02617695, (float)0.02944817, (float)0.03271908, (float)0.03598964, (float)0.03925982,
|
||||
(float)0.04252957, (float)0.04579887, (float)0.04906768, (float)0.05233596, (float)0.05560368,
|
||||
(float)0.05887080, (float)0.06213730, (float)0.06540313, (float)0.06866825, (float)0.07193266,
|
||||
(float)0.07519628, (float)0.07845910, (float)0.08172107, (float)0.08498218, (float)0.08824237,
|
||||
(float)0.09150162, (float)0.09475989, (float)0.09801714, (float)0.10127335, (float)0.10452846,
|
||||
(float)0.10778246, (float)0.11103531, (float)0.11428697, (float)0.11753740, (float)0.12078657,
|
||||
(float)0.12403446, (float)0.12728101, (float)0.13052620, (float)0.13376999, (float)0.13701233,
|
||||
(float)0.14025325, (float)0.14349262, (float)0.14673047, (float)0.14996676, (float)0.15320145,
|
||||
(float)0.15643448, (float)0.15966582, (float)0.16289547, (float)0.16612339, (float)0.16934951,
|
||||
(float)0.17257382, (float)0.17579629, (float)0.17901687, (float)0.18223552, (float)0.18545224,
|
||||
(float)0.18866697, (float)0.19187967, (float)0.19509032, (float)0.19829889, (float)0.20150533,
|
||||
(float)0.20470962, (float)0.20791170, (float)0.21111156, (float)0.21430916, (float)0.21750447,
|
||||
(float)0.22069745, (float)0.22388805, (float)0.22707628, (float)0.23026206, (float)0.23344538,
|
||||
(float)0.23662618, (float)0.23980446, (float)0.24298020, (float)0.24615330, (float)0.24932377,
|
||||
(float)0.25249159, (float)0.25565669, (float)0.25881904, (float)0.26197866, (float)0.26513544,
|
||||
(float)0.26828939, (float)0.27144045, (float)0.27458861, (float)0.27773386, (float)0.28087610,
|
||||
(float)0.28401536, (float)0.28715158, (float)0.29028466, (float)0.29341471, (float)0.29654160,
|
||||
(float)0.29966527, (float)0.30278578, (float)0.30590302, (float)0.30901700, (float)0.31212768,
|
||||
(float)0.31523499, (float)0.31833893, (float)0.32143945, (float)0.32453656, (float)0.32763019,
|
||||
(float)0.33072028, (float)0.33380687, (float)0.33688986, (float)0.33996925, (float)0.34304500,
|
||||
(float)0.34611708, (float)0.34918544, (float)0.35225007, (float)0.35531089, (float)0.35836795,
|
||||
(float)0.36142117, (float)0.36447051, (float)0.36751595, (float)0.37055743, (float)0.37359497,
|
||||
(float)0.37662852, (float)0.37965801, (float)0.38268346, (float)0.38570479, (float)0.38872197,
|
||||
(float)0.39173502, (float)0.39474389, (float)0.39774847, (float)0.40074885, (float)0.40374491,
|
||||
(float)0.40673664, (float)0.40972406, (float)0.41270703, (float)0.41568562, (float)0.41865975,
|
||||
(float)0.42162940, (float)0.42459452, (float)0.42755508, (float)0.43051112, (float)0.43346250,
|
||||
(float)0.43640924, (float)0.43935132, (float)0.44228873, (float)0.44522133, (float)0.44814920,
|
||||
(float)0.45107228, (float)0.45399052, (float)0.45690390, (float)0.45981237, (float)0.46271592,
|
||||
(float)0.46561453, (float)0.46850815, (float)0.47139674, (float)0.47428030, (float)0.47715878,
|
||||
(float)0.48003215, (float)0.48290035, (float)0.48576337, (float)0.48862126, (float)0.49147385,
|
||||
(float)0.49432120, (float)0.49716330, (float)0.50000000, (float)0.50283140, (float)0.50565743,
|
||||
(float)0.50847799, (float)0.51129311, (float)0.51410276, (float)0.51690692, (float)0.51970553,
|
||||
(float)0.52249855, (float)0.52528602, (float)0.52806789, (float)0.53084403, (float)0.53361452,
|
||||
(float)0.53637928, (float)0.53913832, (float)0.54189163, (float)0.54463905, (float)0.54738063,
|
||||
(float)0.55011642, (float)0.55284631, (float)0.55557024, (float)0.55828828, (float)0.56100029,
|
||||
(float)0.56370628, (float)0.56640625, (float)0.56910014, (float)0.57178795, (float)0.57446963,
|
||||
(float)0.57714522, (float)0.57981455, (float)0.58247769, (float)0.58513463, (float)0.58778524,
|
||||
(float)0.59042960, (float)0.59306765, (float)0.59569931, (float)0.59832460, (float)0.60094351,
|
||||
(float)0.60355598, (float)0.60616195, (float)0.60876143, (float)0.61135441, (float)0.61394083,
|
||||
(float)0.61652070, (float)0.61909395, (float)0.62166059, (float)0.62422055, (float)0.62677383,
|
||||
(float)0.62932038, (float)0.63186020, (float)0.63439333, (float)0.63691956, (float)0.63943899,
|
||||
(float)0.64195162, (float)0.64445734, (float)0.64695615, (float)0.64944810, (float)0.65193301,
|
||||
(float)0.65441096, (float)0.65688187, (float)0.65934587, (float)0.66180271, (float)0.66425246,
|
||||
(float)0.66669512, (float)0.66913062, (float)0.67155898, (float)0.67398012, (float)0.67639405,
|
||||
(float)0.67880076, (float)0.68120021, (float)0.68359232, (float)0.68597710, (float)0.68835455,
|
||||
(float)0.69072467, (float)0.69308740, (float)0.69544262, (float)0.69779050, (float)0.70013082,
|
||||
(float)0.70246369, (float)0.70478904, (float)0.70710677, (float)0.70941699, (float)0.71171963,
|
||||
(float)0.71401459, (float)0.71630198, (float)0.71858168, (float)0.72085363, (float)0.72311789,
|
||||
(float)0.72537440, (float)0.72762316, (float)0.72986406, (float)0.73209721, (float)0.73432255,
|
||||
(float)0.73653996, (float)0.73874950, (float)0.74095118, (float)0.74314487, (float)0.74533057,
|
||||
(float)0.74750835, (float)0.74967808, (float)0.75183982, (float)0.75399351, (float)0.75613910,
|
||||
(float)0.75827658, (float)0.76040596, (float)0.76252723, (float)0.76464027, (float)0.76674515,
|
||||
(float)0.76884186, (float)0.77093029, (float)0.77301043, (float)0.77508241, (float)0.77714598,
|
||||
(float)0.77920127, (float)0.78124821, (float)0.78328675, (float)0.78531694, (float)0.78733873,
|
||||
(float)0.78935206, (float)0.79135692, (float)0.79335338, (float)0.79534125, (float)0.79732066,
|
||||
(float)0.79929149, (float)0.80125386, (float)0.80320752, (float)0.80515265, (float)0.80708915,
|
||||
(float)0.80901700, (float)0.81093621, (float)0.81284672, (float)0.81474853, (float)0.81664157,
|
||||
(float)0.81852591, (float)0.82040149, (float)0.82226825, (float)0.82412618, (float)0.82597536,
|
||||
(float)0.82781565, (float)0.82964706, (float)0.83146966, (float)0.83328325, (float)0.83508795,
|
||||
(float)0.83688378, (float)0.83867061, (float)0.84044838, (float)0.84221727, (float)0.84397703,
|
||||
(float)0.84572780, (float)0.84746957, (float)0.84920216, (float)0.85092574, (float)0.85264021,
|
||||
(float)0.85434544, (float)0.85604161, (float)0.85772866, (float)0.85940641, (float)0.86107504,
|
||||
(float)0.86273444, (float)0.86438453, (float)0.86602545, (float)0.86765707, (float)0.86927933,
|
||||
(float)0.87089235, (float)0.87249607, (float)0.87409031, (float)0.87567532, (float)0.87725097,
|
||||
(float)0.87881714, (float)0.88037390, (float)0.88192129, (float)0.88345921, (float)0.88498765,
|
||||
(float)0.88650668, (float)0.88801610, (float)0.88951612, (float)0.89100653, (float)0.89248741,
|
||||
(float)0.89395881, (float)0.89542055, (float)0.89687276, (float)0.89831537, (float)0.89974827,
|
||||
(float)0.90117162, (float)0.90258533, (float)0.90398932, (float)0.90538365, (float)0.90676826,
|
||||
(float)0.90814316, (float)0.90950841, (float)0.91086388, (float)0.91220951, (float)0.91354549,
|
||||
(float)0.91487163, (float)0.91618794, (float)0.91749454, (float)0.91879123, (float)0.92007810,
|
||||
(float)0.92135513, (float)0.92262226, (float)0.92387950, (float)0.92512691, (float)0.92636442,
|
||||
(float)0.92759192, (float)0.92880958, (float)0.93001723, (float)0.93121493, (float)0.93240267,
|
||||
(float)0.93358046, (float)0.93474817, (float)0.93590593, (float)0.93705362, (float)0.93819135,
|
||||
(float)0.93931901, (float)0.94043654, (float)0.94154406, (float)0.94264150, (float)0.94372880,
|
||||
(float)0.94480604, (float)0.94587320, (float)0.94693011, (float)0.94797695, (float)0.94901365,
|
||||
(float)0.95004016, (float)0.95105654, (float)0.95206273, (float)0.95305866, (float)0.95404440,
|
||||
(float)0.95501995, (float)0.95598525, (float)0.95694035, (float)0.95788521, (float)0.95881975,
|
||||
(float)0.95974404, (float)0.96065807, (float)0.96156180, (float)0.96245527, (float)0.96333838,
|
||||
(float)0.96421117, (float)0.96507370, (float)0.96592581, (float)0.96676767, (float)0.96759909,
|
||||
(float)0.96842021, (float)0.96923089, (float)0.97003126, (float)0.97082120, (float)0.97160077,
|
||||
(float)0.97236991, (float)0.97312868, (float)0.97387701, (float)0.97461486, (float)0.97534233,
|
||||
(float)0.97605932, (float)0.97676587, (float)0.97746199, (float)0.97814763, (float)0.97882277,
|
||||
(float)0.97948742, (float)0.98014158, (float)0.98078531, (float)0.98141843, (float)0.98204112,
|
||||
(float)0.98265332, (float)0.98325491, (float)0.98384601, (float)0.98442656, (float)0.98499662,
|
||||
(float)0.98555607, (float)0.98610497, (float)0.98664331, (float)0.98717111, (float)0.98768836,
|
||||
(float)0.98819500, (float)0.98869103, (float)0.98917651, (float)0.98965138, (float)0.99011570,
|
||||
(float)0.99056935, (float)0.99101239, (float)0.99144489, (float)0.99186671, (float)0.99227792,
|
||||
(float)0.99267852, (float)0.99306846, (float)0.99344778, (float)0.99381649, (float)0.99417448,
|
||||
(float)0.99452192, (float)0.99485862, (float)0.99518472, (float)0.99550015, (float)0.99580491,
|
||||
(float)0.99609905, (float)0.99638247, (float)0.99665523, (float)0.99691731, (float)0.99716878,
|
||||
(float)0.99740952, (float)0.99763954, (float)0.99785894, (float)0.99806762, (float)0.99826562,
|
||||
(float)0.99845290, (float)0.99862951, (float)0.99879545, (float)0.99895066, (float)0.99909520,
|
||||
(float)0.99922901, (float)0.99935216, (float)0.99946457, (float)0.99956632, (float)0.99965733,
|
||||
(float)0.99973762, (float)0.99980724, (float)0.99986613, (float)0.99991435, (float)0.99995178,
|
||||
(float)0.99997860, (float)0.99999464, (float)1.00000000, (float)0.99999464, (float)0.99997860,
|
||||
(float)0.99995178, (float)0.99991435, (float)0.99986613, (float)0.99980724, (float)0.99973762,
|
||||
(float)0.99965733, (float)0.99956632, (float)0.99946457, (float)0.99935216, (float)0.99922901,
|
||||
(float)0.99909520, (float)0.99895066, (float)0.99879545, (float)0.99862951, (float)0.99845290,
|
||||
(float)0.99826562, (float)0.99806762, (float)0.99785894, (float)0.99763954, (float)0.99740946,
|
||||
(float)0.99716872, (float)0.99691731, (float)0.99665523, (float)0.99638247, (float)0.99609905,
|
||||
(float)0.99580491, (float)0.99550015, (float)0.99518472, (float)0.99485862, (float)0.99452192,
|
||||
(float)0.99417448, (float)0.99381644, (float)0.99344778, (float)0.99306846, (float)0.99267852,
|
||||
(float)0.99227792, (float)0.99186671, (float)0.99144489, (float)0.99101239, (float)0.99056935,
|
||||
(float)0.99011564, (float)0.98965138, (float)0.98917651, (float)0.98869103, (float)0.98819494,
|
||||
(float)0.98768836, (float)0.98717111, (float)0.98664331, (float)0.98610497, (float)0.98555607,
|
||||
(float)0.98499656, (float)0.98442656, (float)0.98384601, (float)0.98325491, (float)0.98265326,
|
||||
(float)0.98204112, (float)0.98141843, (float)0.98078525, (float)0.98014158, (float)0.97948742,
|
||||
(float)0.97882277, (float)0.97814757, (float)0.97746193, (float)0.97676587, (float)0.97605932,
|
||||
(float)0.97534227, (float)0.97461486, (float)0.97387695, (float)0.97312862, (float)0.97236991,
|
||||
(float)0.97160077, (float)0.97082120, (float)0.97003126, (float)0.96923089, (float)0.96842015,
|
||||
(float)0.96759909, (float)0.96676761, (float)0.96592581, (float)0.96507365, (float)0.96421117,
|
||||
(float)0.96333838, (float)0.96245521, (float)0.96156180, (float)0.96065807, (float)0.95974404,
|
||||
(float)0.95881969, (float)0.95788515, (float)0.95694029, (float)0.95598525, (float)0.95501995,
|
||||
(float)0.95404440, (float)0.95305860, (float)0.95206267, (float)0.95105648, (float)0.95004016,
|
||||
(float)0.94901365, (float)0.94797695, (float)0.94693011, (float)0.94587314, (float)0.94480604,
|
||||
(float)0.94372880, (float)0.94264150, (float)0.94154406, (float)0.94043654, (float)0.93931895,
|
||||
(float)0.93819129, (float)0.93705362, (float)0.93590593, (float)0.93474817, (float)0.93358046,
|
||||
(float)0.93240267, (float)0.93121493, (float)0.93001723, (float)0.92880952, (float)0.92759192,
|
||||
(float)0.92636436, (float)0.92512691, (float)0.92387950, (float)0.92262226, (float)0.92135507,
|
||||
(float)0.92007804, (float)0.91879123, (float)0.91749448, (float)0.91618794, (float)0.91487157,
|
||||
(float)0.91354543, (float)0.91220951, (float)0.91086382, (float)0.90950835, (float)0.90814310,
|
||||
(float)0.90676820, (float)0.90538365, (float)0.90398932, (float)0.90258527, (float)0.90117157,
|
||||
(float)0.89974827, (float)0.89831525, (float)0.89687276, (float)0.89542055, (float)0.89395875,
|
||||
(float)0.89248741, (float)0.89100647, (float)0.88951600, (float)0.88801610, (float)0.88650662,
|
||||
(float)0.88498759, (float)0.88345915, (float)0.88192123, (float)0.88037384, (float)0.87881714,
|
||||
(float)0.87725091, (float)0.87567532, (float)0.87409031, (float)0.87249595, (float)0.87089223,
|
||||
(float)0.86927933, (float)0.86765701, (float)0.86602539, (float)0.86438447, (float)0.86273432,
|
||||
(float)0.86107504, (float)0.85940641, (float)0.85772860, (float)0.85604161, (float)0.85434544,
|
||||
(float)0.85264009, (float)0.85092574, (float)0.84920216, (float)0.84746951, (float)0.84572780,
|
||||
(float)0.84397697, (float)0.84221715, (float)0.84044844, (float)0.83867055, (float)0.83688372,
|
||||
(float)0.83508795, (float)0.83328319, (float)0.83146954, (float)0.82964706, (float)0.82781565,
|
||||
(float)0.82597530, (float)0.82412612, (float)0.82226813, (float)0.82040137, (float)0.81852591,
|
||||
(float)0.81664157, (float)0.81474847, (float)0.81284660, (float)0.81093609, (float)0.80901700,
|
||||
(float)0.80708915, (float)0.80515265, (float)0.80320752, (float)0.80125374, (float)0.79929143,
|
||||
(float)0.79732066, (float)0.79534125, (float)0.79335332, (float)0.79135686, (float)0.78935200,
|
||||
(float)0.78733861, (float)0.78531694, (float)0.78328675, (float)0.78124815, (float)0.77920121,
|
||||
(float)0.77714586, (float)0.77508223, (float)0.77301049, (float)0.77093029, (float)0.76884180,
|
||||
(float)0.76674509, (float)0.76464021, (float)0.76252711, (float)0.76040596, (float)0.75827658,
|
||||
(float)0.75613904, (float)0.75399339, (float)0.75183970, (float)0.74967796, (float)0.74750835,
|
||||
(float)0.74533057, (float)0.74314481, (float)0.74095106, (float)0.73874938, (float)0.73653996,
|
||||
(float)0.73432249, (float)0.73209721, (float)0.72986400, (float)0.72762305, (float)0.72537428,
|
||||
(float)0.72311789, (float)0.72085363, (float)0.71858162, (float)0.71630186, (float)0.71401453,
|
||||
(float)0.71171951, (float)0.70941705, (float)0.70710677, (float)0.70478898, (float)0.70246363,
|
||||
(float)0.70013070, (float)0.69779032, (float)0.69544268, (float)0.69308734, (float)0.69072461,
|
||||
(float)0.68835449, (float)0.68597704, (float)0.68359220, (float)0.68120021, (float)0.67880070,
|
||||
(float)0.67639399, (float)0.67398006, (float)0.67155886, (float)0.66913044, (float)0.66669512,
|
||||
(float)0.66425240, (float)0.66180259, (float)0.65934575, (float)0.65688181, (float)0.65441096,
|
||||
(float)0.65193301, (float)0.64944804, (float)0.64695609, (float)0.64445722, (float)0.64195150,
|
||||
(float)0.63943905, (float)0.63691956, (float)0.63439327, (float)0.63186014, (float)0.62932026,
|
||||
(float)0.62677372, (float)0.62422055, (float)0.62166059, (float)0.61909389, (float)0.61652064,
|
||||
(float)0.61394072, (float)0.61135429, (float)0.60876143, (float)0.60616189, (float)0.60355592,
|
||||
(float)0.60094339, (float)0.59832448, (float)0.59569913, (float)0.59306765, (float)0.59042960,
|
||||
(float)0.58778518, (float)0.58513451, (float)0.58247757, (float)0.57981461, (float)0.57714522,
|
||||
(float)0.57446963, (float)0.57178789, (float)0.56910002, (float)0.56640613, (float)0.56370628,
|
||||
(float)0.56100023, (float)0.55828822, (float)0.55557019, (float)0.55284619, (float)0.55011630,
|
||||
(float)0.54738069, (float)0.54463905, (float)0.54189152, (float)0.53913826, (float)0.53637916,
|
||||
(float)0.53361434, (float)0.53084403, (float)0.52806783, (float)0.52528596, (float)0.52249849,
|
||||
(float)0.51970541, (float)0.51690674, (float)0.51410276, (float)0.51129305, (float)0.50847787,
|
||||
(float)0.50565726, (float)0.50283122, (float)0.50000006, (float)0.49716327, (float)0.49432117,
|
||||
(float)0.49147379, (float)0.48862115, (float)0.48576325, (float)0.48290038, (float)0.48003212,
|
||||
(float)0.47715873, (float)0.47428021, (float)0.47139663, (float)0.46850798, (float)0.46561456,
|
||||
(float)0.46271589, (float)0.45981231, (float)0.45690379, (float)0.45399037, (float)0.45107210,
|
||||
(float)0.44814920, (float)0.44522130, (float)0.44228864, (float)0.43935123, (float)0.43640912,
|
||||
(float)0.43346232, (float)0.43051112, (float)0.42755505, (float)0.42459446, (float)0.42162928,
|
||||
(float)0.41865960, (float)0.41568545, (float)0.41270703, (float)0.40972400, (float)0.40673658,
|
||||
(float)0.40374479, (float)0.40074870, (float)0.39774850, (float)0.39474386, (float)0.39173496,
|
||||
(float)0.38872188, (float)0.38570464, (float)0.38268328, (float)0.37965804, (float)0.37662849,
|
||||
(float)0.37359491, (float)0.37055734, (float)0.36751580, (float)0.36447033, (float)0.36142117,
|
||||
(float)0.35836792, (float)0.35531086, (float)0.35224995, (float)0.34918529, (float)0.34611690,
|
||||
(float)0.34304500, (float)0.33996922, (float)0.33688980, (float)0.33380675, (float)0.33072016,
|
||||
(float)0.32763001, (float)0.32453656, (float)0.32143945, (float)0.31833887, (float)0.31523487,
|
||||
(float)0.31212750, (float)0.30901679, (float)0.30590302, (float)0.30278572, (float)0.29966521,
|
||||
(float)0.29654145, (float)0.29341453, (float)0.29028472, (float)0.28715155, (float)0.28401530,
|
||||
(float)0.28087601, (float)0.27773371, (float)0.27458847, (float)0.27144048, (float)0.26828936,
|
||||
(float)0.26513538, (float)0.26197854, (float)0.25881892, (float)0.25565651, (float)0.25249159,
|
||||
(float)0.24932374, (float)0.24615324, (float)0.24298008, (float)0.23980433, (float)0.23662600,
|
||||
(float)0.23344538, (float)0.23026201, (float)0.22707619, (float)0.22388794, (float)0.22069728,
|
||||
(float)0.21750426, (float)0.21430916, (float)0.21111152, (float)0.20791161, (float)0.20470949,
|
||||
(float)0.20150517, (float)0.19829892, (float)0.19509031, (float)0.19187963, (float)0.18866688,
|
||||
(float)0.18545210, (float)0.18223536, (float)0.17901689, (float)0.17579627, (float)0.17257376,
|
||||
(float)0.16934940, (float)0.16612324, (float)0.16289529, (float)0.15966584, (float)0.15643445,
|
||||
(float)0.15320137, (float)0.14996666, (float)0.14673033, (float)0.14349243, (float)0.14025325,
|
||||
(float)0.13701232, (float)0.13376991, (float)0.13052608, (float)0.12728085, (float)0.12403426,
|
||||
(float)0.12078657, (float)0.11753736, (float)0.11428688, (float)0.11103519, (float)0.10778230,
|
||||
(float)0.10452849, (float)0.10127334, (float)0.09801710, (float)0.09475980, (float)0.09150149,
|
||||
(float)0.08824220, (float)0.08498220, (float)0.08172106, (float)0.07845904, (float)0.07519618,
|
||||
(float)0.07193252, (float)0.06866808, (float)0.06540315, (float)0.06213728, (float)0.05887074,
|
||||
(float)0.05560357, (float)0.05233581, (float)0.04906749, (float)0.04579888, (float)0.04252954,
|
||||
(float)0.03925974, (float)0.03598953, (float)0.03271893, (float)0.02944798, (float)0.02617695,
|
||||
(float)0.02290541, (float)0.01963361, (float)0.01636161, (float)0.01308943, (float)0.00981712,
|
||||
(float)0.00654493, (float)0.00327244, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000,
|
||||
(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000
|
||||
};
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_
|
Reference in New Issue
Block a user