diff --git a/modules/BUILD.gn b/modules/BUILD.gn index ece91afb80..4fe4db5c68 100644 --- a/modules/BUILD.gn +++ b/modules/BUILD.gn @@ -229,6 +229,7 @@ if (rtc_include_tests) { "audio_mixer:audio_mixer_unittests", "audio_processing:audio_processing_unittests", "audio_processing/aec3:aec3_unittests", + "audio_processing/ns:ns_unittests", "congestion_controller:congestion_controller_unittests", "pacing:pacing_unittests", "remote_bitrate_estimator:remote_bitrate_estimator_unittests", diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index f2704169c2..57b49b2fd8 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -132,10 +132,10 @@ rtc_library("audio_processing") { "gain_controller2.h", "include/aec_dump.cc", "include/aec_dump.h", + "legacy_noise_suppression.cc", + "legacy_noise_suppression.h", "level_estimator.cc", "level_estimator.h", - "noise_suppression.cc", - "noise_suppression.h", "render_queue_item_verifier.h", "residual_echo_detector.cc", "residual_echo_detector.h", @@ -199,6 +199,7 @@ rtc_library("audio_processing") { "agc2:adaptive_digital", "agc2:fixed_digital", "agc2:gain_applier", + "ns", "vad", "//third_party/abseil-cpp/absl/types:optional", ] @@ -287,29 +288,29 @@ rtc_library("file_audio_generator") { rtc_source_set("audio_processing_c") { visibility = [ ":*" ] # Only targets in this file can depend on this. sources = [ - "ns/windows_private.h", + "legacy_ns/windows_private.h", ] if (rtc_prefer_fixed_point) { sources += [ - "ns/noise_suppression_x.c", - "ns/noise_suppression_x.h", - "ns/nsx_core.c", - "ns/nsx_core.h", - "ns/nsx_defines.h", + "legacy_ns/noise_suppression_x.c", + "legacy_ns/noise_suppression_x.h", + "legacy_ns/nsx_core.c", + "legacy_ns/nsx_core.h", + "legacy_ns/nsx_defines.h", ] if (current_cpu == "mipsel") { - sources += [ "ns/nsx_core_mips.c" ] + sources += [ "legacy_ns/nsx_core_mips.c" ] } else { - sources += [ "ns/nsx_core_c.c" ] + sources += [ "legacy_ns/nsx_core_c.c" ] } } else { sources += [ - "ns/defines.h", - "ns/noise_suppression.c", - "ns/noise_suppression.h", - "ns/ns_core.c", - "ns/ns_core.h", + "legacy_ns/defines.h", + "legacy_ns/noise_suppression.c", + "legacy_ns/noise_suppression.h", + "legacy_ns/ns_core.c", + "legacy_ns/ns_core.h", ] } @@ -324,7 +325,7 @@ rtc_source_set("audio_processing_c") { ] if (rtc_build_with_neon) { - sources += [ "ns/nsx_core_neon.c" ] + sources += [ "legacy_ns/nsx_core_neon.c" ] if (current_cpu != "arm64") { # Enable compilation for the NEON instruction set. @@ -507,8 +508,8 @@ if (rtc_include_tests) { "echo_detector/normalized_covariance_estimator_unittest.cc", "gain_control_unittest.cc", "high_pass_filter_unittest.cc", + "legacy_noise_suppression_unittest.cc", "level_estimator_unittest.cc", - "noise_suppression_unittest.cc", "residual_echo_detector_unittest.cc", "rms_level_unittest.cc", "test/debug_dump_replayer.cc", diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index f9e7bce959..4573aedf98 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -70,6 +70,11 @@ bool SampleRateSupportsMultiBand(int sample_rate_hz) { sample_rate_hz == AudioProcessing::kSampleRate48kHz; } +// Checks whether the legacy ns functionality should be enforced. +bool DetectLegacyNsEnforcement() { + return field_trial::IsEnabled("WebRTC-NewNoiseSuppressionKillSwitch"); +} + // Identify the native processing rate that best handles a sample rate. int SuitableProcessRate(int minimum_rate, int max_splitting_rate, @@ -306,6 +311,7 @@ AudioProcessingImpl::AudioProcessingImpl( std::unique_ptr capture_analyzer) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), + enforced_usage_of_legacy_ns_(DetectLegacyNsEnforcement()), capture_runtime_settings_(kRuntimeSettingQueueSize), render_runtime_settings_(kRuntimeSettingQueueSize), capture_runtime_settings_enqueuer_(&capture_runtime_settings_), @@ -1303,9 +1309,14 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { if (submodules_.high_pass_filter) { submodules_.high_pass_filter->Process(capture_buffer); } + RETURN_ON_ERR(submodules_.gain_control->AnalyzeCaptureAudio(capture_buffer)); + RTC_DCHECK( + !(submodules_.legacy_noise_suppressor && submodules_.noise_suppressor)); if (submodules_.noise_suppressor) { - submodules_.noise_suppressor->AnalyzeCaptureAudio(capture_buffer); + submodules_.noise_suppressor->Analyze(*capture_buffer); + } else if (submodules_.legacy_noise_suppressor) { + submodules_.legacy_noise_suppressor->AnalyzeCaptureAudio(capture_buffer); } if (submodules_.echo_control_mobile) { @@ -1316,8 +1327,10 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { } if (submodules_.noise_suppressor) { + submodules_.noise_suppressor->Process(capture_buffer); + } else if (submodules_.legacy_noise_suppressor) { submodules_.echo_control_mobile->CopyLowPassReference(capture_buffer); - submodules_.noise_suppressor->ProcessCaptureAudio(capture_buffer); + submodules_.legacy_noise_suppressor->ProcessCaptureAudio(capture_buffer); } RETURN_ON_ERR(submodules_.echo_control_mobile->ProcessCaptureAudio( @@ -1344,7 +1357,9 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { } if (submodules_.noise_suppressor) { - submodules_.noise_suppressor->ProcessCaptureAudio(capture_buffer); + submodules_.noise_suppressor->Process(capture_buffer); + } else if (submodules_.legacy_noise_suppressor) { + submodules_.legacy_noise_suppressor->ProcessCaptureAudio(capture_buffer); } } @@ -1726,9 +1741,9 @@ bool AudioProcessingImpl::UpdateActiveSubmoduleStates() { return submodule_states_.Update( config_.high_pass_filter.enabled, !!submodules_.echo_cancellation, !!submodules_.echo_control_mobile, config_.residual_echo_detector.enabled, - !!submodules_.noise_suppressor, submodules_.gain_control->is_enabled(), - config_.gain_controller2.enabled, config_.pre_amplifier.enabled, - capture_nonlocked_.echo_controller_enabled, + !!submodules_.legacy_noise_suppressor || !!submodules_.noise_suppressor, + submodules_.gain_control->is_enabled(), config_.gain_controller2.enabled, + config_.pre_amplifier.enabled, capture_nonlocked_.echo_controller_enabled, config_.voice_detection.enabled, capture_.transient_suppressor_enabled); } @@ -1868,13 +1883,42 @@ void AudioProcessingImpl::InitializeGainController2() { } void AudioProcessingImpl::InitializeNoiseSuppressor() { + submodules_.legacy_noise_suppressor.reset(); + submodules_.noise_suppressor.reset(); + if (config_.noise_suppression.enabled) { - auto ns_level = - NsConfigLevelToInterfaceLevel(config_.noise_suppression.level); - submodules_.noise_suppressor = std::make_unique( - num_proc_channels(), proc_sample_rate_hz(), ns_level); - } else { - submodules_.noise_suppressor.reset(); + const bool use_legacy_ns = + config_.noise_suppression.use_legacy_ns || enforced_usage_of_legacy_ns_; + + if (!use_legacy_ns) { + auto map_level = + [](AudioProcessing::Config::NoiseSuppression::Level level) { + using NoiseSuppresionConfig = + AudioProcessing::Config::NoiseSuppression; + switch (level) { + case NoiseSuppresionConfig::kLow: + return NsConfig::SuppressionLevel::k6dB; + case NoiseSuppresionConfig::kModerate: + return NsConfig::SuppressionLevel::k12dB; + case NoiseSuppresionConfig::kHigh: + return NsConfig::SuppressionLevel::k18dB; + case NoiseSuppresionConfig::kVeryHigh: + return NsConfig::SuppressionLevel::k21dB; + default: + RTC_NOTREACHED(); + } + }; + + NsConfig cfg; + cfg.target_level = map_level(config_.noise_suppression.level); + submodules_.noise_suppressor = std::make_unique( + cfg, proc_sample_rate_hz(), num_proc_channels()); + } else { + auto ns_level = + NsConfigLevelToInterfaceLevel(config_.noise_suppression.level); + submodules_.legacy_noise_suppressor = std::make_unique( + num_proc_channels(), proc_sample_rate_hz(), ns_level); + } } } diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index eb1fe7f6fb..3e1b466122 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -29,8 +29,9 @@ #include "modules/audio_processing/include/aec_dump.h" #include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/include/audio_processing_statistics.h" +#include "modules/audio_processing/legacy_noise_suppression.h" #include "modules/audio_processing/level_estimator.h" -#include "modules/audio_processing/noise_suppression.h" +#include "modules/audio_processing/ns/noise_suppressor.h" #include "modules/audio_processing/render_queue_item_verifier.h" #include "modules/audio_processing/residual_echo_detector.h" #include "modules/audio_processing/rms_level.h" @@ -150,6 +151,7 @@ class AudioProcessingImpl : public AudioProcessing { std::unique_ptr data_dumper_; static int instance_count_; + const bool enforced_usage_of_legacy_ns_; SwapQueue capture_runtime_settings_; SwapQueue render_runtime_settings_; @@ -343,7 +345,8 @@ class AudioProcessingImpl : public AudioProcessing { std::unique_ptr echo_cancellation; std::unique_ptr echo_controller; std::unique_ptr echo_control_mobile; - std::unique_ptr noise_suppressor; + std::unique_ptr legacy_noise_suppressor; + std::unique_ptr noise_suppressor; std::unique_ptr transient_suppressor; std::unique_ptr capture_post_processor; std::unique_ptr render_pre_processor; diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc index 1aac2cf44a..094823de41 100644 --- a/modules/audio_processing/audio_processing_unittest.cc +++ b/modules/audio_processing/audio_processing_unittest.cc @@ -2145,30 +2145,30 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple(44100, 16000, 32000, 16000, 19, 20), std::make_tuple(44100, 16000, 16000, 16000, 19, 0), - std::make_tuple(32000, 48000, 48000, 48000, 35, 0), + std::make_tuple(32000, 48000, 48000, 48000, 28, 0), std::make_tuple(32000, 48000, 32000, 48000, 65, 30), - std::make_tuple(32000, 48000, 16000, 48000, 40, 20), + std::make_tuple(32000, 48000, 16000, 48000, 30, 20), std::make_tuple(32000, 44100, 48000, 44100, 20, 20), std::make_tuple(32000, 44100, 32000, 44100, 20, 15), std::make_tuple(32000, 44100, 16000, 44100, 20, 15), - std::make_tuple(32000, 32000, 48000, 32000, 35, 35), + std::make_tuple(32000, 32000, 48000, 32000, 29, 35), std::make_tuple(32000, 32000, 32000, 32000, 0, 0), - std::make_tuple(32000, 32000, 16000, 32000, 40, 20), + std::make_tuple(32000, 32000, 16000, 32000, 32, 20), std::make_tuple(32000, 16000, 48000, 16000, 20, 20), std::make_tuple(32000, 16000, 32000, 16000, 20, 20), std::make_tuple(32000, 16000, 16000, 16000, 20, 0), - std::make_tuple(16000, 48000, 48000, 48000, 25, 0), + std::make_tuple(16000, 48000, 48000, 48000, 24, 0), std::make_tuple(16000, 48000, 32000, 48000, 25, 30), std::make_tuple(16000, 48000, 16000, 48000, 25, 20), std::make_tuple(16000, 44100, 48000, 44100, 15, 20), std::make_tuple(16000, 44100, 32000, 44100, 15, 15), std::make_tuple(16000, 44100, 16000, 44100, 15, 15), - std::make_tuple(16000, 32000, 48000, 32000, 25, 35), + std::make_tuple(16000, 32000, 48000, 32000, 24, 35), std::make_tuple(16000, 32000, 32000, 32000, 25, 0), std::make_tuple(16000, 32000, 16000, 32000, 25, 20), - std::make_tuple(16000, 16000, 48000, 16000, 35, 20), - std::make_tuple(16000, 16000, 32000, 16000, 35, 20), + std::make_tuple(16000, 16000, 48000, 16000, 30, 20), + std::make_tuple(16000, 16000, 32000, 16000, 30, 20), std::make_tuple(16000, 16000, 16000, 16000, 0, 0))); #endif diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index f51601538a..8c4615522b 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -285,6 +285,8 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { bool enabled = false; enum Level { kLow, kModerate, kHigh, kVeryHigh }; Level level = kModerate; + // Recommended not to use. Will be removed in the future. + bool use_legacy_ns = false; } noise_suppression; // Enables reporting of |voice_detected| in webrtc::AudioProcessingStats. diff --git a/modules/audio_processing/noise_suppression.cc b/modules/audio_processing/legacy_noise_suppression.cc similarity index 96% rename from modules/audio_processing/noise_suppression.cc rename to modules/audio_processing/legacy_noise_suppression.cc index b8ddd30384..b2c88536ca 100644 --- a/modules/audio_processing/noise_suppression.cc +++ b/modules/audio_processing/legacy_noise_suppression.cc @@ -8,12 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/noise_suppression.h" +#include "modules/audio_processing/legacy_noise_suppression.h" #include "modules/audio_processing/audio_buffer.h" #include "rtc_base/checks.h" #if defined(WEBRTC_NS_FLOAT) -#include "modules/audio_processing/ns/noise_suppression.h" +#include "modules/audio_processing/legacy_ns/noise_suppression.h" #define NS_CREATE WebRtcNs_Create #define NS_FREE WebRtcNs_Free @@ -21,7 +21,7 @@ #define NS_SET_POLICY WebRtcNs_set_policy typedef NsHandle NsState; #elif defined(WEBRTC_NS_FIXED) -#include "modules/audio_processing/ns/noise_suppression_x.h" +#include "modules/audio_processing/legacy_ns/noise_suppression_x.h" #define NS_CREATE WebRtcNsx_Create #define NS_FREE WebRtcNsx_Free diff --git a/modules/audio_processing/noise_suppression.h b/modules/audio_processing/legacy_noise_suppression.h similarity index 90% rename from modules/audio_processing/noise_suppression.h rename to modules/audio_processing/legacy_noise_suppression.h index df5aed4a65..c2435dbc08 100644 --- a/modules/audio_processing/noise_suppression.h +++ b/modules/audio_processing/legacy_noise_suppression.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_H_ -#define MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NOISE_SUPPRESSION_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NOISE_SUPPRESSION_H_ #include #include @@ -54,4 +54,4 @@ class NoiseSuppression { }; } // namespace webrtc -#endif // MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_H_ +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NOISE_SUPPRESSION_H_ diff --git a/modules/audio_processing/noise_suppression_unittest.cc b/modules/audio_processing/legacy_noise_suppression_unittest.cc similarity index 95% rename from modules/audio_processing/noise_suppression_unittest.cc rename to modules/audio_processing/legacy_noise_suppression_unittest.cc index 649fc93fde..57deedb415 100644 --- a/modules/audio_processing/noise_suppression_unittest.cc +++ b/modules/audio_processing/legacy_noise_suppression_unittest.cc @@ -11,7 +11,7 @@ #include "api/array_view.h" #include "modules/audio_processing/audio_buffer.h" -#include "modules/audio_processing/noise_suppression.h" +#include "modules/audio_processing/legacy_noise_suppression.h" #include "modules/audio_processing/test/audio_buffer_tools.h" #include "modules/audio_processing/test/bitexactness_tools.h" #include "test/gtest.h" @@ -90,7 +90,7 @@ void RunBitexactnessTest(int sample_rate_hz, } // namespace -TEST(NoiseSuppresionBitExactnessTest, Mono8kHzLow) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono8kHzLow) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {1432.341431f, 3321.919922f, @@ -113,7 +113,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono8kHzLow) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono16kHzLow) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono16kHzLow) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2534.461914f, 6277.638672f, @@ -136,7 +136,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono16kHzLow) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono32kHzLow) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono32kHzLow) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2540.059082f, 6317.822754f, @@ -159,7 +159,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono32kHzLow) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono48kHzLow) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono48kHzLow) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2135.292480f, 6692.695801f, @@ -182,7 +182,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono48kHzLow) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Stereo16kHzLow) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Stereo16kHzLow) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {9992.127930f, 12689.569336f, @@ -208,7 +208,7 @@ TEST(NoiseSuppresionBitExactnessTest, Stereo16kHzLow) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono16kHzModerate) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono16kHzModerate) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2057.085938f, 7601.055176f, @@ -231,7 +231,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono16kHzModerate) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono16kHzHigh) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono16kHzHigh) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2095.148193f, 7698.553711f, @@ -254,7 +254,7 @@ TEST(NoiseSuppresionBitExactnessTest, Mono16kHzHigh) { kOutputReference); } -TEST(NoiseSuppresionBitExactnessTest, Mono16kHzVeryHigh) { +TEST(LegacyNoiseSuppresionBitExactnessTest, Mono16kHzVeryHigh) { #if defined(WEBRTC_ARCH_ARM64) const float kSpeechProbabilityReference = -4.0f; const float kNoiseEstimateReference[] = {2677.733398f, 6186.987305f, diff --git a/modules/audio_processing/legacy_ns/defines.h b/modules/audio_processing/legacy_ns/defines.h new file mode 100644 index 0000000000..02e03181b1 --- /dev/null +++ b/modules/audio_processing/legacy_ns/defines.h @@ -0,0 +1,52 @@ +/* + * 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 MODULES_AUDIO_PROCESSING_LEGACY_NS_DEFINES_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_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 0.25f + +#define SIMULT 3 +#define END_STARTUP_LONG 200 +#define END_STARTUP_SHORT 50 +#define FACTOR 40.f +#define WIDTH 0.01f + +// 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 0.98f // DD update of prior SNR +#define LRT_TAVG 0.5f // tavg parameter for LRT (previously 0.90) +#define SPECT_FL_TAVG 0.30f // tavg parameter for spectral flatness measure +#define SPECT_DIFF_TAVG 0.30f // tavg parameter for spectral difference measure +#define PRIOR_UPDATE 0.1f // update parameter of prior model +#define NOISE_UPDATE 0.9f // update parameter for noise +#define SPEECH_UPDATE 0.99f // update parameter when likely speech +#define WIDTH_PR_MAP 4.0f // width parameter in sigmoid map for prior model +#define LRT_FEATURE_THR 0.5f // default threshold for LRT feature +#define SF_FEATURE_THR 0.5f // default threshold for Spectral Flatness feature +#define SD_FEATURE_THR \ + 0.5f // default threshold for Spectral Difference feature +#define PROB_RANGE \ + 0.2f // probability threshold for noise state in + // speech/noise likelihood +#define HIST_PAR_EST 1000 // histogram size for estimation of parameters +#define GAMMA_PAUSE 0.05f // update for conservative noise estimate +// +#define B_LIM 0.5f // threshold in final energy gain factor calculation +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_DEFINES_H_ diff --git a/modules/audio_processing/ns/noise_suppression.c b/modules/audio_processing/legacy_ns/noise_suppression.c similarity index 91% rename from modules/audio_processing/ns/noise_suppression.c rename to modules/audio_processing/legacy_ns/noise_suppression.c index e21416f956..8b9564098b 100644 --- a/modules/audio_processing/ns/noise_suppression.c +++ b/modules/audio_processing/legacy_ns/noise_suppression.c @@ -8,14 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/ns/noise_suppression.h" +#include "modules/audio_processing/legacy_ns/noise_suppression.h" #include #include #include "common_audio/signal_processing/include/signal_processing_library.h" -#include "modules/audio_processing/ns/defines.h" -#include "modules/audio_processing/ns/ns_core.h" +#include "modules/audio_processing/legacy_ns/defines.h" +#include "modules/audio_processing/legacy_ns/ns_core.h" NsHandle* WebRtcNs_Create() { NoiseSuppressionC* self = malloc(sizeof(NoiseSuppressionC)); diff --git a/modules/audio_processing/ns/noise_suppression.h b/modules/audio_processing/legacy_ns/noise_suppression.h similarity index 95% rename from modules/audio_processing/ns/noise_suppression.h rename to modules/audio_processing/legacy_ns/noise_suppression.h index 0775ffa243..01f04ccfac 100644 --- a/modules/audio_processing/ns/noise_suppression.h +++ b/modules/audio_processing/legacy_ns/noise_suppression.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ -#define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_H_ #include #include @@ -131,4 +131,4 @@ size_t WebRtcNs_num_freq(void); } #endif -#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_H_ diff --git a/modules/audio_processing/ns/noise_suppression_x.c b/modules/audio_processing/legacy_ns/noise_suppression_x.c similarity index 85% rename from modules/audio_processing/ns/noise_suppression_x.c rename to modules/audio_processing/legacy_ns/noise_suppression_x.c index c6faf75845..faa866ec7b 100644 --- a/modules/audio_processing/ns/noise_suppression_x.c +++ b/modules/audio_processing/legacy_ns/noise_suppression_x.c @@ -8,13 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/ns/noise_suppression_x.h" +#include "modules/audio_processing/legacy_ns/noise_suppression_x.h" #include #include "common_audio/signal_processing/include/real_fft.h" -#include "modules/audio_processing/ns/nsx_core.h" -#include "modules/audio_processing/ns/nsx_defines.h" +#include "modules/audio_processing/legacy_ns/nsx_core.h" +#include "modules/audio_processing/legacy_ns/nsx_defines.h" NsxHandle* WebRtcNsx_Create() { NoiseSuppressionFixedC* self = malloc(sizeof(NoiseSuppressionFixedC)); @@ -37,9 +37,9 @@ int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode) { } void WebRtcNsx_Process(NsxHandle* nsxInst, - const short* const* speechFrame, + const int16_t* const* speechFrame, int num_bands, - short* const* outFrame) { + int16_t* const* outFrame) { WebRtcNsx_ProcessCore((NoiseSuppressionFixedC*)nsxInst, speechFrame, num_bands, outFrame); } diff --git a/modules/audio_processing/ns/noise_suppression_x.h b/modules/audio_processing/legacy_ns/noise_suppression_x.h similarity index 91% rename from modules/audio_processing/ns/noise_suppression_x.h rename to modules/audio_processing/legacy_ns/noise_suppression_x.h index 972784e581..572db4111b 100644 --- a/modules/audio_processing/ns/noise_suppression_x.h +++ b/modules/audio_processing/legacy_ns/noise_suppression_x.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ -#define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_X_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_X_H_ #include #include @@ -78,9 +78,9 @@ int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode); * - outFrame : Pointer to output frame for each band */ void WebRtcNsx_Process(NsxHandle* nsxInst, - const short* const* speechFrame, + const int16_t* const* speechFrame, int num_bands, - short* const* outFrame); + int16_t* const* outFrame); /* Returns a pointer to the noise estimate per frequency bin. The number of * frequency bins can be provided using WebRtcNsx_num_freq(). @@ -109,4 +109,4 @@ size_t WebRtcNsx_num_freq(void); } #endif -#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_NOISE_SUPPRESSION_X_H_ diff --git a/modules/audio_processing/ns/ns_core.c b/modules/audio_processing/legacy_ns/ns_core.c similarity index 99% rename from modules/audio_processing/ns/ns_core.c rename to modules/audio_processing/legacy_ns/ns_core.c index bc5dd6d451..b5dc829775 100644 --- a/modules/audio_processing/ns/ns_core.c +++ b/modules/audio_processing/legacy_ns/ns_core.c @@ -15,9 +15,9 @@ #include "rtc_base/checks.h" #include "common_audio/signal_processing/include/signal_processing_library.h" #include "common_audio/third_party/fft4g/fft4g.h" -#include "modules/audio_processing/ns/noise_suppression.h" -#include "modules/audio_processing/ns/ns_core.h" -#include "modules/audio_processing/ns/windows_private.h" +#include "modules/audio_processing/legacy_ns/noise_suppression.h" +#include "modules/audio_processing/legacy_ns/ns_core.h" +#include "modules/audio_processing/legacy_ns/windows_private.h" // Set Feature Extraction Parameters. static void set_feature_extraction_parameters(NoiseSuppressionC* self) { diff --git a/modules/audio_processing/ns/ns_core.h b/modules/audio_processing/legacy_ns/ns_core.h similarity index 96% rename from modules/audio_processing/ns/ns_core.h rename to modules/audio_processing/legacy_ns/ns_core.h index e90b8ce39b..7a3b0a4acc 100644 --- a/modules/audio_processing/ns/ns_core.h +++ b/modules/audio_processing/legacy_ns/ns_core.h @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ -#define MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NS_NS_CORE_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_NS_CORE_H_ -#include "modules/audio_processing/ns/defines.h" +#include "modules/audio_processing/legacy_ns/defines.h" typedef struct NSParaExtract_ { // Bin size of histogram. @@ -46,7 +46,6 @@ typedef struct NSParaExtract_ { // Criteria of weight of histogram peak to accept/reject feature. int thresWeightSpecFlat; int thresWeightSpecDiff; - } NSParaExtract; typedef struct NoiseSuppressionC_ { @@ -186,4 +185,4 @@ void WebRtcNs_ProcessCore(NoiseSuppressionC* self, #ifdef __cplusplus } #endif -#endif // MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_NS_CORE_H_ diff --git a/modules/audio_processing/ns/nsx_core.c b/modules/audio_processing/legacy_ns/nsx_core.c similarity index 58% rename from modules/audio_processing/ns/nsx_core.c rename to modules/audio_processing/legacy_ns/nsx_core.c index 8043656029..aa1e73bcaa 100644 --- a/modules/audio_processing/ns/nsx_core.c +++ b/modules/audio_processing/legacy_ns/nsx_core.c @@ -8,15 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/ns/noise_suppression_x.h" +#include "modules/audio_processing/legacy_ns/noise_suppression_x.h" #include #include #include -#include "rtc_base/checks.h" #include "common_audio/signal_processing/include/real_fft.h" -#include "modules/audio_processing/ns/nsx_core.h" +#include "modules/audio_processing/legacy_ns/nsx_core.h" +#include "rtc_base/checks.h" #include "system_wrappers/include/cpu_features_wrapper.h" #if defined(WEBRTC_HAS_NEON) @@ -25,46 +25,47 @@ extern const int16_t WebRtcNsx_kLogTable[9]; extern const int16_t WebRtcNsx_kCounterDiv[201]; extern const int16_t WebRtcNsx_kLogTableFrac[256]; #else -static const int16_t WebRtcNsx_kLogTable[9] = { - 0, 177, 355, 532, 710, 887, 1065, 1242, 1420 -}; +static const int16_t WebRtcNsx_kLogTable[9] = {0, 177, 355, 532, 710, + 887, 1065, 1242, 1420}; static 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 -}; + 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}; static 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 -}; + 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}; #endif // WEBRTC_HAS_NEON // Skip first frequency bins during estimation. (0 <= value < 64) @@ -72,55 +73,45 @@ static const size_t kStartBand = 5; // hybrib Hanning & flat window static const int16_t kBlocks80w128x[128] = { - 0, 536, 1072, 1606, 2139, 2669, 3196, 3720, 4240, 4756, 5266, - 5771, 6270, 6762, 7246, 7723, 8192, 8652, 9102, 9543, 9974, 10394, - 10803, 11200, 11585, 11958, 12318, 12665, 12998, 13318, 13623, 13913, 14189, - 14449, 14694, 14924, 15137, 15334, 15515, 15679, 15826, 15956, 16069, 16165, - 16244, 16305, 16349, 16375, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16375, 16349, 16305, 16244, 16165, 16069, 15956, - 15826, 15679, 15515, 15334, 15137, 14924, 14694, 14449, 14189, 13913, 13623, - 13318, 12998, 12665, 12318, 11958, 11585, 11200, 10803, 10394, 9974, 9543, - 9102, 8652, 8192, 7723, 7246, 6762, 6270, 5771, 5266, 4756, 4240, - 3720, 3196, 2669, 2139, 1606, 1072, 536 -}; + 0, 536, 1072, 1606, 2139, 2669, 3196, 3720, 4240, 4756, 5266, + 5771, 6270, 6762, 7246, 7723, 8192, 8652, 9102, 9543, 9974, 10394, + 10803, 11200, 11585, 11958, 12318, 12665, 12998, 13318, 13623, 13913, 14189, + 14449, 14694, 14924, 15137, 15334, 15515, 15679, 15826, 15956, 16069, 16165, + 16244, 16305, 16349, 16375, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16375, 16349, 16305, 16244, 16165, 16069, 15956, + 15826, 15679, 15515, 15334, 15137, 14924, 14694, 14449, 14189, 13913, 13623, + 13318, 12998, 12665, 12318, 11958, 11585, 11200, 10803, 10394, 9974, 9543, + 9102, 8652, 8192, 7723, 7246, 6762, 6270, 5771, 5266, 4756, 4240, + 3720, 3196, 2669, 2139, 1606, 1072, 536}; // hybrib Hanning & flat window static const int16_t kBlocks160w256x[256] = { - 0, 268, 536, 804, 1072, 1339, 1606, 1872, - 2139, 2404, 2669, 2933, 3196, 3459, 3720, 3981, - 4240, 4499, 4756, 5012, 5266, 5520, 5771, 6021, - 6270, 6517, 6762, 7005, 7246, 7486, 7723, 7959, - 8192, 8423, 8652, 8878, 9102, 9324, 9543, 9760, - 9974, 10185, 10394, 10600, 10803, 11003, 11200, 11394, - 11585, 11773, 11958, 12140, 12318, 12493, 12665, 12833, - 12998, 13160, 13318, 13472, 13623, 13770, 13913, 14053, - 14189, 14321, 14449, 14574, 14694, 14811, 14924, 15032, - 15137, 15237, 15334, 15426, 15515, 15599, 15679, 15754, - 15826, 15893, 15956, 16015, 16069, 16119, 16165, 16207, - 16244, 16277, 16305, 16329, 16349, 16364, 16375, 16382, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16382, 16375, 16364, 16349, 16329, 16305, 16277, - 16244, 16207, 16165, 16119, 16069, 16015, 15956, 15893, - 15826, 15754, 15679, 15599, 15515, 15426, 15334, 15237, - 15137, 15032, 14924, 14811, 14694, 14574, 14449, 14321, - 14189, 14053, 13913, 13770, 13623, 13472, 13318, 13160, - 12998, 12833, 12665, 12493, 12318, 12140, 11958, 11773, - 11585, 11394, 11200, 11003, 10803, 10600, 10394, 10185, - 9974, 9760, 9543, 9324, 9102, 8878, 8652, 8423, - 8192, 7959, 7723, 7486, 7246, 7005, 6762, 6517, - 6270, 6021, 5771, 5520, 5266, 5012, 4756, 4499, - 4240, 3981, 3720, 3459, 3196, 2933, 2669, 2404, - 2139, 1872, 1606, 1339, 1072, 804, 536, 268 -}; + 0, 268, 536, 804, 1072, 1339, 1606, 1872, 2139, 2404, 2669, + 2933, 3196, 3459, 3720, 3981, 4240, 4499, 4756, 5012, 5266, 5520, + 5771, 6021, 6270, 6517, 6762, 7005, 7246, 7486, 7723, 7959, 8192, + 8423, 8652, 8878, 9102, 9324, 9543, 9760, 9974, 10185, 10394, 10600, + 10803, 11003, 11200, 11394, 11585, 11773, 11958, 12140, 12318, 12493, 12665, + 12833, 12998, 13160, 13318, 13472, 13623, 13770, 13913, 14053, 14189, 14321, + 14449, 14574, 14694, 14811, 14924, 15032, 15137, 15237, 15334, 15426, 15515, + 15599, 15679, 15754, 15826, 15893, 15956, 16015, 16069, 16119, 16165, 16207, + 16244, 16277, 16305, 16329, 16349, 16364, 16375, 16382, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16382, 16375, 16364, 16349, + 16329, 16305, 16277, 16244, 16207, 16165, 16119, 16069, 16015, 15956, 15893, + 15826, 15754, 15679, 15599, 15515, 15426, 15334, 15237, 15137, 15032, 14924, + 14811, 14694, 14574, 14449, 14321, 14189, 14053, 13913, 13770, 13623, 13472, + 13318, 13160, 12998, 12833, 12665, 12493, 12318, 12140, 11958, 11773, 11585, + 11394, 11200, 11003, 10803, 10600, 10394, 10185, 9974, 9760, 9543, 9324, + 9102, 8878, 8652, 8423, 8192, 7959, 7723, 7486, 7246, 7005, 6762, + 6517, 6270, 6021, 5771, 5520, 5266, 5012, 4756, 4499, 4240, 3981, + 3720, 3459, 3196, 2933, 2669, 2404, 2139, 1872, 1606, 1339, 1072, + 804, 536, 268}; // Gain factor1 table: Input value in Q8 and output value in Q13 // original floating point code @@ -133,27 +124,30 @@ static const int16_t kBlocks160w256x[256] = { // factor1 = 1.0; // } static const int16_t kFactor1Table[257] = { - 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8233, 8274, 8315, 8355, 8396, 8436, 8475, 8515, 8554, 8592, 8631, 8669, - 8707, 8745, 8783, 8820, 8857, 8894, 8931, 8967, 9003, 9039, 9075, 9111, 9146, 9181, - 9216, 9251, 9286, 9320, 9354, 9388, 9422, 9456, 9489, 9523, 9556, 9589, 9622, 9655, - 9687, 9719, 9752, 9784, 9816, 9848, 9879, 9911, 9942, 9973, 10004, 10035, 10066, - 10097, 10128, 10158, 10188, 10218, 10249, 10279, 10308, 10338, 10368, 10397, 10426, - 10456, 10485, 10514, 10543, 10572, 10600, 10629, 10657, 10686, 10714, 10742, 10770, - 10798, 10826, 10854, 10882, 10847, 10810, 10774, 10737, 10701, 10666, 10631, 10596, - 10562, 10527, 10494, 10460, 10427, 10394, 10362, 10329, 10297, 10266, 10235, 10203, - 10173, 10142, 10112, 10082, 10052, 10023, 9994, 9965, 9936, 9908, 9879, 9851, 9824, - 9796, 9769, 9742, 9715, 9689, 9662, 9636, 9610, 9584, 9559, 9534, 9508, 9484, 9459, - 9434, 9410, 9386, 9362, 9338, 9314, 9291, 9268, 9245, 9222, 9199, 9176, 9154, 9132, - 9110, 9088, 9066, 9044, 9023, 9002, 8980, 8959, 8939, 8918, 8897, 8877, 8857, 8836, - 8816, 8796, 8777, 8757, 8738, 8718, 8699, 8680, 8661, 8642, 8623, 8605, 8586, 8568, - 8550, 8532, 8514, 8496, 8478, 8460, 8443, 8425, 8408, 8391, 8373, 8356, 8339, 8323, - 8306, 8289, 8273, 8256, 8240, 8224, 8208, 8192 -}; + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8233, + 8274, 8315, 8355, 8396, 8436, 8475, 8515, 8554, 8592, 8631, 8669, + 8707, 8745, 8783, 8820, 8857, 8894, 8931, 8967, 9003, 9039, 9075, + 9111, 9146, 9181, 9216, 9251, 9286, 9320, 9354, 9388, 9422, 9456, + 9489, 9523, 9556, 9589, 9622, 9655, 9687, 9719, 9752, 9784, 9816, + 9848, 9879, 9911, 9942, 9973, 10004, 10035, 10066, 10097, 10128, 10158, + 10188, 10218, 10249, 10279, 10308, 10338, 10368, 10397, 10426, 10456, 10485, + 10514, 10543, 10572, 10600, 10629, 10657, 10686, 10714, 10742, 10770, 10798, + 10826, 10854, 10882, 10847, 10810, 10774, 10737, 10701, 10666, 10631, 10596, + 10562, 10527, 10494, 10460, 10427, 10394, 10362, 10329, 10297, 10266, 10235, + 10203, 10173, 10142, 10112, 10082, 10052, 10023, 9994, 9965, 9936, 9908, + 9879, 9851, 9824, 9796, 9769, 9742, 9715, 9689, 9662, 9636, 9610, + 9584, 9559, 9534, 9508, 9484, 9459, 9434, 9410, 9386, 9362, 9338, + 9314, 9291, 9268, 9245, 9222, 9199, 9176, 9154, 9132, 9110, 9088, + 9066, 9044, 9023, 9002, 8980, 8959, 8939, 8918, 8897, 8877, 8857, + 8836, 8816, 8796, 8777, 8757, 8738, 8718, 8699, 8680, 8661, 8642, + 8623, 8605, 8586, 8568, 8550, 8532, 8514, 8496, 8478, 8460, 8443, + 8425, 8408, 8391, 8373, 8356, 8339, 8323, 8306, 8289, 8273, 8256, + 8240, 8224, 8208, 8192}; // For Factor2 tables // original floating point code @@ -168,159 +162,149 @@ static const int16_t kFactor1Table[257] = { // // Gain factor table: Input value in Q8 and output value in Q13 static const int16_t kFactor2Aggressiveness1[257] = { - 7577, 7577, 7577, 7577, 7577, 7577, - 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7596, 7614, 7632, - 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, - 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, - 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, - 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 -}; + 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, + 7577, 7577, 7577, 7577, 7577, 7596, 7614, 7632, 7650, 7667, 7683, 7699, + 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 7858, 7871, + 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, + 8152, 8162, 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192}; // Gain factor table: Input value in Q8 and output value in Q13 static const int16_t kFactor2Aggressiveness2[257] = { - 7270, 7270, 7270, 7270, 7270, 7306, - 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, - 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, - 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, - 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, - 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 -}; + 7270, 7270, 7270, 7270, 7270, 7306, 7339, 7369, 7397, 7424, 7448, 7472, + 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, 7650, 7667, 7683, 7699, + 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 7858, 7871, + 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, + 8152, 8162, 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192}; // Gain factor table: Input value in Q8 and output value in Q13 static const int16_t kFactor2Aggressiveness3[257] = { - 7184, 7184, 7184, 7229, 7270, 7306, - 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, - 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, - 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, - 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, - 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 -}; + 7184, 7184, 7184, 7229, 7270, 7306, 7339, 7369, 7397, 7424, 7448, 7472, + 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, 7650, 7667, 7683, 7699, + 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 7858, 7871, + 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, + 8152, 8162, 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192}; // sum of log2(i) from table index to inst->anaLen2 in Q5 // Note that the first table value is invalid, since log2(0) = -infinity static const int16_t kSumLogIndex[66] = { - 0, 22917, 22917, 22885, 22834, 22770, 22696, 22613, - 22524, 22428, 22326, 22220, 22109, 21994, 21876, 21754, - 21629, 21501, 21370, 21237, 21101, 20963, 20822, 20679, - 20535, 20388, 20239, 20089, 19937, 19783, 19628, 19470, - 19312, 19152, 18991, 18828, 18664, 18498, 18331, 18164, - 17994, 17824, 17653, 17480, 17306, 17132, 16956, 16779, - 16602, 16423, 16243, 16063, 15881, 15699, 15515, 15331, - 15146, 14960, 14774, 14586, 14398, 14209, 14019, 13829, - 13637, 13445 -}; + 0, 22917, 22917, 22885, 22834, 22770, 22696, 22613, 22524, 22428, + 22326, 22220, 22109, 21994, 21876, 21754, 21629, 21501, 21370, 21237, + 21101, 20963, 20822, 20679, 20535, 20388, 20239, 20089, 19937, 19783, + 19628, 19470, 19312, 19152, 18991, 18828, 18664, 18498, 18331, 18164, + 17994, 17824, 17653, 17480, 17306, 17132, 16956, 16779, 16602, 16423, + 16243, 16063, 15881, 15699, 15515, 15331, 15146, 14960, 14774, 14586, + 14398, 14209, 14019, 13829, 13637, 13445}; // sum of log2(i)^2 from table index to inst->anaLen2 in Q2 // Note that the first table value is invalid, since log2(0) = -infinity static const int16_t kSumSquareLogIndex[66] = { - 0, 16959, 16959, 16955, 16945, 16929, 16908, 16881, - 16850, 16814, 16773, 16729, 16681, 16630, 16575, 16517, - 16456, 16392, 16325, 16256, 16184, 16109, 16032, 15952, - 15870, 15786, 15700, 15612, 15521, 15429, 15334, 15238, - 15140, 15040, 14938, 14834, 14729, 14622, 14514, 14404, - 14292, 14179, 14064, 13947, 13830, 13710, 13590, 13468, - 13344, 13220, 13094, 12966, 12837, 12707, 12576, 12444, - 12310, 12175, 12039, 11902, 11763, 11624, 11483, 11341, - 11198, 11054 -}; + 0, 16959, 16959, 16955, 16945, 16929, 16908, 16881, 16850, 16814, + 16773, 16729, 16681, 16630, 16575, 16517, 16456, 16392, 16325, 16256, + 16184, 16109, 16032, 15952, 15870, 15786, 15700, 15612, 15521, 15429, + 15334, 15238, 15140, 15040, 14938, 14834, 14729, 14622, 14514, 14404, + 14292, 14179, 14064, 13947, 13830, 13710, 13590, 13468, 13344, 13220, + 13094, 12966, 12837, 12707, 12576, 12444, 12310, 12175, 12039, 11902, + 11763, 11624, 11483, 11341, 11198, 11054}; // log2(table index) in Q12 // Note that the first table value is invalid, since log2(0) = -infinity static const int16_t kLogIndex[129] = { - 0, 0, 4096, 6492, 8192, 9511, 10588, 11499, - 12288, 12984, 13607, 14170, 14684, 15157, 15595, 16003, - 16384, 16742, 17080, 17400, 17703, 17991, 18266, 18529, - 18780, 19021, 19253, 19476, 19691, 19898, 20099, 20292, - 20480, 20662, 20838, 21010, 21176, 21338, 21496, 21649, - 21799, 21945, 22087, 22226, 22362, 22495, 22625, 22752, - 22876, 22998, 23117, 23234, 23349, 23462, 23572, 23680, - 23787, 23892, 23994, 24095, 24195, 24292, 24388, 24483, - 24576, 24668, 24758, 24847, 24934, 25021, 25106, 25189, - 25272, 25354, 25434, 25513, 25592, 25669, 25745, 25820, - 25895, 25968, 26041, 26112, 26183, 26253, 26322, 26390, - 26458, 26525, 26591, 26656, 26721, 26784, 26848, 26910, - 26972, 27033, 27094, 27154, 27213, 27272, 27330, 27388, - 27445, 27502, 27558, 27613, 27668, 27722, 27776, 27830, - 27883, 27935, 27988, 28039, 28090, 28141, 28191, 28241, - 28291, 28340, 28388, 28437, 28484, 28532, 28579, 28626, - 28672 -}; + 0, 0, 4096, 6492, 8192, 9511, 10588, 11499, 12288, 12984, 13607, + 14170, 14684, 15157, 15595, 16003, 16384, 16742, 17080, 17400, 17703, 17991, + 18266, 18529, 18780, 19021, 19253, 19476, 19691, 19898, 20099, 20292, 20480, + 20662, 20838, 21010, 21176, 21338, 21496, 21649, 21799, 21945, 22087, 22226, + 22362, 22495, 22625, 22752, 22876, 22998, 23117, 23234, 23349, 23462, 23572, + 23680, 23787, 23892, 23994, 24095, 24195, 24292, 24388, 24483, 24576, 24668, + 24758, 24847, 24934, 25021, 25106, 25189, 25272, 25354, 25434, 25513, 25592, + 25669, 25745, 25820, 25895, 25968, 26041, 26112, 26183, 26253, 26322, 26390, + 26458, 26525, 26591, 26656, 26721, 26784, 26848, 26910, 26972, 27033, 27094, + 27154, 27213, 27272, 27330, 27388, 27445, 27502, 27558, 27613, 27668, 27722, + 27776, 27830, 27883, 27935, 27988, 28039, 28090, 28141, 28191, 28241, 28291, + 28340, 28388, 28437, 28484, 28532, 28579, 28626, 28672}; // determinant of estimation matrix in Q0 corresponding to the log2 tables above // Note that the first table value is invalid, since log2(0) = -infinity static const int16_t kDeterminantEstMatrix[66] = { - 0, 29814, 25574, 22640, 20351, 18469, 16873, 15491, - 14277, 13199, 12233, 11362, 10571, 9851, 9192, 8587, - 8030, 7515, 7038, 6596, 6186, 5804, 5448, 5115, - 4805, 4514, 4242, 3988, 3749, 3524, 3314, 3116, - 2930, 2755, 2590, 2435, 2289, 2152, 2022, 1900, - 1785, 1677, 1575, 1478, 1388, 1302, 1221, 1145, - 1073, 1005, 942, 881, 825, 771, 721, 674, - 629, 587, 547, 510, 475, 442, 411, 382, - 355, 330 -}; + 0, 29814, 25574, 22640, 20351, 18469, 16873, 15491, 14277, 13199, 12233, + 11362, 10571, 9851, 9192, 8587, 8030, 7515, 7038, 6596, 6186, 5804, + 5448, 5115, 4805, 4514, 4242, 3988, 3749, 3524, 3314, 3116, 2930, + 2755, 2590, 2435, 2289, 2152, 2022, 1900, 1785, 1677, 1575, 1478, + 1388, 1302, 1221, 1145, 1073, 1005, 942, 881, 825, 771, 721, + 674, 629, 587, 547, 510, 475, 442, 411, 382, 355, 330}; // Update the noise estimation information. static void UpdateNoiseEstimate(NoiseSuppressionFixedC* inst, int offset) { int32_t tmp32no1 = 0; int32_t tmp32no2 = 0; int16_t tmp16 = 0; - const int16_t kExp2Const = 11819; // Q13 + const int16_t kExp2Const = 11819; // Q13 size_t i = 0; - tmp16 = WebRtcSpl_MaxValueW16(inst->noiseEstLogQuantile + offset, - inst->magnLen); + 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); + inst->qNoise = + 14 - (int)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2Const, tmp16, 21); for (i = 0; i < inst->magnLen; i++) { // inst->quantile[i]=exp(inst->lquantile[offset+i]); // in Q21 tmp32no2 = kExp2Const * inst->noiseEstLogQuantile[offset + i]; - tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF)); // 2^21 + frac + 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) + 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 { @@ -338,7 +322,7 @@ static void NoiseEstimationC(NoiseSuppressionFixedC* inst, 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; // Q15 + const int16_t log2_const = 22713; // Q15 const int16_t width_factor = 21845; size_t i, s, offset; @@ -359,18 +343,16 @@ static void NoiseEstimationC(NoiseSuppressionFixedC* inst, 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); + frac = (int16_t)((((uint32_t)magn[i] << zeros) & 0x7FFFFFFF) >> 23); // log2(magn(i)) RTC_DCHECK_LT(frac, 256); - log2 = (int16_t)(((31 - zeros) << 8) - + WebRtcNsx_kLogTableFrac[frac]); + 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;//0; + lmagn[i] = logval; // 0; } } @@ -421,12 +403,12 @@ static void NoiseEstimationC(NoiseSuppressionFixedC* inst, } // update density estimate - if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i]) - < WIDTH_Q8) { + 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], countProd, 15); + tmp16no2 = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(width_factor, + countDiv, 15); inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2; } } // end loop over magnitude spectrum @@ -447,7 +429,7 @@ static void NoiseEstimationC(NoiseSuppressionFixedC* inst, } for (i = 0; i < inst->magnLen; i++) { - noise[i] = (uint32_t)(inst->noiseEstQuantile[i]); // Q(qNoise) + noise[i] = (uint32_t)(inst->noiseEstQuantile[i]); // Q(qNoise) } (*q_noise) = (int16_t)inst->qNoise; } @@ -457,10 +439,12 @@ static void PrepareSpectrumC(NoiseSuppressionFixedC* inst, int16_t* freq_buf) { size_t i = 0, j = 0; 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) + 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) } freq_buf[0] = inst->real[0]; @@ -480,9 +464,8 @@ static void DenormalizeC(NoiseSuppressionFixedC* inst, size_t i = 0; int32_t tmp32 = 0; for (i = 0; i < inst->anaLen; i += 1) { - tmp32 = WEBRTC_SPL_SHIFT_W32((int32_t)in[i], - factor - inst->normData); - inst->real[i] = WebRtcSpl_SatW32ToW16(tmp32); // Q0 + tmp32 = WEBRTC_SPL_SHIFT_W32((int32_t)in[i], factor - inst->normData); + inst->real[i] = WebRtcSpl_SatW32ToW16(tmp32); // Q0 } } @@ -499,24 +482,26 @@ static void SynthesisUpdateC(NoiseSuppressionFixedC* inst, // synthesis for (i = 0; i < inst->anaLen; i++) { tmp16a = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( - inst->window[i], inst->real[i], 14); // Q0, window in Q14 - tmp32 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16a, gain_factor, 13); // Q0 + inst->window[i], inst->real[i], 14); // Q0, window in Q14 + tmp32 = + WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16a, gain_factor, 13); // Q0 // Down shift with rounding - tmp16b = WebRtcSpl_SatW32ToW16(tmp32); // Q0 + tmp16b = WebRtcSpl_SatW32ToW16(tmp32); // Q0 inst->synthesisBuffer[i] = WebRtcSpl_AddSatW16(inst->synthesisBuffer[i], - tmp16b); // Q0 + tmp16b); // Q0 } // read out fully processed segment for (i = 0; i < inst->blockLen10ms; i++) { - out_frame[i] = inst->synthesisBuffer[i]; // Q0 + out_frame[i] = inst->synthesisBuffer[i]; // Q0 } // update synthesis buffer memcpy(inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms, - (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->synthesisBuffer)); - WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer - + inst->anaLen - inst->blockLen10ms, inst->blockLen10ms); + (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->synthesisBuffer)); + WebRtcSpl_ZerosArrayW16( + inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, + inst->blockLen10ms); } // Update analysis buffer for lower band, and window data before FFT. @@ -527,14 +512,14 @@ static void AnalysisUpdateC(NoiseSuppressionFixedC* inst, // For lower band update analysis buffer. memcpy(inst->analysisBuffer, inst->analysisBuffer + inst->blockLen10ms, - (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->analysisBuffer)); + (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->analysisBuffer)); memcpy(inst->analysisBuffer + inst->anaLen - inst->blockLen10ms, new_speech, - inst->blockLen10ms * sizeof(*inst->analysisBuffer)); + inst->blockLen10ms * sizeof(*inst->analysisBuffer)); // Window data before FFT. for (i = 0; i < inst->anaLen; i++) { out[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( - inst->window[i], inst->analysisBuffer[i], 14); // Q0 + inst->window[i], inst->analysisBuffer[i], 14); // Q0 } } @@ -597,14 +582,14 @@ void WebRtcNsx_CalcParametricNoiseEstimate(NoiseSuppressionFixedC* inst, RTC_DCHECK_GE(freq_index, 0); RTC_DCHECK_LT(freq_index, 129); tmp32no2 = (pink_noise_exp_avg * kLogIndex[freq_index]) >> 15; // Q11 - tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 + tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 // Calculate output: 2^tmp32no1 // Output in Q(minNorm-stages) tmp32no1 += (inst->minNorm - inst->stages) << 11; if (tmp32no1 > 0) { int_part = (int16_t)(tmp32no1 >> 11); - frac_part = (int16_t)(tmp32no1 & 0x000007ff); // Q11 + frac_part = (int16_t)(tmp32no1 & 0x000007ff); // Q11 // Piecewise linear approximation of 'b' in // 2^(int_part+frac_part) = 2^int_part * (1 + b) // 'b' is given in Q11 and below stored in frac_part. @@ -628,7 +613,7 @@ void WebRtcNsx_CalcParametricNoiseEstimate(NoiseSuppressionFixedC* inst, int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { int i; - //check for valid pointer + // check for valid pointer if (inst == NULL) { return -1; } @@ -646,7 +631,7 @@ int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { inst->anaLen = 128; inst->stages = 7; inst->window = kBlocks80w128x; - inst->thresholdLogLrt = 131072; //default threshold for LRT feature + inst->thresholdLogLrt = 131072; // default threshold for LRT feature inst->maxLrt = 0x0040000; inst->minLrt = 52429; } else { @@ -654,7 +639,7 @@ int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { inst->anaLen = 256; inst->stages = 8; inst->window = kBlocks160w256x; - inst->thresholdLogLrt = 212644; //default threshold for LRT feature + inst->thresholdLogLrt = 212644; // default threshold for LRT feature inst->maxLrt = 0x0080000; inst->minLrt = 104858; } @@ -678,8 +663,8 @@ int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { // for quantile noise estimation WebRtcSpl_ZerosArrayW16(inst->noiseEstQuantile, HALF_ANAL_BLOCKL); for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) { - inst->noiseEstLogQuantile[i] = 2048; // Q8 - inst->noiseEstDensity[i] = 153; // Q9 + inst->noiseEstLogQuantile[i] = 2048; // Q8 + inst->noiseEstDensity[i] = 153; // Q9 } for (i = 0; i < SIMULT; i++) { inst->noiseEstCounter[i] = (int16_t)(END_STARTUP_LONG * (i + 1)) / SIMULT; @@ -691,40 +676,49 @@ int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { // Set the aggressiveness: default inst->aggrMode = 0; - //initialize variables for new method - inst->priorNonSpeechProb = 8192; // Q14(0.5) prior probability for speech/noise + // initialize variables for new method + inst->priorNonSpeechProb = + 8192; // Q14(0.5) prior probability for speech/noise for (i = 0; i < HALF_ANAL_BLOCKL; i++) { inst->prevMagnU16[i] = 0; - inst->prevNoiseU32[i] = 0; //previous noise-spectrum - inst->logLrtTimeAvgW32[i] = 0; //smooth LR ratio - inst->avgMagnPause[i] = 0; //conservative noise spectrum estimate - inst->initMagnEst[i] = 0; //initial average magnitude spectrum + inst->prevNoiseU32[i] = 0; // previous noise-spectrum + inst->logLrtTimeAvgW32[i] = 0; // smooth LR ratio + inst->avgMagnPause[i] = 0; // conservative noise spectrum estimate + inst->initMagnEst[i] = 0; // initial average magnitude spectrum } - //feature quantities - inst->thresholdSpecDiff = 50; //threshold for difference feature: determined on-line - inst->thresholdSpecFlat = 20480; //threshold for flatness: determined on-line - inst->featureLogLrt = inst->thresholdLogLrt; //average LRT factor (= threshold) - inst->featureSpecFlat = inst->thresholdSpecFlat; //spectral flatness (= threshold) - inst->featureSpecDiff = inst->thresholdSpecDiff; //spectral difference (= threshold) - inst->weightLogLrt = 6; //default weighting par for LRT feature - inst->weightSpecFlat = 0; //default weighting par for spectral flatness feature - inst->weightSpecDiff = 0; //default weighting par for spectral difference feature + // feature quantities + inst->thresholdSpecDiff = + 50; // threshold for difference feature: determined on-line + inst->thresholdSpecFlat = 20480; // threshold for flatness: determined + // on-line + inst->featureLogLrt = + inst->thresholdLogLrt; // average LRT factor (= threshold) + inst->featureSpecFlat = + inst->thresholdSpecFlat; // spectral flatness (= threshold) + inst->featureSpecDiff = + inst->thresholdSpecDiff; // spectral difference (= threshold) + inst->weightLogLrt = 6; // default weighting par for LRT feature + inst->weightSpecFlat = + 0; // default weighting par for spectral flatness feature + inst->weightSpecDiff = + 0; // default weighting par for spectral difference feature - inst->curAvgMagnEnergy = 0; //window time-average of input magnitude spectrum - inst->timeAvgMagnEnergy = 0; //normalization for spectral difference - inst->timeAvgMagnEnergyTmp = 0; //normalization for spectral difference + inst->curAvgMagnEnergy = 0; // window time-average of input magnitude + // spectrum + inst->timeAvgMagnEnergy = 0; // normalization for spectral difference + inst->timeAvgMagnEnergyTmp = 0; // normalization for spectral difference - //histogram quantities: used to estimate/update thresholds for features + // histogram quantities: used to estimate/update thresholds for features WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST); WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST); WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST); - inst->blockIndex = -1; //frame counter + inst->blockIndex = -1; // frame counter - //inst->modelUpdate = 500; //window for update - inst->modelUpdate = (1 << STAT_UPDATES); //window for update - inst->cntThresUpdate = 0; //counter feature thresholds updates + // inst->modelUpdate = 500; //window for update + inst->modelUpdate = (1 << STAT_UPDATES); // window for update + inst->cntThresUpdate = 0; // counter feature thresholds updates inst->sumMagn = 0; inst->magnEnergy = 0; @@ -738,10 +732,10 @@ int32_t WebRtcNsx_InitCore(NoiseSuppressionFixedC* inst, uint32_t fs) { inst->whiteNoiseLevel = 0; inst->pinkNoiseNumerator = 0; inst->pinkNoiseExp = 0; - inst->minNorm = 15; // Start with full scale + inst->minNorm = 15; // Start with full scale inst->zeroInputSignal = 0; - //default mode + // default mode WebRtcNsx_set_policy_core(inst, 0); #ifdef NS_FILEDEBUG @@ -783,22 +777,22 @@ int WebRtcNsx_set_policy_core(NoiseSuppressionFixedC* inst, int mode) { inst->aggrMode = mode; if (mode == 0) { - inst->overdrive = 256; // Q8(1.0) - inst->denoiseBound = 8192; // Q14(0.5) - inst->gainMap = 0; // No gain compensation + inst->overdrive = 256; // Q8(1.0) + inst->denoiseBound = 8192; // Q14(0.5) + inst->gainMap = 0; // No gain compensation } else if (mode == 1) { - inst->overdrive = 256; // Q8(1.0) - inst->denoiseBound = 4096; // Q14(0.25) + inst->overdrive = 256; // Q8(1.0) + inst->denoiseBound = 4096; // Q14(0.25) inst->factor2Table = kFactor2Aggressiveness1; inst->gainMap = 1; } else if (mode == 2) { - inst->overdrive = 282; // ~= Q8(1.1) - inst->denoiseBound = 2048; // Q14(0.125) + inst->overdrive = 282; // ~= Q8(1.1) + inst->denoiseBound = 2048; // Q14(0.125) inst->factor2Table = kFactor2Aggressiveness2; inst->gainMap = 1; } else if (mode == 3) { - inst->overdrive = 320; // Q8(1.25) - inst->denoiseBound = 1475; // ~= Q14(0.09) + inst->overdrive = 320; // Q8(1.25) + inst->denoiseBound = 1475; // ~= Q14(0.09) inst->factor2Table = kFactor2Aggressiveness3; inst->gainMap = 1; } @@ -808,8 +802,9 @@ int WebRtcNsx_set_policy_core(NoiseSuppressionFixedC* inst, int mode) { // Extract thresholds for feature parameters // histograms are computed over some window_size (given by window_pars) // thresholds and weights are extracted every window -// flag 0 means update histogram only, flag 1 means compute the thresholds/weights -// threshold and weights are returned in: inst->priorModelPars +// flag 0 means update histogram only, flag 1 means compute the +// thresholds/weights threshold and weights are returned in: +// inst->priorModelPars void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, int flag) { uint32_t tmpU32; @@ -830,11 +825,11 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, int weightPeak1SpecFlat, weightPeak2SpecFlat; int weightPeak1SpecDiff, weightPeak2SpecDiff; - //update histograms + // update histograms if (!flag) { // LRT - // Type casting to UWord32 is safe since negative values will not be wrapped to larger - // values than HIST_PAR_EST + // Type casting to UWord32 is safe since negative values will not be wrapped + // to larger values than HIST_PAR_EST histIndex = (uint32_t)(inst->featureLogLrt); if (histIndex < HIST_PAR_EST) { inst->histLrt[histIndex]++; @@ -852,7 +847,7 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, // If timeAvgMagnEnergy == 0 we have no normalizing statistics and // therefore can't update the histogram histIndex = ((inst->featureSpecDiff * 5) >> inst->stages) / - inst->timeAvgMagnEnergy; + inst->timeAvgMagnEnergy; } if (histIndex < HIST_PAR_EST) { inst->histSpecDiff[histIndex]++; @@ -862,7 +857,7 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, // extract parameters for speech/noise probability if (flag) { useFeatureSpecDiff = 1; - //for LRT feature: + // for LRT feature: // compute the average over inst->featureExtractionParams.rangeAvgHistLrt avgHistLrtFX = 0; avgSquareHistLrtFX = 0; @@ -881,30 +876,28 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, avgHistLrtComplFX += tmp32; avgSquareHistLrtFX += tmp32 * j; } - fluctLrtFX = avgSquareHistLrtFX * numHistLrt - - avgHistLrtFX * avgHistLrtComplFX; + fluctLrtFX = + avgSquareHistLrtFX * numHistLrt - avgHistLrtFX * avgHistLrtComplFX; thresFluctLrtFX = THRES_FLUCT_LRT * numHistLrt; // get threshold for LRT feature: tmpU32 = (FACTOR_1_LRT_DIFF * (uint32_t)avgHistLrtFX); if ((fluctLrtFX < thresFluctLrtFX) || (numHistLrt == 0) || (tmpU32 > (uint32_t)(100 * numHistLrt))) { - //very low fluctuation, so likely noise + // very low fluctuation, so likely noise inst->thresholdLogLrt = inst->maxLrt; } else { - tmp32 = (int32_t)((tmpU32 << (9 + inst->stages)) / numHistLrt / - 25); + tmp32 = (int32_t)((tmpU32 << (9 + inst->stages)) / numHistLrt / 25); // check if value is within min/max range - inst->thresholdLogLrt = WEBRTC_SPL_SAT(inst->maxLrt, - tmp32, - inst->minLrt); + inst->thresholdLogLrt = WEBRTC_SPL_SAT(inst->maxLrt, tmp32, inst->minLrt); } if (fluctLrtFX < thresFluctLrtFX) { - // Do not use difference feature if fluctuation of LRT feature is very low: - // most likely just noise state + // Do not use difference feature if fluctuation of LRT feature is very + // low: most likely just noise state useFeatureSpecDiff = 0; } - // for spectral flatness and spectral difference: compute the main peaks of histogram + // for spectral flatness and spectral difference: compute the main peaks of + // histogram maxPeak1 = 0; maxPeak2 = 0; posPeak1SpecFlatFX = 0; @@ -934,24 +927,26 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, // for spectral flatness feature useFeatureSpecFlat = 1; // merge the two peaks if they are close - if ((posPeak1SpecFlatFX - posPeak2SpecFlatFX < LIM_PEAK_SPACE_FLAT_DIFF) - && (weightPeak2SpecFlat * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecFlat)) { + if ((posPeak1SpecFlatFX - posPeak2SpecFlatFX < LIM_PEAK_SPACE_FLAT_DIFF) && + (weightPeak2SpecFlat * LIM_PEAK_WEIGHT_FLAT_DIFF > + weightPeak1SpecFlat)) { weightPeak1SpecFlat += weightPeak2SpecFlat; posPeak1SpecFlatFX = (posPeak1SpecFlatFX + posPeak2SpecFlatFX) >> 1; } - //reject if weight of peaks is not large enough, or peak value too small - if (weightPeak1SpecFlat < THRES_WEIGHT_FLAT_DIFF || posPeak1SpecFlatFX - < THRES_PEAK_FLAT) { + // reject if weight of peaks is not large enough, or peak value too small + if (weightPeak1SpecFlat < THRES_WEIGHT_FLAT_DIFF || + posPeak1SpecFlatFX < THRES_PEAK_FLAT) { useFeatureSpecFlat = 0; - } else { // if selected, get the threshold + } else { // if selected, get the threshold // compute the threshold and check if value is within min/max range - inst->thresholdSpecFlat = WEBRTC_SPL_SAT(MAX_FLAT_Q10, FACTOR_2_FLAT_Q10 - * posPeak1SpecFlatFX, MIN_FLAT_Q10); //Q10 + inst->thresholdSpecFlat = + WEBRTC_SPL_SAT(MAX_FLAT_Q10, FACTOR_2_FLAT_Q10 * posPeak1SpecFlatFX, + MIN_FLAT_Q10); // Q10 } // done with flatness feature if (useFeatureSpecDiff) { - //compute two peaks for spectral difference + // compute two peaks for spectral difference maxPeak1 = 0; maxPeak2 = 0; posPeak1SpecDiffFX = 0; @@ -978,15 +973,18 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, } // merge the two peaks if they are close - if ((posPeak1SpecDiffFX - posPeak2SpecDiffFX < LIM_PEAK_SPACE_FLAT_DIFF) - && (weightPeak2SpecDiff * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecDiff)) { + if ((posPeak1SpecDiffFX - posPeak2SpecDiffFX < + LIM_PEAK_SPACE_FLAT_DIFF) && + (weightPeak2SpecDiff * LIM_PEAK_WEIGHT_FLAT_DIFF > + weightPeak1SpecDiff)) { weightPeak1SpecDiff += weightPeak2SpecDiff; posPeak1SpecDiffFX = (posPeak1SpecDiffFX + posPeak2SpecDiffFX) >> 1; } // get the threshold value and check if value is within min/max range - inst->thresholdSpecDiff = WEBRTC_SPL_SAT(MAX_DIFF, FACTOR_1_LRT_DIFF - * posPeak1SpecDiffFX, MIN_DIFF); //5x bigger - //reject if weight of peaks is not large enough + inst->thresholdSpecDiff = + WEBRTC_SPL_SAT(MAX_DIFF, FACTOR_1_LRT_DIFF * posPeak1SpecDiffFX, + MIN_DIFF); // 5x bigger + // reject if weight of peaks is not large enough if (weightPeak1SpecDiff < THRES_WEIGHT_FLAT_DIFF) { useFeatureSpecDiff = 0; } @@ -1007,7 +1005,6 @@ void WebRtcNsx_FeatureParameterExtraction(NoiseSuppressionFixedC* inst, } // end of flag == 1 } - // Compute spectral flatness on input spectrum // magn is the magnitude spectrum // spectral flatness is returned in inst->featureSpecFlat @@ -1025,42 +1022,47 @@ void WebRtcNsx_ComputeSpectralFlatness(NoiseSuppressionFixedC* inst, // for flatness avgSpectralFlatnessNum = 0; - avgSpectralFlatnessDen = inst->sumMagn - (uint32_t)magn[0]; // Q(normData-stages) + avgSpectralFlatnessDen = + inst->sumMagn - (uint32_t)magn[0]; // Q(normData-stages) - // compute log of ratio of the geometric to arithmetic mean: check for log(0) case - // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) + // compute log of ratio of the geometric to arithmetic mean: check for log(0) + // case flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) // = exp( sum(log(magn[i]))/N ) * N / sum(magn[i]) - // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [This is used] + // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) + // [This is used] for (i = 1; i < inst->magnLen; i++) { - // First bin is excluded from spectrum measures. Number of bins is now a power of 2 + // First bin is excluded from spectrum measures. Number of bins is now a + // power of 2 if (magn[i]) { zeros = WebRtcSpl_NormU32((uint32_t)magn[i]); - frac = (int16_t)(((uint32_t)((uint32_t)(magn[i]) << zeros) - & 0x7FFFFFFF) >> 23); + frac = (int16_t)( + ((uint32_t)((uint32_t)(magn[i]) << zeros) & 0x7FFFFFFF) >> 23); // log2(magn(i)) RTC_DCHECK_LT(frac, 256); - tmpU32 = (uint32_t)(((31 - zeros) << 8) - + WebRtcNsx_kLogTableFrac[frac]); // Q8 - avgSpectralFlatnessNum += tmpU32; // Q8 + tmpU32 = (uint32_t)(((31 - zeros) << 8) + + WebRtcNsx_kLogTableFrac[frac]); // Q8 + avgSpectralFlatnessNum += tmpU32; // Q8 } else { - //if at least one frequency component is zero, treat separately - tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14); // Q24 - inst->featureSpecFlat -= tmpU32 >> 14; // Q10 + // if at least one frequency component is zero, treat separately + tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, + SPECT_FLAT_TAVG_Q14); // Q24 + inst->featureSpecFlat -= tmpU32 >> 14; // Q10 return; } } - //ratio and inverse log: check for case of log(0) + // ratio and inverse log: check for case of log(0) zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen); frac = (int16_t)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23); // log2(avgSpectralFlatnessDen) RTC_DCHECK_LT(frac, 256); - tmp32 = (int32_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); // Q8 + tmp32 = (int32_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); // Q8 logCurSpectralFlatness = (int32_t)avgSpectralFlatnessNum; - logCurSpectralFlatness += ((int32_t)(inst->stages - 1) << (inst->stages + 7)); // Q(8+stages-1) + logCurSpectralFlatness += + ((int32_t)(inst->stages - 1) << (inst->stages + 7)); // Q(8+stages-1) logCurSpectralFlatness -= (tmp32 << (inst->stages - 1)); logCurSpectralFlatness <<= (10 - inst->stages); // Q17 - tmp32 = (int32_t)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) - & 0x0001FFFF)); //Q17 + tmp32 = (int32_t)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) & + 0x0001FFFF)); // Q17 intPart = 7 - (logCurSpectralFlatness >> 17); // Add 7 for output in Q10. if (intPart > 0) { currentSpectralFlatness = tmp32 >> intPart; @@ -1068,22 +1070,22 @@ void WebRtcNsx_ComputeSpectralFlatness(NoiseSuppressionFixedC* inst, currentSpectralFlatness = tmp32 << -intPart; } - //time average update of spectral flatness feature - tmp32 = currentSpectralFlatness - (int32_t)inst->featureSpecFlat; // Q10 - tmp32 *= SPECT_FLAT_TAVG_Q14; // Q24 - inst->featureSpecFlat += tmp32 >> 14; // Q10 + // time average update of spectral flatness feature + tmp32 = currentSpectralFlatness - (int32_t)inst->featureSpecFlat; // Q10 + tmp32 *= SPECT_FLAT_TAVG_Q14; // Q24 + inst->featureSpecFlat += tmp32 >> 14; // Q10 // done with flatness feature } - -// Compute the difference measure between input spectrum and a template/learned noise spectrum -// magn_tmp is the input spectrum -// the reference/template spectrum is inst->magn_avg_pause[i] -// returns (normalized) spectral difference in inst->featureSpecDiff +// Compute the difference measure between input spectrum and a template/learned +// noise spectrum magn_tmp is the input spectrum the reference/template spectrum +// is inst->magn_avg_pause[i] returns (normalized) spectral difference in +// inst->featureSpecDiff void WebRtcNsx_ComputeSpectralDifference(NoiseSuppressionFixedC* inst, uint16_t* magnIn) { // This is to be calculated: - // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause) + // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / + // var(magnAvgPause) uint32_t tmpU32no1, tmpU32no2; uint32_t varMagnUFX, varPauseUFX, avgDiffNormMagnUFX; @@ -1099,11 +1101,11 @@ void WebRtcNsx_ComputeSpectralDifference(NoiseSuppressionFixedC* inst, avgPauseFX = 0; maxPause = 0; - minPause = inst->avgMagnPause[0]; // Q(prevQMagn) + minPause = inst->avgMagnPause[0]; // Q(prevQMagn) // compute average quantities for (i = 0; i < inst->magnLen; i++) { // Compute mean of magn_pause - avgPauseFX += inst->avgMagnPause[i]; // in Q(prevQMagn) + avgPauseFX += inst->avgMagnPause[i]; // in Q(prevQMagn) maxPause = WEBRTC_SPL_MAX(maxPause, inst->avgMagnPause[i]); minPause = WEBRTC_SPL_MIN(minPause, inst->avgMagnPause[i]); } @@ -1123,30 +1125,33 @@ void WebRtcNsx_ComputeSpectralDifference(NoiseSuppressionFixedC* inst, tmp16no1 = (int16_t)((int32_t)magnIn[i] - avgMagnFX); tmp32no2 = inst->avgMagnPause[i] - avgPauseFX; varMagnUFX += (uint32_t)(tmp16no1 * tmp16no1); // Q(2*qMagn) - tmp32no1 = tmp32no2 * tmp16no1; // Q(prevQMagn+qMagn) - covMagnPauseFX += tmp32no1; // Q(prevQMagn+qMagn) - tmp32no1 = tmp32no2 >> nShifts; // Q(prevQMagn-minPause). - varPauseUFX += tmp32no1 * tmp32no1; // Q(2*(prevQMagn-minPause)) + tmp32no1 = tmp32no2 * tmp16no1; // Q(prevQMagn+qMagn) + covMagnPauseFX += tmp32no1; // Q(prevQMagn+qMagn) + tmp32no1 = tmp32no2 >> nShifts; // Q(prevQMagn-minPause). + varPauseUFX += tmp32no1 * tmp32no1; // Q(2*(prevQMagn-minPause)) } - //update of average magnitude spectrum: Q(-2*stages) and averaging replaced by shifts + // update of average magnitude spectrum: Q(-2*stages) and averaging replaced + // by shifts inst->curAvgMagnEnergy += inst->magnEnergy >> (2 * inst->normData + inst->stages - 1); - avgDiffNormMagnUFX = varMagnUFX; // Q(2*qMagn) + avgDiffNormMagnUFX = varMagnUFX; // Q(2*qMagn) if ((varPauseUFX) && (covMagnPauseFX)) { - tmpU32no1 = (uint32_t)WEBRTC_SPL_ABS_W32(covMagnPauseFX); // Q(prevQMagn+qMagn) + tmpU32no1 = + (uint32_t)WEBRTC_SPL_ABS_W32(covMagnPauseFX); // Q(prevQMagn+qMagn) norm32 = WebRtcSpl_NormU32(tmpU32no1) - 16; if (norm32 > 0) { tmpU32no1 <<= norm32; // Q(prevQMagn+qMagn+norm32) } else { tmpU32no1 >>= -norm32; // Q(prevQMagn+qMagn+norm32) } - tmpU32no2 = WEBRTC_SPL_UMUL(tmpU32no1, tmpU32no1); // Q(2*(prevQMagn+qMagn-norm32)) + tmpU32no2 = + WEBRTC_SPL_UMUL(tmpU32no1, tmpU32no1); // Q(2*(prevQMagn+qMagn-norm32)) nShifts += norm32; nShifts <<= 1; if (nShifts < 0) { - varPauseUFX >>= (-nShifts); // Q(2*(qMagn+norm32+minPause)) + varPauseUFX >>= (-nShifts); // Q(2*(qMagn+norm32+minPause)) nShifts = 0; } if (varPauseUFX > 0) { @@ -1160,16 +1165,16 @@ void WebRtcNsx_ComputeSpectralDifference(NoiseSuppressionFixedC* inst, avgDiffNormMagnUFX = 0; } } - //normalize and compute time average update of difference feature + // normalize and compute time average update of difference feature tmpU32no1 = avgDiffNormMagnUFX >> (2 * inst->normData); if (inst->featureSpecDiff > tmpU32no1) { tmpU32no2 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecDiff - tmpU32no1, - SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) - inst->featureSpecDiff -= tmpU32no2 >> 8; // Q(-2*stages) + SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) + inst->featureSpecDiff -= tmpU32no2 >> 8; // Q(-2*stages) } else { tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no1 - inst->featureSpecDiff, - SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) - inst->featureSpecDiff += tmpU32no2 >> 8; // Q(-2*stages) + SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) + inst->featureSpecDiff += tmpU32no2 >> 8; // Q(-2*stages) } } @@ -1179,20 +1184,20 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, uint16_t* magnU16) { uint32_t tmpU32no1; - int32_t tmp_1_w32 = 0; - int32_t tmp_2_w32 = 0; - int32_t sum_log_magn = 0; - int32_t sum_log_i_log_magn = 0; + int32_t tmp_1_w32 = 0; + int32_t tmp_2_w32 = 0; + int32_t sum_log_magn = 0; + int32_t sum_log_i_log_magn = 0; - uint16_t sum_log_magn_u16 = 0; - uint16_t tmp_u16 = 0; + uint16_t sum_log_magn_u16 = 0; + uint16_t tmp_u16 = 0; - int16_t sum_log_i = 0; - int16_t sum_log_i_square = 0; - int16_t frac = 0; - int16_t log2 = 0; - int16_t matrix_determinant = 0; - int16_t maxWinData; + int16_t sum_log_i = 0; + int16_t sum_log_i_square = 0; + int16_t frac = 0; + int16_t log2 = 0; + int16_t matrix_determinant = 0; + int16_t maxWinData; size_t i, j; int zeros; @@ -1204,8 +1209,8 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, int16_t realImag_buff[ANAL_BLOCKL_MAX * 2 + 16]; // Align the structures to 32-byte boundary for the FFT function. - int16_t* winData = (int16_t*) (((uintptr_t)winData_buff + 31) & ~31); - int16_t* realImag = (int16_t*) (((uintptr_t) realImag_buff + 31) & ~31); + int16_t* winData = (int16_t*)(((uintptr_t)winData_buff + 31) & ~31); + int16_t* realImag = (int16_t*)(((uintptr_t)realImag_buff + 31) & ~31); // Update analysis buffer for lower band, and window data before FFT. WebRtcNsx_AnalysisUpdate(inst, winData, speechFrame); @@ -1227,29 +1232,33 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, // Determine the net normalization in the frequency domain net_norm = inst->stages - inst->normData; - // Track lowest normalization factor and use it to prevent wrap around in shifting + // Track lowest normalization factor and use it to prevent wrap around in + // shifting right_shifts_in_magnU16 = inst->normData - inst->minNorm; right_shifts_in_initMagnEst = WEBRTC_SPL_MAX(-right_shifts_in_magnU16, 0); inst->minNorm -= right_shifts_in_initMagnEst; right_shifts_in_magnU16 = WEBRTC_SPL_MAX(right_shifts_in_magnU16, 0); - // create realImag as winData interleaved with zeros (= imag. part), normalize it + // create realImag as winData interleaved with zeros (= imag. part), normalize + // it WebRtcNsx_NormalizeRealBuffer(inst, winData, realImag); // FFT output will be in winData[]. WebRtcSpl_RealForwardFFT(inst->real_fft, realImag, winData); - inst->imag[0] = 0; // Q(normData-stages) + inst->imag[0] = 0; // Q(normData-stages) inst->imag[inst->anaLen2] = 0; - inst->real[0] = winData[0]; // Q(normData-stages) + inst->real[0] = winData[0]; // Q(normData-stages) inst->real[inst->anaLen2] = winData[inst->anaLen]; // Q(2*(normData-stages)) inst->magnEnergy = (uint32_t)(inst->real[0] * inst->real[0]); - inst->magnEnergy += (uint32_t)(inst->real[inst->anaLen2] * - inst->real[inst->anaLen2]); - magnU16[0] = (uint16_t)WEBRTC_SPL_ABS_W16(inst->real[0]); // Q(normData-stages) - magnU16[inst->anaLen2] = (uint16_t)WEBRTC_SPL_ABS_W16(inst->real[inst->anaLen2]); - inst->sumMagn = (uint32_t)magnU16[0]; // Q(normData-stages) + inst->magnEnergy += + (uint32_t)(inst->real[inst->anaLen2] * inst->real[inst->anaLen2]); + magnU16[0] = + (uint16_t)WEBRTC_SPL_ABS_W16(inst->real[0]); // Q(normData-stages) + magnU16[inst->anaLen2] = + (uint16_t)WEBRTC_SPL_ABS_W16(inst->real[inst->anaLen2]); + inst->sumMagn = (uint32_t)magnU16[0]; // Q(normData-stages) inst->sumMagn += (uint32_t)magnU16[inst->anaLen2]; if (inst->blockIndex >= END_STARTUP_SHORT) { @@ -1260,10 +1269,11 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, // energy in Q(2*(normData-stages)) tmpU32no1 = (uint32_t)(winData[j] * winData[j]); tmpU32no1 += (uint32_t)(winData[j + 1] * winData[j + 1]); - inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) + inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) - magnU16[i] = (uint16_t)WebRtcSpl_SqrtFloor(tmpU32no1); // Q(normData-stages) - inst->sumMagn += (uint32_t)magnU16[i]; // Q(normData-stages) + magnU16[i] = + (uint16_t)WebRtcSpl_SqrtFloor(tmpU32no1); // Q(normData-stages) + inst->sumMagn += (uint32_t)magnU16[i]; // Q(normData-stages) } } else { // @@ -1283,14 +1293,15 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, if (magnU16[inst->anaLen2]) { // Calculate log2(magnU16[inst->anaLen2]) zeros = WebRtcSpl_NormU32((uint32_t)magnU16[inst->anaLen2]); - frac = (int16_t)((((uint32_t)magnU16[inst->anaLen2] << zeros) & - 0x7FFFFFFF) >> 23); // Q8 + frac = (int16_t)( + (((uint32_t)magnU16[inst->anaLen2] << zeros) & 0x7FFFFFFF) >> + 23); // Q8 // log2(magnU16(i)) in Q8 RTC_DCHECK_LT(frac, 256); log2 = (int16_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); } - sum_log_magn = (int32_t)log2; // Q8 + sum_log_magn = (int32_t)log2; // Q8 // sum_log_i_log_magn in Q17 sum_log_i_log_magn = (kLogIndex[inst->anaLen2] * log2) >> 3; @@ -1301,10 +1312,11 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, // energy in Q(2*(normData-stages)) tmpU32no1 = (uint32_t)(winData[j] * winData[j]); tmpU32no1 += (uint32_t)(winData[j + 1] * winData[j + 1]); - inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) + inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) - magnU16[i] = (uint16_t)WebRtcSpl_SqrtFloor(tmpU32no1); // Q(normData-stages) - inst->sumMagn += (uint32_t)magnU16[i]; // Q(normData-stages) + magnU16[i] = + (uint16_t)WebRtcSpl_SqrtFloor(tmpU32no1); // Q(normData-stages) + inst->sumMagn += (uint32_t)magnU16[i]; // Q(normData-stages) // Switch initMagnEst to Q(minNorm-stages) inst->initMagnEst[i] >>= right_shifts_in_initMagnEst; @@ -1313,25 +1325,25 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, inst->initMagnEst[i] += magnU16[i] >> right_shifts_in_magnU16; if (i >= kStartBand) { - // For pink noise estimation. Collect data neglecting lower frequency band + // For pink noise estimation. Collect data neglecting lower frequency + // band log2 = 0; if (magnU16[i]) { zeros = WebRtcSpl_NormU32((uint32_t)magnU16[i]); - frac = (int16_t)((((uint32_t)magnU16[i] << zeros) & - 0x7FFFFFFF) >> 23); + frac = + (int16_t)((((uint32_t)magnU16[i] << zeros) & 0x7FFFFFFF) >> 23); // log2(magnU16(i)) in Q8 RTC_DCHECK_LT(frac, 256); - log2 = (int16_t)(((31 - zeros) << 8) - + WebRtcNsx_kLogTableFrac[frac]); + log2 = (int16_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); } - sum_log_magn += (int32_t)log2; // Q8 + sum_log_magn += (int32_t)log2; // Q8 // sum_log_i_log_magn in Q17 sum_log_i_log_magn += (kLogIndex[i] * log2) >> 3; } } // - //compute simplified noise model during startup + // compute simplified noise model during startup // // Estimate White noise @@ -1346,18 +1358,20 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, // Replacing division above with 'stages' shifts // Shift to same Q-domain as whiteNoiseLevel tmpU32no1 >>= right_shifts_in_magnU16; - // This operation is safe from wrap around as long as END_STARTUP_SHORT < 128 + // This operation is safe from wrap around as long as END_STARTUP_SHORT < + // 128 RTC_DCHECK_LT(END_STARTUP_SHORT, 128); - inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) + inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) // Estimate Pink noise parameters // Denominator used in both parameter estimates. - // The value is only dependent on the size of the frequency band (kStartBand) - // and to reduce computational complexity stored in a table (kDeterminantEstMatrix[]) + // The value is only dependent on the size of the frequency band + // (kStartBand) and to reduce computational complexity stored in a table + // (kDeterminantEstMatrix[]) RTC_DCHECK_LT(kStartBand, 66); - matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 - sum_log_i = kSumLogIndex[kStartBand]; // Q5 - sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 + matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 + sum_log_i = kSumLogIndex[kStartBand]; // Q5 + sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 if (inst->fs == 8000) { // Adjust values to shorter blocks in narrow band. tmp_1_w32 = (int32_t)matrix_determinant; @@ -1366,8 +1380,8 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, tmp_1_w32 -= (int32_t)sum_log_i_square << 4; tmp_1_w32 -= ((inst->magnLen - kStartBand) * kSumSquareLogIndex[65]) >> 2; matrix_determinant = (int16_t)tmp_1_w32; - sum_log_i -= kSumLogIndex[65]; // Q5 - sum_log_i_square -= kSumSquareLogIndex[65]; // Q2 + sum_log_i -= kSumLogIndex[65]; // Q5 + sum_log_i_square -= kSumSquareLogIndex[65]; // Q2 } // Necessary number of shifts to fit sum_log_magn in a word16 @@ -1375,12 +1389,13 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, if (zeros < 0) { zeros = 0; } - tmp_1_w32 = sum_log_magn << 1; // Q9 + tmp_1_w32 = sum_log_magn << 1; // Q9 sum_log_magn_u16 = (uint16_t)(tmp_1_w32 >> zeros); // Q(9-zeros). // Calculate and update pinkNoiseNumerator. Result in Q11. - tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i_square, sum_log_magn_u16); // Q(11-zeros) - tmpU32no1 = sum_log_i_log_magn >> 12; // Q5 + tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i_square, + sum_log_magn_u16); // Q(11-zeros) + tmpU32no1 = sum_log_i_log_magn >> 12; // Q5 // Shift the largest value of sum_log_i and tmp32no3 before multiplication tmp_u16 = ((uint16_t)sum_log_i << 1); // Q6 @@ -1389,25 +1404,27 @@ void WebRtcNsx_DataAnalysis(NoiseSuppressionFixedC* inst, } else { tmpU32no1 >>= zeros; } - tmp_2_w32 -= (int32_t)WEBRTC_SPL_UMUL_32_16(tmpU32no1, tmp_u16); // Q(11-zeros) - matrix_determinant >>= zeros; // Q(-zeros) - tmp_2_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q11 - tmp_2_w32 += (int32_t)net_norm << 11; // Q11 + tmp_2_w32 -= + (int32_t)WEBRTC_SPL_UMUL_32_16(tmpU32no1, tmp_u16); // Q(11-zeros) + matrix_determinant >>= zeros; // Q(-zeros) + tmp_2_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q11 + tmp_2_w32 += (int32_t)net_norm << 11; // Q11 if (tmp_2_w32 < 0) { tmp_2_w32 = 0; } - inst->pinkNoiseNumerator += tmp_2_w32; // Q11 + inst->pinkNoiseNumerator += tmp_2_w32; // Q11 // Calculate and update pinkNoiseExp. Result in Q14. - tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i, sum_log_magn_u16); // Q(14-zeros) + tmp_2_w32 = + WEBRTC_SPL_MUL_16_U16(sum_log_i, sum_log_magn_u16); // Q(14-zeros) tmp_1_w32 = sum_log_i_log_magn >> (3 + zeros); tmp_1_w32 *= inst->magnLen - kStartBand; - tmp_2_w32 -= tmp_1_w32; // Q(14-zeros) + tmp_2_w32 -= tmp_1_w32; // Q(14-zeros) if (tmp_2_w32 > 0) { - // If the exponential parameter is negative force it to zero, which means a - // flat spectrum. - tmp_1_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q14 - inst->pinkNoiseExp += WEBRTC_SPL_SAT(16384, tmp_1_w32, 0); // Q14 + // If the exponential parameter is negative force it to zero, which means + // a flat spectrum. + tmp_1_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q14 + inst->pinkNoiseExp += WEBRTC_SPL_SAT(16384, tmp_1_w32, 0); // Q14 } } } @@ -1419,8 +1436,8 @@ void WebRtcNsx_DataSynthesis(NoiseSuppressionFixedC* inst, short* outFrame) { int16_t rfft_out_buff[ANAL_BLOCKL_MAX * 2 + 16]; // Align the structures to 32-byte boundary for the FFT function. - int16_t* realImag = (int16_t*) (((uintptr_t)realImag_buff + 31) & ~31); - int16_t* rfft_out = (int16_t*) (((uintptr_t) rfft_out_buff + 31) & ~31); + int16_t* realImag = (int16_t*)(((uintptr_t)realImag_buff + 31) & ~31); + int16_t* rfft_out = (int16_t*)(((uintptr_t)rfft_out_buff + 31) & ~31); int16_t tmp16no1, tmp16no2; int16_t energyRatio; @@ -1434,13 +1451,15 @@ void WebRtcNsx_DataSynthesis(NoiseSuppressionFixedC* inst, short* outFrame) { // synthesize the special case of zero input // read out fully processed segment for (i = 0; i < inst->blockLen10ms; i++) { - outFrame[i] = inst->synthesisBuffer[i]; // Q0 + outFrame[i] = inst->synthesisBuffer[i]; // Q0 } // update synthesis buffer - memcpy(inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms, + memcpy( + inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms, (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->synthesisBuffer)); - WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, - inst->blockLen10ms); + WebRtcSpl_ZerosArrayW16( + inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, + inst->blockLen10ms); return; } @@ -1452,16 +1471,15 @@ void WebRtcNsx_DataSynthesis(NoiseSuppressionFixedC* inst, short* outFrame) { WebRtcNsx_Denormalize(inst, rfft_out, outCIFFT); - //scale factor: only do it after END_STARTUP_LONG time - gainFactor = 8192; // 8192 = Q13(1.0) - if (inst->gainMap == 1 && - inst->blockIndex > END_STARTUP_LONG && + // scale factor: only do it after END_STARTUP_LONG time + gainFactor = 8192; // 8192 = Q13(1.0) + if (inst->gainMap == 1 && inst->blockIndex > END_STARTUP_LONG && inst->energyIn > 0) { // Q(-scaleEnergyOut) energyOut = WebRtcSpl_Energy(inst->real, inst->anaLen, &scaleEnergyOut); if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000)) { - energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut - - inst->scaleEnergyIn); + energyOut = WEBRTC_SPL_SHIFT_W32( + energyOut, 8 + scaleEnergyOut - inst->scaleEnergyIn); } else { // |energyIn| is currently in Q(|scaleEnergyIn|), but to later on end up // with an |energyRatio| in Q8 we need to change the Q-domain to @@ -1476,26 +1494,28 @@ void WebRtcNsx_DataSynthesis(NoiseSuppressionFixedC* inst, short* outFrame) { // all done in lookup tables now RTC_DCHECK_LT(energyRatio, 257); - gainFactor1 = kFactor1Table[energyRatio]; // Q8 - gainFactor2 = inst->factor2Table[energyRatio]; // Q8 + gainFactor1 = kFactor1Table[energyRatio]; // Q8 + gainFactor2 = inst->factor2Table[energyRatio]; // Q8 - //combine both scales with speech/noise prob: note prior (priorSpeechProb) is not frequency dependent + // combine both scales with speech/noise prob: note prior (priorSpeechProb) + // is not frequency dependent - // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*factor2; // original code + // factor = inst->priorSpeechProb*factor1 + + // (1.0-inst->priorSpeechProb)*factor2; // original code tmp16no1 = (int16_t)(((16384 - inst->priorNonSpeechProb) * gainFactor1) >> - 14); // in Q13, where 16384 = Q14(1.0) + 14); // in Q13, where 16384 = Q14(1.0) tmp16no2 = (int16_t)((inst->priorNonSpeechProb * gainFactor2) >> 14); - gainFactor = tmp16no1 + tmp16no2; // Q13 - } // out of flag_gain_map==1 + gainFactor = tmp16no1 + tmp16no2; // Q13 + } // out of flag_gain_map==1 // Synthesis, read out fully processed segment, and update synthesis buffer. WebRtcNsx_SynthesisUpdate(inst, outFrame, gainFactor); } void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, - const short* const* speechFrame, + const int16_t* const* speechFrame, int num_bands, - short* const* outFrame) { + int16_t* const* outFrame) { // main routine for noise suppression uint32_t tmpU32no1, tmpU32no2, tmpU32no3; @@ -1543,8 +1563,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, RTC_DCHECK_EQ(inst->magnLen, inst->anaLen2 + 1); #ifdef NS_FILEDEBUG - if (fwrite(spframe, sizeof(short), - inst->blockLen10ms, inst->infile) != inst->blockLen10ms) { + if (fwrite(spframe, sizeof(short), inst->blockLen10ms, inst->infile) != + inst->blockLen10ms) { RTC_NOTREACHED(); } #endif @@ -1553,8 +1573,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, RTC_DCHECK_EQ(1, inst->initFlag); RTC_DCHECK_LE(num_bands - 1, NUM_HIGH_BANDS_MAX); - const short* const* speechFrameHB = NULL; - short* const* outFrameHB = NULL; + const int16_t* const* speechFrameHB = NULL; + int16_t* const* outFrameHB = NULL; size_t num_high_bands = 0; if (num_bands > 1) { speechFrameHB = &speechFrame[1]; @@ -1563,7 +1583,7 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, } // Store speechFrame and transform to frequency domain - WebRtcNsx_DataAnalysis(inst, (short*)speechFrame[0], magnU16); + WebRtcNsx_DataAnalysis(inst, (int16_t*)speechFrame[0], magnU16); if (inst->zeroInputSignal) { WebRtcNsx_DataSynthesis(inst, outFrame[0]); @@ -1574,11 +1594,11 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, for (i = 0; i < num_high_bands; ++i) { int block_shift = inst->anaLen - inst->blockLen10ms; memcpy(inst->dataBufHBFX[i], inst->dataBufHBFX[i] + inst->blockLen10ms, - block_shift * sizeof(*inst->dataBufHBFX[i])); + block_shift * sizeof(*inst->dataBufHBFX[i])); memcpy(inst->dataBufHBFX[i] + block_shift, speechFrameHB[i], - inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); + inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); for (j = 0; j < inst->blockLen10ms; j++) { - outFrameHB[i][j] = inst->dataBufHBFX[i][j]; // Q0 + outFrameHB[i][j] = inst->dataBufHBFX[i][j]; // Q0 } } } // end of H band gain computation @@ -1598,7 +1618,7 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // quantile noise estimate WebRtcNsx_NoiseEstimation(inst, magnU16, noiseU32, &qNoise); - //noise estimate from previous frame + // noise estimate from previous frame for (i = 0; i < inst->magnLen; i++) { prevNoiseU16[i] = (uint16_t)(inst->prevNoiseU32[i] >> 11); // Q(prevQNoise) } @@ -1607,37 +1627,36 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // Noise Q-domain to be used later; see description at end of section. q_domain_to_use = WEBRTC_SPL_MIN((int)qNoise, inst->minNorm - inst->stages); - // Calculate frequency independent parts in parametric noise estimate and calculate - // the estimate for the lower frequency band (same values for all frequency bins) + // Calculate frequency independent parts in parametric noise estimate and + // calculate the estimate for the lower frequency band (same values for all + // frequency bins) if (inst->pinkNoiseExp) { - pink_noise_exp_avg = (int16_t)WebRtcSpl_DivW32W16(inst->pinkNoiseExp, - (int16_t)(inst->blockIndex + 1)); // Q14 - pink_noise_num_avg = WebRtcSpl_DivW32W16(inst->pinkNoiseNumerator, - (int16_t)(inst->blockIndex + 1)); // Q11 - WebRtcNsx_CalcParametricNoiseEstimate(inst, - pink_noise_exp_avg, - pink_noise_num_avg, - kStartBand, - &noise_estimate, - &noise_estimate_avg); + pink_noise_exp_avg = + (int16_t)WebRtcSpl_DivW32W16(inst->pinkNoiseExp, + (int16_t)(inst->blockIndex + 1)); // Q14 + pink_noise_num_avg = + WebRtcSpl_DivW32W16(inst->pinkNoiseNumerator, + (int16_t)(inst->blockIndex + 1)); // Q11 + WebRtcNsx_CalcParametricNoiseEstimate( + inst, pink_noise_exp_avg, pink_noise_num_avg, kStartBand, + &noise_estimate, &noise_estimate_avg); } else { // Use white noise estimate if we have poor pink noise parameter estimates - noise_estimate = inst->whiteNoiseLevel; // Q(minNorm-stages) - noise_estimate_avg = noise_estimate / (inst->blockIndex + 1); // Q(minNorm-stages) + noise_estimate = inst->whiteNoiseLevel; // Q(minNorm-stages) + noise_estimate_avg = + noise_estimate / (inst->blockIndex + 1); // Q(minNorm-stages) } for (i = 0; i < inst->magnLen; i++) { - // Estimate the background noise using the pink noise parameters if permitted + // Estimate the background noise using the pink noise parameters if + // permitted if ((inst->pinkNoiseExp) && (i >= kStartBand)) { // Reset noise_estimate noise_estimate = 0; noise_estimate_avg = 0; // Calculate the parametric noise estimate for current frequency bin - WebRtcNsx_CalcParametricNoiseEstimate(inst, - pink_noise_exp_avg, - pink_noise_num_avg, - i, - &noise_estimate, - &noise_estimate_avg); + WebRtcNsx_CalcParametricNoiseEstimate( + inst, pink_noise_exp_avg, pink_noise_num_avg, i, &noise_estimate, + &noise_estimate_avg); } // Calculate parametric Wiener filter noiseSupFilterTmp[i] = inst->denoiseBound; @@ -1650,8 +1669,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // Suppression filter coefficient larger than zero, so calculate. numerator -= tmpU32no1; - // Determine number of left shifts in numerator for best accuracy after - // division + // Determine number of left shifts in numerator for best accuracy + // after division nShifts = WebRtcSpl_NormU32(numerator); nShifts = WEBRTC_SPL_SAT(6, nShifts, 0); @@ -1666,24 +1685,25 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, tmpU32no1 = 1; } tmpU32no2 = numerator / tmpU32no1; // Q14 - noiseSupFilterTmp[i] = (uint16_t)WEBRTC_SPL_SAT(16384, tmpU32no2, - (uint32_t)(inst->denoiseBound)); // Q14 + noiseSupFilterTmp[i] = + (uint16_t)WEBRTC_SPL_SAT(16384, tmpU32no2, + (uint32_t)(inst->denoiseBound)); // Q14 } } - // Weight quantile noise 'noiseU32' with modeled noise 'noise_estimate_avg' - // 'noiseU32 is in Q(qNoise) and 'noise_estimate' in Q(minNorm-stages) - // To guarantee that we do not get wrap around when shifting to the same domain - // we use the lowest one. Furthermore, we need to save 6 bits for the weighting. - // 'noise_estimate_avg' can handle this operation by construction, but 'noiseU32' - // may not. + // Weight quantile noise 'noiseU32' with modeled noise + // 'noise_estimate_avg' 'noiseU32 is in Q(qNoise) and 'noise_estimate' in + // Q(minNorm-stages) To guarantee that we do not get wrap around when + // shifting to the same domain we use the lowest one. Furthermore, we need + // to save 6 bits for the weighting. 'noise_estimate_avg' can handle this + // operation by construction, but 'noiseU32' may not. // Shift 'noiseU32' to 'q_domain_to_use' tmpU32no1 = noiseU32[i] >> (qNoise - q_domain_to_use); // Shift 'noise_estimate_avg' to 'q_domain_to_use' tmpU32no2 = noise_estimate_avg >> - (inst->minNorm - inst->stages - q_domain_to_use); - // Make a simple check to see if we have enough room for weighting 'tmpU32no1' - // without wrap around + (inst->minNorm - inst->stages - q_domain_to_use); + // Make a simple check to see if we have enough room for weighting + // 'tmpU32no1' without wrap around nShifts = 0; if (tmpU32no1 & 0xfc000000) { tmpU32no1 >>= 6; @@ -1693,7 +1713,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, tmpU32no1 *= inst->blockIndex; tmpU32no2 *= (END_STARTUP_SHORT - inst->blockIndex); // Add them together and divide by startup length - noiseU32[i] = WebRtcSpl_DivU32U16(tmpU32no1 + tmpU32no2, END_STARTUP_SHORT); + noiseU32[i] = + WebRtcSpl_DivU32U16(tmpU32no1 + tmpU32no2, END_STARTUP_SHORT); // Shift back if necessary noiseU32[i] <<= nShifts; } @@ -1706,15 +1727,16 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // substituting division with shift ending up in Q(-2*stages) inst->timeAvgMagnEnergyTmp += inst->magnEnergy >> (2 * inst->normData + inst->stages - 1); - inst->timeAvgMagnEnergy = WebRtcSpl_DivU32U16(inst->timeAvgMagnEnergyTmp, - inst->blockIndex + 1); + inst->timeAvgMagnEnergy = + WebRtcSpl_DivU32U16(inst->timeAvgMagnEnergyTmp, inst->blockIndex + 1); } - //start processing at frames == converged+1 + // start processing at frames == converged+1 // STEP 1: compute prior and post SNR based on quantile noise estimates // compute direct decision (DD) estimate of prior SNR: needed for new method - satMax = (uint32_t)1048575;// Largest possible value without getting overflow despite shifting 12 steps + satMax = (uint32_t)1048575; // Largest possible value without getting + // overflow despite shifting 12 steps postShifts = 6 + qMagn - qNoise; nShifts = 5 - inst->prevQMagn + inst->prevQNoise; for (i = 0; i < inst->magnLen; i++) { @@ -1726,17 +1748,22 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // postLocSnr[i] = magn[i] / (noise[i] + 0.0001); // } // // previous post SNR - // // previous estimate: based on previous frame with gain filter (smooth is previous filter) + // // previous estimate: based on previous frame with gain filter (smooth is + // previous filter) // - // prevNearSnr[i] = inst->prevMagnU16[i] / (inst->noisePrev[i] + 0.0001) * (inst->smooth[i]); + // prevNearSnr[i] = inst->prevMagnU16[i] / (inst->noisePrev[i] + 0.0001) * + // (inst->smooth[i]); // - // // DD estimate is sum of two terms: current estimate and previous estimate - // // directed decision update of priorSnr (or we actually store [2*priorSnr+1]) + // // DD estimate is sum of two terms: current estimate and previous + // estimate + // // directed decision update of priorSnr (or we actually store + // [2*priorSnr+1]) // - // priorLocSnr[i] = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * (postLocSnr[i] - 1.0); + // priorLocSnr[i] = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * + // (postLocSnr[i] - 1.0); // calculate post SNR: output in Q11 - postLocSnr[i] = 2048; // 1.0 in Q11 + postLocSnr[i] = 2048; // 1.0 in Q11 tmpU32no1 = (uint32_t)magnU16[i] << 6; // Q(6+qMagn) if (postShifts < 0) { tmpU32no2 = noiseU32[i] >> -postShifts; // Q(6+qMagn) @@ -1747,57 +1774,59 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // Current magnitude larger than noise tmpU32no1 <<= 11; // Q(17+qMagn) if (tmpU32no2 > 0) { - tmpU32no1 /= tmpU32no2; // Q11 - postLocSnr[i] = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + tmpU32no1 /= tmpU32no2; // Q11 + postLocSnr[i] = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 } else { postLocSnr[i] = satMax; } } - // calculate prevNearSnr[i] and save for later instead of recalculating it later - // |nearMagnEst| in Q(prevQMagn + 14) + // calculate prevNearSnr[i] and save for later instead of recalculating it + // later |nearMagnEst| in Q(prevQMagn + 14) nearMagnEst = inst->prevMagnU16[i] * inst->noiseSupFilter[i]; - tmpU32no1 = nearMagnEst << 3; // Q(prevQMagn+17) + tmpU32no1 = nearMagnEst << 3; // Q(prevQMagn+17) tmpU32no2 = inst->prevNoiseU32[i] >> nShifts; // Q(prevQMagn+6) if (tmpU32no2 > 0) { - tmpU32no1 /= tmpU32no2; // Q11 - tmpU32no1 = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + tmpU32no1 /= tmpU32no2; // Q11 + tmpU32no1 = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 } else { - tmpU32no1 = satMax; // Q11 + tmpU32no1 = satMax; // Q11 } - prevNearSnr[i] = tmpU32no1; // Q11 + prevNearSnr[i] = tmpU32no1; // Q11 - //directed decision update of priorSnr - tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 - tmpU32no2 = WEBRTC_SPL_UMUL_32_16(postLocSnr[i] - 2048, ONE_MINUS_DD_PR_SNR_Q11); // Q22 - priorSnr = tmpU32no1 + tmpU32no2 + 512; // Q22 (added 512 for rounding) + // directed decision update of priorSnr + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(postLocSnr[i] - 2048, + ONE_MINUS_DD_PR_SNR_Q11); // Q22 + priorSnr = tmpU32no1 + tmpU32no2 + 512; // Q22 (added 512 for rounding) // priorLocSnr = 1 + 2*priorSnr priorLocSnr[i] = 2048 + (priorSnr >> 10); // Q11 - } // end of loop over frequencies + } // end of loop over frequencies // done with step 1: DD computation of prior and post SNR // STEP 2: compute speech/noise likelihood - //compute difference of input spectrum with learned/estimated noise spectrum + // compute difference of input spectrum with learned/estimated noise spectrum WebRtcNsx_ComputeSpectralDifference(inst, magnU16); - //compute histograms for determination of parameters (thresholds and weights for features) - //parameters are extracted once every window time (=inst->modelUpdate) - //counter update + // compute histograms for determination of parameters (thresholds and weights + // for features) parameters are extracted once every window time + // (=inst->modelUpdate) counter update inst->cntThresUpdate++; flag = (int)(inst->cntThresUpdate == inst->modelUpdate); - //update histogram + // update histogram WebRtcNsx_FeatureParameterExtraction(inst, flag); - //compute model parameters + // compute model parameters if (flag) { - inst->cntThresUpdate = 0; // Reset counter - //update every window: + inst->cntThresUpdate = 0; // Reset counter + // update every window: // get normalization for spectral difference for next window estimate // Shift to Q(-2*stages) inst->curAvgMagnEnergy >>= STAT_UPDATES; - tmpU32no1 = (inst->curAvgMagnEnergy + inst->timeAvgMagnEnergy + 1) >> 1; //Q(-2*stages) + tmpU32no1 = (inst->curAvgMagnEnergy + inst->timeAvgMagnEnergy + 1) >> + 1; // Q(-2*stages) // Update featureSpecDiff if ((tmpU32no1 != inst->timeAvgMagnEnergy) && (inst->featureSpecDiff) && (inst->timeAvgMagnEnergy > 0)) { @@ -1817,28 +1846,29 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, if (WebRtcSpl_NormU32(tmpU32no3) < norm32no1) { inst->featureSpecDiff = 0x007FFFFF; } else { - inst->featureSpecDiff = WEBRTC_SPL_MIN(0x007FFFFF, - tmpU32no3 << norm32no1); + inst->featureSpecDiff = + WEBRTC_SPL_MIN(0x007FFFFF, tmpU32no3 << norm32no1); } } - inst->timeAvgMagnEnergy = tmpU32no1; // Q(-2*stages) + inst->timeAvgMagnEnergy = tmpU32no1; // Q(-2*stages) inst->curAvgMagnEnergy = 0; } - //compute speech/noise probability + // compute speech/noise probability WebRtcNsx_SpeechNoiseProb(inst, nonSpeechProbFinal, priorLocSnr, postLocSnr); - //time-avg parameter for noise update - gammaNoise = NOISE_UPDATE_Q8; // Q8 + // time-avg parameter for noise update + gammaNoise = NOISE_UPDATE_Q8; // Q8 maxNoiseU32 = 0; postShifts = inst->prevQNoise - qMagn; nShifts = inst->prevQMagn - qMagn; for (i = 0; i < inst->magnLen; i++) { - // temporary noise update: use it for speech frames if update value is less than previous - // the formula has been rewritten into: - // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) + // temporary noise update: use it for speech frames if update value is less + // than previous the formula has been rewritten into: noiseUpdate = + // noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - + // noisePrev[i]) if (postShifts < 0) { tmpU32no2 = magnU16[i] >> -postShifts; // Q(prevQNoise) @@ -1852,11 +1882,12 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, sign = 1; tmpU32no1 = tmpU32no2 - prevNoiseU16[i]; } - noiseUpdateU32 = inst->prevNoiseU32[i]; // Q(prevQNoise+11) + noiseUpdateU32 = inst->prevNoiseU32[i]; // Q(prevQNoise+11) tmpU32no3 = 0; if ((tmpU32no1) && (nonSpeechProbFinal[i])) { // This value will be used later, if gammaNoise changes - tmpU32no3 = WEBRTC_SPL_UMUL_32_16(tmpU32no1, nonSpeechProbFinal[i]); // Q(prevQNoise+8) + tmpU32no3 = WEBRTC_SPL_UMUL_32_16( + tmpU32no1, nonSpeechProbFinal[i]); // Q(prevQNoise+8) if (0x7c000000 & tmpU32no3) { // Shifting required before multiplication tmpU32no2 = (tmpU32no3 >> 5) * gammaNoise; // Q(prevQNoise+11) @@ -1865,29 +1896,30 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, tmpU32no2 = (tmpU32no3 * gammaNoise) >> 5; // Q(prevQNoise+11) } if (sign > 0) { - noiseUpdateU32 += tmpU32no2; // Q(prevQNoise+11) + noiseUpdateU32 += tmpU32no2; // Q(prevQNoise+11) } else { // This operation is safe. We can never get wrap around, since worst // case scenario means magnU16 = 0 - noiseUpdateU32 -= tmpU32no2; // Q(prevQNoise+11) + noiseUpdateU32 -= tmpU32no2; // Q(prevQNoise+11) } } - //increase gamma (i.e., less noise update) for frame likely to be speech + // increase gamma (i.e., less noise update) for frame likely to be speech prevGammaNoise = gammaNoise; gammaNoise = NOISE_UPDATE_Q8; - //time-constant based on speech/noise state - //increase gamma (i.e., less noise update) for frames likely to be speech + // time-constant based on speech/noise state + // increase gamma (i.e., less noise update) for frames likely to be speech if (nonSpeechProbFinal[i] < ONE_MINUS_PROB_RANGE_Q8) { gammaNoise = GAMMA_NOISE_TRANS_AND_SPEECH_Q8; } if (prevGammaNoise != gammaNoise) { // new noise update - // this line is the same as above, only that the result is stored in a different variable and the gammaNoise - // has changed + // this line is the same as above, only that the result is stored in a + // different variable and the gammaNoise has changed // - // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) + // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * + // (magn[i] - noisePrev[i]) if (0x7c000000 & tmpU32no3) { // Shifting required before multiplication @@ -1897,15 +1929,15 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, tmpU32no2 = (tmpU32no3 * gammaNoise) >> 5; // Q(prevQNoise+11) } if (sign > 0) { - tmpU32no1 = inst->prevNoiseU32[i] + tmpU32no2; // Q(prevQNoise+11) + tmpU32no1 = inst->prevNoiseU32[i] + tmpU32no2; // Q(prevQNoise+11) } else { - tmpU32no1 = inst->prevNoiseU32[i] - tmpU32no2; // Q(prevQNoise+11) + tmpU32no1 = inst->prevNoiseU32[i] - tmpU32no2; // Q(prevQNoise+11) } if (noiseUpdateU32 > tmpU32no1) { - noiseUpdateU32 = tmpU32no1; // Q(prevQNoise+11) + noiseUpdateU32 = tmpU32no1; // Q(prevQNoise+11) } } - noiseU32[i] = noiseUpdateU32; // Q(prevQNoise+11) + noiseU32[i] = noiseUpdateU32; // Q(prevQNoise+11) if (noiseUpdateU32 > maxNoiseU32) { maxNoiseU32 = noiseUpdateU32; } @@ -1913,22 +1945,23 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // conservative noise update // // original FLOAT code // if (prob_speech < PROB_RANGE) { - // inst->avgMagnPause[i] = inst->avgMagnPause[i] + (1.0 - gamma_pause)*(magn[i] - inst->avgMagnPause[i]); + // inst->avgMagnPause[i] = inst->avgMagnPause[i] + (1.0 - + // gamma_pause)*(magn[i] - inst->avgMagnPause[i]); // } tmp32no2 = WEBRTC_SPL_SHIFT_W32(inst->avgMagnPause[i], -nShifts); if (nonSpeechProbFinal[i] > ONE_MINUS_PROB_RANGE_Q8) { if (nShifts < 0) { - tmp32no1 = (int32_t)magnU16[i] - tmp32no2; // Q(qMagn) - tmp32no1 *= ONE_MINUS_GAMMA_PAUSE_Q8; // Q(8+prevQMagn+nShifts) - tmp32no1 = (tmp32no1 + 128) >> 8; // Q(qMagn). + tmp32no1 = (int32_t)magnU16[i] - tmp32no2; // Q(qMagn) + tmp32no1 *= ONE_MINUS_GAMMA_PAUSE_Q8; // Q(8+prevQMagn+nShifts) + tmp32no1 = (tmp32no1 + 128) >> 8; // Q(qMagn). } else { // In Q(qMagn+nShifts) tmp32no1 = ((int32_t)magnU16[i] << nShifts) - inst->avgMagnPause[i]; tmp32no1 *= ONE_MINUS_GAMMA_PAUSE_Q8; // Q(8+prevQMagn+nShifts) tmp32no1 = (tmp32no1 + (128 << nShifts)) >> (8 + nShifts); // Q(qMagn). } - tmp32no2 += tmp32no1; // Q(qMagn) + tmp32no2 += tmp32no1; // Q(qMagn) } inst->avgMagnPause[i] = tmp32no2; } // end of frequency loop @@ -1937,7 +1970,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, qNoise = inst->prevQNoise + norm32no1 - 5; // done with step 2: noise update - // STEP 3: compute dd update of prior snr and post snr based on new noise estimate + // STEP 3: compute dd update of prior snr and post snr based on new noise + // estimate nShifts = inst->prevQNoise + 11 - qMagn; for (i = 0; i < inst->magnLen; i++) { // FLOAT code @@ -1947,7 +1981,8 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // { // curNearSnr = magn[i] / (noise[i] + 0.0001) - 1.0; // } - // // DD estimate is sum of two terms: current estimate and previous estimate + // // DD estimate is sum of two terms: current estimate and previous + // estimate // // directed decision update of snrPrior // snrPrior = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * curNearSnr; // // gain filter @@ -1955,56 +1990,58 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // tmpFloat2 = snrPrior / tmpFloat1; // theFilter[i] = tmpFloat2; - // calculate curNearSnr again, this is necessary because a new noise estimate has been made since then. for the original - curNearSnr = 0; // Q11 + // calculate curNearSnr again, this is necessary because a new noise + // estimate has been made since then. for the original + curNearSnr = 0; // Q11 if (nShifts < 0) { // This case is equivalent with magn < noise which implies curNearSnr = 0; - tmpMagnU32 = (uint32_t)magnU16[i]; // Q(qMagn) + tmpMagnU32 = (uint32_t)magnU16[i]; // Q(qMagn) tmpNoiseU32 = noiseU32[i] << -nShifts; // Q(qMagn) } else if (nShifts > 17) { - tmpMagnU32 = (uint32_t)magnU16[i] << 17; // Q(qMagn+17) + tmpMagnU32 = (uint32_t)magnU16[i] << 17; // Q(qMagn+17) tmpNoiseU32 = noiseU32[i] >> (nShifts - 17); // Q(qMagn+17) } else { tmpMagnU32 = (uint32_t)magnU16[i] << nShifts; // Q(qNoise_prev+11) - tmpNoiseU32 = noiseU32[i]; // Q(qNoise_prev+11) + tmpNoiseU32 = noiseU32[i]; // Q(qNoise_prev+11) } if (tmpMagnU32 > tmpNoiseU32) { - tmpU32no1 = tmpMagnU32 - tmpNoiseU32; // Q(qCur) + tmpU32no1 = tmpMagnU32 - tmpNoiseU32; // Q(qCur) norm32no2 = WEBRTC_SPL_MIN(11, WebRtcSpl_NormU32(tmpU32no1)); - tmpU32no1 <<= norm32no2; // Q(qCur+norm32no2) + tmpU32no1 <<= norm32no2; // Q(qCur+norm32no2) tmpU32no2 = tmpNoiseU32 >> (11 - norm32no2); // Q(qCur+norm32no2-11) if (tmpU32no2 > 0) { tmpU32no1 /= tmpU32no2; // Q11 } - curNearSnr = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + curNearSnr = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 } - //directed decision update of priorSnr + // directed decision update of priorSnr // FLOAT // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr; - tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 - tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q22 - priorSnr = tmpU32no1 + tmpU32no2; // Q22 + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 + tmpU32no2 = + WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q22 + priorSnr = tmpU32no1 + tmpU32no2; // Q22 - //gain filter + // gain filter tmpU32no1 = inst->overdrive + ((priorSnr + 8192) >> 14); // Q8 RTC_DCHECK_GT(inst->overdrive, 0); tmpU16no1 = (priorSnr + tmpU32no1 / 2) / tmpU32no1; // Q14 - inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBound); // 16384 = Q14(1.0) // Q14 + inst->noiseSupFilter[i] = WEBRTC_SPL_SAT( + 16384, tmpU16no1, inst->denoiseBound); // 16384 = Q14(1.0) // Q14 // Weight in the parametric Wiener filter during startup if (inst->blockIndex < END_STARTUP_SHORT) { // Weight the two suppression filters tmpU32no1 = inst->noiseSupFilter[i] * inst->blockIndex; - tmpU32no2 = noiseSupFilterTmp[i] * - (END_STARTUP_SHORT - inst->blockIndex); + tmpU32no2 = noiseSupFilterTmp[i] * (END_STARTUP_SHORT - inst->blockIndex); tmpU32no1 += tmpU32no2; - inst->noiseSupFilter[i] = (uint16_t)WebRtcSpl_DivU32U16(tmpU32no1, - END_STARTUP_SHORT); + inst->noiseSupFilter[i] = + (uint16_t)WebRtcSpl_DivU32U16(tmpU32no1, END_STARTUP_SHORT); } } // end of loop over frequencies - //done with step3 + // done with step3 // save noise and magnitude spectrum for next frame inst->prevQNoise = qNoise; @@ -2012,45 +2049,48 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, if (norm32no1 > 5) { for (i = 0; i < inst->magnLen; i++) { inst->prevNoiseU32[i] = noiseU32[i] << (norm32no1 - 5); // Q(qNoise+11) - inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) + inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) } } else { for (i = 0; i < inst->magnLen; i++) { inst->prevNoiseU32[i] = noiseU32[i] >> (5 - norm32no1); // Q(qNoise+11) - inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) + inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) } } WebRtcNsx_DataSynthesis(inst, outFrame[0]); #ifdef NS_FILEDEBUG - if (fwrite(outframe, sizeof(short), - inst->blockLen10ms, inst->outfile) != inst->blockLen10ms) { + if (fwrite(outframe, sizeof(short), inst->blockLen10ms, inst->outfile) != + inst->blockLen10ms) { RTC_NOTREACHED(); } #endif - //for H band: - // only update data buffer, then apply time-domain gain is applied derived from L band + // for H band: + // only update data buffer, then apply time-domain gain is applied derived + // from L band if (num_bands > 1) { // update analysis buffer for H band // append new data to buffer FX for (i = 0; i < num_high_bands; ++i) { - memcpy(inst->dataBufHBFX[i], inst->dataBufHBFX[i] + inst->blockLen10ms, + memcpy( + inst->dataBufHBFX[i], inst->dataBufHBFX[i] + inst->blockLen10ms, (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->dataBufHBFX[i])); memcpy(inst->dataBufHBFX[i] + inst->anaLen - inst->blockLen10ms, - speechFrameHB[i], inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); + speechFrameHB[i], + inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); } // range for averaging low band quantities for H band gain - gainTimeDomainHB = 16384; // 16384 = Q14(1.0) - //average speech prob from low band - //average filter gain from low band - //avg over second half (i.e., 4->8kHz) of freq. spectrum - tmpU32no1 = 0; // Q12 - tmpU16no1 = 0; // Q8 + gainTimeDomainHB = 16384; // 16384 = Q14(1.0) + // average speech prob from low band + // average filter gain from low band + // avg over second half (i.e., 4->8kHz) of freq. spectrum + tmpU32no1 = 0; // Q12 + tmpU16no1 = 0; // Q8 for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++) { - tmpU16no1 += nonSpeechProbFinal[i]; // Q8 - tmpU32no1 += (uint32_t)(inst->noiseSupFilter[i]); // Q14 + tmpU16no1 += nonSpeechProbFinal[i]; // Q8 + tmpU32no1 += (uint32_t)(inst->noiseSupFilter[i]); // Q14 } RTC_DCHECK_GE(inst->stages, 7); avgProbSpeechHB = (4096 - (tmpU16no1 >> (inst->stages - 7))); // Q12 @@ -2059,16 +2099,23 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // // original FLOAT code // // gain based on speech probability: // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0; - // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // between 0 and 1 + // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // + // between 0 and 1 // gain based on speech probability: // original expression: "0.5 * (1 + tanh(2x-1))" - // avgProbSpeechHB has been anyway saturated to a value between 0 and 1 so the other cases don't have to be dealt with - // avgProbSpeechHB and gainModHB are in Q12, 3607 = Q12(0.880615234375) which is a zero point of - // |0.5 * (1 + tanh(2x-1)) - x| - |0.5 * (1 + tanh(2x-1)) - 0.880615234375| meaning that from that point the error of approximating - // the expression with f(x) = x would be greater than the error of approximating the expression with f(x) = 0.880615234375 - // error: "|0.5 * (1 + tanh(2x-1)) - x| from x=0 to 0.880615234375" -> http://www.wolframalpha.com/input/?i=|0.5+*+(1+%2B+tanh(2x-1))+-+x|+from+x%3D0+to+0.880615234375 - // and: "|0.5 * (1 + tanh(2x-1)) - 0.880615234375| from x=0.880615234375 to 1" -> http://www.wolframalpha.com/input/?i=+|0.5+*+(1+%2B+tanh(2x-1))+-+0.880615234375|+from+x%3D0.880615234375+to+1 + // avgProbSpeechHB has been anyway saturated to a value between 0 and 1 so + // the other cases don't have to be dealt with avgProbSpeechHB and gainModHB + // are in Q12, 3607 = Q12(0.880615234375) which is a zero point of |0.5 * (1 + // + tanh(2x-1)) - x| - |0.5 * (1 + tanh(2x-1)) - 0.880615234375| meaning + // that from that point the error of approximating the expression with f(x) + // = x would be greater than the error of approximating the expression with + // f(x) = 0.880615234375 error: "|0.5 * (1 + tanh(2x-1)) - x| from x=0 to + // 0.880615234375" -> + // http://www.wolframalpha.com/input/?i=|0.5+*+(1+%2B+tanh(2x-1))+-+x|+from+x%3D0+to+0.880615234375 + // and: "|0.5 * (1 + tanh(2x-1)) - 0.880615234375| from x=0.880615234375 to + // 1" -> + // http://www.wolframalpha.com/input/?i=+|0.5+*+(1+%2B+tanh(2x-1))+-+0.880615234375|+from+x%3D0.880615234375+to+1 gainModHB = WEBRTC_SPL_MIN(avgProbSpeechHB, 3607); // // original FLOAT code @@ -2080,27 +2127,27 @@ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, // gain_time_domain_HB=(float)0.25*gain_mod+(float)0.75*avg_filter_gain; // } - - //combine gain with low band gain + // combine gain with low band gain if (avgProbSpeechHB < 2048) { // 2048 = Q12(0.5) - // the next two lines in float are "gain_time_domain = 0.5 * gain_mod + 0.5 * avg_filter_gain"; Q2(0.5) = 2 equals one left shift - gainTimeDomainHB = (gainModHB << 1) + (avgFilterGainHB >> 1); // Q14 + // the next two lines in float are "gain_time_domain = 0.5 * gain_mod + + // 0.5 * avg_filter_gain"; Q2(0.5) = 2 equals one left shift + gainTimeDomainHB = (gainModHB << 1) + (avgFilterGainHB >> 1); // Q14 } else { // "gain_time_domain = 0.25 * gain_mod + 0.75 * agv_filter_gain;" gainTimeDomainHB = (int16_t)((3 * avgFilterGainHB) >> 2); // 3 = Q2(0.75) - gainTimeDomainHB += gainModHB; // Q14 + gainTimeDomainHB += gainModHB; // Q14 } - //make sure gain is within flooring range - gainTimeDomainHB - = WEBRTC_SPL_SAT(16384, gainTimeDomainHB, (int16_t)(inst->denoiseBound)); // 16384 = Q14(1.0) + // make sure gain is within flooring range + gainTimeDomainHB = + WEBRTC_SPL_SAT(16384, gainTimeDomainHB, + (int16_t)(inst->denoiseBound)); // 16384 = Q14(1.0) - - //apply gain + // apply gain for (i = 0; i < num_high_bands; ++i) { for (j = 0; j < inst->blockLen10ms; j++) { - outFrameHB[i][j] = (int16_t)((gainTimeDomainHB * - inst->dataBufHBFX[i][j]) >> 14); // Q0 + outFrameHB[i][j] = (int16_t)( + (gainTimeDomainHB * inst->dataBufHBFX[i][j]) >> 14); // Q0 } } } // end of H band gain computation diff --git a/modules/audio_processing/ns/nsx_core.h b/modules/audio_processing/legacy_ns/nsx_core.h similarity index 96% rename from modules/audio_processing/ns/nsx_core.h rename to modules/audio_processing/legacy_ns/nsx_core.h index 9e9d142818..a3f224acc7 100644 --- a/modules/audio_processing/ns/nsx_core.h +++ b/modules/audio_processing/legacy_ns/nsx_core.h @@ -8,15 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ -#define MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_CORE_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_CORE_H_ #ifdef NS_FILEDEBUG #include #endif #include "common_audio/signal_processing/include/signal_processing_library.h" -#include "modules/audio_processing/ns/nsx_defines.h" +#include "modules/audio_processing/legacy_ns/nsx_defines.h" typedef struct NoiseSuppressionFixedC_ { uint32_t fs; @@ -161,9 +161,9 @@ int WebRtcNsx_set_policy_core(NoiseSuppressionFixedC* inst, int mode); * - outFrame : Output speech frame for each band */ void WebRtcNsx_ProcessCore(NoiseSuppressionFixedC* inst, - const short* const* inFrame, + const int16_t* const* inFrame, int num_bands, - short* const* outFrame); + int16_t* const* outFrame); /**************************************************************************** * Some function pointers, for internal functions shared by ARM NEON and @@ -258,4 +258,4 @@ void WebRtcNsx_Denormalize_mips(NoiseSuppressionFixedC* inst, } #endif -#endif // MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_CORE_H_ diff --git a/modules/audio_processing/ns/nsx_core_c.c b/modules/audio_processing/legacy_ns/nsx_core_c.c similarity index 98% rename from modules/audio_processing/ns/nsx_core_c.c rename to modules/audio_processing/legacy_ns/nsx_core_c.c index 162fb1990a..2b0bb2f66f 100644 --- a/modules/audio_processing/ns/nsx_core_c.c +++ b/modules/audio_processing/legacy_ns/nsx_core_c.c @@ -9,9 +9,9 @@ */ #include "rtc_base/checks.h" -#include "modules/audio_processing/ns/noise_suppression_x.h" -#include "modules/audio_processing/ns/nsx_core.h" -#include "modules/audio_processing/ns/nsx_defines.h" +#include "modules/audio_processing/legacy_ns/noise_suppression_x.h" +#include "modules/audio_processing/legacy_ns/nsx_core.h" +#include "modules/audio_processing/legacy_ns/nsx_defines.h" static const int16_t kIndicatorTable[17] = { 0, 2017, 3809, 5227, 6258, 6963, 7424, 7718, @@ -257,4 +257,3 @@ void WebRtcNsx_SpeechNoiseProb(NoiseSuppressionFixedC* inst, } } } - diff --git a/modules/audio_processing/ns/nsx_core_mips.c b/modules/audio_processing/legacy_ns/nsx_core_mips.c similarity index 99% rename from modules/audio_processing/ns/nsx_core_mips.c rename to modules/audio_processing/legacy_ns/nsx_core_mips.c index d58a9b2347..af4c287289 100644 --- a/modules/audio_processing/ns/nsx_core_mips.c +++ b/modules/audio_processing/legacy_ns/nsx_core_mips.c @@ -11,8 +11,8 @@ #include #include "rtc_base/checks.h" -#include "modules/audio_processing/ns/noise_suppression_x.h" -#include "modules/audio_processing/ns/nsx_core.h" +#include "modules/audio_processing/legacy_ns/noise_suppression_x.h" +#include "modules/audio_processing/legacy_ns/nsx_core.h" static const int16_t kIndicatorTable[17] = { 0, 2017, 3809, 5227, 6258, 6963, 7424, 7718, @@ -999,4 +999,3 @@ void WebRtcNsx_NormalizeRealBuffer_mips(NoiseSuppressionFixedC* inst, : "memory" ); } - diff --git a/modules/audio_processing/ns/nsx_core_neon.c b/modules/audio_processing/legacy_ns/nsx_core_neon.c similarity index 99% rename from modules/audio_processing/ns/nsx_core_neon.c rename to modules/audio_processing/legacy_ns/nsx_core_neon.c index 64ce99c32c..244111c7ed 100644 --- a/modules/audio_processing/ns/nsx_core_neon.c +++ b/modules/audio_processing/legacy_ns/nsx_core_neon.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/ns/nsx_core.h" +#include "modules/audio_processing/legacy_ns/nsx_core.h" #include diff --git a/modules/audio_processing/ns/nsx_defines.h b/modules/audio_processing/legacy_ns/nsx_defines.h similarity index 94% rename from modules/audio_processing/ns/nsx_defines.h rename to modules/audio_processing/legacy_ns/nsx_defines.h index dc14dbc793..18db3117ce 100644 --- a/modules/audio_processing/ns/nsx_defines.h +++ b/modules/audio_processing/legacy_ns/nsx_defines.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ -#define MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ +#ifndef MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_DEFINES_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_DEFINES_H_ #define ANAL_BLOCKL_MAX 256 /* Max analysis block length */ #define HALF_ANAL_BLOCKL 129 /* Half max analysis block length + 1 */ @@ -71,4 +71,4 @@ #define GAMMA_NOISE_TRANS_AND_SPEECH_Q8 \ 3 /* ~= Q8(0.01) Update for transition and noise region */ -#endif /* MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ */ +#endif /* MODULES_AUDIO_PROCESSING_LEGACY_NS_NSX_DEFINES_H_ */ diff --git a/modules/audio_processing/legacy_ns/windows_private.h b/modules/audio_processing/legacy_ns/windows_private.h new file mode 100644 index 0000000000..21bb7d4bad --- /dev/null +++ b/modules/audio_processing/legacy_ns/windows_private.h @@ -0,0 +1,553 @@ +/* + * 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 MODULES_AUDIO_PROCESSING_LEGACY_NS_WINDOWS_PRIVATE_H_ +#define MODULES_AUDIO_PROCESSING_LEGACY_NS_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] = { + 0.00000000f, 0.03271908f, 0.06540313f, 0.09801714f, 0.13052619f, + 0.16289547f, 0.19509032f, 0.22707626f, 0.25881905f, 0.29028468f, + 0.32143947f, 0.35225005f, 0.38268343f, 0.41270703f, 0.44228869f, + 0.47139674f, 0.50000000f, 0.52806785f, 0.55557023f, 0.58247770f, + 0.60876143f, 0.63439328f, 0.65934582f, 0.68359230f, 0.70710678f, + 0.72986407f, 0.75183981f, 0.77301045f, 0.79335334f, 0.81284668f, + 0.83146961f, 0.84920218f, 0.86602540f, 0.88192126f, 0.89687274f, + 0.91086382f, 0.92387953f, 0.93590593f, 0.94693013f, 0.95694034f, + 0.96592583f, 0.97387698f, 0.98078528f, 0.98664333f, 0.99144486f, + 0.99518473f, 0.99785892f, 0.99946459f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 0.99946459f, 0.99785892f, 0.99518473f, 0.99144486f, + 0.98664333f, 0.98078528f, 0.97387698f, 0.96592583f, 0.95694034f, + 0.94693013f, 0.93590593f, 0.92387953f, 0.91086382f, 0.89687274f, + 0.88192126f, 0.86602540f, 0.84920218f, 0.83146961f, 0.81284668f, + 0.79335334f, 0.77301045f, 0.75183981f, 0.72986407f, 0.70710678f, + 0.68359230f, 0.65934582f, 0.63439328f, 0.60876143f, 0.58247770f, + 0.55557023f, 0.52806785f, 0.50000000f, 0.47139674f, 0.44228869f, + 0.41270703f, 0.38268343f, 0.35225005f, 0.32143947f, 0.29028468f, + 0.25881905f, 0.22707626f, 0.19509032f, 0.16289547f, 0.13052619f, + 0.09801714f, 0.06540313f, 0.03271908f}; + +// hybrib Hanning & flat window +static const float kBlocks160w256[256] = { + 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, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 0.99986614f, 0.99946459f, 0.99879546f, 0.99785892f, + 0.99665524f, 0.99518473f, 0.99344778f, 0.99144486f, 0.98917651f, + 0.98664333f, 0.98384601f, 0.98078528f, 0.97746197f, 0.97387698f, + 0.97003125f, 0.96592583f, 0.96156180f, 0.95694034f, 0.95206268f, + 0.94693013f, 0.94154407f, 0.93590593f, 0.93001722f, 0.92387953f, + 0.91749450f, 0.91086382f, 0.90398929f, 0.89687274f, 0.88951608f, + 0.88192126f, 0.87409034f, 0.86602540f, 0.85772861f, 0.84920218f, + 0.84044840f, 0.83146961f, 0.82226822f, 0.81284668f, 0.80320753f, + 0.79335334f, 0.78328675f, 0.77301045f, 0.76252720f, 0.75183981f, + 0.74095113f, 0.72986407f, 0.71858162f, 0.70710678f, 0.69544264f, + 0.68359230f, 0.67155895f, 0.65934582f, 0.64695615f, 0.63439328f, + 0.62166057f, 0.60876143f, 0.59569930f, 0.58247770f, 0.56910015f, + 0.55557023f, 0.54189158f, 0.52806785f, 0.51410274f, 0.50000000f, + 0.48576339f, 0.47139674f, 0.45690388f, 0.44228869f, 0.42755509f, + 0.41270703f, 0.39774847f, 0.38268343f, 0.36751594f, 0.35225005f, + 0.33688985f, 0.32143947f, 0.30590302f, 0.29028468f, 0.27458862f, + 0.25881905f, 0.24298018f, 0.22707626f, 0.21111155f, 0.19509032f, + 0.17901686f, 0.16289547f, 0.14673047f, 0.13052619f, 0.11428696f, + 0.09801714f, 0.08172107f, 0.06540313f, 0.04906767f, 0.03271908f, + 0.01636173f}; + +// hybrib Hanning & flat window: for 20ms +static const float kBlocks320w512[512] = { + 0.00000000f, 0.00818114f, 0.01636173f, 0.02454123f, 0.03271908f, + 0.04089475f, 0.04906767f, 0.05723732f, 0.06540313f, 0.07356456f, + 0.08172107f, 0.08987211f, 0.09801714f, 0.10615561f, 0.11428696f, + 0.12241068f, 0.13052619f, 0.13863297f, 0.14673047f, 0.15481816f, + 0.16289547f, 0.17096189f, 0.17901686f, 0.18705985f, 0.19509032f, + 0.20310773f, 0.21111155f, 0.21910124f, 0.22707626f, 0.23503609f, + 0.24298018f, 0.25090801f, 0.25881905f, 0.26671276f, 0.27458862f, + 0.28244610f, 0.29028468f, 0.29810383f, 0.30590302f, 0.31368174f, + 0.32143947f, 0.32917568f, 0.33688985f, 0.34458148f, 0.35225005f, + 0.35989504f, 0.36751594f, 0.37511224f, 0.38268343f, 0.39022901f, + 0.39774847f, 0.40524131f, 0.41270703f, 0.42014512f, 0.42755509f, + 0.43493645f, 0.44228869f, 0.44961133f, 0.45690388f, 0.46416584f, + 0.47139674f, 0.47859608f, 0.48576339f, 0.49289819f, 0.50000000f, + 0.50706834f, 0.51410274f, 0.52110274f, 0.52806785f, 0.53499762f, + 0.54189158f, 0.54874927f, 0.55557023f, 0.56235401f, 0.56910015f, + 0.57580819f, 0.58247770f, 0.58910822f, 0.59569930f, 0.60225052f, + 0.60876143f, 0.61523159f, 0.62166057f, 0.62804795f, 0.63439328f, + 0.64069616f, 0.64695615f, 0.65317284f, 0.65934582f, 0.66547466f, + 0.67155895f, 0.67759830f, 0.68359230f, 0.68954054f, 0.69544264f, + 0.70129818f, 0.70710678f, 0.71286806f, 0.71858162f, 0.72424708f, + 0.72986407f, 0.73543221f, 0.74095113f, 0.74642045f, 0.75183981f, + 0.75720885f, 0.76252720f, 0.76779452f, 0.77301045f, 0.77817464f, + 0.78328675f, 0.78834643f, 0.79335334f, 0.79830715f, 0.80320753f, + 0.80805415f, 0.81284668f, 0.81758481f, 0.82226822f, 0.82689659f, + 0.83146961f, 0.83598698f, 0.84044840f, 0.84485357f, 0.84920218f, + 0.85349396f, 0.85772861f, 0.86190585f, 0.86602540f, 0.87008699f, + 0.87409034f, 0.87803519f, 0.88192126f, 0.88574831f, 0.88951608f, + 0.89322430f, 0.89687274f, 0.90046115f, 0.90398929f, 0.90745693f, + 0.91086382f, 0.91420976f, 0.91749450f, 0.92071783f, 0.92387953f, + 0.92697940f, 0.93001722f, 0.93299280f, 0.93590593f, 0.93875641f, + 0.94154407f, 0.94426870f, 0.94693013f, 0.94952818f, 0.95206268f, + 0.95453345f, 0.95694034f, 0.95928317f, 0.96156180f, 0.96377607f, + 0.96592583f, 0.96801094f, 0.97003125f, 0.97198664f, 0.97387698f, + 0.97570213f, 0.97746197f, 0.97915640f, 0.98078528f, 0.98234852f, + 0.98384601f, 0.98527764f, 0.98664333f, 0.98794298f, 0.98917651f, + 0.99034383f, 0.99144486f, 0.99247953f, 0.99344778f, 0.99434953f, + 0.99518473f, 0.99595331f, 0.99665524f, 0.99729046f, 0.99785892f, + 0.99836060f, 0.99879546f, 0.99916346f, 0.99946459f, 0.99969882f, + 0.99986614f, 0.99996653f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 0.99996653f, 0.99986614f, 0.99969882f, 0.99946459f, + 0.99916346f, 0.99879546f, 0.99836060f, 0.99785892f, 0.99729046f, + 0.99665524f, 0.99595331f, 0.99518473f, 0.99434953f, 0.99344778f, + 0.99247953f, 0.99144486f, 0.99034383f, 0.98917651f, 0.98794298f, + 0.98664333f, 0.98527764f, 0.98384601f, 0.98234852f, 0.98078528f, + 0.97915640f, 0.97746197f, 0.97570213f, 0.97387698f, 0.97198664f, + 0.97003125f, 0.96801094f, 0.96592583f, 0.96377607f, 0.96156180f, + 0.95928317f, 0.95694034f, 0.95453345f, 0.95206268f, 0.94952818f, + 0.94693013f, 0.94426870f, 0.94154407f, 0.93875641f, 0.93590593f, + 0.93299280f, 0.93001722f, 0.92697940f, 0.92387953f, 0.92071783f, + 0.91749450f, 0.91420976f, 0.91086382f, 0.90745693f, 0.90398929f, + 0.90046115f, 0.89687274f, 0.89322430f, 0.88951608f, 0.88574831f, + 0.88192126f, 0.87803519f, 0.87409034f, 0.87008699f, 0.86602540f, + 0.86190585f, 0.85772861f, 0.85349396f, 0.84920218f, 0.84485357f, + 0.84044840f, 0.83598698f, 0.83146961f, 0.82689659f, 0.82226822f, + 0.81758481f, 0.81284668f, 0.80805415f, 0.80320753f, 0.79830715f, + 0.79335334f, 0.78834643f, 0.78328675f, 0.77817464f, 0.77301045f, + 0.76779452f, 0.76252720f, 0.75720885f, 0.75183981f, 0.74642045f, + 0.74095113f, 0.73543221f, 0.72986407f, 0.72424708f, 0.71858162f, + 0.71286806f, 0.70710678f, 0.70129818f, 0.69544264f, 0.68954054f, + 0.68359230f, 0.67759830f, 0.67155895f, 0.66547466f, 0.65934582f, + 0.65317284f, 0.64695615f, 0.64069616f, 0.63439328f, 0.62804795f, + 0.62166057f, 0.61523159f, 0.60876143f, 0.60225052f, 0.59569930f, + 0.58910822f, 0.58247770f, 0.57580819f, 0.56910015f, 0.56235401f, + 0.55557023f, 0.54874927f, 0.54189158f, 0.53499762f, 0.52806785f, + 0.52110274f, 0.51410274f, 0.50706834f, 0.50000000f, 0.49289819f, + 0.48576339f, 0.47859608f, 0.47139674f, 0.46416584f, 0.45690388f, + 0.44961133f, 0.44228869f, 0.43493645f, 0.42755509f, 0.42014512f, + 0.41270703f, 0.40524131f, 0.39774847f, 0.39022901f, 0.38268343f, + 0.37511224f, 0.36751594f, 0.35989504f, 0.35225005f, 0.34458148f, + 0.33688985f, 0.32917568f, 0.32143947f, 0.31368174f, 0.30590302f, + 0.29810383f, 0.29028468f, 0.28244610f, 0.27458862f, 0.26671276f, + 0.25881905f, 0.25090801f, 0.24298018f, 0.23503609f, 0.22707626f, + 0.21910124f, 0.21111155f, 0.20310773f, 0.19509032f, 0.18705985f, + 0.17901686f, 0.17096189f, 0.16289547f, 0.15481816f, 0.14673047f, + 0.13863297f, 0.13052619f, 0.12241068f, 0.11428696f, 0.10615561f, + 0.09801714f, 0.08987211f, 0.08172107f, 0.07356456f, 0.06540313f, + 0.05723732f, 0.04906767f, 0.04089475f, 0.03271908f, 0.02454123f, + 0.01636173f, 0.00818114f}; + +// Hanning window: for 15ms at 16kHz with symmetric zeros +static const float kBlocks240w512[512] = { + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00654494f, 0.01308960f, 0.01963369f, + 0.02617695f, 0.03271908f, 0.03925982f, 0.04579887f, 0.05233596f, + 0.05887080f, 0.06540313f, 0.07193266f, 0.07845910f, 0.08498218f, + 0.09150162f, 0.09801714f, 0.10452846f, 0.11103531f, 0.11753740f, + 0.12403446f, 0.13052620f, 0.13701233f, 0.14349262f, 0.14996676f, + 0.15643448f, 0.16289547f, 0.16934951f, 0.17579629f, 0.18223552f, + 0.18866697f, 0.19509032f, 0.20150533f, 0.20791170f, 0.21430916f, + 0.22069745f, 0.22707628f, 0.23344538f, 0.23980446f, 0.24615330f, + 0.25249159f, 0.25881904f, 0.26513544f, 0.27144045f, 0.27773386f, + 0.28401536f, 0.29028466f, 0.29654160f, 0.30278578f, 0.30901700f, + 0.31523499f, 0.32143945f, 0.32763019f, 0.33380687f, 0.33996925f, + 0.34611708f, 0.35225007f, 0.35836795f, 0.36447051f, 0.37055743f, + 0.37662852f, 0.38268346f, 0.38872197f, 0.39474389f, 0.40074885f, + 0.40673664f, 0.41270703f, 0.41865975f, 0.42459452f, 0.43051112f, + 0.43640924f, 0.44228873f, 0.44814920f, 0.45399052f, 0.45981237f, + 0.46561453f, 0.47139674f, 0.47715878f, 0.48290035f, 0.48862126f, + 0.49432120f, 0.50000000f, 0.50565743f, 0.51129311f, 0.51690692f, + 0.52249855f, 0.52806789f, 0.53361452f, 0.53913832f, 0.54463905f, + 0.55011642f, 0.55557024f, 0.56100029f, 0.56640625f, 0.57178795f, + 0.57714522f, 0.58247769f, 0.58778524f, 0.59306765f, 0.59832460f, + 0.60355598f, 0.60876143f, 0.61394083f, 0.61909395f, 0.62422055f, + 0.62932038f, 0.63439333f, 0.63943899f, 0.64445734f, 0.64944810f, + 0.65441096f, 0.65934587f, 0.66425246f, 0.66913062f, 0.67398012f, + 0.67880076f, 0.68359232f, 0.68835455f, 0.69308740f, 0.69779050f, + 0.70246369f, 0.70710677f, 0.71171963f, 0.71630198f, 0.72085363f, + 0.72537440f, 0.72986406f, 0.73432255f, 0.73874950f, 0.74314487f, + 0.74750835f, 0.75183982f, 0.75613910f, 0.76040596f, 0.76464027f, + 0.76884186f, 0.77301043f, 0.77714598f, 0.78124821f, 0.78531694f, + 0.78935206f, 0.79335338f, 0.79732066f, 0.80125386f, 0.80515265f, + 0.80901700f, 0.81284672f, 0.81664157f, 0.82040149f, 0.82412618f, + 0.82781565f, 0.83146966f, 0.83508795f, 0.83867061f, 0.84221727f, + 0.84572780f, 0.84920216f, 0.85264021f, 0.85604161f, 0.85940641f, + 0.86273444f, 0.86602545f, 0.86927933f, 0.87249607f, 0.87567532f, + 0.87881714f, 0.88192129f, 0.88498765f, 0.88801610f, 0.89100653f, + 0.89395881f, 0.89687276f, 0.89974827f, 0.90258533f, 0.90538365f, + 0.90814316f, 0.91086388f, 0.91354549f, 0.91618794f, 0.91879123f, + 0.92135513f, 0.92387950f, 0.92636442f, 0.92880958f, 0.93121493f, + 0.93358046f, 0.93590593f, 0.93819135f, 0.94043654f, 0.94264150f, + 0.94480604f, 0.94693011f, 0.94901365f, 0.95105654f, 0.95305866f, + 0.95501995f, 0.95694035f, 0.95881975f, 0.96065807f, 0.96245527f, + 0.96421117f, 0.96592581f, 0.96759909f, 0.96923089f, 0.97082120f, + 0.97236991f, 0.97387701f, 0.97534233f, 0.97676587f, 0.97814763f, + 0.97948742f, 0.98078531f, 0.98204112f, 0.98325491f, 0.98442656f, + 0.98555607f, 0.98664331f, 0.98768836f, 0.98869103f, 0.98965138f, + 0.99056935f, 0.99144489f, 0.99227792f, 0.99306846f, 0.99381649f, + 0.99452192f, 0.99518472f, 0.99580491f, 0.99638247f, 0.99691731f, + 0.99740952f, 0.99785894f, 0.99826562f, 0.99862951f, 0.99895066f, + 0.99922901f, 0.99946457f, 0.99965733f, 0.99980724f, 0.99991435f, + 0.99997860f, 1.00000000f, 0.99997860f, 0.99991435f, 0.99980724f, + 0.99965733f, 0.99946457f, 0.99922901f, 0.99895066f, 0.99862951f, + 0.99826562f, 0.99785894f, 0.99740946f, 0.99691731f, 0.99638247f, + 0.99580491f, 0.99518472f, 0.99452192f, 0.99381644f, 0.99306846f, + 0.99227792f, 0.99144489f, 0.99056935f, 0.98965138f, 0.98869103f, + 0.98768836f, 0.98664331f, 0.98555607f, 0.98442656f, 0.98325491f, + 0.98204112f, 0.98078525f, 0.97948742f, 0.97814757f, 0.97676587f, + 0.97534227f, 0.97387695f, 0.97236991f, 0.97082120f, 0.96923089f, + 0.96759909f, 0.96592581f, 0.96421117f, 0.96245521f, 0.96065807f, + 0.95881969f, 0.95694029f, 0.95501995f, 0.95305860f, 0.95105648f, + 0.94901365f, 0.94693011f, 0.94480604f, 0.94264150f, 0.94043654f, + 0.93819129f, 0.93590593f, 0.93358046f, 0.93121493f, 0.92880952f, + 0.92636436f, 0.92387950f, 0.92135507f, 0.91879123f, 0.91618794f, + 0.91354543f, 0.91086382f, 0.90814310f, 0.90538365f, 0.90258527f, + 0.89974827f, 0.89687276f, 0.89395875f, 0.89100647f, 0.88801610f, + 0.88498759f, 0.88192123f, 0.87881714f, 0.87567532f, 0.87249595f, + 0.86927933f, 0.86602539f, 0.86273432f, 0.85940641f, 0.85604161f, + 0.85264009f, 0.84920216f, 0.84572780f, 0.84221715f, 0.83867055f, + 0.83508795f, 0.83146954f, 0.82781565f, 0.82412612f, 0.82040137f, + 0.81664157f, 0.81284660f, 0.80901700f, 0.80515265f, 0.80125374f, + 0.79732066f, 0.79335332f, 0.78935200f, 0.78531694f, 0.78124815f, + 0.77714586f, 0.77301049f, 0.76884180f, 0.76464021f, 0.76040596f, + 0.75613904f, 0.75183970f, 0.74750835f, 0.74314481f, 0.73874938f, + 0.73432249f, 0.72986400f, 0.72537428f, 0.72085363f, 0.71630186f, + 0.71171951f, 0.70710677f, 0.70246363f, 0.69779032f, 0.69308734f, + 0.68835449f, 0.68359220f, 0.67880070f, 0.67398006f, 0.66913044f, + 0.66425240f, 0.65934575f, 0.65441096f, 0.64944804f, 0.64445722f, + 0.63943905f, 0.63439327f, 0.62932026f, 0.62422055f, 0.61909389f, + 0.61394072f, 0.60876143f, 0.60355592f, 0.59832448f, 0.59306765f, + 0.58778518f, 0.58247757f, 0.57714522f, 0.57178789f, 0.56640613f, + 0.56100023f, 0.55557019f, 0.55011630f, 0.54463905f, 0.53913826f, + 0.53361434f, 0.52806783f, 0.52249849f, 0.51690674f, 0.51129305f, + 0.50565726f, 0.50000006f, 0.49432117f, 0.48862115f, 0.48290038f, + 0.47715873f, 0.47139663f, 0.46561456f, 0.45981231f, 0.45399037f, + 0.44814920f, 0.44228864f, 0.43640912f, 0.43051112f, 0.42459446f, + 0.41865960f, 0.41270703f, 0.40673658f, 0.40074870f, 0.39474386f, + 0.38872188f, 0.38268328f, 0.37662849f, 0.37055734f, 0.36447033f, + 0.35836792f, 0.35224995f, 0.34611690f, 0.33996922f, 0.33380675f, + 0.32763001f, 0.32143945f, 0.31523487f, 0.30901679f, 0.30278572f, + 0.29654145f, 0.29028472f, 0.28401530f, 0.27773371f, 0.27144048f, + 0.26513538f, 0.25881892f, 0.25249159f, 0.24615324f, 0.23980433f, + 0.23344538f, 0.22707619f, 0.22069728f, 0.21430916f, 0.20791161f, + 0.20150517f, 0.19509031f, 0.18866688f, 0.18223536f, 0.17579627f, + 0.16934940f, 0.16289529f, 0.15643445f, 0.14996666f, 0.14349243f, + 0.13701232f, 0.13052608f, 0.12403426f, 0.11753736f, 0.11103519f, + 0.10452849f, 0.09801710f, 0.09150149f, 0.08498220f, 0.07845904f, + 0.07193252f, 0.06540315f, 0.05887074f, 0.05233581f, 0.04579888f, + 0.03925974f, 0.03271893f, 0.02617695f, 0.01963361f, 0.01308943f, + 0.00654493f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f}; + +// Hanning window: for 30ms with 1024 fft with symmetric zeros at 16kHz +static const float kBlocks480w1024[1024] = { + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00327249f, 0.00654494f, + 0.00981732f, 0.01308960f, 0.01636173f, 0.01963369f, 0.02290544f, + 0.02617695f, 0.02944817f, 0.03271908f, 0.03598964f, 0.03925982f, + 0.04252957f, 0.04579887f, 0.04906768f, 0.05233596f, 0.05560368f, + 0.05887080f, 0.06213730f, 0.06540313f, 0.06866825f, 0.07193266f, + 0.07519628f, 0.07845910f, 0.08172107f, 0.08498218f, 0.08824237f, + 0.09150162f, 0.09475989f, 0.09801714f, 0.10127335f, 0.10452846f, + 0.10778246f, 0.11103531f, 0.11428697f, 0.11753740f, 0.12078657f, + 0.12403446f, 0.12728101f, 0.13052620f, 0.13376999f, 0.13701233f, + 0.14025325f, 0.14349262f, 0.14673047f, 0.14996676f, 0.15320145f, + 0.15643448f, 0.15966582f, 0.16289547f, 0.16612339f, 0.16934951f, + 0.17257382f, 0.17579629f, 0.17901687f, 0.18223552f, 0.18545224f, + 0.18866697f, 0.19187967f, 0.19509032f, 0.19829889f, 0.20150533f, + 0.20470962f, 0.20791170f, 0.21111156f, 0.21430916f, 0.21750447f, + 0.22069745f, 0.22388805f, 0.22707628f, 0.23026206f, 0.23344538f, + 0.23662618f, 0.23980446f, 0.24298020f, 0.24615330f, 0.24932377f, + 0.25249159f, 0.25565669f, 0.25881904f, 0.26197866f, 0.26513544f, + 0.26828939f, 0.27144045f, 0.27458861f, 0.27773386f, 0.28087610f, + 0.28401536f, 0.28715158f, 0.29028466f, 0.29341471f, 0.29654160f, + 0.29966527f, 0.30278578f, 0.30590302f, 0.30901700f, 0.31212768f, + 0.31523499f, 0.31833893f, 0.32143945f, 0.32453656f, 0.32763019f, + 0.33072028f, 0.33380687f, 0.33688986f, 0.33996925f, 0.34304500f, + 0.34611708f, 0.34918544f, 0.35225007f, 0.35531089f, 0.35836795f, + 0.36142117f, 0.36447051f, 0.36751595f, 0.37055743f, 0.37359497f, + 0.37662852f, 0.37965801f, 0.38268346f, 0.38570479f, 0.38872197f, + 0.39173502f, 0.39474389f, 0.39774847f, 0.40074885f, 0.40374491f, + 0.40673664f, 0.40972406f, 0.41270703f, 0.41568562f, 0.41865975f, + 0.42162940f, 0.42459452f, 0.42755508f, 0.43051112f, 0.43346250f, + 0.43640924f, 0.43935132f, 0.44228873f, 0.44522133f, 0.44814920f, + 0.45107228f, 0.45399052f, 0.45690390f, 0.45981237f, 0.46271592f, + 0.46561453f, 0.46850815f, 0.47139674f, 0.47428030f, 0.47715878f, + 0.48003215f, 0.48290035f, 0.48576337f, 0.48862126f, 0.49147385f, + 0.49432120f, 0.49716330f, 0.50000000f, 0.50283140f, 0.50565743f, + 0.50847799f, 0.51129311f, 0.51410276f, 0.51690692f, 0.51970553f, + 0.52249855f, 0.52528602f, 0.52806789f, 0.53084403f, 0.53361452f, + 0.53637928f, 0.53913832f, 0.54189163f, 0.54463905f, 0.54738063f, + 0.55011642f, 0.55284631f, 0.55557024f, 0.55828828f, 0.56100029f, + 0.56370628f, 0.56640625f, 0.56910014f, 0.57178795f, 0.57446963f, + 0.57714522f, 0.57981455f, 0.58247769f, 0.58513463f, 0.58778524f, + 0.59042960f, 0.59306765f, 0.59569931f, 0.59832460f, 0.60094351f, + 0.60355598f, 0.60616195f, 0.60876143f, 0.61135441f, 0.61394083f, + 0.61652070f, 0.61909395f, 0.62166059f, 0.62422055f, 0.62677383f, + 0.62932038f, 0.63186020f, 0.63439333f, 0.63691956f, 0.63943899f, + 0.64195162f, 0.64445734f, 0.64695615f, 0.64944810f, 0.65193301f, + 0.65441096f, 0.65688187f, 0.65934587f, 0.66180271f, 0.66425246f, + 0.66669512f, 0.66913062f, 0.67155898f, 0.67398012f, 0.67639405f, + 0.67880076f, 0.68120021f, 0.68359232f, 0.68597710f, 0.68835455f, + 0.69072467f, 0.69308740f, 0.69544262f, 0.69779050f, 0.70013082f, + 0.70246369f, 0.70478904f, 0.70710677f, 0.70941699f, 0.71171963f, + 0.71401459f, 0.71630198f, 0.71858168f, 0.72085363f, 0.72311789f, + 0.72537440f, 0.72762316f, 0.72986406f, 0.73209721f, 0.73432255f, + 0.73653996f, 0.73874950f, 0.74095118f, 0.74314487f, 0.74533057f, + 0.74750835f, 0.74967808f, 0.75183982f, 0.75399351f, 0.75613910f, + 0.75827658f, 0.76040596f, 0.76252723f, 0.76464027f, 0.76674515f, + 0.76884186f, 0.77093029f, 0.77301043f, 0.77508241f, 0.77714598f, + 0.77920127f, 0.78124821f, 0.78328675f, 0.78531694f, 0.78733873f, + 0.78935206f, 0.79135692f, 0.79335338f, 0.79534125f, 0.79732066f, + 0.79929149f, 0.80125386f, 0.80320752f, 0.80515265f, 0.80708915f, + 0.80901700f, 0.81093621f, 0.81284672f, 0.81474853f, 0.81664157f, + 0.81852591f, 0.82040149f, 0.82226825f, 0.82412618f, 0.82597536f, + 0.82781565f, 0.82964706f, 0.83146966f, 0.83328325f, 0.83508795f, + 0.83688378f, 0.83867061f, 0.84044838f, 0.84221727f, 0.84397703f, + 0.84572780f, 0.84746957f, 0.84920216f, 0.85092574f, 0.85264021f, + 0.85434544f, 0.85604161f, 0.85772866f, 0.85940641f, 0.86107504f, + 0.86273444f, 0.86438453f, 0.86602545f, 0.86765707f, 0.86927933f, + 0.87089235f, 0.87249607f, 0.87409031f, 0.87567532f, 0.87725097f, + 0.87881714f, 0.88037390f, 0.88192129f, 0.88345921f, 0.88498765f, + 0.88650668f, 0.88801610f, 0.88951612f, 0.89100653f, 0.89248741f, + 0.89395881f, 0.89542055f, 0.89687276f, 0.89831537f, 0.89974827f, + 0.90117162f, 0.90258533f, 0.90398932f, 0.90538365f, 0.90676826f, + 0.90814316f, 0.90950841f, 0.91086388f, 0.91220951f, 0.91354549f, + 0.91487163f, 0.91618794f, 0.91749454f, 0.91879123f, 0.92007810f, + 0.92135513f, 0.92262226f, 0.92387950f, 0.92512691f, 0.92636442f, + 0.92759192f, 0.92880958f, 0.93001723f, 0.93121493f, 0.93240267f, + 0.93358046f, 0.93474817f, 0.93590593f, 0.93705362f, 0.93819135f, + 0.93931901f, 0.94043654f, 0.94154406f, 0.94264150f, 0.94372880f, + 0.94480604f, 0.94587320f, 0.94693011f, 0.94797695f, 0.94901365f, + 0.95004016f, 0.95105654f, 0.95206273f, 0.95305866f, 0.95404440f, + 0.95501995f, 0.95598525f, 0.95694035f, 0.95788521f, 0.95881975f, + 0.95974404f, 0.96065807f, 0.96156180f, 0.96245527f, 0.96333838f, + 0.96421117f, 0.96507370f, 0.96592581f, 0.96676767f, 0.96759909f, + 0.96842021f, 0.96923089f, 0.97003126f, 0.97082120f, 0.97160077f, + 0.97236991f, 0.97312868f, 0.97387701f, 0.97461486f, 0.97534233f, + 0.97605932f, 0.97676587f, 0.97746199f, 0.97814763f, 0.97882277f, + 0.97948742f, 0.98014158f, 0.98078531f, 0.98141843f, 0.98204112f, + 0.98265332f, 0.98325491f, 0.98384601f, 0.98442656f, 0.98499662f, + 0.98555607f, 0.98610497f, 0.98664331f, 0.98717111f, 0.98768836f, + 0.98819500f, 0.98869103f, 0.98917651f, 0.98965138f, 0.99011570f, + 0.99056935f, 0.99101239f, 0.99144489f, 0.99186671f, 0.99227792f, + 0.99267852f, 0.99306846f, 0.99344778f, 0.99381649f, 0.99417448f, + 0.99452192f, 0.99485862f, 0.99518472f, 0.99550015f, 0.99580491f, + 0.99609905f, 0.99638247f, 0.99665523f, 0.99691731f, 0.99716878f, + 0.99740952f, 0.99763954f, 0.99785894f, 0.99806762f, 0.99826562f, + 0.99845290f, 0.99862951f, 0.99879545f, 0.99895066f, 0.99909520f, + 0.99922901f, 0.99935216f, 0.99946457f, 0.99956632f, 0.99965733f, + 0.99973762f, 0.99980724f, 0.99986613f, 0.99991435f, 0.99995178f, + 0.99997860f, 0.99999464f, 1.00000000f, 0.99999464f, 0.99997860f, + 0.99995178f, 0.99991435f, 0.99986613f, 0.99980724f, 0.99973762f, + 0.99965733f, 0.99956632f, 0.99946457f, 0.99935216f, 0.99922901f, + 0.99909520f, 0.99895066f, 0.99879545f, 0.99862951f, 0.99845290f, + 0.99826562f, 0.99806762f, 0.99785894f, 0.99763954f, 0.99740946f, + 0.99716872f, 0.99691731f, 0.99665523f, 0.99638247f, 0.99609905f, + 0.99580491f, 0.99550015f, 0.99518472f, 0.99485862f, 0.99452192f, + 0.99417448f, 0.99381644f, 0.99344778f, 0.99306846f, 0.99267852f, + 0.99227792f, 0.99186671f, 0.99144489f, 0.99101239f, 0.99056935f, + 0.99011564f, 0.98965138f, 0.98917651f, 0.98869103f, 0.98819494f, + 0.98768836f, 0.98717111f, 0.98664331f, 0.98610497f, 0.98555607f, + 0.98499656f, 0.98442656f, 0.98384601f, 0.98325491f, 0.98265326f, + 0.98204112f, 0.98141843f, 0.98078525f, 0.98014158f, 0.97948742f, + 0.97882277f, 0.97814757f, 0.97746193f, 0.97676587f, 0.97605932f, + 0.97534227f, 0.97461486f, 0.97387695f, 0.97312862f, 0.97236991f, + 0.97160077f, 0.97082120f, 0.97003126f, 0.96923089f, 0.96842015f, + 0.96759909f, 0.96676761f, 0.96592581f, 0.96507365f, 0.96421117f, + 0.96333838f, 0.96245521f, 0.96156180f, 0.96065807f, 0.95974404f, + 0.95881969f, 0.95788515f, 0.95694029f, 0.95598525f, 0.95501995f, + 0.95404440f, 0.95305860f, 0.95206267f, 0.95105648f, 0.95004016f, + 0.94901365f, 0.94797695f, 0.94693011f, 0.94587314f, 0.94480604f, + 0.94372880f, 0.94264150f, 0.94154406f, 0.94043654f, 0.93931895f, + 0.93819129f, 0.93705362f, 0.93590593f, 0.93474817f, 0.93358046f, + 0.93240267f, 0.93121493f, 0.93001723f, 0.92880952f, 0.92759192f, + 0.92636436f, 0.92512691f, 0.92387950f, 0.92262226f, 0.92135507f, + 0.92007804f, 0.91879123f, 0.91749448f, 0.91618794f, 0.91487157f, + 0.91354543f, 0.91220951f, 0.91086382f, 0.90950835f, 0.90814310f, + 0.90676820f, 0.90538365f, 0.90398932f, 0.90258527f, 0.90117157f, + 0.89974827f, 0.89831525f, 0.89687276f, 0.89542055f, 0.89395875f, + 0.89248741f, 0.89100647f, 0.88951600f, 0.88801610f, 0.88650662f, + 0.88498759f, 0.88345915f, 0.88192123f, 0.88037384f, 0.87881714f, + 0.87725091f, 0.87567532f, 0.87409031f, 0.87249595f, 0.87089223f, + 0.86927933f, 0.86765701f, 0.86602539f, 0.86438447f, 0.86273432f, + 0.86107504f, 0.85940641f, 0.85772860f, 0.85604161f, 0.85434544f, + 0.85264009f, 0.85092574f, 0.84920216f, 0.84746951f, 0.84572780f, + 0.84397697f, 0.84221715f, 0.84044844f, 0.83867055f, 0.83688372f, + 0.83508795f, 0.83328319f, 0.83146954f, 0.82964706f, 0.82781565f, + 0.82597530f, 0.82412612f, 0.82226813f, 0.82040137f, 0.81852591f, + 0.81664157f, 0.81474847f, 0.81284660f, 0.81093609f, 0.80901700f, + 0.80708915f, 0.80515265f, 0.80320752f, 0.80125374f, 0.79929143f, + 0.79732066f, 0.79534125f, 0.79335332f, 0.79135686f, 0.78935200f, + 0.78733861f, 0.78531694f, 0.78328675f, 0.78124815f, 0.77920121f, + 0.77714586f, 0.77508223f, 0.77301049f, 0.77093029f, 0.76884180f, + 0.76674509f, 0.76464021f, 0.76252711f, 0.76040596f, 0.75827658f, + 0.75613904f, 0.75399339f, 0.75183970f, 0.74967796f, 0.74750835f, + 0.74533057f, 0.74314481f, 0.74095106f, 0.73874938f, 0.73653996f, + 0.73432249f, 0.73209721f, 0.72986400f, 0.72762305f, 0.72537428f, + 0.72311789f, 0.72085363f, 0.71858162f, 0.71630186f, 0.71401453f, + 0.71171951f, 0.70941705f, 0.70710677f, 0.70478898f, 0.70246363f, + 0.70013070f, 0.69779032f, 0.69544268f, 0.69308734f, 0.69072461f, + 0.68835449f, 0.68597704f, 0.68359220f, 0.68120021f, 0.67880070f, + 0.67639399f, 0.67398006f, 0.67155886f, 0.66913044f, 0.66669512f, + 0.66425240f, 0.66180259f, 0.65934575f, 0.65688181f, 0.65441096f, + 0.65193301f, 0.64944804f, 0.64695609f, 0.64445722f, 0.64195150f, + 0.63943905f, 0.63691956f, 0.63439327f, 0.63186014f, 0.62932026f, + 0.62677372f, 0.62422055f, 0.62166059f, 0.61909389f, 0.61652064f, + 0.61394072f, 0.61135429f, 0.60876143f, 0.60616189f, 0.60355592f, + 0.60094339f, 0.59832448f, 0.59569913f, 0.59306765f, 0.59042960f, + 0.58778518f, 0.58513451f, 0.58247757f, 0.57981461f, 0.57714522f, + 0.57446963f, 0.57178789f, 0.56910002f, 0.56640613f, 0.56370628f, + 0.56100023f, 0.55828822f, 0.55557019f, 0.55284619f, 0.55011630f, + 0.54738069f, 0.54463905f, 0.54189152f, 0.53913826f, 0.53637916f, + 0.53361434f, 0.53084403f, 0.52806783f, 0.52528596f, 0.52249849f, + 0.51970541f, 0.51690674f, 0.51410276f, 0.51129305f, 0.50847787f, + 0.50565726f, 0.50283122f, 0.50000006f, 0.49716327f, 0.49432117f, + 0.49147379f, 0.48862115f, 0.48576325f, 0.48290038f, 0.48003212f, + 0.47715873f, 0.47428021f, 0.47139663f, 0.46850798f, 0.46561456f, + 0.46271589f, 0.45981231f, 0.45690379f, 0.45399037f, 0.45107210f, + 0.44814920f, 0.44522130f, 0.44228864f, 0.43935123f, 0.43640912f, + 0.43346232f, 0.43051112f, 0.42755505f, 0.42459446f, 0.42162928f, + 0.41865960f, 0.41568545f, 0.41270703f, 0.40972400f, 0.40673658f, + 0.40374479f, 0.40074870f, 0.39774850f, 0.39474386f, 0.39173496f, + 0.38872188f, 0.38570464f, 0.38268328f, 0.37965804f, 0.37662849f, + 0.37359491f, 0.37055734f, 0.36751580f, 0.36447033f, 0.36142117f, + 0.35836792f, 0.35531086f, 0.35224995f, 0.34918529f, 0.34611690f, + 0.34304500f, 0.33996922f, 0.33688980f, 0.33380675f, 0.33072016f, + 0.32763001f, 0.32453656f, 0.32143945f, 0.31833887f, 0.31523487f, + 0.31212750f, 0.30901679f, 0.30590302f, 0.30278572f, 0.29966521f, + 0.29654145f, 0.29341453f, 0.29028472f, 0.28715155f, 0.28401530f, + 0.28087601f, 0.27773371f, 0.27458847f, 0.27144048f, 0.26828936f, + 0.26513538f, 0.26197854f, 0.25881892f, 0.25565651f, 0.25249159f, + 0.24932374f, 0.24615324f, 0.24298008f, 0.23980433f, 0.23662600f, + 0.23344538f, 0.23026201f, 0.22707619f, 0.22388794f, 0.22069728f, + 0.21750426f, 0.21430916f, 0.21111152f, 0.20791161f, 0.20470949f, + 0.20150517f, 0.19829892f, 0.19509031f, 0.19187963f, 0.18866688f, + 0.18545210f, 0.18223536f, 0.17901689f, 0.17579627f, 0.17257376f, + 0.16934940f, 0.16612324f, 0.16289529f, 0.15966584f, 0.15643445f, + 0.15320137f, 0.14996666f, 0.14673033f, 0.14349243f, 0.14025325f, + 0.13701232f, 0.13376991f, 0.13052608f, 0.12728085f, 0.12403426f, + 0.12078657f, 0.11753736f, 0.11428688f, 0.11103519f, 0.10778230f, + 0.10452849f, 0.10127334f, 0.09801710f, 0.09475980f, 0.09150149f, + 0.08824220f, 0.08498220f, 0.08172106f, 0.07845904f, 0.07519618f, + 0.07193252f, 0.06866808f, 0.06540315f, 0.06213728f, 0.05887074f, + 0.05560357f, 0.05233581f, 0.04906749f, 0.04579888f, 0.04252954f, + 0.03925974f, 0.03598953f, 0.03271893f, 0.02944798f, 0.02617695f, + 0.02290541f, 0.01963361f, 0.01636161f, 0.01308943f, 0.00981712f, + 0.00654493f, 0.00327244f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f}; + +#endif // MODULES_AUDIO_PROCESSING_LEGACY_NS_WINDOWS_PRIVATE_H_ diff --git a/modules/audio_processing/ns/BUILD.gn b/modules/audio_processing/ns/BUILD.gn new file mode 100644 index 0000000000..077cb002f5 --- /dev/null +++ b/modules/audio_processing/ns/BUILD.gn @@ -0,0 +1,104 @@ +# 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/fft4g", + "../../../rtc_base:checks", + "../../../rtc_base:rtc_base_approved", + "../../../rtc_base:safe_minmax", + "../../../rtc_base/system:arch", + "../../../system_wrappers:cpu_features_api", + "../../../system_wrappers:field_trial", + "../../../system_wrappers:metrics", + "../utility:cascaded_biquad_filter", + "../utility:ooura_fft", + "//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:cpu_features_api", + "../../../test:test_support", + "../utility:cascaded_biquad_filter", + "//third_party/abseil-cpp/absl/types:optional", + ] + + defines = [] + + if (rtc_enable_protobuf) { + sources += [] + } + } +} diff --git a/modules/audio_processing/ns/defines.h b/modules/audio_processing/ns/defines.h deleted file mode 100644 index 2935f2591a..0000000000 --- a/modules/audio_processing/ns/defines.h +++ /dev/null @@ -1,56 +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 MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ -#define 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 // MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ diff --git a/modules/audio_processing/ns/fast_math.cc b/modules/audio_processing/ns/fast_math.cc new file mode 100644 index 0000000000..d13110c43f --- /dev/null +++ b/modules/audio_processing/ns/fast_math.cc @@ -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 +#include + +#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 x, rtc::ArrayView 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 x, rtc::ArrayView y) { + for (size_t k = 0; k < x.size(); ++k) { + y[k] = ExpApproximation(x[k]); + } +} + +void ExpApproximationSignFlip(rtc::ArrayView x, + rtc::ArrayView y) { + for (size_t k = 0; k < x.size(); ++k) { + y[k] = ExpApproximation(-x[k]); + } +} + +} // namespace webrtc diff --git a/modules/audio_processing/ns/fast_math.h b/modules/audio_processing/ns/fast_math.h new file mode 100644 index 0000000000..0aefee940b --- /dev/null +++ b/modules/audio_processing/ns/fast_math.h @@ -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 x, rtc::ArrayView 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 x, rtc::ArrayView y); +void ExpApproximationSignFlip(rtc::ArrayView x, + rtc::ArrayView y); +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_FAST_MATH_H_ diff --git a/modules/audio_processing/ns/histograms.cc b/modules/audio_processing/ns/histograms.cc new file mode 100644 index 0000000000..1d4f4590d2 --- /dev/null +++ b/modules/audio_processing/ns/histograms.cc @@ -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 diff --git a/modules/audio_processing/ns/histograms.h b/modules/audio_processing/ns/histograms.h new file mode 100644 index 0000000000..9640e743cf --- /dev/null +++ b/modules/audio_processing/ns/histograms.h @@ -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 + +#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 get_lrt() const { return lrt_; } + rtc::ArrayView get_spectral_flatness() const { + return spectral_flatness_; + } + rtc::ArrayView get_spectral_diff() const { + return spectral_diff_; + } + + private: + std::array lrt_; + std::array spectral_flatness_; + std::array spectral_diff_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_HISTOGRAMS_H_ diff --git a/modules/audio_processing/ns/noise_estimator.cc b/modules/audio_processing/ns/noise_estimator.cc new file mode 100644 index 0000000000..5367545f25 --- /dev/null +++ b/modules/audio_processing/ns/noise_estimator.cc @@ -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 + +#include "modules/audio_processing/ns/fast_math.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +namespace { + +// Log(i). +constexpr std::array 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 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 speech_probability, + rtc::ArrayView 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 diff --git a/modules/audio_processing/ns/noise_estimator.h b/modules/audio_processing/ns/noise_estimator.h new file mode 100644 index 0000000000..0c0466a679 --- /dev/null +++ b/modules/audio_processing/ns/noise_estimator.h @@ -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 + +#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 signal_spectrum, + float signal_spectral_sum); + + // Performs the second step of the estimator update. + void PostUpdate( + rtc::ArrayView speech_probability, + rtc::ArrayView signal_spectrum); + + // Returns the noise spectral estimate. + rtc::ArrayView get_noise_spectrum() const { + return noise_spectrum_; + } + + // Returns the noise from the previous frame. + rtc::ArrayView get_prev_noise_spectrum() + const { + return prev_noise_spectrum_; + } + + // Returns a noise spectral estimate based on white and pink noise parameters. + rtc::ArrayView get_parametric_noise_spectrum() + const { + return parametric_noise_spectrum_; + } + rtc::ArrayView + 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 prev_noise_spectrum_; + std::array conservative_noise_spectrum_; + std::array parametric_noise_spectrum_; + std::array noise_spectrum_; + QuantileNoiseEstimator quantile_noise_estimator_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_ESTIMATOR_H_ diff --git a/modules/audio_processing/ns/noise_suppressor.cc b/modules/audio_processing/ns/noise_suppressor.cc new file mode 100644 index 0000000000..89e1fe0d91 --- /dev/null +++ b/modules/audio_processing/ns/noise_suppressor.cc @@ -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 +#include +#include +#include + +#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 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 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 frame, + rtc::ArrayView old_data, + rtc::ArrayView 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 extended_frame, + rtc::ArrayView overlap_memory, + rtc::ArrayView 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 frame, + rtc::ArrayView delay_buffer, + rtc::ArrayView 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 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 frame, + rtc::ArrayView 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 real, + rtc::ArrayView imag, + rtc::ArrayView 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 filter, + rtc::ArrayView prev_signal_spectrum, + rtc::ArrayView signal_spectrum, + rtc::ArrayView prev_noise_spectrum, + rtc::ArrayView noise_spectrum, + rtc::ArrayView prior_snr, + rtc::ArrayView 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 filter, + rtc::ArrayView speech_probability, + rtc::ArrayView prev_analysis_signal_spectrum, + rtc::ArrayView 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(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(suppression_params_, num_bands_); + } +} + +void NoiseSuppressor::AggregateWienerFilters( + rtc::ArrayView filter) const { + rtc::ArrayView 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 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 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& ch_p = channels_[ch]; + rtc::ArrayView y_band0( + &audio.split_bands_const(ch)[0][0], kNsFrameSize); + + // Form an extended frame and apply analysis filter bank windowing. + std::array extended_frame; + FormExtendedFrame(y_band0, ch_p->analyze_analysis_memory, extended_frame); + ApplyFilterBankWindow(extended_frame); + + // Compute the magnitude spectrum. + std::array real; + std::array imag; + fft_.Fft(extended_frame, real, imag); + + std::array 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 post_snr; + std::array 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 filter_bank_states_stack; + rtc::ArrayView filter_bank_states( + filter_bank_states_stack.data(), num_channels_); + std::array upper_band_gains_stack; + rtc::ArrayView upper_band_gains(upper_band_gains_stack.data(), + num_channels_); + std::array energies_before_filtering_stack; + rtc::ArrayView energies_before_filtering( + energies_before_filtering_stack.data(), num_channels_); + std::array gain_adjustments_stack; + rtc::ArrayView 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( + filter_bank_states_heap_.data(), num_channels_); + upper_band_gains = + rtc::ArrayView(upper_band_gains_heap_.data(), num_channels_); + energies_before_filtering = rtc::ArrayView( + energies_before_filtering_heap_.data(), num_channels_); + gain_adjustments = + rtc::ArrayView(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 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 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 filter_data; + rtc::ArrayView 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 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 y_band( + &audio->split_bands(ch)[b][0], kNsFrameSize); + std::array 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 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 diff --git a/modules/audio_processing/ns/noise_suppressor.h b/modules/audio_processing/ns/noise_suppressor.h new file mode 100644 index 0000000000..d9628869bb --- /dev/null +++ b/modules/audio_processing/ns/noise_suppressor.h @@ -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 +#include + +#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 prev_analysis_signal_spectrum; + std::array analyze_analysis_memory; + std::array process_analysis_memory; + std::array process_synthesis_memory; + std::vector> process_delay_memory; + }; + + struct FilterBankState { + std::array real; + std::array imag; + std::array extended_frame; + }; + + std::vector filter_bank_states_heap_; + std::vector upper_band_gains_heap_; + std::vector energies_before_filtering_heap_; + std::vector gain_adjustments_heap_; + std::vector> channels_; + + // Aggregates the Wiener filters into a single filter to use. + void AggregateWienerFilters( + rtc::ArrayView filter) const; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSOR_H_ diff --git a/modules/audio_processing/ns/noise_suppressor_unittest.cc b/modules/audio_processing/ns/noise_suppressor_unittest.cc new file mode 100644 index 0000000000..28ea63ae40 --- /dev/null +++ b/modules/audio_processing/ns/noise_suppressor_unittest.cc @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include +#include + +#include "rtc_base/strings/string_builder.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +std::string ProduceDebugText(int sample_rate_hz, + size_t num_channels, + NsConfig::SuppressionLevel level) { + rtc::StringBuilder ss; + ss << "Sample rate: " << sample_rate_hz << ", num_channels: " << num_channels + << ", level: " << static_cast(level); + return ss.Release(); +} + +void PopulateInputFrameWithIdenticalChannels(size_t num_channels, + size_t num_bands, + size_t frame_index, + AudioBuffer* audio) { + for (size_t ch = 0; ch < num_channels; ++ch) { + for (size_t b = 0; b < num_bands; ++b) { + for (size_t i = 0; i < 160; ++i) { + float value = static_cast(frame_index * 160 + i); + audio->split_bands(ch)[b][i] = (value > 0 ? 5000 * b + value : 0); + } + } + } +} + +void VerifyIdenticalChannels(size_t num_channels, + size_t num_bands, + size_t frame_index, + const AudioBuffer& audio) { + EXPECT_GT(num_channels, 1u); + for (size_t ch = 1; ch < num_channels; ++ch) { + for (size_t b = 0; b < num_bands; ++b) { + for (size_t i = 0; i < 160; ++i) { + EXPECT_EQ(audio.split_bands_const(ch)[b][i], + audio.split_bands_const(0)[b][i]); + } + } + } +} + +} // namespace + +// Verifies that the same noise reduction effect is applied to all channels. +TEST(NoiseSuppressor, IdenticalChannelEffects) { + for (auto rate : {16000, 32000, 48000}) { + for (auto num_channels : {1, 4, 8}) { + for (auto level : + {NsConfig::SuppressionLevel::k6dB, NsConfig::SuppressionLevel::k12dB, + NsConfig::SuppressionLevel::k18dB, + NsConfig::SuppressionLevel::k21dB}) { + SCOPED_TRACE(ProduceDebugText(rate, num_channels, level)); + + const size_t num_bands = rate / 16000; + // const int frame_length = rtc::CheckedDivExact(rate, 100); + AudioBuffer audio(rate, num_channels, rate, num_channels, rate, + num_channels); + NsConfig cfg; + NoiseSuppressor ns(cfg, rate, num_channels); + for (size_t frame_index = 0; frame_index < 1000; ++frame_index) { + if (rate > 16000) { + audio.SplitIntoFrequencyBands(); + } + + PopulateInputFrameWithIdenticalChannels(num_channels, num_bands, + frame_index, &audio); + + ns.Analyze(audio); + ns.Process(&audio); + if (num_channels > 1) { + VerifyIdenticalChannels(num_channels, num_bands, frame_index, + audio); + } + } + } + } + } +} + +} // namespace webrtc diff --git a/modules/audio_processing/ns/ns_common.h b/modules/audio_processing/ns/ns_common.h new file mode 100644 index 0000000000..d6149f72a7 --- /dev/null +++ b/modules/audio_processing/ns/ns_common.h @@ -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 + +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_ diff --git a/modules/audio_processing/ns/ns_config.h b/modules/audio_processing/ns/ns_config.h new file mode 100644 index 0000000000..0a285e9cea --- /dev/null +++ b/modules/audio_processing/ns/ns_config.h @@ -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_ diff --git a/modules/audio_processing/ns/ns_fft.cc b/modules/audio_processing/ns/ns_fft.cc new file mode 100644 index 0000000000..8d1c43fea7 --- /dev/null +++ b/modules/audio_processing/ns/ns_fft.cc @@ -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/fft4g/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 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 time_data, + rtc::ArrayView real, + rtc::ArrayView 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 real, + rtc::ArrayView imag, + rtc::ArrayView 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 diff --git a/modules/audio_processing/ns/ns_fft.h b/modules/audio_processing/ns/ns_fft.h new file mode 100644 index 0000000000..539251eef2 --- /dev/null +++ b/modules/audio_processing/ns/ns_fft.h @@ -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 + +#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 time_data, + rtc::ArrayView real, + rtc::ArrayView imag); + + // Transforms the signal from frequency to time domain. + void Ifft(rtc::ArrayView real, + rtc::ArrayView imag, + rtc::ArrayView time_data); + + private: + std::vector bit_reversal_state_; + std::vector tables_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_NS_FFT_H_ diff --git a/modules/audio_processing/ns/prior_signal_model.cc b/modules/audio_processing/ns/prior_signal_model.cc new file mode 100644 index 0000000000..f25a1e2060 --- /dev/null +++ b/modules/audio_processing/ns/prior_signal_model.cc @@ -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 diff --git a/modules/audio_processing/ns/prior_signal_model.h b/modules/audio_processing/ns/prior_signal_model.h new file mode 100644 index 0000000000..dcfa7ea709 --- /dev/null +++ b/modules/audio_processing/ns/prior_signal_model.h @@ -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_ diff --git a/modules/audio_processing/ns/prior_signal_model_estimator.cc b/modules/audio_processing/ns/prior_signal_model_estimator.cc new file mode 100644 index 0000000000..c814658e57 --- /dev/null +++ b/modules/audio_processing/ns/prior_signal_model_estimator.cc @@ -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 +#include + +#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 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 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 diff --git a/modules/audio_processing/ns/prior_signal_model_estimator.h b/modules/audio_processing/ns/prior_signal_model_estimator.h new file mode 100644 index 0000000000..d178323dba --- /dev/null +++ b/modules/audio_processing/ns/prior_signal_model_estimator.h @@ -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_ diff --git a/modules/audio_processing/ns/quantile_noise_estimator.cc b/modules/audio_processing/ns/quantile_noise_estimator.cc new file mode 100644 index 0000000000..bab494ff21 --- /dev/null +++ b/modules/audio_processing/ns/quantile_noise_estimator.cc @@ -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 + +#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 signal_spectrum, + rtc::ArrayView noise_spectrum) { + std::array 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(kFftSizeBy2Plus1)) { + const float one_by_counter_plus_1 = 1.f / (counter_[s] + 1.f); + for (int i = 0, j = k; i < static_cast(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(&log_quantile_[quantile_index_to_return], + kFftSizeBy2Plus1), + quantile_); + } + + std::copy(quantile_.begin(), quantile_.end(), noise_spectrum.begin()); +} + +} // namespace webrtc diff --git a/modules/audio_processing/ns/quantile_noise_estimator.h b/modules/audio_processing/ns/quantile_noise_estimator.h new file mode 100644 index 0000000000..67d1512209 --- /dev/null +++ b/modules/audio_processing/ns/quantile_noise_estimator.h @@ -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 +#include + +#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 signal_spectrum, + rtc::ArrayView noise_spectrum); + + private: + std::array density_; + std::array log_quantile_; + std::array quantile_; + std::array counter_; + int num_updates_ = 1; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_QUANTILE_NOISE_ESTIMATOR_H_ diff --git a/modules/audio_processing/ns/signal_model.cc b/modules/audio_processing/ns/signal_model.cc new file mode 100644 index 0000000000..364bfd00d8 --- /dev/null +++ b/modules/audio_processing/ns/signal_model.cc @@ -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 diff --git a/modules/audio_processing/ns/signal_model.h b/modules/audio_processing/ns/signal_model.h new file mode 100644 index 0000000000..6614d38a38 --- /dev/null +++ b/modules/audio_processing/ns/signal_model.h @@ -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 + +#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 avg_log_lrt; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_SIGNAL_MODEL_H_ diff --git a/modules/audio_processing/ns/signal_model_estimator.cc b/modules/audio_processing/ns/signal_model_estimator.cc new file mode 100644 index 0000000000..67dd3bb687 --- /dev/null +++ b/modules/audio_processing/ns/signal_model_estimator.cc @@ -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 conservative_noise_spectrum, + rtc::ArrayView 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 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 prior_snr, + rtc::ArrayView post_snr, + rtc::ArrayView 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 prior_snr, + rtc::ArrayView post_snr, + rtc::ArrayView conservative_noise_spectrum, + rtc::ArrayView 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 diff --git a/modules/audio_processing/ns/signal_model_estimator.h b/modules/audio_processing/ns/signal_model_estimator.h new file mode 100644 index 0000000000..58ce00acbf --- /dev/null +++ b/modules/audio_processing/ns/signal_model_estimator.h @@ -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 + +#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 prior_snr, + rtc::ArrayView post_snr, + rtc::ArrayView conservative_noise_spectrum, + rtc::ArrayView 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_ diff --git a/modules/audio_processing/ns/speech_probability_estimator.cc b/modules/audio_processing/ns/speech_probability_estimator.cc new file mode 100644 index 0000000000..fce9bc8e07 --- /dev/null +++ b/modules/audio_processing/ns/speech_probability_estimator.cc @@ -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 +#include + +#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 prior_snr, + rtc::ArrayView post_snr, + rtc::ArrayView conservative_noise_spectrum, + rtc::ArrayView 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 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 diff --git a/modules/audio_processing/ns/speech_probability_estimator.h b/modules/audio_processing/ns/speech_probability_estimator.h new file mode 100644 index 0000000000..259c3b6776 --- /dev/null +++ b/modules/audio_processing/ns/speech_probability_estimator.h @@ -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 + +#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 prior_snr, + rtc::ArrayView post_snr, + rtc::ArrayView conservative_noise_spectrum, + rtc::ArrayView signal_spectrum, + float signal_spectral_sum, + float signal_energy); + + float get_prior_probability() const { return prior_speech_prob_; } + rtc::ArrayView get_probability() { return speech_probability_; } + + private: + SignalModelEstimator signal_model_estimator_; + float prior_speech_prob_ = .5f; + std::array speech_probability_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_SPEECH_PROBABILITY_ESTIMATOR_H_ diff --git a/modules/audio_processing/ns/suppression_params.cc b/modules/audio_processing/ns/suppression_params.cc new file mode 100644 index 0000000000..9a6bd5a587 --- /dev/null +++ b/modules/audio_processing/ns/suppression_params.cc @@ -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 diff --git a/modules/audio_processing/ns/suppression_params.h b/modules/audio_processing/ns/suppression_params.h new file mode 100644 index 0000000000..ad11977d81 --- /dev/null +++ b/modules/audio_processing/ns/suppression_params.h @@ -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_ diff --git a/modules/audio_processing/ns/wiener_filter.cc b/modules/audio_processing/ns/wiener_filter.cc new file mode 100644 index 0000000000..e14b7970d9 --- /dev/null +++ b/modules/audio_processing/ns/wiener_filter.cc @@ -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 +#include +#include +#include + +#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 noise_spectrum, + rtc::ArrayView prev_noise_spectrum, + rtc::ArrayView parametric_noise_spectrum, + rtc::ArrayView 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 diff --git a/modules/audio_processing/ns/wiener_filter.h b/modules/audio_processing/ns/wiener_filter.h new file mode 100644 index 0000000000..b55c5dc59d --- /dev/null +++ b/modules/audio_processing/ns/wiener_filter.h @@ -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 + +#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 noise_spectrum, + rtc::ArrayView prev_noise_spectrum, + rtc::ArrayView parametric_noise_spectrum, + rtc::ArrayView 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 get_filter() const { + return filter_; + } + + private: + const SuppressionParams& suppression_params_; + std::array spectrum_prev_process_; + std::array initial_spectral_estimate_; + std::array filter_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_NS_WIENER_FILTER_H_ diff --git a/modules/audio_processing/ns/windows_private.h b/modules/audio_processing/ns/windows_private.h deleted file mode 100644 index 17792ecdfe..0000000000 --- a/modules/audio_processing/ns/windows_private.h +++ /dev/null @@ -1,672 +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 MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_ -#define 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 // MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_ diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc index 8c6a46d778..7f354a9164 100644 --- a/modules/audio_processing/test/audio_processing_simulator.cc +++ b/modules/audio_processing/test/audio_processing_simulator.cc @@ -504,6 +504,12 @@ void AudioProcessingSimulator::CreateAudioProcessor() { *settings_.maximum_internal_processing_rate; } + const bool use_legacy_ns = + settings_.use_legacy_ns && *settings_.use_legacy_ns; + if (use_legacy_ns) { + apm_config.noise_suppression.use_legacy_ns = use_legacy_ns; + } + if (settings_.use_ns) { apm_config.noise_suppression.enabled = *settings_.use_ns; } diff --git a/modules/audio_processing/test/audio_processing_simulator.h b/modules/audio_processing/test/audio_processing_simulator.h index 340c9d331d..bf718b2fe5 100644 --- a/modules/audio_processing/test/audio_processing_simulator.h +++ b/modules/audio_processing/test/audio_processing_simulator.h @@ -65,6 +65,7 @@ struct SimulationSettings { absl::optional use_extended_filter; absl::optional use_drift_compensation; absl::optional use_legacy_aec; + absl::optional use_legacy_ns; absl::optional use_experimental_agc; absl::optional use_experimental_agc_agc2_level_estimator; absl::optional experimental_agc_disable_digital_adaptive; diff --git a/modules/audio_processing/test/audioproc_float_impl.cc b/modules/audio_processing/test/audioproc_float_impl.cc index 6428e9d40d..3e755b585c 100644 --- a/modules/audio_processing/test/audioproc_float_impl.cc +++ b/modules/audio_processing/test/audioproc_float_impl.cc @@ -129,6 +129,10 @@ ABSL_FLAG(int, use_legacy_aec, kParameterNotSpecifiedValue, "Activate (1) or deactivate(0) the legacy AEC"); +ABSL_FLAG(int, + use_legacy_ns, + kParameterNotSpecifiedValue, + "Activate (1) or deactivate(0) the legacy AEC"); ABSL_FLAG(int, experimental_agc, kParameterNotSpecifiedValue, @@ -393,6 +397,8 @@ SimulationSettings CreateSettings() { SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_legacy_aec), &settings.use_legacy_aec); + SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_legacy_ns), + &settings.use_legacy_ns); SetSettingIfFlagSet(absl::GetFlag(FLAGS_experimental_agc), &settings.use_experimental_agc); SetSettingIfFlagSet( diff --git a/modules/audio_processing/transient/transient_suppressor.cc b/modules/audio_processing/transient/transient_suppressor.cc index 2463efaacc..b10b05518d 100644 --- a/modules/audio_processing/transient/transient_suppressor.cc +++ b/modules/audio_processing/transient/transient_suppressor.cc @@ -20,7 +20,7 @@ #include "common_audio/include/audio_util.h" #include "common_audio/signal_processing/include/signal_processing_library.h" #include "common_audio/third_party/fft4g/fft4g.h" -#include "modules/audio_processing/ns/windows_private.h" +#include "modules/audio_processing/legacy_ns/windows_private.h" #include "modules/audio_processing/transient/common.h" #include "modules/audio_processing/transient/transient_detector.h" #include "rtc_base/checks.h" diff --git a/resources/audio_processing/output_data_fixed.pb.sha1 b/resources/audio_processing/output_data_fixed.pb.sha1 index ea3d97919e..421756f9fc 100644 --- a/resources/audio_processing/output_data_fixed.pb.sha1 +++ b/resources/audio_processing/output_data_fixed.pb.sha1 @@ -1 +1 @@ -e9569d846d21e027bfdcae76a40146bc10d49d54 \ No newline at end of file +a3bf32dd233cbc5009bd4efce12a5e019771cafb \ No newline at end of file diff --git a/resources/audio_processing/output_data_float.pb.sha1 b/resources/audio_processing/output_data_float.pb.sha1 index b5d123d641..c654056a94 100644 --- a/resources/audio_processing/output_data_float.pb.sha1 +++ b/resources/audio_processing/output_data_float.pb.sha1 @@ -1 +1 @@ -53dd63154cc2694a3425596d9a8300fa2c66215d \ No newline at end of file +d2c18cded77614146135b1fd1296c4211d22d754 \ No newline at end of file