├── assets ├── babble_15dB.wav ├── 1531809169657.png ├── 1531809187181.png ├── 1544091468844.png ├── speech with noise 32k.wav ├── NoisySpeech-16k_16bit_stereo.wav ├── test_case │ ├── rnnoise_babble_15dB.wav │ ├── speexdsp_babble_15dB.wav │ ├── webrtc_ns_kHigh_babble_15dB.wav │ ├── webrtc_ns_kLow_babble_15dB.wav │ ├── webrtc_ns_kModerate_babble_15dB.wav │ └── test_case.md └── music_with_noise_48k_16bit_21db.wav ├── WebRtc_official ├── stdafx.cpp ├── stdafx.h ├── include │ ├── splitting_filter │ │ ├── readme.txt │ │ ├── sparse_fir_filter.h │ │ ├── sparse_fir_filter.cc │ │ ├── splitting_filter.h │ │ ├── three_band_filter_bank.h │ │ ├── splitting_filter_unittest.cc │ │ ├── splitting_filter.cc │ │ └── splitting_filter.c │ ├── rtc_base │ │ ├── checks.h │ │ ├── checks.cc │ │ ├── inline.h │ │ ├── compile_assert_c.h │ │ ├── constructormagic.h │ │ ├── type_traits.h │ │ └── safe_compare.h │ ├── AduioFile │ │ ├── AudioFile.cpp │ │ └── AudioFile.h │ ├── audio_processing │ │ ├── fft4g.h │ │ ├── spl_sqrt_floor.h │ │ ├── dot_product_with_scale.cc │ │ ├── dot_product_with_scale.h │ │ ├── audio_util.cc │ │ ├── spl_sqrt_floor.c │ │ ├── spl_inl.h │ │ └── audio_util.h │ └── ns │ │ ├── noise_suppression_x.c │ │ ├── noise_suppression.c │ │ ├── defines.h │ │ ├── nsx_defines.h │ │ ├── noise_suppression_x.h │ │ ├── noise_suppression.h │ │ └── ns_core.h ├── targetver.h ├── WebRtc_official.cpp ├── WebRtc_official.vcxproj.filters └── WebRtc_NS.h ├── my_splitting_filter ├── audio_48k_mono.wav ├── rtc_base │ ├── checks.cc │ ├── checks.h │ ├── inline.h │ ├── compile_assert_c.h │ ├── constructormagic.h │ ├── type_traits.h │ └── safe_compare.h ├── AduioFile │ ├── AudioFile.cpp │ └── AudioFile.h ├── my_splitting_filter.cpp ├── my_splitting_filter.rc ├── audio_with_noise_16k_stereo.wav ├── 3 bands splitting sync output.wav ├── splitting_filter │ ├── spl_sqrt_floor.h │ ├── dot_product_with_scale.cc │ ├── dot_product_with_scale.h │ ├── audio_util.cc │ ├── sparse_fir_filter.h │ ├── sparse_fir_filter.cc │ ├── spl_sqrt_floor.c │ ├── splitting_filter.h │ ├── three_band_filter_bank.h │ ├── splitting_filter_unittest.cc │ ├── splitting_filter.cc │ ├── spl_inl.h │ ├── audio_util.h │ └── splitting_filter.c └── my_splitting_filter.vcxproj.filters ├── WebRtc_official.sln ├── .gitattributes ├── readme.md ├── readme_cn.md └── .gitignore /assets/babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/babble_15dB.wav -------------------------------------------------------------------------------- /WebRtc_official/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/stdafx.cpp -------------------------------------------------------------------------------- /WebRtc_official/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/stdafx.h -------------------------------------------------------------------------------- /assets/1531809169657.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/1531809169657.png -------------------------------------------------------------------------------- /assets/1531809187181.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/1531809187181.png -------------------------------------------------------------------------------- /assets/1544091468844.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/1544091468844.png -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/readme.txt: -------------------------------------------------------------------------------- 1 | splitting_filter_unittest.cc 2 | splitting_filter.cc 3 | 4 | can be deleted. -------------------------------------------------------------------------------- /WebRtc_official/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/targetver.h -------------------------------------------------------------------------------- /assets/speech with noise 32k.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/speech with noise 32k.wav -------------------------------------------------------------------------------- /WebRtc_official/WebRtc_official.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/WebRtc_official.cpp -------------------------------------------------------------------------------- /my_splitting_filter/audio_48k_mono.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/audio_48k_mono.wav -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/checks.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/rtc_base/checks.cc -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/checks.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/rtc_base/checks.h -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/checks.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/include/rtc_base/checks.h -------------------------------------------------------------------------------- /assets/NoisySpeech-16k_16bit_stereo.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/NoisySpeech-16k_16bit_stereo.wav -------------------------------------------------------------------------------- /assets/test_case/rnnoise_babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/test_case/rnnoise_babble_15dB.wav -------------------------------------------------------------------------------- /assets/test_case/speexdsp_babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/test_case/speexdsp_babble_15dB.wav -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/checks.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/include/rtc_base/checks.cc -------------------------------------------------------------------------------- /assets/music_with_noise_48k_16bit_21db.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/music_with_noise_48k_16bit_21db.wav -------------------------------------------------------------------------------- /my_splitting_filter/AduioFile/AudioFile.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/AduioFile/AudioFile.cpp -------------------------------------------------------------------------------- /my_splitting_filter/my_splitting_filter.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/my_splitting_filter.cpp -------------------------------------------------------------------------------- /my_splitting_filter/my_splitting_filter.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/my_splitting_filter.rc -------------------------------------------------------------------------------- /WebRtc_official/include/AduioFile/AudioFile.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/WebRtc_official/include/AduioFile/AudioFile.cpp -------------------------------------------------------------------------------- /assets/test_case/webrtc_ns_kHigh_babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/test_case/webrtc_ns_kHigh_babble_15dB.wav -------------------------------------------------------------------------------- /assets/test_case/webrtc_ns_kLow_babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/test_case/webrtc_ns_kLow_babble_15dB.wav -------------------------------------------------------------------------------- /my_splitting_filter/audio_with_noise_16k_stereo.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/audio_with_noise_16k_stereo.wav -------------------------------------------------------------------------------- /assets/test_case/webrtc_ns_kModerate_babble_15dB.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/assets/test_case/webrtc_ns_kModerate_babble_15dB.wav -------------------------------------------------------------------------------- /my_splitting_filter/ 3 bands splitting sync output.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagger2048/WebRtc_noise_suppression/HEAD/my_splitting_filter/ 3 bands splitting sync output.wav -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/fft4g.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the ../../../LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_ 12 | #define COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_ 13 | 14 | #if defined(__cplusplus) 15 | extern "C" { 16 | #endif 17 | 18 | // Refer to fft4g.c for documentation. 19 | void WebRtc_rdft(size_t n, int isgn, float* a, size_t* ip, float* w); 20 | 21 | #if defined(__cplusplus) 22 | } 23 | #endif 24 | 25 | #endif /* COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_ */ 26 | -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/inline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_SYSTEM_INLINE_H_ 12 | #define RTC_BASE_SYSTEM_INLINE_H_ 13 | 14 | #if defined(_MSC_VER) 15 | 16 | #define RTC_FORCE_INLINE __forceinline 17 | #define RTC_NO_INLINE __declspec(noinline) 18 | 19 | #elif defined(__GNUC__) 20 | 21 | #define RTC_FORCE_INLINE __attribute__((__always_inline__)) 22 | #define RTC_NO_INLINE __attribute__((__noinline__)) 23 | 24 | #else 25 | 26 | #define RTC_FORCE_INLINE 27 | #define RTC_NO_INLINE 28 | 29 | #endif 30 | 31 | #endif // RTC_BASE_SYSTEM_INLINE_H_ 32 | -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/inline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_SYSTEM_INLINE_H_ 12 | #define RTC_BASE_SYSTEM_INLINE_H_ 13 | 14 | #if defined(_MSC_VER) 15 | 16 | #define RTC_FORCE_INLINE __forceinline 17 | #define RTC_NO_INLINE __declspec(noinline) 18 | 19 | #elif defined(__GNUC__) 20 | 21 | #define RTC_FORCE_INLINE __attribute__((__always_inline__)) 22 | #define RTC_NO_INLINE __attribute__((__noinline__)) 23 | 24 | #else 25 | 26 | #define RTC_FORCE_INLINE 27 | #define RTC_NO_INLINE 28 | 29 | #endif 30 | 31 | #endif // RTC_BASE_SYSTEM_INLINE_H_ 32 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/spl_sqrt_floor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include 12 | 13 | // 14 | // WebRtcSpl_SqrtFloor(...) 15 | // 16 | // Returns the square root of the input value |value|. The precision of this 17 | // function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer. 18 | // If |value| is a negative number then 0 is returned. 19 | // 20 | // Algorithm: 21 | // 22 | // An iterative 4 cylce/bit routine 23 | // 24 | // Input: 25 | // - value : Value to calculate sqrt of 26 | // 27 | // Return value : Result of the sqrt calculation 28 | // 29 | int32_t WebRtcSpl_SqrtFloor(int32_t value); 30 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/spl_sqrt_floor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include 12 | 13 | // 14 | // WebRtcSpl_SqrtFloor(...) 15 | // 16 | // Returns the square root of the input value |value|. The precision of this 17 | // function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer. 18 | // If |value| is a negative number then 0 is returned. 19 | // 20 | // Algorithm: 21 | // 22 | // An iterative 4 cylce/bit routine 23 | // 24 | // Input: 25 | // - value : Value to calculate sqrt of 26 | // 27 | // Return value : Result of the sqrt calculation 28 | // 29 | int32_t WebRtcSpl_SqrtFloor(int32_t value); 30 | -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/compile_assert_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_COMPILE_ASSERT_C_H_ 12 | #define RTC_BASE_COMPILE_ASSERT_C_H_ 13 | 14 | // Use this macro to verify at compile time that certain restrictions are met. 15 | // The argument is the boolean expression to evaluate. 16 | // Example: 17 | // RTC_COMPILE_ASSERT(sizeof(foo) < 128); 18 | // Note: In C++, use static_assert instead! 19 | #define RTC_COMPILE_ASSERT(expression) \ 20 | switch (0) { \ 21 | case 0: \ 22 | case expression:; \ 23 | } 24 | 25 | #endif // RTC_BASE_COMPILE_ASSERT_C_H_ 26 | -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/compile_assert_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_COMPILE_ASSERT_C_H_ 12 | #define RTC_BASE_COMPILE_ASSERT_C_H_ 13 | 14 | // Use this macro to verify at compile time that certain restrictions are met. 15 | // The argument is the boolean expression to evaluate. 16 | // Example: 17 | // RTC_COMPILE_ASSERT(sizeof(foo) < 128); 18 | // Note: In C++, use static_assert instead! 19 | #define RTC_COMPILE_ASSERT(expression) \ 20 | switch (0) { \ 21 | case 0: \ 22 | case expression:; \ 23 | } 24 | 25 | #endif // RTC_BASE_COMPILE_ASSERT_C_H_ 26 | -------------------------------------------------------------------------------- /assets/test_case/test_case.md: -------------------------------------------------------------------------------- 1 | ## Test case 2 | 3 | input : 4 | 5 | assets\babble_15dB.wav 6 | 7 | output: 8 | 9 | ns_level = kLow || webrtc_ns_kLow_babble_15dB.wav 10 | ns_level = kModerate || webrtc_ns_kModerate_babble_15dB.wav 11 | ns_level = kHigh || webrtc_ns_kHigh_babble_15dB.wav 12 | 13 | The rnnoise and speexdsp's noise suppression test case wav files are captured from the https://people.xiph.rog/~jm/demo/rnnoise/ 14 | 15 | Thses files can be found in the assets\test_case . 16 | 17 | ## Performance 18 | 19 | With the same input,babble_15dB.wav, we set up a contrast among RNNoise, speexdsp and webrtc_ns.In the listening test, RNNoise performs well and suppresses the noise in babble.. It introduces a bit of artifacts which sounds unnature but it is tolerable. 20 | 21 | For the webrtc's ns, kHigh performs better than kModerate which can suppress the whole noise.The kLow case has a poor performance than the others. Notes that the webrtc's ns has an impacts of the Gain when processed the audio data, maybe it should be interfaced with AGC module. 22 | 23 | Finally, speexdsp's ns can suppress the babble noise but not completely reduce the backgourd noise. These noise suppression algorithm performance can be summed up as blows: 24 | $$ 25 | kLow < speechx \approx kModerate > scaling; 27 | sum += (vector1[i + 1] * vector2[i + 1]) >> scaling; 28 | sum += (vector1[i + 2] * vector2[i + 2]) >> scaling; 29 | sum += (vector1[i + 3] * vector2[i + 3]) >> scaling; 30 | } 31 | for (; i < length; i++) { 32 | sum += (vector1[i] * vector2[i]) >> scaling; 33 | } 34 | 35 | //return rtc::saturated_cast(sum); ////#include "rtc_base/numerics/safe_conversions.h" 36 | return static_cast(sum); 37 | } 38 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/dot_product_with_scale.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "common_audio/signal_processing/dot_product_with_scale.h" 12 | #include "dot_product_with_scale.h" 13 | 14 | //#include "rtc_base/numerics/safe_conversions.h" 15 | //#include "safe_conversions.h" 16 | 17 | int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1, 18 | const int16_t* vector2, 19 | size_t length, 20 | int scaling) { 21 | int64_t sum = 0; 22 | size_t i = 0; 23 | 24 | /* Unroll the loop to improve performance. */ 25 | for (i = 0; i + 3 < length; i += 4) { 26 | sum += (vector1[i + 0] * vector2[i + 0]) >> scaling; 27 | sum += (vector1[i + 1] * vector2[i + 1]) >> scaling; 28 | sum += (vector1[i + 2] * vector2[i + 2]) >> scaling; 29 | sum += (vector1[i + 3] * vector2[i + 3]) >> scaling; 30 | } 31 | for (; i < length; i++) { 32 | sum += (vector1[i] * vector2[i]) >> scaling; 33 | } 34 | 35 | //return rtc::saturated_cast(sum); ////#include "rtc_base/numerics/safe_conversions.h" 36 | return static_cast(sum); 37 | } 38 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/dot_product_with_scale.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 12 | #define COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 13 | 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | // Calculates the dot product between two (int16_t) vectors. 22 | // 23 | // Input: 24 | // - vector1 : Vector 1 25 | // - vector2 : Vector 2 26 | // - vector_length : Number of samples used in the dot product 27 | // - scaling : The number of right bit shifts to apply on each term 28 | // during calculation to avoid overflow, i.e., the 29 | // output will be in Q(-|scaling|) 30 | // 31 | // Return value : The dot product in Q(-scaling) 32 | int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1, 33 | const int16_t* vector2, 34 | size_t length, 35 | int scaling); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif // __cplusplus 40 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 41 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/dot_product_with_scale.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 12 | #define COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 13 | 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | // Calculates the dot product between two (int16_t) vectors. 22 | // 23 | // Input: 24 | // - vector1 : Vector 1 25 | // - vector2 : Vector 2 26 | // - vector_length : Number of samples used in the dot product 27 | // - scaling : The number of right bit shifts to apply on each term 28 | // during calculation to avoid overflow, i.e., the 29 | // output will be in Q(-|scaling|) 30 | // 31 | // Return value : The dot product in Q(-scaling) 32 | int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1, 33 | const int16_t* vector2, 34 | size_t length, 35 | int scaling); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif // __cplusplus 40 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_ 41 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/audio_util.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "common_audio/include/audio_util.h" 12 | #include "audio_util.h" 13 | 14 | namespace webrtc { 15 | 16 | void FloatToS16(const float* src, size_t size, int16_t* dest) { 17 | for (size_t i = 0; i < size; ++i) 18 | dest[i] = FloatToS16(src[i]); 19 | } 20 | 21 | void S16ToFloat(const int16_t* src, size_t size, float* dest) { 22 | for (size_t i = 0; i < size; ++i) 23 | dest[i] = S16ToFloat(src[i]); 24 | } 25 | 26 | void FloatS16ToS16(const float* src, size_t size, int16_t* dest) { 27 | for (size_t i = 0; i < size; ++i) 28 | dest[i] = FloatS16ToS16(src[i]); 29 | } 30 | 31 | void FloatToFloatS16(const float* src, size_t size, float* dest) { 32 | for (size_t i = 0; i < size; ++i) 33 | dest[i] = FloatToFloatS16(src[i]); 34 | } 35 | 36 | void FloatS16ToFloat(const float* src, size_t size, float* dest) { 37 | for (size_t i = 0; i < size; ++i) 38 | dest[i] = FloatS16ToFloat(src[i]); 39 | } 40 | 41 | template <> 42 | void DownmixInterleavedToMono(const int16_t* interleaved, 43 | size_t num_frames, 44 | int num_channels, 45 | int16_t* deinterleaved) { 46 | DownmixInterleavedToMonoImpl(interleaved, num_frames, 47 | num_channels, deinterleaved); 48 | } 49 | 50 | } // namespace webrtc 51 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/audio_util.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "common_audio/include/audio_util.h" 12 | #include "audio_util.h" 13 | 14 | namespace webrtc { 15 | 16 | void FloatToS16(const float* src, size_t size, int16_t* dest) { 17 | for (size_t i = 0; i < size; ++i) 18 | dest[i] = FloatToS16(src[i]); 19 | } 20 | 21 | void S16ToFloat(const int16_t* src, size_t size, float* dest) { 22 | for (size_t i = 0; i < size; ++i) 23 | dest[i] = S16ToFloat(src[i]); 24 | } 25 | 26 | void FloatS16ToS16(const float* src, size_t size, int16_t* dest) { 27 | for (size_t i = 0; i < size; ++i) 28 | dest[i] = FloatS16ToS16(src[i]); 29 | } 30 | 31 | void FloatToFloatS16(const float* src, size_t size, float* dest) { 32 | for (size_t i = 0; i < size; ++i) 33 | dest[i] = FloatToFloatS16(src[i]); 34 | } 35 | 36 | void FloatS16ToFloat(const float* src, size_t size, float* dest) { 37 | for (size_t i = 0; i < size; ++i) 38 | dest[i] = FloatS16ToFloat(src[i]); 39 | } 40 | 41 | template <> 42 | void DownmixInterleavedToMono(const int16_t* interleaved, 43 | size_t num_frames, 44 | int num_channels, 45 | int16_t* deinterleaved) { 46 | DownmixInterleavedToMonoImpl(interleaved, num_frames, 47 | num_channels, deinterleaved); 48 | } 49 | 50 | } // namespace webrtc 51 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/sparse_fir_filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 12 | #define COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 13 | 14 | #include 15 | #include 16 | 17 | //#include "rtc_base/constructormagic.h" 18 | 19 | namespace webrtc { 20 | 21 | // A Finite Impulse Response filter implementation which takes advantage of a 22 | // sparse structure with uniformly distributed non-zero coefficients. 23 | class SparseFIRFilter final { 24 | public: 25 | // |num_nonzero_coeffs| is the number of non-zero coefficients, 26 | // |nonzero_coeffs|. They are assumed to be uniformly distributed every 27 | // |sparsity| samples and with an initial |offset|. The rest of the filter 28 | // coefficients will be assumed zeros. For example, with sparsity = 3, and 29 | // offset = 1 the filter coefficients will be: 30 | // B = [0 coeffs[0] 0 0 coeffs[1] 0 0 coeffs[2] ... ] 31 | // All initial state values will be zeros. 32 | SparseFIRFilter(const float* nonzero_coeffs, 33 | size_t num_nonzero_coeffs, 34 | size_t sparsity, 35 | size_t offset); 36 | ~SparseFIRFilter(); 37 | 38 | // Filters the |in| data supplied. 39 | // |out| must be previously allocated and it must be at least of |length|. 40 | void Filter(const float* in, size_t length, float* out); 41 | 42 | private: 43 | const size_t sparsity_; 44 | const size_t offset_; 45 | const std::vector nonzero_coeffs_; 46 | std::vector state_; 47 | 48 | //RTC_DISALLOW_COPY_AND_ASSIGN(SparseFIRFilter); 49 | }; 50 | 51 | } // namespace webrtc 52 | 53 | #endif // COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 54 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/sparse_fir_filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 12 | #define COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 13 | 14 | #include 15 | #include 16 | 17 | //#include "rtc_base/constructormagic.h" 18 | 19 | namespace webrtc { 20 | 21 | // A Finite Impulse Response filter implementation which takes advantage of a 22 | // sparse structure with uniformly distributed non-zero coefficients. 23 | class SparseFIRFilter final { 24 | public: 25 | // |num_nonzero_coeffs| is the number of non-zero coefficients, 26 | // |nonzero_coeffs|. They are assumed to be uniformly distributed every 27 | // |sparsity| samples and with an initial |offset|. The rest of the filter 28 | // coefficients will be assumed zeros. For example, with sparsity = 3, and 29 | // offset = 1 the filter coefficients will be: 30 | // B = [0 coeffs[0] 0 0 coeffs[1] 0 0 coeffs[2] ... ] 31 | // All initial state values will be zeros. 32 | SparseFIRFilter(const float* nonzero_coeffs, 33 | size_t num_nonzero_coeffs, 34 | size_t sparsity, 35 | size_t offset); 36 | ~SparseFIRFilter(); 37 | 38 | // Filters the |in| data supplied. 39 | // |out| must be previously allocated and it must be at least of |length|. 40 | void Filter(const float* in, size_t length, float* out); 41 | 42 | private: 43 | const size_t sparsity_; 44 | const size_t offset_; 45 | const std::vector nonzero_coeffs_; 46 | std::vector state_; 47 | 48 | //RTC_DISALLOW_COPY_AND_ASSIGN(SparseFIRFilter); 49 | }; 50 | 51 | } // namespace webrtc 52 | 53 | #endif // COMMON_AUDIO_SPARSE_FIR_FILTER_H_ 54 | -------------------------------------------------------------------------------- /WebRtc_official.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2000 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebRtc_official", "WebRtc_official\WebRtc_official.vcxproj", "{797546CD-8DC5-4F76-A90F-01923052E5AE}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "my_splitting_filter", "my_splitting_filter\my_splitting_filter.vcxproj", "{49C49095-8BA5-42D3-9319-7333001A30F4}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Debug|x64.ActiveCfg = Debug|x64 19 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Debug|x64.Build.0 = Debug|x64 20 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Debug|x86.ActiveCfg = Debug|Win32 21 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Debug|x86.Build.0 = Debug|Win32 22 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Release|x64.ActiveCfg = Release|x64 23 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Release|x64.Build.0 = Release|x64 24 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Release|x86.ActiveCfg = Release|Win32 25 | {797546CD-8DC5-4F76-A90F-01923052E5AE}.Release|x86.Build.0 = Release|Win32 26 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Debug|x64.ActiveCfg = Debug|x64 27 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Debug|x64.Build.0 = Debug|x64 28 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Debug|x86.ActiveCfg = Debug|Win32 29 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Debug|x86.Build.0 = Debug|Win32 30 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Release|x64.ActiveCfg = Release|x64 31 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Release|x64.Build.0 = Release|x64 32 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Release|x86.ActiveCfg = Release|Win32 33 | {49C49095-8BA5-42D3-9319-7333001A30F4}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {7941AFFA-F62C-474A-B272-747A094F1BCB} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /WebRtc_official/include/ns/noise_suppression_x.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "modules/audio_processing/ns/noise_suppression_x.h" 12 | #include "noise_suppression_x.h" 13 | 14 | #include 15 | 16 | //#include "common_audio/signal_processing/include/real_fft.h" 17 | //#include "modules/audio_processing/ns/nsx_core.h" 18 | //#include "modules/audio_processing/ns/nsx_defines.h" 19 | #include "real_fft.h" 20 | #include "nsx_core.h" 21 | #include "nsx_defines.h" 22 | 23 | NsxHandle* WebRtcNsx_Create() { 24 | NoiseSuppressionFixedC* self = malloc(sizeof(NoiseSuppressionFixedC)); 25 | WebRtcSpl_Init(); 26 | self->real_fft = NULL; 27 | self->initFlag = 0; 28 | return (NsxHandle*)self; 29 | } 30 | 31 | void WebRtcNsx_Free(NsxHandle* nsxInst) { 32 | WebRtcSpl_FreeRealFFT(((NoiseSuppressionFixedC*)nsxInst)->real_fft); 33 | free(nsxInst); 34 | } 35 | 36 | int WebRtcNsx_Init(NsxHandle* nsxInst, uint32_t fs) { 37 | return WebRtcNsx_InitCore((NoiseSuppressionFixedC*)nsxInst, fs); 38 | } 39 | 40 | int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode) { 41 | return WebRtcNsx_set_policy_core((NoiseSuppressionFixedC*)nsxInst, mode); 42 | } 43 | 44 | void WebRtcNsx_Process(NsxHandle* nsxInst, 45 | const short* const* speechFrame, 46 | int num_bands, 47 | short* const* outFrame) { 48 | WebRtcNsx_ProcessCore((NoiseSuppressionFixedC*)nsxInst, speechFrame, 49 | num_bands, outFrame); 50 | } 51 | 52 | const uint32_t* WebRtcNsx_noise_estimate(const NsxHandle* nsxInst, 53 | int* q_noise) { 54 | *q_noise = 11; 55 | const NoiseSuppressionFixedC* self = (const NoiseSuppressionFixedC*)nsxInst; 56 | if (nsxInst == NULL || self->initFlag == 0) { 57 | return NULL; 58 | } 59 | *q_noise += self->prevQNoise; 60 | return self->prevNoiseU32; 61 | } 62 | 63 | size_t WebRtcNsx_num_freq() { 64 | return HALF_ANAL_BLOCKL; 65 | } 66 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/sparse_fir_filter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "common_audio/sparse_fir_filter.h" 12 | // 13 | //#include "rtc_base/checks.h" 14 | 15 | #include "sparse_fir_filter.h" 16 | 17 | #include "checks.h" 18 | 19 | namespace webrtc { 20 | 21 | SparseFIRFilter::SparseFIRFilter(const float* nonzero_coeffs, 22 | size_t num_nonzero_coeffs, 23 | size_t sparsity, 24 | size_t offset) 25 | : sparsity_(sparsity), 26 | offset_(offset), 27 | nonzero_coeffs_(nonzero_coeffs, nonzero_coeffs + num_nonzero_coeffs), 28 | state_(sparsity_ * (num_nonzero_coeffs - 1) + offset_, 0.f) { 29 | RTC_CHECK_GE(num_nonzero_coeffs, 1); 30 | RTC_CHECK_GE(sparsity, 1); 31 | } 32 | 33 | SparseFIRFilter::~SparseFIRFilter() = default; 34 | 35 | void SparseFIRFilter::Filter(const float* in, size_t length, float* out) { 36 | // Convolves the input signal |in| with the filter kernel |nonzero_coeffs_| 37 | // taking into account the previous state. 38 | for (size_t i = 0; i < length; ++i) { 39 | out[i] = 0.f; 40 | size_t j; 41 | for (j = 0; i >= j * sparsity_ + offset_ && j < nonzero_coeffs_.size(); 42 | ++j) { 43 | out[i] += in[i - j * sparsity_ - offset_] * nonzero_coeffs_[j]; 44 | } 45 | for (; j < nonzero_coeffs_.size(); ++j) { 46 | out[i] += state_[i + (nonzero_coeffs_.size() - j - 1) * sparsity_] * 47 | nonzero_coeffs_[j]; 48 | } 49 | } 50 | 51 | // Update current state. 52 | if (state_.size() > 0u) { 53 | if (length >= state_.size()) { 54 | std::memcpy(&state_[0], &in[length - state_.size()], 55 | state_.size() * sizeof(*in)); 56 | } else { 57 | std::memmove(&state_[0], &state_[length], 58 | (state_.size() - length) * sizeof(state_[0])); 59 | std::memcpy(&state_[state_.size() - length], in, length * sizeof(*in)); 60 | } 61 | } 62 | } 63 | 64 | } // namespace webrtc 65 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/sparse_fir_filter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "common_audio/sparse_fir_filter.h" 12 | // 13 | //#include "rtc_base/checks.h" 14 | 15 | #include "sparse_fir_filter.h" 16 | 17 | #include "checks.h" 18 | 19 | namespace webrtc { 20 | 21 | SparseFIRFilter::SparseFIRFilter(const float* nonzero_coeffs, 22 | size_t num_nonzero_coeffs, 23 | size_t sparsity, 24 | size_t offset) 25 | : sparsity_(sparsity), 26 | offset_(offset), 27 | nonzero_coeffs_(nonzero_coeffs, nonzero_coeffs + num_nonzero_coeffs), 28 | state_(sparsity_ * (num_nonzero_coeffs - 1) + offset_, 0.f) { 29 | RTC_CHECK_GE(num_nonzero_coeffs, 1); 30 | RTC_CHECK_GE(sparsity, 1); 31 | } 32 | 33 | SparseFIRFilter::~SparseFIRFilter() = default; 34 | 35 | void SparseFIRFilter::Filter(const float* in, size_t length, float* out) { 36 | // Convolves the input signal |in| with the filter kernel |nonzero_coeffs_| 37 | // taking into account the previous state. 38 | for (size_t i = 0; i < length; ++i) { 39 | out[i] = 0.f; 40 | size_t j; 41 | for (j = 0; i >= j * sparsity_ + offset_ && j < nonzero_coeffs_.size(); 42 | ++j) { 43 | out[i] += in[i - j * sparsity_ - offset_] * nonzero_coeffs_[j]; 44 | } 45 | for (; j < nonzero_coeffs_.size(); ++j) { 46 | out[i] += state_[i + (nonzero_coeffs_.size() - j - 1) * sparsity_] * 47 | nonzero_coeffs_[j]; 48 | } 49 | } 50 | 51 | // Update current state. 52 | if (state_.size() > 0u) { 53 | if (length >= state_.size()) { 54 | std::memcpy(&state_[0], &in[length - state_.size()], 55 | state_.size() * sizeof(*in)); 56 | } else { 57 | std::memmove(&state_[0], &state_[length], 58 | (state_.size() - length) * sizeof(state_[0])); 59 | std::memcpy(&state_[state_.size() - length], in, length * sizeof(*in)); 60 | } 61 | } 62 | } 63 | 64 | } // namespace webrtc 65 | -------------------------------------------------------------------------------- /WebRtc_official/include/ns/noise_suppression.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "modules/audio_processing/ns/noise_suppression.h" 12 | #include "noise_suppression.h" 13 | 14 | #include 15 | #include 16 | 17 | //#include "common_audio/signal_processing/include/signal_processing_library.h" 18 | //#include "modules/audio_processing/ns/defines.h" 19 | //#include "modules/audio_processing/ns/ns_core.h" 20 | #include "signal_processing_library.h" 21 | #include "defines.h" 22 | #include "ns_core.h" 23 | 24 | NsHandle* WebRtcNs_Create() { 25 | //NoiseSuppressionC* self = malloc(sizeof(NoiseSuppressionC)); 26 | NoiseSuppressionC* self =(NoiseSuppressionC*) malloc(sizeof(NoiseSuppressionC)); 27 | self->initFlag = 0; 28 | return (NsHandle*)self; 29 | } 30 | 31 | void WebRtcNs_Free(NsHandle* NS_inst) { 32 | free(NS_inst); 33 | } 34 | 35 | int WebRtcNs_Init(NsHandle* NS_inst, uint32_t fs) { 36 | return WebRtcNs_InitCore((NoiseSuppressionC*)NS_inst, fs); 37 | } 38 | 39 | int WebRtcNs_set_policy(NsHandle* NS_inst, int mode) { 40 | return WebRtcNs_set_policy_core((NoiseSuppressionC*)NS_inst, mode); 41 | } 42 | 43 | void WebRtcNs_Analyze(NsHandle* NS_inst, const float* spframe) { 44 | WebRtcNs_AnalyzeCore((NoiseSuppressionC*)NS_inst, spframe); 45 | } 46 | 47 | void WebRtcNs_Process(NsHandle* NS_inst, 48 | const float* const* spframe, 49 | size_t num_bands, 50 | float* const* outframe) { 51 | WebRtcNs_ProcessCore((NoiseSuppressionC*)NS_inst, spframe, num_bands, 52 | outframe); 53 | } 54 | 55 | float WebRtcNs_prior_speech_probability(NsHandle* handle) { 56 | NoiseSuppressionC* self = (NoiseSuppressionC*)handle; 57 | if (handle == NULL) { 58 | return -1; 59 | } 60 | if (self->initFlag == 0) { 61 | return -1; 62 | } 63 | return self->priorSpeechProb; 64 | } 65 | 66 | const float* WebRtcNs_noise_estimate(const NsHandle* handle) { 67 | const NoiseSuppressionC* self = (const NoiseSuppressionC*)handle; 68 | if (handle == NULL || self->initFlag == 0) { 69 | return NULL; 70 | } 71 | return self->noise; 72 | } 73 | 74 | size_t WebRtcNs_num_freq() { 75 | return HALF_ANAL_BLOCKL; 76 | } 77 | -------------------------------------------------------------------------------- /WebRtc_official/include/ns/defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ 12 | #define MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ 13 | 14 | #define BLOCKL_MAX 160 // max processing block length: 160 15 | #define ANAL_BLOCKL_MAX 256 // max analysis block length: 256 16 | #define HALF_ANAL_BLOCKL 129 // half max analysis block length + 1 17 | #define NUM_HIGH_BANDS_MAX 2 // max number of high bands: 2 18 | 19 | #define QUANTILE (float)0.25 20 | 21 | #define SIMULT 3 22 | #define END_STARTUP_LONG 200 23 | #define END_STARTUP_SHORT 50 24 | #define FACTOR (float)40.0 25 | #define WIDTH (float)0.01 26 | 27 | // Length of fft work arrays. 28 | #define IP_LENGTH \ 29 | (ANAL_BLOCKL_MAX >> 1) // must be at least ceil(2 + sqrt(ANAL_BLOCKL_MAX/2)) 30 | #define W_LENGTH (ANAL_BLOCKL_MAX >> 1) 31 | 32 | // PARAMETERS FOR NEW METHOD 33 | #define DD_PR_SNR (float)0.98 // DD update of prior SNR 34 | #define LRT_TAVG (float)0.50 // tavg parameter for LRT (previously 0.90) 35 | #define SPECT_FL_TAVG \ 36 | (float)0.30 // tavg parameter for spectral flatness measure 37 | #define SPECT_DIFF_TAVG \ 38 | (float)0.30 // tavg parameter for spectral difference measure 39 | #define PRIOR_UPDATE (float)0.10 // update parameter of prior model 40 | #define NOISE_UPDATE (float)0.90 // update parameter for noise 41 | #define SPEECH_UPDATE (float)0.99 // update parameter when likely speech 42 | #define WIDTH_PR_MAP \ 43 | (float)4.0 // width parameter in sigmoid map for prior model 44 | #define LRT_FEATURE_THR (float)0.5 // default threshold for LRT feature 45 | #define SF_FEATURE_THR \ 46 | (float)0.5 // default threshold for Spectral Flatness feature 47 | #define SD_FEATURE_THR \ 48 | (float)0.5 // default threshold for Spectral Difference feature 49 | #define PROB_RANGE (float)0.20 // probability threshold for noise state in 50 | // speech/noise likelihood 51 | #define HIST_PAR_EST 1000 // histogram size for estimation of parameters 52 | #define GAMMA_PAUSE (float)0.05 // update for conservative noise estimate 53 | // 54 | #define B_LIM (float)0.5 // threshold in final energy gain factor calculation 55 | #endif // MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ 56 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/spl_sqrt_floor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by Wilco Dijkstra, 1996. The following email exchange establishes the 3 | * license. 4 | * 5 | * From: Wilco Dijkstra 6 | * Date: Fri, Jun 24, 2011 at 3:20 AM 7 | * Subject: Re: sqrt routine 8 | * To: Kevin Ma 9 | * Hi Kevin, 10 | * Thanks for asking. Those routines are public domain (originally posted to 11 | * comp.sys.arm a long time ago), so you can use them freely for any purpose. 12 | * Cheers, 13 | * Wilco 14 | * 15 | * ----- Original Message ----- 16 | * From: "Kevin Ma" 17 | * To: 18 | * Sent: Thursday, June 23, 2011 11:44 PM 19 | * Subject: Fwd: sqrt routine 20 | * Hi Wilco, 21 | * I saw your sqrt routine from several web sites, including 22 | * http://www.finesse.demon.co.uk/steven/sqrt.html. 23 | * Just wonder if there's any copyright information with your Successive 24 | * approximation routines, or if I can freely use it for any purpose. 25 | * Thanks. 26 | * Kevin 27 | */ 28 | 29 | // Minor modifications in code style for WebRTC, 2012. 30 | 31 | //#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h" 32 | #include "spl_sqrt_floor.h" 33 | 34 | /* 35 | * Algorithm: 36 | * Successive approximation of the equation (root + delta) ^ 2 = N 37 | * until delta < 1. If delta < 1 we have the integer part of SQRT (N). 38 | * Use delta = 2^i for i = 15 .. 0. 39 | * 40 | * Output precision is 16 bits. Note for large input values (close to 41 | * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word) 42 | * contains the MSB information (a non-sign value). Do with caution 43 | * if you need to cast the output to int16_t type. 44 | * 45 | * If the input value is negative, it returns 0. 46 | */ 47 | 48 | #define WEBRTC_SPL_SQRT_ITER(N) \ 49 | try1 = root + (1 << (N)); \ 50 | if (value >= try1 << (N)) \ 51 | { \ 52 | value -= try1 << (N); \ 53 | root |= 2 << (N); \ 54 | } 55 | 56 | int32_t WebRtcSpl_SqrtFloor(int32_t value) 57 | { 58 | int32_t root = 0, try1; 59 | 60 | WEBRTC_SPL_SQRT_ITER (15); 61 | WEBRTC_SPL_SQRT_ITER (14); 62 | WEBRTC_SPL_SQRT_ITER (13); 63 | WEBRTC_SPL_SQRT_ITER (12); 64 | WEBRTC_SPL_SQRT_ITER (11); 65 | WEBRTC_SPL_SQRT_ITER (10); 66 | WEBRTC_SPL_SQRT_ITER ( 9); 67 | WEBRTC_SPL_SQRT_ITER ( 8); 68 | WEBRTC_SPL_SQRT_ITER ( 7); 69 | WEBRTC_SPL_SQRT_ITER ( 6); 70 | WEBRTC_SPL_SQRT_ITER ( 5); 71 | WEBRTC_SPL_SQRT_ITER ( 4); 72 | WEBRTC_SPL_SQRT_ITER ( 3); 73 | WEBRTC_SPL_SQRT_ITER ( 2); 74 | WEBRTC_SPL_SQRT_ITER ( 1); 75 | WEBRTC_SPL_SQRT_ITER ( 0); 76 | 77 | return root >> 1; 78 | } 79 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/spl_sqrt_floor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by Wilco Dijkstra, 1996. The following email exchange establishes the 3 | * license. 4 | * 5 | * From: Wilco Dijkstra 6 | * Date: Fri, Jun 24, 2011 at 3:20 AM 7 | * Subject: Re: sqrt routine 8 | * To: Kevin Ma 9 | * Hi Kevin, 10 | * Thanks for asking. Those routines are public domain (originally posted to 11 | * comp.sys.arm a long time ago), so you can use them freely for any purpose. 12 | * Cheers, 13 | * Wilco 14 | * 15 | * ----- Original Message ----- 16 | * From: "Kevin Ma" 17 | * To: 18 | * Sent: Thursday, June 23, 2011 11:44 PM 19 | * Subject: Fwd: sqrt routine 20 | * Hi Wilco, 21 | * I saw your sqrt routine from several web sites, including 22 | * http://www.finesse.demon.co.uk/steven/sqrt.html. 23 | * Just wonder if there's any copyright information with your Successive 24 | * approximation routines, or if I can freely use it for any purpose. 25 | * Thanks. 26 | * Kevin 27 | */ 28 | 29 | // Minor modifications in code style for WebRTC, 2012. 30 | 31 | //#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h" 32 | #include "spl_sqrt_floor.h" 33 | 34 | /* 35 | * Algorithm: 36 | * Successive approximation of the equation (root + delta) ^ 2 = N 37 | * until delta < 1. If delta < 1 we have the integer part of SQRT (N). 38 | * Use delta = 2^i for i = 15 .. 0. 39 | * 40 | * Output precision is 16 bits. Note for large input values (close to 41 | * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word) 42 | * contains the MSB information (a non-sign value). Do with caution 43 | * if you need to cast the output to int16_t type. 44 | * 45 | * If the input value is negative, it returns 0. 46 | */ 47 | 48 | #define WEBRTC_SPL_SQRT_ITER(N) \ 49 | try1 = root + (1 << (N)); \ 50 | if (value >= try1 << (N)) \ 51 | { \ 52 | value -= try1 << (N); \ 53 | root |= 2 << (N); \ 54 | } 55 | 56 | int32_t WebRtcSpl_SqrtFloor(int32_t value) 57 | { 58 | int32_t root = 0, try1; 59 | 60 | WEBRTC_SPL_SQRT_ITER (15); 61 | WEBRTC_SPL_SQRT_ITER (14); 62 | WEBRTC_SPL_SQRT_ITER (13); 63 | WEBRTC_SPL_SQRT_ITER (12); 64 | WEBRTC_SPL_SQRT_ITER (11); 65 | WEBRTC_SPL_SQRT_ITER (10); 66 | WEBRTC_SPL_SQRT_ITER ( 9); 67 | WEBRTC_SPL_SQRT_ITER ( 8); 68 | WEBRTC_SPL_SQRT_ITER ( 7); 69 | WEBRTC_SPL_SQRT_ITER ( 6); 70 | WEBRTC_SPL_SQRT_ITER ( 5); 71 | WEBRTC_SPL_SQRT_ITER ( 4); 72 | WEBRTC_SPL_SQRT_ITER ( 3); 73 | WEBRTC_SPL_SQRT_ITER ( 2); 74 | WEBRTC_SPL_SQRT_ITER ( 1); 75 | WEBRTC_SPL_SQRT_ITER ( 0); 76 | 77 | return root >> 1; 78 | } 79 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/splitting_filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 12 | #define MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | //#include "modules/audio_processing/three_band_filter_bank.h" 19 | #include "three_band_filter_bank.h" 20 | 21 | namespace webrtc { 22 | 23 | class IFChannelBuffer; 24 | 25 | struct TwoBandsStates { 26 | TwoBandsStates() { 27 | memset(analysis_state1, 0, sizeof(analysis_state1)); 28 | memset(analysis_state2, 0, sizeof(analysis_state2)); 29 | memset(synthesis_state1, 0, sizeof(synthesis_state1)); 30 | memset(synthesis_state2, 0, sizeof(synthesis_state2)); 31 | } 32 | 33 | static const int kStateSize = 6; 34 | int analysis_state1[kStateSize]; 35 | int analysis_state2[kStateSize]; 36 | int synthesis_state1[kStateSize]; 37 | int synthesis_state2[kStateSize]; 38 | }; 39 | 40 | // Splitting filter which is able to split into and merge from 2 or 3 frequency 41 | // bands. The number of channels needs to be provided at construction time. 42 | // 43 | // For each block, Analysis() is called to split into bands and then Synthesis() 44 | // to merge these bands again. The input and output signals are contained in 45 | // IFChannelBuffers and for the different bands an array of IFChannelBuffers is 46 | // used. 47 | class SplittingFilter { 48 | public: 49 | SplittingFilter(size_t num_channels, size_t num_bands, size_t num_frames); 50 | ~SplittingFilter(); 51 | 52 | void Analysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 53 | void Synthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 54 | 55 | private: 56 | // Two-band analysis and synthesis work for 640 samples or less. 57 | void TwoBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 58 | void TwoBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 59 | void ThreeBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 60 | void ThreeBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 61 | void InitBuffers(); 62 | 63 | const size_t num_bands_; 64 | std::vector two_bands_states_; 65 | std::vector> three_band_filter_banks_; 66 | }; 67 | 68 | } // namespace webrtc 69 | 70 | #endif // MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 71 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/splitting_filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 12 | #define MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | //#include "modules/audio_processing/three_band_filter_bank.h" 19 | #include "three_band_filter_bank.h" 20 | 21 | namespace webrtc { 22 | 23 | class IFChannelBuffer; 24 | 25 | struct TwoBandsStates { 26 | TwoBandsStates() { 27 | memset(analysis_state1, 0, sizeof(analysis_state1)); 28 | memset(analysis_state2, 0, sizeof(analysis_state2)); 29 | memset(synthesis_state1, 0, sizeof(synthesis_state1)); 30 | memset(synthesis_state2, 0, sizeof(synthesis_state2)); 31 | } 32 | 33 | static const int kStateSize = 6; 34 | int analysis_state1[kStateSize]; 35 | int analysis_state2[kStateSize]; 36 | int synthesis_state1[kStateSize]; 37 | int synthesis_state2[kStateSize]; 38 | }; 39 | 40 | // Splitting filter which is able to split into and merge from 2 or 3 frequency 41 | // bands. The number of channels needs to be provided at construction time. 42 | // 43 | // For each block, Analysis() is called to split into bands and then Synthesis() 44 | // to merge these bands again. The input and output signals are contained in 45 | // IFChannelBuffers and for the different bands an array of IFChannelBuffers is 46 | // used. 47 | class SplittingFilter { 48 | public: 49 | SplittingFilter(size_t num_channels, size_t num_bands, size_t num_frames); 50 | ~SplittingFilter(); 51 | 52 | void Analysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 53 | void Synthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 54 | 55 | private: 56 | // Two-band analysis and synthesis work for 640 samples or less. 57 | void TwoBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 58 | void TwoBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 59 | void ThreeBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands); 60 | void ThreeBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data); 61 | void InitBuffers(); 62 | 63 | const size_t num_bands_; 64 | std::vector two_bands_states_; 65 | std::vector> three_band_filter_banks_; 66 | }; 67 | 68 | } // namespace webrtc 69 | 70 | #endif // MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_ 71 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/three_band_filter_bank.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 12 | #define MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | //#include "common_audio/sparse_fir_filter.h" 19 | #include "sparse_fir_filter.h" 20 | 21 | namespace webrtc { 22 | 23 | // An implementation of a 3-band FIR filter-bank with DCT modulation, similar to 24 | // the proposed in "Multirate Signal Processing for Communication Systems" by 25 | // Fredric J Harris. 26 | // The low-pass filter prototype has these characteristics: 27 | // * Pass-band ripple = 0.3dB 28 | // * Pass-band frequency = 0.147 (7kHz at 48kHz) 29 | // * Stop-band attenuation = 40dB 30 | // * Stop-band frequency = 0.192 (9.2kHz at 48kHz) 31 | // * Delay = 24 samples (500us at 48kHz) 32 | // * Linear phase 33 | // This filter bank does not satisfy perfect reconstruction. The SNR after 34 | // analysis and synthesis (with no processing in between) is approximately 9.5dB 35 | // depending on the input signal after compensating for the delay. 36 | class ThreeBandFilterBank final { 37 | public: 38 | explicit ThreeBandFilterBank(size_t length); 39 | ~ThreeBandFilterBank(); 40 | 41 | // Splits |in| into 3 downsampled frequency bands in |out|. 42 | // |length| is the |in| length. Each of the 3 bands of |out| has to have a 43 | // length of |length| / 3. 44 | void Analysis(const float* in, size_t length, float* const* out); 45 | 46 | // Merges the 3 downsampled frequency bands in |in| into |out|. 47 | // |split_length| is the length of each band of |in|. |out| has to have at 48 | // least a length of 3 * |split_length|. 49 | void Synthesis(const float* const* in, size_t split_length, float* out); 50 | 51 | private: 52 | void DownModulate(const float* in, 53 | size_t split_length, 54 | size_t offset, 55 | float* const* out); 56 | void UpModulate(const float* const* in, 57 | size_t split_length, 58 | size_t offset, 59 | float* out); 60 | 61 | std::vector in_buffer_; 62 | std::vector out_buffer_; 63 | std::vector> analysis_filters_; 64 | std::vector> synthesis_filters_; 65 | std::vector> dct_modulation_; 66 | }; 67 | 68 | } // namespace webrtc 69 | 70 | #endif // MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 71 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/three_band_filter_bank.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 12 | #define MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | //#include "common_audio/sparse_fir_filter.h" 19 | #include "sparse_fir_filter.h" 20 | 21 | namespace webrtc { 22 | 23 | // An implementation of a 3-band FIR filter-bank with DCT modulation, similar to 24 | // the proposed in "Multirate Signal Processing for Communication Systems" by 25 | // Fredric J Harris. 26 | // The low-pass filter prototype has these characteristics: 27 | // * Pass-band ripple = 0.3dB 28 | // * Pass-band frequency = 0.147 (7kHz at 48kHz) 29 | // * Stop-band attenuation = 40dB 30 | // * Stop-band frequency = 0.192 (9.2kHz at 48kHz) 31 | // * Delay = 24 samples (500us at 48kHz) 32 | // * Linear phase 33 | // This filter bank does not satisfy perfect reconstruction. The SNR after 34 | // analysis and synthesis (with no processing in between) is approximately 9.5dB 35 | // depending on the input signal after compensating for the delay. 36 | class ThreeBandFilterBank final { 37 | public: 38 | explicit ThreeBandFilterBank(size_t length); 39 | ~ThreeBandFilterBank(); 40 | 41 | // Splits |in| into 3 downsampled frequency bands in |out|. 42 | // |length| is the |in| length. Each of the 3 bands of |out| has to have a 43 | // length of |length| / 3. 44 | void Analysis(const float* in, size_t length, float* const* out); 45 | 46 | // Merges the 3 downsampled frequency bands in |in| into |out|. 47 | // |split_length| is the length of each band of |in|. |out| has to have at 48 | // least a length of 3 * |split_length|. 49 | void Synthesis(const float* const* in, size_t split_length, float* out); 50 | 51 | private: 52 | void DownModulate(const float* in, 53 | size_t split_length, 54 | size_t offset, 55 | float* const* out); 56 | void UpModulate(const float* const* in, 57 | size_t split_length, 58 | size_t offset, 59 | float* out); 60 | 61 | std::vector in_buffer_; 62 | std::vector out_buffer_; 63 | std::vector> analysis_filters_; 64 | std::vector> synthesis_filters_; 65 | std::vector> dct_modulation_; 66 | }; 67 | 68 | } // namespace webrtc 69 | 70 | #endif // MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_ 71 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # WebRtc noise suppression 2 | 3 | This project is a standalone noise suppression module which reference from google's official webrtc project. I rewraped it so that it can be used in other places. The files used in this project in sync with official webrtc project respository. (branch de10eea, 2018.12). 4 | 5 | 6 | 7 | **TODO List:** 8 | 9 | - [x] noise suppression in hight sample rate - DONE supproted 32khz and 48 khz. 10 | - [ ] Explaining the principle of Webrtc's noise suppression algorithm. - TODO 11 | 12 | 13 | The noise suppression process flow can be summed up as below: 14 | 15 | ![1544091468844](assets/1544091468844.png) 16 | 17 | 18 | 19 | WebRtc uses AudioBuffer class to split audio date into different bands. I have capture the main splitting filter function in order to support 32khz and 48khz. 20 | 21 | For more details, please find https://chromium.googlesource.com/external/webrtc/+/master and the codes. 22 | 23 | ------ 24 | 25 | ## Test cases 26 | 27 | input : 28 | 29 | assets\babble_15dB.wav 30 | 31 | output: 32 | 33 | ns_level = kLow || webrtc_ns_kLow_babble_15dB.wav 34 | 35 | ns_level = kModerate || webrtc_ns_kModerate_babble_15dB.wav 36 | 37 | ns_level = kHigh || webrtc_ns_kHigh_babble_15dB.wav 38 | 39 | 40 | The rnnoise and speexdsp's noise suppression test case wav files are captured from the https://people.xiph.org/~jm/demo/rnnoise/ 41 | 42 | Thses files can be found in the link [TEST_CASES](https://github.com/jagger2048/WebRtc_noise_suppression/tree/master/assets/test_case) 43 | 44 | ## Performance 45 | 46 | With the same input,babble_15dB.wav, we set up a contrast among RNNoise, speexdsp and webrtc_ns.In the listening test, RNNoise performs well and suppresses the noise in babble.. It introduces a bit of artifacts which sounds unnature but it is tolerable. 47 | 48 | For the webrtc's ns, kHigh performs better than kModerate which can suppress the whole noise.The kLow case has a poor performance than the others. Notes that the webrtc's ns has an impacts of the Gain when processed the audio data, maybe it should be interfaced with AGC module. 49 | 50 | Finally, speexdsp's ns can suppress the babble noise but not completely reduce the backgourd noise. These noise suppression algorithm's performance can be summed up as blows: 51 | 52 | $$ 53 | 54 | kLow < speechx \approx kModerate modelUpdate; fluctuation limit of LRT feat. */ 59 | /* Limit on the max and min values for the feature thresholds */ 60 | #define MAX_FLAT_Q10 38912 /* * 2 * BIN_SIZE_FLAT_FX */ 61 | #define MIN_FLAT_Q10 4096 /* * 2 * BIN_SIZE_FLAT_FX */ 62 | #define MAX_DIFF 100 /* * 2 * BIN_SIZE_DIFF_FX */ 63 | #define MIN_DIFF 16 /* * 2 * BIN_SIZE_DIFF_FX */ 64 | /* Criteria of weight of histogram peak to accept/reject feature */ 65 | #define THRES_WEIGHT_FLAT_DIFF \ 66 | 154 /*(int)(0.3*(inst->modelUpdate)) for flatness and difference */ 67 | 68 | #define STAT_UPDATES 9 /* Update every 512 = 1 << 9 block */ 69 | #define ONE_MINUS_GAMMA_PAUSE_Q8 \ 70 | 13 /* ~= Q8(0.05) Update for conservative noise estimate */ 71 | #define GAMMA_NOISE_TRANS_AND_SPEECH_Q8 \ 72 | 3 /* ~= Q8(0.01) Update for transition and noise region */ 73 | 74 | #endif /* MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ */ 75 | -------------------------------------------------------------------------------- /readme_cn.md: -------------------------------------------------------------------------------- 1 | # WebRtc Noise suppression 2 | 3 | 本文将会介绍如何使用 google 的 webtrc 项目中的 noise suppression 模块。该模块可以对输入的音频信号进行降噪处理,并输出降噪后的信号,从时域图来看有点类似于 noise gate,从效果上来看降噪后的信号频谱图变化不大,但是实际听感会有点干,总体而言效果还是不错的。 4 | 5 | 需要注意的是,webrtc 中的 noise suppression 算法是针对于语音信号设计的,如果直接应用在音乐信号上效果会有所折扣(后续的测试也验证了这一点),并且对于输入信号的采样率有一定的要求,不能大于32k(大于32k需要 resample),因此本文仅就如何从 webrtc 项目中提取 noise suppression 模块以及如何使用该模块进行讲解,如何应用需要根据实际的需求进行取舍。 6 | 7 | ## 背景介绍 8 | 9 | WebRtc,*web real-time communication*,是由谷歌创立并开源的为浏览器、手机应用提供简单而又高效的实时通信解决方案的项目,该项目同时包含视频处理、音频处理、网络交互等模块,主要在浏览器中应用。Noise suppression ,为音频处理模块下的一个子项,音频处理模块(APM,*audio processing module*)下还有 AGC、AEC 、VAD等子模块。 10 | 11 | 在开源领域,还有另一个项目 Speex 也提供了类似于 webrtc 的全套音频解决方案,该项目的商业化项目为 Opus。除了使用传统的音频处理的方式降噪之外,还有一些使用更为现代的方式进行降噪,RNNoise 项目就是基于 RNN 神经网络实现对噪声的滤除,并且由于该方法的特性,可适用于全频带降噪(音乐信号),因此应用场景会更广。 12 | 13 | 以上提及的项目可以从以下链接中找到更详细的介绍: 14 | 15 | https://webrtc.org 16 | 17 | https://www.speex.org 18 | 19 | https://people.xiph.org/~jm/demo/rnnoise/ 20 | 21 | 本文将会介绍如何提取 WebRtc 中的 noise suppression 模块。 22 | 23 | ## 程序框架及过程 24 | 25 | 首先,到官方程序库下载 noise suppression 需要用到的文件: 26 | 27 | https://chromium.googlesource.com/external/webrtc/stable/webrtc/+/master/modules/audio_processing 28 | 29 | 在 module/audio_processing/ns 下获取以下文件: 30 | 31 | ![1531809169657](assets/1531809169657.png) 32 | 33 | 在 webrtc-refs_heads_master-**rtc_base** 中也有一些补充的文件,根据程序依赖在程序库中自行搜索下载: 34 | 35 | ![1531809187181](assets/1531809187181.png) 36 | 37 | 需要**注意**的是,提取出来的文件要**修改**对应的 #include 选项才可以正常使用 38 | 39 | 接下来进入正题,了解 noise suppression 模块的程序流程,并以此重新构建自己的处理模块。 40 | 41 | ## 处理流程 42 | 43 | WebRtc noisesuppression 模块的处理流程主要是按照以下来进行: 44 | 45 | ​ 开始->初始化->设置处理模式->帧处理->释放句柄->结束 46 | 47 | 具体的步骤如下: 48 | 49 | - 初始化句柄 50 | 51 | ```c++ 52 | NsHandle *nsHandle = WebRtcNs_Create(); 53 | int status = WebRtcNs_Init(nsHandle, sample_rate); 54 | ``` 55 | 56 | 其中初始化成功则 **status** 返回 0 57 | 58 | - 设置处理模式 59 | 60 | ```c++ 61 | status = WebRtcNs_set_policy(nsHandle, kVeryHigh); 62 | ``` 63 | 64 | **kVeryHigh** 为降噪的等级,取值 0~3 ,对应降噪等级从低到高,根据实际应用选择,本文选择2。**status** 设置成功返回 0 65 | 66 | - 帧处理 67 | 68 | - 分帧输入 69 | 70 | ```c++ 71 | float inf_buffer[maxSamples]; 72 | float outf_buffer[maxSamples]; 73 | // input the signal to process 74 | for (int n = 0; n != samples; ++n) { 75 | inf_buffer[n] = input[0][samples * i + n]; // 后续考虑使用其他方式 76 | } 77 | ... 78 | ``` 79 | 80 | 从输入信号中,取 10ms 的信号,16k的采样率也就是160点,8khz 则是 80 点。webRtc的函数最多只能处理160点,对大于16k的输入信号,需要降采样输入处理 81 | 82 | ps:此处存疑,按照查阅的资料,内置函数最高可以处理 32k 的信号,不过需要进行分频后按照不同的频带进行输入(由于内置的分频函数需要用到Q16定点数,因此不推荐使用分频法处理高采样率的信号),因此对大于16k的信号,可以直接降采样为16k进行处理,也可以降采样为32k,然后分频段输入处理。为简单起见直接降采样处理。 83 | 84 | - 噪声分析 85 | 86 | ```c++ 87 | float *nsIn[1] = { inf_buffer }; //ns input[band][data] 88 | float *nsOut[1] = { outf_buffer };//ns output[band][data] 89 | WebRtcNs_Analyze(nsHandle, nsIn[0]); 90 | ``` 91 | 92 | 调用用函数进行处理,注意输入待处理的数据 93 | 94 | - 降噪处理 95 | 96 | ```c++ 97 | WebRtcNs_Process(nsHandle, (const float *const *)nsIn, num_bands, nsOut); 98 | 99 | ``` 100 | 101 | 对输入信号进行降噪,函数中 num_bands 参数(取值1~2)对应着分频带之后的频段,对于16khz 的输入信号来讲可以可以不用管,鉴于我们直接使用降采样的方式处理高采样率的信号,因此该参数可以设置为 1 102 | 103 | - 按帧输出 104 | 105 | ```c++ 106 | // output the processed signal 107 | for (int n = 0; n != samples; ++n) { 108 | output[0].push_back(nsOut[0][n]); // test 109 | } 110 | ``` 111 | 112 | 按帧输出信号 113 | 114 | - 释放句柄 115 | 116 | ```c++ 117 | WebRtcNs_Free(nsHandle); 118 | ``` 119 | 120 | 对应的例程可以在 webRtc_official 中找到,后续我们会补充处理 16khz 采样率以上的音频信号的例程【直接使用降采样将高采样率的信号降成16k的信号,然后降噪输出,输出的分辨率视情况而定,指定/不变】 121 | 122 | ps: 123 | 124 | 1. 由于分频法在最新的文件依赖中有所改动,并且还需要将原有浮点数转成定点格式才能处理,因此不再尝试用该方法处理高采样率下的情况 125 | 2. 对于音乐信号,经过本算法处理后虽然也有降噪效果,但实际听感会有点不自然,因此不推荐对音乐信号降噪时使用本算法,推荐用于语音信号的降噪。 126 | 3. 在经过降噪后,会使信号增益下降,实际应用中需考虑增加 AGC,*Auto gain control*, 模块 127 | -------------------------------------------------------------------------------- /my_splitting_filter/my_splitting_filter.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {873dca42-749d-432d-9244-9c52c93a0658} 14 | 15 | 16 | 17 | 18 | 头文件 19 | 20 | 21 | WebRtc splitting filter 22 | 23 | 24 | WebRtc splitting filter 25 | 26 | 27 | WebRtc splitting filter 28 | 29 | 30 | WebRtc splitting filter 31 | 32 | 33 | WebRtc splitting filter 34 | 35 | 36 | WebRtc splitting filter 37 | 38 | 39 | WebRtc splitting filter 40 | 41 | 42 | WebRtc splitting filter 43 | 44 | 45 | WebRtc splitting filter 46 | 47 | 48 | WebRtc splitting filter 49 | 50 | 51 | WebRtc splitting filter 52 | 53 | 54 | WebRtc splitting filter 55 | 56 | 57 | WebRtc splitting filter 58 | 59 | 60 | WebRtc splitting filter 61 | 62 | 63 | 64 | 65 | 源文件 66 | 67 | 68 | 源文件 69 | 70 | 71 | WebRtc splitting filter 72 | 73 | 74 | WebRtc splitting filter 75 | 76 | 77 | WebRtc splitting filter 78 | 79 | 80 | WebRtc splitting filter 81 | 82 | 83 | WebRtc splitting filter 84 | 85 | 86 | WebRtc splitting filter 87 | 88 | 89 | WebRtc splitting filter 90 | 91 | 92 | -------------------------------------------------------------------------------- /WebRtc_official/include/ns/noise_suppression_x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ 12 | #define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ 13 | 14 | #include 15 | #include 16 | 17 | typedef struct NsxHandleT NsxHandle; 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | * This function creates an instance of the fixed point Noise Suppression. 25 | */ 26 | NsxHandle* WebRtcNsx_Create(void); 27 | 28 | /* 29 | * This function frees the dynamic memory of a specified Noise Suppression 30 | * instance. 31 | * 32 | * Input: 33 | * - nsxInst : Pointer to NS instance that should be freed 34 | */ 35 | void WebRtcNsx_Free(NsxHandle* nsxInst); 36 | 37 | /* 38 | * This function initializes a NS instance 39 | * 40 | * Input: 41 | * - nsxInst : Instance that should be initialized 42 | * - fs : sampling frequency 43 | * 44 | * Output: 45 | * - nsxInst : Initialized instance 46 | * 47 | * Return value : 0 - Ok 48 | * -1 - Error 49 | */ 50 | int WebRtcNsx_Init(NsxHandle* nsxInst, uint32_t fs); 51 | 52 | /* 53 | * This changes the aggressiveness of the noise suppression method. 54 | * 55 | * Input: 56 | * - nsxInst : Instance that should be initialized 57 | * - mode : 0: Mild, 1: Medium , 2: Aggressive 58 | * 59 | * Output: 60 | * - nsxInst : Initialized instance 61 | * 62 | * Return value : 0 - Ok 63 | * -1 - Error 64 | */ 65 | int WebRtcNsx_set_policy(NsxHandle* nsxInst, int mode); 66 | 67 | /* 68 | * This functions does noise suppression for the inserted speech frame. The 69 | * input and output signals should always be 10ms (80 or 160 samples). 70 | * 71 | * Input 72 | * - nsxInst : NSx instance. Needs to be initiated before call. 73 | * - speechFrame : Pointer to speech frame buffer for each band 74 | * - num_bands : Number of bands 75 | * 76 | * Output: 77 | * - nsxInst : Updated NSx instance 78 | * - outFrame : Pointer to output frame for each band 79 | */ 80 | void WebRtcNsx_Process(NsxHandle* nsxInst, 81 | const short* const* speechFrame, 82 | int num_bands, 83 | short* const* outFrame); 84 | 85 | /* Returns a pointer to the noise estimate per frequency bin. The number of 86 | * frequency bins can be provided using WebRtcNsx_num_freq(). 87 | * 88 | * Input 89 | * - nsxInst : NSx instance. Needs to be initiated before call. 90 | * - q_noise : Q value of the noise estimate, which is the number of 91 | * bits that it needs to be right-shifted to be 92 | * normalized. 93 | * 94 | * Return value : Pointer to the noise estimate per frequency bin. 95 | * Returns NULL if the input is a NULL pointer or an 96 | * uninitialized instance. 97 | */ 98 | const uint32_t* WebRtcNsx_noise_estimate(const NsxHandle* nsxInst, 99 | int* q_noise); 100 | 101 | /* Returns the number of frequency bins, which is the length of the noise 102 | * estimate for example. 103 | * 104 | * Return value : Number of frequency bins. 105 | */ 106 | size_t WebRtcNsx_num_freq(void); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_ 113 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/splitting_filter_unittest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // MSVC++ requires this to be set before any other includes to get M_PI. 12 | #define _USE_MATH_DEFINES 13 | 14 | #include 15 | 16 | //#include "common_audio/channel_buffer.h" 17 | //#include "modules/audio_processing/splitting_filter.h" 18 | //#include "test/gtest.h" 19 | #include "channel_buffer.h" 20 | #include "splitting_filter.h" 21 | #include "gtest.h" 22 | 23 | namespace webrtc { 24 | namespace { 25 | 26 | const size_t kSamplesPer16kHzChannel = 160; 27 | const size_t kSamplesPer48kHzChannel = 480; 28 | 29 | } // namespace 30 | 31 | // Generates a signal from presence or absence of sine waves of different 32 | // frequencies. 33 | // Splits into 3 bands and checks their presence or absence. 34 | // Recombines the bands. 35 | // Calculates the delay. 36 | // Checks that the cross correlation of input and output is high enough at the 37 | // calculated delay. 38 | TEST(SplittingFilterTest, SplitsIntoThreeBandsAndReconstructs) { 39 | static const int kChannels = 1; 40 | static const int kSampleRateHz = 48000; 41 | static const size_t kNumBands = 3; 42 | static const int kFrequenciesHz[kNumBands] = {1000, 12000, 18000}; 43 | static const float kAmplitude = 8192.f; 44 | static const size_t kChunks = 8; 45 | SplittingFilter splitting_filter(kChannels, kNumBands, 46 | kSamplesPer48kHzChannel); 47 | IFChannelBuffer in_data(kSamplesPer48kHzChannel, kChannels, kNumBands); 48 | IFChannelBuffer bands(kSamplesPer48kHzChannel, kChannels, kNumBands); 49 | IFChannelBuffer out_data(kSamplesPer48kHzChannel, kChannels, kNumBands); 50 | for (size_t i = 0; i < kChunks; ++i) { 51 | // Input signal generation. 52 | bool is_present[kNumBands]; 53 | memset(in_data.fbuf()->channels()[0], 0, 54 | kSamplesPer48kHzChannel * sizeof(in_data.fbuf()->channels()[0][0])); 55 | for (size_t j = 0; j < kNumBands; ++j) { 56 | is_present[j] = i & (static_cast(1) << j); 57 | float amplitude = is_present[j] ? kAmplitude : 0.f; 58 | for (size_t k = 0; k < kSamplesPer48kHzChannel; ++k) { 59 | in_data.fbuf()->channels()[0][k] += 60 | amplitude * sin(2.f * M_PI * kFrequenciesHz[j] * 61 | (i * kSamplesPer48kHzChannel + k) / kSampleRateHz); 62 | } 63 | } 64 | // Three band splitting filter. 65 | splitting_filter.Analysis(&in_data, &bands); 66 | // Energy calculation. 67 | float energy[kNumBands]; 68 | for (size_t j = 0; j < kNumBands; ++j) { 69 | energy[j] = 0.f; 70 | for (size_t k = 0; k < kSamplesPer16kHzChannel; ++k) { 71 | energy[j] += bands.fbuf_const()->channels(j)[0][k] * 72 | bands.fbuf_const()->channels(j)[0][k]; 73 | } 74 | energy[j] /= kSamplesPer16kHzChannel; 75 | if (is_present[j]) { 76 | EXPECT_GT(energy[j], kAmplitude * kAmplitude / 4); 77 | } else { 78 | EXPECT_LT(energy[j], kAmplitude * kAmplitude / 4); 79 | } 80 | } 81 | // Three band merge. 82 | splitting_filter.Synthesis(&bands, &out_data); 83 | // Delay and cross correlation estimation. 84 | float xcorr = 0.f; 85 | for (size_t delay = 0; delay < kSamplesPer48kHzChannel; ++delay) { 86 | float tmpcorr = 0.f; 87 | for (size_t j = delay; j < kSamplesPer48kHzChannel; ++j) { 88 | tmpcorr += in_data.fbuf_const()->channels()[0][j - delay] * 89 | out_data.fbuf_const()->channels()[0][j]; 90 | } 91 | tmpcorr /= kSamplesPer48kHzChannel; 92 | if (tmpcorr > xcorr) { 93 | xcorr = tmpcorr; 94 | } 95 | } 96 | // High cross correlation check. 97 | bool any_present = false; 98 | for (size_t j = 0; j < kNumBands; ++j) { 99 | any_present |= is_present[j]; 100 | } 101 | if (any_present) { 102 | EXPECT_GT(xcorr, kAmplitude * kAmplitude / 4); 103 | } 104 | } 105 | } 106 | 107 | } // namespace webrtc 108 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/splitting_filter_unittest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // MSVC++ requires this to be set before any other includes to get M_PI. 12 | #define _USE_MATH_DEFINES 13 | 14 | #include 15 | 16 | //#include "common_audio/channel_buffer.h" 17 | //#include "modules/audio_processing/splitting_filter.h" 18 | //#include "test/gtest.h" 19 | #include "channel_buffer.h" 20 | #include "splitting_filter.h" 21 | #include "gtest.h" 22 | 23 | namespace webrtc { 24 | namespace { 25 | 26 | const size_t kSamplesPer16kHzChannel = 160; 27 | const size_t kSamplesPer48kHzChannel = 480; 28 | 29 | } // namespace 30 | 31 | // Generates a signal from presence or absence of sine waves of different 32 | // frequencies. 33 | // Splits into 3 bands and checks their presence or absence. 34 | // Recombines the bands. 35 | // Calculates the delay. 36 | // Checks that the cross correlation of input and output is high enough at the 37 | // calculated delay. 38 | TEST(SplittingFilterTest, SplitsIntoThreeBandsAndReconstructs) { 39 | static const int kChannels = 1; 40 | static const int kSampleRateHz = 48000; 41 | static const size_t kNumBands = 3; 42 | static const int kFrequenciesHz[kNumBands] = {1000, 12000, 18000}; 43 | static const float kAmplitude = 8192.f; 44 | static const size_t kChunks = 8; 45 | SplittingFilter splitting_filter(kChannels, kNumBands, 46 | kSamplesPer48kHzChannel); 47 | IFChannelBuffer in_data(kSamplesPer48kHzChannel, kChannels, kNumBands); 48 | IFChannelBuffer bands(kSamplesPer48kHzChannel, kChannels, kNumBands); 49 | IFChannelBuffer out_data(kSamplesPer48kHzChannel, kChannels, kNumBands); 50 | for (size_t i = 0; i < kChunks; ++i) { 51 | // Input signal generation. 52 | bool is_present[kNumBands]; 53 | memset(in_data.fbuf()->channels()[0], 0, 54 | kSamplesPer48kHzChannel * sizeof(in_data.fbuf()->channels()[0][0])); 55 | for (size_t j = 0; j < kNumBands; ++j) { 56 | is_present[j] = i & (static_cast(1) << j); 57 | float amplitude = is_present[j] ? kAmplitude : 0.f; 58 | for (size_t k = 0; k < kSamplesPer48kHzChannel; ++k) { 59 | in_data.fbuf()->channels()[0][k] += 60 | amplitude * sin(2.f * M_PI * kFrequenciesHz[j] * 61 | (i * kSamplesPer48kHzChannel + k) / kSampleRateHz); 62 | } 63 | } 64 | // Three band splitting filter. 65 | splitting_filter.Analysis(&in_data, &bands); 66 | // Energy calculation. 67 | float energy[kNumBands]; 68 | for (size_t j = 0; j < kNumBands; ++j) { 69 | energy[j] = 0.f; 70 | for (size_t k = 0; k < kSamplesPer16kHzChannel; ++k) { 71 | energy[j] += bands.fbuf_const()->channels(j)[0][k] * 72 | bands.fbuf_const()->channels(j)[0][k]; 73 | } 74 | energy[j] /= kSamplesPer16kHzChannel; 75 | if (is_present[j]) { 76 | EXPECT_GT(energy[j], kAmplitude * kAmplitude / 4); 77 | } else { 78 | EXPECT_LT(energy[j], kAmplitude * kAmplitude / 4); 79 | } 80 | } 81 | // Three band merge. 82 | splitting_filter.Synthesis(&bands, &out_data); 83 | // Delay and cross correlation estimation. 84 | float xcorr = 0.f; 85 | for (size_t delay = 0; delay < kSamplesPer48kHzChannel; ++delay) { 86 | float tmpcorr = 0.f; 87 | for (size_t j = delay; j < kSamplesPer48kHzChannel; ++j) { 88 | tmpcorr += in_data.fbuf_const()->channels()[0][j - delay] * 89 | out_data.fbuf_const()->channels()[0][j]; 90 | } 91 | tmpcorr /= kSamplesPer48kHzChannel; 92 | if (tmpcorr > xcorr) { 93 | xcorr = tmpcorr; 94 | } 95 | } 96 | // High cross correlation check. 97 | bool any_present = false; 98 | for (size_t j = 0; j < kNumBands; ++j) { 99 | any_present |= is_present[j]; 100 | } 101 | if (any_present) { 102 | EXPECT_GT(xcorr, kAmplitude * kAmplitude / 4); 103 | } 104 | } 105 | } 106 | 107 | } // namespace webrtc 108 | -------------------------------------------------------------------------------- /WebRtc_official/include/ns/noise_suppression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ 12 | #define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ 13 | 14 | #include 15 | #include 16 | 17 | typedef struct NsHandleT NsHandle; 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | * This function creates an instance of the floating point Noise Suppression. 25 | */ 26 | NsHandle* WebRtcNs_Create(void); 27 | 28 | /* 29 | * This function frees the dynamic memory of a specified noise suppression 30 | * instance. 31 | * 32 | * Input: 33 | * - NS_inst : Pointer to NS instance that should be freed 34 | */ 35 | void WebRtcNs_Free(NsHandle* NS_inst); 36 | 37 | /* 38 | * This function initializes a NS instance and has to be called before any other 39 | * processing is made. 40 | * 41 | * Input: 42 | * - NS_inst : Instance that should be initialized 43 | * - fs : sampling frequency 44 | * 45 | * Output: 46 | * - NS_inst : Initialized instance 47 | * 48 | * Return value : 0 - Ok 49 | * -1 - Error 50 | */ 51 | int WebRtcNs_Init(NsHandle* NS_inst, uint32_t fs); 52 | 53 | /* 54 | * This changes the aggressiveness of the noise suppression method. 55 | * 56 | * Input: 57 | * - NS_inst : Noise suppression instance. 58 | * - mode : 0: Mild, 1: Medium , 2: Aggressive 59 | * 60 | * Output: 61 | * - NS_inst : Updated instance. 62 | * 63 | * Return value : 0 - Ok 64 | * -1 - Error 65 | */ 66 | int WebRtcNs_set_policy(NsHandle* NS_inst, int mode); 67 | 68 | /* 69 | * This functions estimates the background noise for the inserted speech frame. 70 | * The input and output signals should always be 10ms (80 or 160 samples). 71 | * 72 | * Input 73 | * - NS_inst : Noise suppression instance. 74 | * - spframe : Pointer to speech frame buffer for L band 75 | * 76 | * Output: 77 | * - NS_inst : Updated NS instance 78 | */ 79 | void WebRtcNs_Analyze(NsHandle* NS_inst, const float* spframe); 80 | 81 | /* 82 | * This functions does Noise Suppression for the inserted speech frame. The 83 | * input and output signals should always be 10ms (80 or 160 samples). 84 | * 85 | * Input 86 | * - NS_inst : Noise suppression instance. 87 | * - spframe : Pointer to speech frame buffer for each band 88 | * - num_bands : Number of bands 89 | * 90 | * Output: 91 | * - NS_inst : Updated NS instance 92 | * - outframe : Pointer to output frame for each band 93 | */ 94 | void WebRtcNs_Process(NsHandle* NS_inst, 95 | const float* const* spframe, 96 | size_t num_bands, 97 | float* const* outframe); 98 | 99 | /* Returns the internally used prior speech probability of the current frame. 100 | * There is a frequency bin based one as well, with which this should not be 101 | * confused. 102 | * 103 | * Input 104 | * - handle : Noise suppression instance. 105 | * 106 | * Return value : Prior speech probability in interval [0.0, 1.0]. 107 | * -1 - NULL pointer or uninitialized instance. 108 | */ 109 | float WebRtcNs_prior_speech_probability(NsHandle* handle); 110 | 111 | /* Returns a pointer to the noise estimate per frequency bin. The number of 112 | * frequency bins can be provided using WebRtcNs_num_freq(). 113 | * 114 | * Input 115 | * - handle : Noise suppression instance. 116 | * 117 | * Return value : Pointer to the noise estimate per frequency bin. 118 | * Returns NULL if the input is a NULL pointer or an 119 | * uninitialized instance. 120 | */ 121 | const float* WebRtcNs_noise_estimate(const NsHandle* handle); 122 | 123 | /* Returns the number of frequency bins, which is the length of the noise 124 | * estimate for example. 125 | * 126 | * Return value : Number of frequency bins. 127 | */ 128 | size_t WebRtcNs_num_freq(void); 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | #endif // MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_ 135 | -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/type_traits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_TYPE_TRAITS_H_ 12 | #define RTC_BASE_TYPE_TRAITS_H_ 13 | 14 | #include 15 | #include 16 | 17 | namespace rtc { 18 | 19 | // Determines if the given class has zero-argument .data() and .size() methods 20 | // whose return values are convertible to T* and size_t, respectively. 21 | template 22 | class HasDataAndSize { 23 | private: 24 | template < 25 | typename C, 26 | typename std::enable_if< 27 | std::is_convertible().data()), T*>::value && 28 | std::is_convertible().size()), 29 | std::size_t>::value>::type* = nullptr> 30 | static int Test(int); 31 | 32 | template 33 | static char Test(...); 34 | 35 | public: 36 | static constexpr bool value = std::is_same(0)), int>::value; 37 | }; 38 | 39 | namespace test_has_data_and_size { 40 | 41 | template 42 | struct Test1 { 43 | DR data(); 44 | SR size(); 45 | }; 46 | static_assert(HasDataAndSize, int>::value, ""); 47 | static_assert(HasDataAndSize, const int>::value, ""); 48 | static_assert(HasDataAndSize, const int>::value, ""); 49 | static_assert(!HasDataAndSize, int>::value, 50 | "implicit cast of const int* to int*"); 51 | static_assert(!HasDataAndSize, int>::value, 52 | "implicit cast of char* to int*"); 53 | 54 | struct Test2 { 55 | int* data; 56 | size_t size; 57 | }; 58 | static_assert(!HasDataAndSize::value, 59 | ".data and .size aren't functions"); 60 | 61 | struct Test3 { 62 | int* data(); 63 | }; 64 | static_assert(!HasDataAndSize::value, ".size() is missing"); 65 | 66 | class Test4 { 67 | int* data(); 68 | size_t size(); 69 | }; 70 | static_assert(!HasDataAndSize::value, 71 | ".data() and .size() are private"); 72 | 73 | } // namespace test_has_data_and_size 74 | 75 | namespace type_traits_impl { 76 | 77 | // Determines if the given type is an enum that converts implicitly to 78 | // an integral type. 79 | template 80 | struct IsIntEnum { 81 | private: 82 | // This overload is used if the type is an enum, and unary plus 83 | // compiles and turns it into an integral type. 84 | template ::value && 87 | std::is_integral())>::value>::type* = 88 | nullptr> 89 | static int Test(int); 90 | 91 | // Otherwise, this overload is used. 92 | template 93 | static char Test(...); 94 | 95 | public: 96 | static constexpr bool value = 97 | std::is_same::type>(0)), 98 | int>::value; 99 | }; 100 | 101 | } // namespace type_traits_impl 102 | 103 | // Determines if the given type is integral, or an enum that 104 | // converts implicitly to an integral type. 105 | template 106 | struct IsIntlike { 107 | private: 108 | using X = typename std::remove_reference::type; 109 | 110 | public: 111 | static constexpr bool value = 112 | std::is_integral::value || type_traits_impl::IsIntEnum::value; 113 | }; 114 | 115 | namespace test_enum_intlike { 116 | 117 | enum E1 { e1 }; 118 | enum { e2 }; 119 | enum class E3 { e3 }; 120 | struct S {}; 121 | 122 | static_assert(type_traits_impl::IsIntEnum::value, ""); 123 | static_assert(type_traits_impl::IsIntEnum::value, ""); 124 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 125 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 126 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 127 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 128 | 129 | static_assert(IsIntlike::value, ""); 130 | static_assert(IsIntlike::value, ""); 131 | static_assert(!IsIntlike::value, ""); 132 | static_assert(IsIntlike::value, ""); 133 | static_assert(!IsIntlike::value, ""); 134 | static_assert(!IsIntlike::value, ""); 135 | 136 | } // namespace test_enum_intlike 137 | 138 | } // namespace rtc 139 | 140 | #endif // RTC_BASE_TYPE_TRAITS_H_ 141 | -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/type_traits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_TYPE_TRAITS_H_ 12 | #define RTC_BASE_TYPE_TRAITS_H_ 13 | 14 | #include 15 | #include 16 | 17 | namespace rtc { 18 | 19 | // Determines if the given class has zero-argument .data() and .size() methods 20 | // whose return values are convertible to T* and size_t, respectively. 21 | template 22 | class HasDataAndSize { 23 | private: 24 | template < 25 | typename C, 26 | typename std::enable_if< 27 | std::is_convertible().data()), T*>::value && 28 | std::is_convertible().size()), 29 | std::size_t>::value>::type* = nullptr> 30 | static int Test(int); 31 | 32 | template 33 | static char Test(...); 34 | 35 | public: 36 | static constexpr bool value = std::is_same(0)), int>::value; 37 | }; 38 | 39 | namespace test_has_data_and_size { 40 | 41 | template 42 | struct Test1 { 43 | DR data(); 44 | SR size(); 45 | }; 46 | static_assert(HasDataAndSize, int>::value, ""); 47 | static_assert(HasDataAndSize, const int>::value, ""); 48 | static_assert(HasDataAndSize, const int>::value, ""); 49 | static_assert(!HasDataAndSize, int>::value, 50 | "implicit cast of const int* to int*"); 51 | static_assert(!HasDataAndSize, int>::value, 52 | "implicit cast of char* to int*"); 53 | 54 | struct Test2 { 55 | int* data; 56 | size_t size; 57 | }; 58 | static_assert(!HasDataAndSize::value, 59 | ".data and .size aren't functions"); 60 | 61 | struct Test3 { 62 | int* data(); 63 | }; 64 | static_assert(!HasDataAndSize::value, ".size() is missing"); 65 | 66 | class Test4 { 67 | int* data(); 68 | size_t size(); 69 | }; 70 | static_assert(!HasDataAndSize::value, 71 | ".data() and .size() are private"); 72 | 73 | } // namespace test_has_data_and_size 74 | 75 | namespace type_traits_impl { 76 | 77 | // Determines if the given type is an enum that converts implicitly to 78 | // an integral type. 79 | template 80 | struct IsIntEnum { 81 | private: 82 | // This overload is used if the type is an enum, and unary plus 83 | // compiles and turns it into an integral type. 84 | template ::value && 87 | std::is_integral())>::value>::type* = 88 | nullptr> 89 | static int Test(int); 90 | 91 | // Otherwise, this overload is used. 92 | template 93 | static char Test(...); 94 | 95 | public: 96 | static constexpr bool value = 97 | std::is_same::type>(0)), 98 | int>::value; 99 | }; 100 | 101 | } // namespace type_traits_impl 102 | 103 | // Determines if the given type is integral, or an enum that 104 | // converts implicitly to an integral type. 105 | template 106 | struct IsIntlike { 107 | private: 108 | using X = typename std::remove_reference::type; 109 | 110 | public: 111 | static constexpr bool value = 112 | std::is_integral::value || type_traits_impl::IsIntEnum::value; 113 | }; 114 | 115 | namespace test_enum_intlike { 116 | 117 | enum E1 { e1 }; 118 | enum { e2 }; 119 | enum class E3 { e3 }; 120 | struct S {}; 121 | 122 | static_assert(type_traits_impl::IsIntEnum::value, ""); 123 | static_assert(type_traits_impl::IsIntEnum::value, ""); 124 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 125 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 126 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 127 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 128 | 129 | static_assert(IsIntlike::value, ""); 130 | static_assert(IsIntlike::value, ""); 131 | static_assert(!IsIntlike::value, ""); 132 | static_assert(IsIntlike::value, ""); 133 | static_assert(!IsIntlike::value, ""); 134 | static_assert(!IsIntlike::value, ""); 135 | 136 | } // namespace test_enum_intlike 137 | 138 | } // namespace rtc 139 | 140 | #endif // RTC_BASE_TYPE_TRAITS_H_ 141 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/splitting_filter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "modules/audio_processing/splitting_filter.h" 12 | // 13 | //#include "common_audio/channel_buffer.h" 14 | //#include "common_audio/signal_processing/include/signal_processing_library.h" 15 | //#include "rtc_base/checks.h" 16 | 17 | #include "splitting_filter.h" 18 | 19 | #include "channel_buffer.h" 20 | #include "signal_processing_library.h" 21 | #include "checks.h" 22 | 23 | namespace webrtc { 24 | 25 | SplittingFilter::SplittingFilter(size_t num_channels, 26 | size_t num_bands, 27 | size_t num_frames) 28 | : num_bands_(num_bands) { 29 | RTC_CHECK(num_bands_ == 2 || num_bands_ == 3); 30 | if (num_bands_ == 2) { 31 | two_bands_states_.resize(num_channels); 32 | } else if (num_bands_ == 3) { 33 | for (size_t i = 0; i < num_channels; ++i) { 34 | three_band_filter_banks_.push_back(std::unique_ptr( 35 | new ThreeBandFilterBank(num_frames))); 36 | } 37 | } 38 | } 39 | 40 | SplittingFilter::~SplittingFilter() = default; 41 | 42 | void SplittingFilter::Analysis(const IFChannelBuffer* data, 43 | IFChannelBuffer* bands) { 44 | RTC_DCHECK_EQ(num_bands_, bands->num_bands()); 45 | RTC_DCHECK_EQ(data->num_channels(), bands->num_channels()); 46 | RTC_DCHECK_EQ(data->num_frames(), 47 | bands->num_frames_per_band() * bands->num_bands()); 48 | if (bands->num_bands() == 2) { 49 | TwoBandsAnalysis(data, bands); 50 | } else if (bands->num_bands() == 3) { 51 | ThreeBandsAnalysis(data, bands); 52 | } 53 | } 54 | 55 | void SplittingFilter::Synthesis(const IFChannelBuffer* bands, 56 | IFChannelBuffer* data) { 57 | RTC_DCHECK_EQ(num_bands_, bands->num_bands()); 58 | RTC_DCHECK_EQ(data->num_channels(), bands->num_channels()); 59 | RTC_DCHECK_EQ(data->num_frames(), 60 | bands->num_frames_per_band() * bands->num_bands()); 61 | if (bands->num_bands() == 2) { 62 | TwoBandsSynthesis(bands, data); 63 | } else if (bands->num_bands() == 3) { 64 | ThreeBandsSynthesis(bands, data); 65 | } 66 | } 67 | 68 | void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* data, 69 | IFChannelBuffer* bands) { 70 | RTC_DCHECK_EQ(two_bands_states_.size(), data->num_channels()); 71 | for (size_t i = 0; i < two_bands_states_.size(); ++i) { 72 | WebRtcSpl_AnalysisQMF(data->ibuf_const()->channels()[i], data->num_frames(), 73 | bands->ibuf()->channels(0)[i], 74 | bands->ibuf()->channels(1)[i], 75 | two_bands_states_[i].analysis_state1, 76 | two_bands_states_[i].analysis_state2); 77 | } 78 | } 79 | 80 | void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* bands, 81 | IFChannelBuffer* data) { 82 | RTC_DCHECK_LE(data->num_channels(), two_bands_states_.size()); 83 | for (size_t i = 0; i < data->num_channels(); ++i) { 84 | WebRtcSpl_SynthesisQMF( 85 | bands->ibuf_const()->channels(0)[i], 86 | bands->ibuf_const()->channels(1)[i], bands->num_frames_per_band(), 87 | data->ibuf()->channels()[i], two_bands_states_[i].synthesis_state1, 88 | two_bands_states_[i].synthesis_state2); 89 | } 90 | } 91 | 92 | void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* data, 93 | IFChannelBuffer* bands) { 94 | RTC_DCHECK_EQ(three_band_filter_banks_.size(), data->num_channels()); 95 | for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) { 96 | three_band_filter_banks_[i]->Analysis(data->fbuf_const()->channels()[i], 97 | data->num_frames(), 98 | bands->fbuf()->bands(i)); 99 | } 100 | } 101 | 102 | void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* bands, 103 | IFChannelBuffer* data) { 104 | RTC_DCHECK_LE(data->num_channels(), three_band_filter_banks_.size()); 105 | for (size_t i = 0; i < data->num_channels(); ++i) { 106 | three_band_filter_banks_[i]->Synthesis(bands->fbuf_const()->bands(i), 107 | bands->num_frames_per_band(), 108 | data->fbuf()->channels()[i]); 109 | } 110 | } 111 | 112 | } // namespace webrtc 113 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/splitting_filter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | //#include "modules/audio_processing/splitting_filter.h" 12 | // 13 | //#include "common_audio/channel_buffer.h" 14 | //#include "common_audio/signal_processing/include/signal_processing_library.h" 15 | //#include "rtc_base/checks.h" 16 | 17 | #include "splitting_filter.h" 18 | 19 | #include "channel_buffer.h" 20 | #include "signal_processing_library.h" 21 | #include "checks.h" 22 | 23 | namespace webrtc { 24 | 25 | SplittingFilter::SplittingFilter(size_t num_channels, 26 | size_t num_bands, 27 | size_t num_frames) 28 | : num_bands_(num_bands) { 29 | RTC_CHECK(num_bands_ == 2 || num_bands_ == 3); 30 | if (num_bands_ == 2) { 31 | two_bands_states_.resize(num_channels); 32 | } else if (num_bands_ == 3) { 33 | for (size_t i = 0; i < num_channels; ++i) { 34 | three_band_filter_banks_.push_back(std::unique_ptr( 35 | new ThreeBandFilterBank(num_frames))); 36 | } 37 | } 38 | } 39 | 40 | SplittingFilter::~SplittingFilter() = default; 41 | 42 | void SplittingFilter::Analysis(const IFChannelBuffer* data, 43 | IFChannelBuffer* bands) { 44 | RTC_DCHECK_EQ(num_bands_, bands->num_bands()); 45 | RTC_DCHECK_EQ(data->num_channels(), bands->num_channels()); 46 | RTC_DCHECK_EQ(data->num_frames(), 47 | bands->num_frames_per_band() * bands->num_bands()); 48 | if (bands->num_bands() == 2) { 49 | TwoBandsAnalysis(data, bands); 50 | } else if (bands->num_bands() == 3) { 51 | ThreeBandsAnalysis(data, bands); 52 | } 53 | } 54 | 55 | void SplittingFilter::Synthesis(const IFChannelBuffer* bands, 56 | IFChannelBuffer* data) { 57 | RTC_DCHECK_EQ(num_bands_, bands->num_bands()); 58 | RTC_DCHECK_EQ(data->num_channels(), bands->num_channels()); 59 | RTC_DCHECK_EQ(data->num_frames(), 60 | bands->num_frames_per_band() * bands->num_bands()); 61 | if (bands->num_bands() == 2) { 62 | TwoBandsSynthesis(bands, data); 63 | } else if (bands->num_bands() == 3) { 64 | ThreeBandsSynthesis(bands, data); 65 | } 66 | } 67 | 68 | void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* data, 69 | IFChannelBuffer* bands) { 70 | RTC_DCHECK_EQ(two_bands_states_.size(), data->num_channels()); 71 | for (size_t i = 0; i < two_bands_states_.size(); ++i) { 72 | WebRtcSpl_AnalysisQMF(data->ibuf_const()->channels()[i], data->num_frames(), 73 | bands->ibuf()->channels(0)[i], 74 | bands->ibuf()->channels(1)[i], 75 | two_bands_states_[i].analysis_state1, 76 | two_bands_states_[i].analysis_state2); 77 | } 78 | } 79 | 80 | void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* bands, 81 | IFChannelBuffer* data) { 82 | RTC_DCHECK_LE(data->num_channels(), two_bands_states_.size()); 83 | for (size_t i = 0; i < data->num_channels(); ++i) { 84 | WebRtcSpl_SynthesisQMF( 85 | bands->ibuf_const()->channels(0)[i], 86 | bands->ibuf_const()->channels(1)[i], bands->num_frames_per_band(), 87 | data->ibuf()->channels()[i], two_bands_states_[i].synthesis_state1, 88 | two_bands_states_[i].synthesis_state2); 89 | } 90 | } 91 | 92 | void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* data, 93 | IFChannelBuffer* bands) { 94 | RTC_DCHECK_EQ(three_band_filter_banks_.size(), data->num_channels()); 95 | for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) { 96 | three_band_filter_banks_[i]->Analysis(data->fbuf_const()->channels()[i], 97 | data->num_frames(), 98 | bands->fbuf()->bands(i)); 99 | } 100 | } 101 | 102 | void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* bands, 103 | IFChannelBuffer* data) { 104 | RTC_DCHECK_LE(data->num_channels(), three_band_filter_banks_.size()); 105 | for (size_t i = 0; i < data->num_channels(); ++i) { 106 | three_band_filter_banks_[i]->Synthesis(bands->fbuf_const()->bands(i), 107 | bands->num_frames_per_band(), 108 | data->fbuf()->channels()[i]); 109 | } 110 | } 111 | 112 | } // namespace webrtc 113 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/spl_inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This header file includes the inline functions in 12 | // the fix point signal processing library. 13 | 14 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 15 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 16 | 17 | //#include "./rtc_base/compile_assert_c.h" 18 | #include "compile_assert_c.h" 19 | 20 | extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64]; 21 | 22 | // Don't call this directly except in tests! 23 | static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) { 24 | // Normalize n by rounding up to the nearest number that is a sequence of 0 25 | // bits followed by a sequence of 1 bits. This number has the same number of 26 | // leading zeros as the original n. There are exactly 33 such values. 27 | n |= n >> 1; 28 | n |= n >> 2; 29 | n |= n >> 4; 30 | n |= n >> 8; 31 | n |= n >> 16; 32 | 33 | // Multiply the modified n with a constant selected (by exhaustive search) 34 | // such that each of the 33 possible values of n give a product whose 6 most 35 | // significant bits are unique. Then look up the answer in the table. 36 | return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26]; 37 | } 38 | 39 | // Don't call this directly except in tests! 40 | static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) { 41 | const int leading_zeros = n >> 32 == 0 ? 32 : 0; 42 | return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin( 43 | (uint32_t)(n >> (32 - leading_zeros))); 44 | } 45 | 46 | // Returns the number of leading zero bits in the argument. 47 | static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) { 48 | #ifdef __GNUC__ 49 | RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t)); 50 | return n == 0 ? 32 : __builtin_clz(n); 51 | #else 52 | return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n); 53 | #endif 54 | } 55 | 56 | // Returns the number of leading zero bits in the argument. 57 | static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) { 58 | #ifdef __GNUC__ 59 | RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT 60 | return n == 0 ? 64 : __builtin_clzll(n); 61 | #else 62 | return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n); 63 | #endif 64 | } 65 | 66 | #ifdef WEBRTC_ARCH_ARM_V7 67 | #include "common_audio/signal_processing/include/spl_inl_armv7.h" 68 | #else 69 | 70 | #if defined(MIPS32_LE) 71 | #include "common_audio/signal_processing/include/spl_inl_mips.h" 72 | #endif 73 | 74 | #if !defined(MIPS_DSP_R1_LE) 75 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { 76 | int16_t out16 = (int16_t)value32; 77 | 78 | if (value32 > 32767) 79 | out16 = 32767; 80 | else if (value32 < -32768) 81 | out16 = -32768; 82 | 83 | return out16; 84 | } 85 | 86 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) { 87 | // Do the addition in unsigned numbers, since signed overflow is undefined 88 | // behavior. 89 | const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b); 90 | 91 | // a + b can't overflow if a and b have different signs. If they have the 92 | // same sign, a + b also has the same sign iff it didn't overflow. 93 | if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) { 94 | // The direction of the overflow is obvious from the sign of a + b. 95 | return sum < 0 ? INT32_MAX : INT32_MIN; 96 | } 97 | return sum; 98 | } 99 | 100 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) { 101 | // Do the subtraction in unsigned numbers, since signed overflow is undefined 102 | // behavior. 103 | const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b); 104 | 105 | // a - b can't overflow if a and b have the same sign. If they have different 106 | // signs, a - b has the same sign as a iff it didn't overflow. 107 | if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) { 108 | // The direction of the overflow is obvious from the sign of a - b. 109 | return diff < 0 ? INT32_MAX : INT32_MIN; 110 | } 111 | return diff; 112 | } 113 | 114 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { 115 | return WebRtcSpl_SatW32ToW16((int32_t)a + (int32_t)b); 116 | } 117 | 118 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { 119 | return WebRtcSpl_SatW32ToW16((int32_t)var1 - (int32_t)var2); 120 | } 121 | #endif // #if !defined(MIPS_DSP_R1_LE) 122 | 123 | #if !defined(MIPS32_LE) 124 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 125 | return 32 - WebRtcSpl_CountLeadingZeros32(n); 126 | } 127 | 128 | // Return the number of steps a can be left-shifted without overflow, 129 | // or 0 if a == 0. 130 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 131 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1; 132 | } 133 | 134 | // Return the number of steps a can be left-shifted without overflow, 135 | // or 0 if a == 0. 136 | static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { 137 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a); 138 | } 139 | 140 | // Return the number of steps a can be left-shifted without overflow, 141 | // or 0 if a == 0. 142 | static __inline int16_t WebRtcSpl_NormW16(int16_t a) { 143 | const int32_t a32 = a; 144 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17; 145 | } 146 | 147 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { 148 | return (a * b + c); 149 | } 150 | #endif // #if !defined(MIPS32_LE) 151 | 152 | #endif // WEBRTC_ARCH_ARM_V7 153 | 154 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 155 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/spl_inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This header file includes the inline functions in 12 | // the fix point signal processing library. 13 | 14 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 15 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 16 | 17 | //#include "./rtc_base/compile_assert_c.h" 18 | #include "compile_assert_c.h" 19 | 20 | extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64]; 21 | 22 | // Don't call this directly except in tests! 23 | static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) { 24 | // Normalize n by rounding up to the nearest number that is a sequence of 0 25 | // bits followed by a sequence of 1 bits. This number has the same number of 26 | // leading zeros as the original n. There are exactly 33 such values. 27 | n |= n >> 1; 28 | n |= n >> 2; 29 | n |= n >> 4; 30 | n |= n >> 8; 31 | n |= n >> 16; 32 | 33 | // Multiply the modified n with a constant selected (by exhaustive search) 34 | // such that each of the 33 possible values of n give a product whose 6 most 35 | // significant bits are unique. Then look up the answer in the table. 36 | return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26]; 37 | } 38 | 39 | // Don't call this directly except in tests! 40 | static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) { 41 | const int leading_zeros = n >> 32 == 0 ? 32 : 0; 42 | return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin( 43 | (uint32_t)(n >> (32 - leading_zeros))); 44 | } 45 | 46 | // Returns the number of leading zero bits in the argument. 47 | static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) { 48 | #ifdef __GNUC__ 49 | RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t)); 50 | return n == 0 ? 32 : __builtin_clz(n); 51 | #else 52 | return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n); 53 | #endif 54 | } 55 | 56 | // Returns the number of leading zero bits in the argument. 57 | static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) { 58 | #ifdef __GNUC__ 59 | RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT 60 | return n == 0 ? 64 : __builtin_clzll(n); 61 | #else 62 | return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n); 63 | #endif 64 | } 65 | 66 | #ifdef WEBRTC_ARCH_ARM_V7 67 | #include "common_audio/signal_processing/include/spl_inl_armv7.h" 68 | #else 69 | 70 | #if defined(MIPS32_LE) 71 | #include "common_audio/signal_processing/include/spl_inl_mips.h" 72 | #endif 73 | 74 | #if !defined(MIPS_DSP_R1_LE) 75 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { 76 | int16_t out16 = (int16_t)value32; 77 | 78 | if (value32 > 32767) 79 | out16 = 32767; 80 | else if (value32 < -32768) 81 | out16 = -32768; 82 | 83 | return out16; 84 | } 85 | 86 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) { 87 | // Do the addition in unsigned numbers, since signed overflow is undefined 88 | // behavior. 89 | const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b); 90 | 91 | // a + b can't overflow if a and b have different signs. If they have the 92 | // same sign, a + b also has the same sign iff it didn't overflow. 93 | if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) { 94 | // The direction of the overflow is obvious from the sign of a + b. 95 | return sum < 0 ? INT32_MAX : INT32_MIN; 96 | } 97 | return sum; 98 | } 99 | 100 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) { 101 | // Do the subtraction in unsigned numbers, since signed overflow is undefined 102 | // behavior. 103 | const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b); 104 | 105 | // a - b can't overflow if a and b have the same sign. If they have different 106 | // signs, a - b has the same sign as a iff it didn't overflow. 107 | if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) { 108 | // The direction of the overflow is obvious from the sign of a - b. 109 | return diff < 0 ? INT32_MAX : INT32_MIN; 110 | } 111 | return diff; 112 | } 113 | 114 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { 115 | return WebRtcSpl_SatW32ToW16((int32_t)a + (int32_t)b); 116 | } 117 | 118 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { 119 | return WebRtcSpl_SatW32ToW16((int32_t)var1 - (int32_t)var2); 120 | } 121 | #endif // #if !defined(MIPS_DSP_R1_LE) 122 | 123 | #if !defined(MIPS32_LE) 124 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 125 | return 32 - WebRtcSpl_CountLeadingZeros32(n); 126 | } 127 | 128 | // Return the number of steps a can be left-shifted without overflow, 129 | // or 0 if a == 0. 130 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 131 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1; 132 | } 133 | 134 | // Return the number of steps a can be left-shifted without overflow, 135 | // or 0 if a == 0. 136 | static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { 137 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a); 138 | } 139 | 140 | // Return the number of steps a can be left-shifted without overflow, 141 | // or 0 if a == 0. 142 | static __inline int16_t WebRtcSpl_NormW16(int16_t a) { 143 | const int32_t a32 = a; 144 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17; 145 | } 146 | 147 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { 148 | return (a * b + c); 149 | } 150 | #endif // #if !defined(MIPS32_LE) 151 | 152 | #endif // WEBRTC_ARCH_ARM_V7 153 | 154 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 155 | -------------------------------------------------------------------------------- /WebRtc_official/WebRtc_official.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {c945063c-1abc-4e88-a2dd-2fa7b22e303a} 18 | 19 | 20 | {ce1da8a1-9061-478b-bda8-53fdb4b9f014} 21 | 22 | 23 | {1f40fee6-f243-42ca-90b7-ef31f6134727} 24 | 25 | 26 | {ceeaa698-2f45-400d-b616-841e699d993c} 27 | 28 | 29 | {ec1f8cd2-ff9d-4ff8-b392-fa03bbc1f9d2} 30 | 31 | 32 | 33 | 34 | 头文件 35 | 36 | 37 | 头文件 38 | 39 | 40 | 头文件 41 | 42 | 43 | 头文件 44 | 45 | 46 | WebRtc\Noise suppression 47 | 48 | 49 | WebRtc\Noise suppression 50 | 51 | 52 | WebRtc\Noise suppression 53 | 54 | 55 | WebRtc\Noise suppression 56 | 57 | 58 | WebRtc\Audio processing 59 | 60 | 61 | WebRtc\Audio processing 62 | 63 | 64 | WebRtc\Audio processing 65 | 66 | 67 | WebRtc\Audio processing 68 | 69 | 70 | WebRtc\Audio processing 71 | 72 | 73 | WebRtc\Audio processing 74 | 75 | 76 | WebRtc\Rtc base 77 | 78 | 79 | WebRtc\Rtc base 80 | 81 | 82 | WebRtc\Rtc base 83 | 84 | 85 | WebRtc\Rtc base 86 | 87 | 88 | WebRtc\Rtc base 89 | 90 | 91 | WebRtc\Rtc base 92 | 93 | 94 | WebRtc\Splitting filter 95 | 96 | 97 | WebRtc\Splitting filter 98 | 99 | 100 | WebRtc\Splitting filter 101 | 102 | 103 | 104 | 105 | 源文件 106 | 107 | 108 | 源文件 109 | 110 | 111 | 源文件 112 | 113 | 114 | WebRtc\Noise suppression 115 | 116 | 117 | WebRtc\Noise suppression 118 | 119 | 120 | WebRtc\Audio processing 121 | 122 | 123 | WebRtc\Audio processing 124 | 125 | 126 | WebRtc\Audio processing 127 | 128 | 129 | WebRtc\Audio processing 130 | 131 | 132 | WebRtc\Rtc base 133 | 134 | 135 | WebRtc\Splitting filter 136 | 137 | 138 | WebRtc\Splitting filter 139 | 140 | 141 | WebRtc\Splitting filter 142 | 143 | 144 | -------------------------------------------------------------------------------- /WebRtc_official/WebRtc_NS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "noise_suppression.h" 3 | #include "ns_core.h" 4 | #include 5 | 6 | 7 | #include "signal_processing_library.h" 8 | #include "splitting_filter.h" 9 | #include "three_band_filter_bank.h" 10 | #include "audio_util.h" 11 | 12 | /* 13 | WebRtc noise suppression module had been supported 48 khz sample reate since c5ebbdq branch. 14 | The noise suppression process flow can be summed up as below: 15 | 16 | audio data in -> if fs > 16khz -> split into frequency bands (16kdz per band,numMaxUpperBands is 2,that is 48 khz) 17 | -> analyze / process per bands 18 | -> merge frequency bands 19 | -> output 20 | -> if fs < 16khz -> analyze / process per bands 21 | -> output 22 | WebRtc uses AudioBuffer class to split audio date into different bands. 23 | 24 | */ 25 | //#ifndef nullptr 26 | //#define nullptr 0 27 | //#endif 28 | 29 | class WebRtc_NS 30 | { 31 | public: 32 | enum nsLevel { 33 | kLow, 34 | kModerate, 35 | kHigh, 36 | kVeryHigh 37 | }; 38 | unsigned int sample_rate_ = 48000; 39 | nsLevel ns_level_ = kHigh; 40 | 41 | int Init(unsigned int sample_rate, nsLevel _ns_level); 42 | void Process(float *_data_in, float *_data_out, size_t data_size); 43 | void frame_process(float *_data_in, float *_data_out);; 44 | 45 | WebRtc_NS(); 46 | virtual ~WebRtc_NS(); 47 | private: 48 | NsHandle * nsHandle = 0; 49 | size_t num_per_frame_ = 160; 50 | webrtc::TwoBandsStates TwoBands; 51 | webrtc::ThreeBandFilterBank *three_bands_filter_48k = 0; 52 | }; 53 | 54 | 55 | 56 | inline int WebRtc_NS::Init(unsigned int sample_rate, nsLevel ns_level) 57 | { 58 | // Initialization 59 | if (sample_rate == 8000 || sample_rate == 16000 || sample_rate == 32000 || sample_rate == 48000 || sample_rate == 44100) 60 | { 61 | if (sample_rate == 44100) { 62 | std::cout << "Warnning : 44.1 khz sample rate is not support originally by webrtc,processing blow regard it as 48 khz for a test.\n"; 63 | // It's a good choice to UpResample the sample rate to 48k. 64 | // If not, maybe you can modify the ThreeBandFilterBank class's intialization 65 | // to support 44100 althought it is constructed for 48khz . 66 | 67 | sample_rate_ = 48000; 68 | } 69 | else { 70 | sample_rate_ = sample_rate; 71 | } 72 | 73 | } 74 | else { 75 | std::cout << "Cann't support this sample rate ->" << sample_rate << std::endl; 76 | return -1; 77 | } 78 | num_per_frame_ = sample_rate_ / 100; 79 | ns_level_ = ns_level; 80 | nsHandle = WebRtcNs_Create(); 81 | int status = WebRtcNs_Init(nsHandle, sample_rate_); 82 | if (status != 0) { 83 | std::cout<<"WebRtcNs_Init fail\n"; 84 | return -1; 85 | } 86 | status = WebRtcNs_set_policy(nsHandle, ns_level_); 87 | if (status != 0) { 88 | std::cout<<"WebRtcNs_set_policy fail\n"; 89 | return -1; 90 | } 91 | three_bands_filter_48k = new webrtc::ThreeBandFilterBank(480); 92 | 93 | return 0; 94 | } 95 | 96 | inline void WebRtc_NS::Process(float * _data_in, float * _data_out, size_t data_size) { 97 | for (size_t nFrames = 0; nFrames < data_size / num_per_frame_ ; nFrames++) 98 | { 99 | frame_process(_data_in + nFrames * num_per_frame_, _data_out + nFrames * num_per_frame_); 100 | } 101 | //std::cout << "Pass"; 102 | } 103 | 104 | inline void WebRtc_NS::frame_process(float * _data_in, float * _data_out) { 105 | // process per frame should be 10ms, different sample rate requires different points per frame. 106 | // Max input size is 320 points for 32 khz 107 | // As to unify,160 points per band is suggested. 108 | if (num_per_frame_ == 80 || num_per_frame_ == 160) 109 | { 110 | float *input_buffer[1] = { _data_in }; //ns input buffer [band][data] band:1~2 [L H] 111 | float *output_buffer[1] = { _data_out }; //ns output buffer [band][data] band:1~2 [L H] 112 | WebRtcNs_Analyze(nsHandle, input_buffer[0]); 113 | WebRtcNs_Process(nsHandle, (const float *const *)input_buffer, 1, output_buffer); // num_bands = 1 or 2 114 | return; 115 | } 116 | else if (num_per_frame_ == 320) { 117 | // DONE: add a slpltting filter for 32k sample rate 118 | // Note: 119 | // QMF's input is int16_t while WebRtcNs supports float data in this version,so there are some extra conversion. 120 | 121 | int16_t data_twobands_int16[2][160]{ { 0 } ,{ 0 } }; 122 | int16_t data_in_int16[320]{}; 123 | webrtc::FloatToS16(_data_in, 320, data_in_int16); 124 | // analysis 125 | WebRtcSpl_AnalysisQMF(data_in_int16, 320, data_twobands_int16[0], data_twobands_int16[1], TwoBands.analysis_state1, TwoBands.analysis_state2); 126 | // Two bands process 127 | float data_in_twobands_f[2][160] = { { 0 },{ 0 } }; //ns input buffer [band][data] band:1~2 [L H] 128 | float data_out_twobands_f[2][160] = { { 0 },{ 0 } }; //ns output buffer [band][data] band:1~2 [L H] 129 | 130 | webrtc::S16ToFloat(data_twobands_int16[0], 160, data_in_twobands_f[0]); 131 | webrtc::S16ToFloat(data_twobands_int16[1], 160, data_in_twobands_f[1]); 132 | 133 | float *input_buffer[2] = { data_in_twobands_f[0],data_in_twobands_f[1] }; 134 | float *output_buffer[2] = { data_out_twobands_f[0],data_out_twobands_f[1] }; 135 | // noise supression analyze and process. 136 | WebRtcNs_Analyze(nsHandle, input_buffer[0]); 137 | WebRtcNs_Process(nsHandle, input_buffer, 2, output_buffer); // num_bands = 1~3 ,in 32k mode, num_bands = 2 138 | 139 | webrtc::FloatToS16(output_buffer[0], 160, data_twobands_int16[0]); 140 | webrtc::FloatToS16(output_buffer[1], 160, data_twobands_int16[1]); 141 | // synthesis 142 | WebRtcSpl_SynthesisQMF(data_twobands_int16[0], data_twobands_int16[1], 160, data_in_int16, TwoBands.synthesis_state1, TwoBands.synthesis_state2); 143 | webrtc::S16ToFloat(data_in_int16, 320, _data_out); 144 | return; 145 | } 146 | else if (num_per_frame_ == 480 || num_per_frame_ == 441) 147 | { 148 | // DONE: add a slpltting filter for 48k sample rate 149 | 150 | float band_in[3][160]{ {},{},{} }; 151 | float band_out[3][160]{ {},{},{} }; 152 | float * three_band_in[3] = { band_in[0],band_in[1],band_in[2] }; 153 | float * three_band_out[3] = { band_out[0],band_out[1],band_out[2] }; 154 | three_bands_filter_48k->Analysis(_data_in, 480, three_band_in); 155 | WebRtcNs_Analyze(nsHandle, three_band_in[0]); 156 | WebRtcNs_Process(nsHandle, three_band_in, 3, three_band_out); // num_bands = 3 for 48khz 157 | three_bands_filter_48k->Synthesis(three_band_out, 160, _data_out); 158 | return; 159 | } 160 | else { 161 | std::cout << "Only support up to 48000khz"; 162 | return; 163 | } 164 | 165 | } 166 | 167 | WebRtc_NS::WebRtc_NS() 168 | { 169 | } 170 | 171 | 172 | WebRtc_NS::~WebRtc_NS() 173 | { 174 | //delete[] nsHandle; 175 | WebRtcNs_Free(nsHandle); 176 | //delete[] three_bands_filter_48k; 177 | } -------------------------------------------------------------------------------- /WebRtc_official/include/ns/ns_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ 12 | #define MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ 13 | 14 | //#include "./modules/audio_processing/ns/defines.h" 15 | #include "defines.h" 16 | 17 | typedef struct NSParaExtract_ { 18 | // Bin size of histogram. 19 | float binSizeLrt; 20 | float binSizeSpecFlat; 21 | float binSizeSpecDiff; 22 | // Range of histogram over which LRT threshold is computed. 23 | float rangeAvgHistLrt; 24 | // Scale parameters: multiply dominant peaks of the histograms by scale factor 25 | // to obtain thresholds for prior model. 26 | float factor1ModelPars; // For LRT and spectral difference. 27 | float factor2ModelPars; // For spectral_flatness: used when noise is flatter 28 | // than speech. 29 | // Peak limit for spectral flatness (varies between 0 and 1). 30 | float thresPosSpecFlat; 31 | // Limit on spacing of two highest peaks in histogram: spacing determined by 32 | // bin size. 33 | float limitPeakSpacingSpecFlat; 34 | float limitPeakSpacingSpecDiff; 35 | // Limit on relevance of second peak. 36 | float limitPeakWeightsSpecFlat; 37 | float limitPeakWeightsSpecDiff; 38 | // Limit on fluctuation of LRT feature. 39 | float thresFluctLrt; 40 | // Limit on the max and min values for the feature thresholds. 41 | float maxLrt; 42 | float minLrt; 43 | float maxSpecFlat; 44 | float minSpecFlat; 45 | float maxSpecDiff; 46 | float minSpecDiff; 47 | // Criteria of weight of histogram peak to accept/reject feature. 48 | int thresWeightSpecFlat; 49 | int thresWeightSpecDiff; 50 | 51 | } NSParaExtract; 52 | 53 | typedef struct NoiseSuppressionC_ { 54 | uint32_t fs; 55 | size_t blockLen; 56 | size_t windShift; 57 | size_t anaLen; 58 | size_t magnLen; 59 | int aggrMode; 60 | const float* window; 61 | float analyzeBuf[ANAL_BLOCKL_MAX]; 62 | float dataBuf[ANAL_BLOCKL_MAX]; 63 | float syntBuf[ANAL_BLOCKL_MAX]; 64 | 65 | int initFlag; 66 | // Parameters for quantile noise estimation. 67 | float density[SIMULT * HALF_ANAL_BLOCKL]; 68 | float lquantile[SIMULT * HALF_ANAL_BLOCKL]; 69 | float quantile[HALF_ANAL_BLOCKL]; 70 | int counter[SIMULT]; 71 | int updates; 72 | // Parameters for Wiener filter. 73 | float smooth[HALF_ANAL_BLOCKL]; 74 | float overdrive; 75 | float denoiseBound; 76 | int gainmap; 77 | // FFT work arrays. 78 | size_t ip[IP_LENGTH]; 79 | float wfft[W_LENGTH]; 80 | 81 | // Parameters for new method: some not needed, will reduce/cleanup later. 82 | int32_t blockInd; // Frame index counter. 83 | int modelUpdatePars[4]; // Parameters for updating or estimating. 84 | // Thresholds/weights for prior model. 85 | float priorModelPars[7]; // Parameters for prior model. 86 | float noise[HALF_ANAL_BLOCKL]; // Noise spectrum from current frame. 87 | float noisePrev[HALF_ANAL_BLOCKL]; // Noise spectrum from previous frame. 88 | // Magnitude spectrum of previous analyze frame. 89 | float magnPrevAnalyze[HALF_ANAL_BLOCKL]; 90 | // Magnitude spectrum of previous process frame. 91 | float magnPrevProcess[HALF_ANAL_BLOCKL]; 92 | float logLrtTimeAvg[HALF_ANAL_BLOCKL]; // Log LRT factor with time-smoothing. 93 | float priorSpeechProb; // Prior speech/noise probability. 94 | float featureData[7]; 95 | // Conservative noise spectrum estimate. 96 | float magnAvgPause[HALF_ANAL_BLOCKL]; 97 | float signalEnergy; // Energy of |magn|. 98 | float sumMagn; 99 | float whiteNoiseLevel; // Initial noise estimate. 100 | float initMagnEst[HALF_ANAL_BLOCKL]; // Initial magnitude spectrum estimate. 101 | float pinkNoiseNumerator; // Pink noise parameter: numerator. 102 | float pinkNoiseExp; // Pink noise parameter: power of frequencies. 103 | float parametricNoise[HALF_ANAL_BLOCKL]; 104 | // Parameters for feature extraction. 105 | NSParaExtract featureExtractionParams; 106 | // Histograms for parameter estimation. 107 | int histLrt[HIST_PAR_EST]; 108 | int histSpecFlat[HIST_PAR_EST]; 109 | int histSpecDiff[HIST_PAR_EST]; 110 | // Quantities for high band estimate. 111 | float speechProb[HALF_ANAL_BLOCKL]; // Final speech/noise prob: prior + LRT. 112 | // Buffering data for HB. 113 | float dataBufHB[NUM_HIGH_BANDS_MAX][ANAL_BLOCKL_MAX]; 114 | } NoiseSuppressionC; 115 | 116 | #ifdef __cplusplus 117 | extern "C" { 118 | #endif 119 | 120 | /**************************************************************************** 121 | * WebRtcNs_InitCore(...) 122 | * 123 | * This function initializes a noise suppression instance 124 | * 125 | * Input: 126 | * - self : Instance that should be initialized 127 | * - fs : Sampling frequency 128 | * 129 | * Output: 130 | * - self : Initialized instance 131 | * 132 | * Return value : 0 - Ok 133 | * -1 - Error 134 | */ 135 | int WebRtcNs_InitCore(NoiseSuppressionC* self, uint32_t fs); 136 | 137 | /**************************************************************************** 138 | * WebRtcNs_set_policy_core(...) 139 | * 140 | * This changes the aggressiveness of the noise suppression method. 141 | * 142 | * Input: 143 | * - self : Instance that should be initialized 144 | * - mode : 0: Mild (6dB), 1: Medium (10dB), 2: Aggressive (15dB) 145 | * 146 | * Output: 147 | * - self : Initialized instance 148 | * 149 | * Return value : 0 - Ok 150 | * -1 - Error 151 | */ 152 | int WebRtcNs_set_policy_core(NoiseSuppressionC* self, int mode); 153 | 154 | /**************************************************************************** 155 | * WebRtcNs_AnalyzeCore 156 | * 157 | * Estimate the background noise. 158 | * 159 | * Input: 160 | * - self : Instance that should be initialized 161 | * - speechFrame : Input speech frame for lower band 162 | * 163 | * Output: 164 | * - self : Updated instance 165 | */ 166 | void WebRtcNs_AnalyzeCore(NoiseSuppressionC* self, const float* speechFrame); 167 | 168 | /**************************************************************************** 169 | * WebRtcNs_ProcessCore 170 | * 171 | * Do noise suppression. 172 | * 173 | * Input: 174 | * - self : Instance that should be initialized 175 | * - inFrame : Input speech frame for each band 176 | * - num_bands : Number of bands 177 | * 178 | * Output: 179 | * - self : Updated instance 180 | * - outFrame : Output speech frame for each band 181 | */ 182 | void WebRtcNs_ProcessCore(NoiseSuppressionC* self, 183 | const float* const* inFrame, 184 | size_t num_bands, 185 | float* const* outFrame); 186 | 187 | #ifdef __cplusplus 188 | } 189 | #endif 190 | #endif // MODULES_AUDIO_PROCESSING_NS_NS_CORE_H_ 191 | -------------------------------------------------------------------------------- /my_splitting_filter/rtc_base/safe_compare.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This file defines six constexpr functions: 12 | // 13 | // rtc::SafeEq // == 14 | // rtc::SafeNe // != 15 | // rtc::SafeLt // < 16 | // rtc::SafeLe // <= 17 | // rtc::SafeGt // > 18 | // rtc::SafeGe // >= 19 | // 20 | // They each accept two arguments of arbitrary types, and in almost all cases, 21 | // they simply call the appropriate comparison operator. However, if both 22 | // arguments are integers, they don't compare them using C++'s quirky rules, 23 | // but instead adhere to the true mathematical definitions. It is as if the 24 | // arguments were first converted to infinite-range signed integers, and then 25 | // compared, although of course nothing expensive like that actually takes 26 | // place. In practice, for signed/signed and unsigned/unsigned comparisons and 27 | // some mixed-signed comparisons with a compile-time constant, the overhead is 28 | // zero; in the remaining cases, it is just a few machine instructions (no 29 | // branches). 30 | 31 | #ifndef RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 32 | #define RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | //#include "rtc_base/type_traits.h" 41 | #include "type_traits.h" 42 | 43 | namespace rtc { 44 | 45 | namespace safe_cmp_impl { 46 | 47 | template 48 | struct LargerIntImpl : std::false_type {}; 49 | template <> 50 | struct LargerIntImpl : std::true_type { 51 | using type = int16_t; 52 | }; 53 | template <> 54 | struct LargerIntImpl : std::true_type { 55 | using type = int32_t; 56 | }; 57 | template <> 58 | struct LargerIntImpl : std::true_type { 59 | using type = int64_t; 60 | }; 61 | 62 | // LargerInt::value is true iff there's a signed type that's larger 63 | // than T1 (and no larger than the larger of T2 and int*, for performance 64 | // reasons); and if there is such a type, LargerInt::type is an alias 65 | // for it. 66 | template 67 | struct LargerInt 68 | : LargerIntImpl {}; 71 | 72 | template 73 | constexpr typename std::make_unsigned::type MakeUnsigned(T a) { 74 | return static_cast::type>(a); 75 | } 76 | 77 | // Overload for when both T1 and T2 have the same signedness. 78 | template ::value == 82 | std::is_signed::value>::type* = nullptr> 83 | constexpr bool Cmp(T1 a, T2 b) { 84 | return Op::Op(a, b); 85 | } 86 | 87 | // Overload for signed - unsigned comparison that can be promoted to a bigger 88 | // signed type. 89 | template ::value && 93 | std::is_unsigned::value && 94 | LargerInt::value>::type* = nullptr> 95 | constexpr bool Cmp(T1 a, T2 b) { 96 | return Op::Op(a, static_cast::type>(b)); 97 | } 98 | 99 | // Overload for unsigned - signed comparison that can be promoted to a bigger 100 | // signed type. 101 | template ::value && 105 | std::is_signed::value && 106 | LargerInt::value>::type* = nullptr> 107 | constexpr bool Cmp(T1 a, T2 b) { 108 | return Op::Op(static_cast::type>(a), b); 109 | } 110 | 111 | // Overload for signed - unsigned comparison that can't be promoted to a bigger 112 | // signed type. 113 | template ::value && 117 | std::is_unsigned::value && 118 | !LargerInt::value>::type* = nullptr> 119 | constexpr bool Cmp(T1 a, T2 b) { 120 | return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b); 121 | } 122 | 123 | // Overload for unsigned - signed comparison that can't be promoted to a bigger 124 | // signed type. 125 | template ::value && 129 | std::is_signed::value && 130 | !LargerInt::value>::type* = nullptr> 131 | constexpr bool Cmp(T1 a, T2 b) { 132 | return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b)); 133 | } 134 | 135 | #define RTC_SAFECMP_MAKE_OP(name, op) \ 136 | struct name { \ 137 | template \ 138 | static constexpr bool Op(T1 a, T2 b) { \ 139 | return a op b; \ 140 | } \ 141 | }; 142 | RTC_SAFECMP_MAKE_OP(EqOp, ==) 143 | RTC_SAFECMP_MAKE_OP(NeOp, !=) 144 | RTC_SAFECMP_MAKE_OP(LtOp, <) 145 | RTC_SAFECMP_MAKE_OP(LeOp, <=) 146 | RTC_SAFECMP_MAKE_OP(GtOp, >) 147 | RTC_SAFECMP_MAKE_OP(GeOp, >=) 148 | #undef RTC_SAFECMP_MAKE_OP 149 | 150 | } // namespace safe_cmp_impl 151 | 152 | #define RTC_SAFECMP_MAKE_FUN(name) \ 153 | template \ 154 | constexpr \ 155 | typename std::enable_if::value && IsIntlike::value, \ 156 | bool>::type Safe##name(T1 a, T2 b) { \ 157 | /* Unary plus here turns enums into real integral types. */ \ 158 | return safe_cmp_impl::Cmp(+a, +b); \ 159 | } \ 160 | template \ 161 | constexpr \ 162 | typename std::enable_if::value || !IsIntlike::value, \ 163 | bool>::type Safe##name(const T1& a, \ 164 | const T2& b) { \ 165 | return safe_cmp_impl::name##Op::Op(a, b); \ 166 | } 167 | RTC_SAFECMP_MAKE_FUN(Eq) 168 | RTC_SAFECMP_MAKE_FUN(Ne) 169 | RTC_SAFECMP_MAKE_FUN(Lt) 170 | RTC_SAFECMP_MAKE_FUN(Le) 171 | RTC_SAFECMP_MAKE_FUN(Gt) 172 | RTC_SAFECMP_MAKE_FUN(Ge) 173 | #undef RTC_SAFECMP_MAKE_FUN 174 | 175 | } // namespace rtc 176 | 177 | #endif // RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 178 | -------------------------------------------------------------------------------- /WebRtc_official/include/rtc_base/safe_compare.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This file defines six constexpr functions: 12 | // 13 | // rtc::SafeEq // == 14 | // rtc::SafeNe // != 15 | // rtc::SafeLt // < 16 | // rtc::SafeLe // <= 17 | // rtc::SafeGt // > 18 | // rtc::SafeGe // >= 19 | // 20 | // They each accept two arguments of arbitrary types, and in almost all cases, 21 | // they simply call the appropriate comparison operator. However, if both 22 | // arguments are integers, they don't compare them using C++'s quirky rules, 23 | // but instead adhere to the true mathematical definitions. It is as if the 24 | // arguments were first converted to infinite-range signed integers, and then 25 | // compared, although of course nothing expensive like that actually takes 26 | // place. In practice, for signed/signed and unsigned/unsigned comparisons and 27 | // some mixed-signed comparisons with a compile-time constant, the overhead is 28 | // zero; in the remaining cases, it is just a few machine instructions (no 29 | // branches). 30 | 31 | #ifndef RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 32 | #define RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | //#include "rtc_base/type_traits.h" 41 | #include "type_traits.h" 42 | 43 | namespace rtc { 44 | 45 | namespace safe_cmp_impl { 46 | 47 | template 48 | struct LargerIntImpl : std::false_type {}; 49 | template <> 50 | struct LargerIntImpl : std::true_type { 51 | using type = int16_t; 52 | }; 53 | template <> 54 | struct LargerIntImpl : std::true_type { 55 | using type = int32_t; 56 | }; 57 | template <> 58 | struct LargerIntImpl : std::true_type { 59 | using type = int64_t; 60 | }; 61 | 62 | // LargerInt::value is true iff there's a signed type that's larger 63 | // than T1 (and no larger than the larger of T2 and int*, for performance 64 | // reasons); and if there is such a type, LargerInt::type is an alias 65 | // for it. 66 | template 67 | struct LargerInt 68 | : LargerIntImpl {}; 71 | 72 | template 73 | constexpr typename std::make_unsigned::type MakeUnsigned(T a) { 74 | return static_cast::type>(a); 75 | } 76 | 77 | // Overload for when both T1 and T2 have the same signedness. 78 | template ::value == 82 | std::is_signed::value>::type* = nullptr> 83 | constexpr bool Cmp(T1 a, T2 b) { 84 | return Op::Op(a, b); 85 | } 86 | 87 | // Overload for signed - unsigned comparison that can be promoted to a bigger 88 | // signed type. 89 | template ::value && 93 | std::is_unsigned::value && 94 | LargerInt::value>::type* = nullptr> 95 | constexpr bool Cmp(T1 a, T2 b) { 96 | return Op::Op(a, static_cast::type>(b)); 97 | } 98 | 99 | // Overload for unsigned - signed comparison that can be promoted to a bigger 100 | // signed type. 101 | template ::value && 105 | std::is_signed::value && 106 | LargerInt::value>::type* = nullptr> 107 | constexpr bool Cmp(T1 a, T2 b) { 108 | return Op::Op(static_cast::type>(a), b); 109 | } 110 | 111 | // Overload for signed - unsigned comparison that can't be promoted to a bigger 112 | // signed type. 113 | template ::value && 117 | std::is_unsigned::value && 118 | !LargerInt::value>::type* = nullptr> 119 | constexpr bool Cmp(T1 a, T2 b) { 120 | return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b); 121 | } 122 | 123 | // Overload for unsigned - signed comparison that can't be promoted to a bigger 124 | // signed type. 125 | template ::value && 129 | std::is_signed::value && 130 | !LargerInt::value>::type* = nullptr> 131 | constexpr bool Cmp(T1 a, T2 b) { 132 | return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b)); 133 | } 134 | 135 | #define RTC_SAFECMP_MAKE_OP(name, op) \ 136 | struct name { \ 137 | template \ 138 | static constexpr bool Op(T1 a, T2 b) { \ 139 | return a op b; \ 140 | } \ 141 | }; 142 | RTC_SAFECMP_MAKE_OP(EqOp, ==) 143 | RTC_SAFECMP_MAKE_OP(NeOp, !=) 144 | RTC_SAFECMP_MAKE_OP(LtOp, <) 145 | RTC_SAFECMP_MAKE_OP(LeOp, <=) 146 | RTC_SAFECMP_MAKE_OP(GtOp, >) 147 | RTC_SAFECMP_MAKE_OP(GeOp, >=) 148 | #undef RTC_SAFECMP_MAKE_OP 149 | 150 | } // namespace safe_cmp_impl 151 | 152 | #define RTC_SAFECMP_MAKE_FUN(name) \ 153 | template \ 154 | constexpr \ 155 | typename std::enable_if::value && IsIntlike::value, \ 156 | bool>::type Safe##name(T1 a, T2 b) { \ 157 | /* Unary plus here turns enums into real integral types. */ \ 158 | return safe_cmp_impl::Cmp(+a, +b); \ 159 | } \ 160 | template \ 161 | constexpr \ 162 | typename std::enable_if::value || !IsIntlike::value, \ 163 | bool>::type Safe##name(const T1& a, \ 164 | const T2& b) { \ 165 | return safe_cmp_impl::name##Op::Op(a, b); \ 166 | } 167 | RTC_SAFECMP_MAKE_FUN(Eq) 168 | RTC_SAFECMP_MAKE_FUN(Ne) 169 | RTC_SAFECMP_MAKE_FUN(Lt) 170 | RTC_SAFECMP_MAKE_FUN(Le) 171 | RTC_SAFECMP_MAKE_FUN(Gt) 172 | RTC_SAFECMP_MAKE_FUN(Ge) 173 | #undef RTC_SAFECMP_MAKE_FUN 174 | 175 | } // namespace rtc 176 | 177 | #endif // RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 178 | -------------------------------------------------------------------------------- /my_splitting_filter/AduioFile/AudioFile.h: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | /** @file AudioFile.h 3 | * @author Adam Stark 4 | * @copyright Copyright (C) 2017 Adam Stark 5 | * 6 | * This file is part of the 'AudioFile' library 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | //======================================================================= 22 | 23 | #ifndef _AS_AudioFile_h 24 | #define _AS_AudioFile_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | //============================================================= 33 | /** The different types of audio file, plus some other types to 34 | * indicate a failure to load a file, or that one hasn't been 35 | * loaded yet 36 | */ 37 | enum class AudioFileFormat 38 | { 39 | Error, 40 | NotLoaded, 41 | Wave, 42 | Aiff 43 | }; 44 | 45 | //============================================================= 46 | template 47 | class AudioFile 48 | { 49 | public: 50 | 51 | //============================================================= 52 | typedef std::vector > AudioBuffer; 53 | 54 | //============================================================= 55 | /** Constructor */ 56 | AudioFile(); 57 | 58 | //============================================================= 59 | /** Loads an audio file from a given file path. 60 | * @Returns true if the file was successfully loaded 61 | */ 62 | bool load (std::string filePath); 63 | 64 | /** Saves an audio file to a given file path. 65 | * @Returns true if the file was successfully saved 66 | */ 67 | bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave); 68 | 69 | //============================================================= 70 | /** @Returns the sample rate */ 71 | uint32_t getSampleRate() const; 72 | 73 | /** @Returns the number of audio channels in the buffer */ 74 | int getNumChannels() const; 75 | 76 | /** @Returns true if the audio file is mono */ 77 | bool isMono() const; 78 | 79 | /** @Returns true if the audio file is stereo */ 80 | bool isStereo() const; 81 | 82 | /** @Returns the bit depth of each sample */ 83 | int getBitDepth() const; 84 | 85 | /** @Returns the number of samples per channel */ 86 | int getNumSamplesPerChannel() const; 87 | 88 | /** @Returns the length in seconds of the audio file based on the number of samples and sample rate */ 89 | double getLengthInSeconds() const; 90 | 91 | /** Prints a summary of the audio file to the console */ 92 | void printSummary() const; 93 | 94 | //============================================================= 95 | 96 | /** Set the audio buffer for this AudioFile by copying samples from another buffer. 97 | * @Returns true if the buffer was copied successfully. 98 | */ 99 | bool setAudioBuffer (AudioBuffer& newBuffer); 100 | 101 | /** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve 102 | * the existing audio, adding zeros to any new channels or new samples in a given channel. 103 | */ 104 | void setAudioBufferSize (int numChannels, int numSamples); 105 | 106 | /** Sets the number of samples per channel in the audio buffer. This will try to preserve 107 | * the existing audio, adding zeros to new samples in a given channel if the number of samples is increased. 108 | */ 109 | void setNumSamplesPerChannel (int numSamples); 110 | 111 | /** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */ 112 | void setNumChannels (int numChannels); 113 | 114 | /** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */ 115 | void setBitDepth (int numBitsPerSample); 116 | 117 | /** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */ 118 | void setSampleRate (uint32_t newSampleRate); 119 | 120 | //============================================================= 121 | /** A vector of vectors holding the audio samples for the AudioFile. You can 122 | * access the samples by channel and then by sample index, i.e: 123 | * 124 | * samples[channel][sampleIndex] 125 | */ 126 | AudioBuffer samples; 127 | 128 | private: 129 | 130 | //============================================================= 131 | enum class Endianness 132 | { 133 | LittleEndian, 134 | BigEndian 135 | }; 136 | 137 | //============================================================= 138 | AudioFileFormat determineAudioFileFormat (std::vector& fileData); 139 | bool decodeWaveFile (std::vector& fileData); 140 | bool decodeAiffFile (std::vector& fileData); 141 | 142 | //============================================================= 143 | bool saveToWaveFile (std::string filePath); 144 | bool saveToAiffFile (std::string filePath); 145 | 146 | //============================================================= 147 | void clearAudioBuffer(); 148 | 149 | //============================================================= 150 | int32_t fourBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); 151 | int16_t twoBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); 152 | int getIndexOfString (std::vector& source, std::string s); 153 | T sixteenBitIntToSample (int16_t sample); 154 | uint32_t getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex); 155 | bool tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2); 156 | void addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate); 157 | 158 | //============================================================= 159 | void addStringToFileData (std::vector& fileData, std::string s); 160 | void addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian); 161 | void addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian); 162 | 163 | //============================================================= 164 | bool writeDataToFile (std::vector& fileData, std::string filePath); 165 | 166 | //============================================================= 167 | AudioFileFormat audioFileFormat; 168 | uint32_t sampleRate; 169 | int bitDepth; 170 | }; 171 | 172 | #endif /* AudioFile_h */ 173 | -------------------------------------------------------------------------------- /WebRtc_official/include/AduioFile/AudioFile.h: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | /** @file AudioFile.h 3 | * @author Adam Stark 4 | * @copyright Copyright (C) 2017 Adam Stark 5 | * 6 | * This file is part of the 'AudioFile' library 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | //======================================================================= 22 | 23 | #ifndef _AS_AudioFile_h 24 | #define _AS_AudioFile_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | //============================================================= 33 | /** The different types of audio file, plus some other types to 34 | * indicate a failure to load a file, or that one hasn't been 35 | * loaded yet 36 | */ 37 | enum class AudioFileFormat 38 | { 39 | Error, 40 | NotLoaded, 41 | Wave, 42 | Aiff 43 | }; 44 | 45 | //============================================================= 46 | template 47 | class AudioFile 48 | { 49 | public: 50 | 51 | //============================================================= 52 | typedef std::vector > AudioBuffer; 53 | 54 | //============================================================= 55 | /** Constructor */ 56 | AudioFile(); 57 | 58 | //============================================================= 59 | /** Loads an audio file from a given file path. 60 | * @Returns true if the file was successfully loaded 61 | */ 62 | bool load (std::string filePath); 63 | 64 | /** Saves an audio file to a given file path. 65 | * @Returns true if the file was successfully saved 66 | */ 67 | bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave); 68 | 69 | //============================================================= 70 | /** @Returns the sample rate */ 71 | uint32_t getSampleRate() const; 72 | 73 | /** @Returns the number of audio channels in the buffer */ 74 | int getNumChannels() const; 75 | 76 | /** @Returns true if the audio file is mono */ 77 | bool isMono() const; 78 | 79 | /** @Returns true if the audio file is stereo */ 80 | bool isStereo() const; 81 | 82 | /** @Returns the bit depth of each sample */ 83 | int getBitDepth() const; 84 | 85 | /** @Returns the number of samples per channel */ 86 | int getNumSamplesPerChannel() const; 87 | 88 | /** @Returns the length in seconds of the audio file based on the number of samples and sample rate */ 89 | double getLengthInSeconds() const; 90 | 91 | /** Prints a summary of the audio file to the console */ 92 | void printSummary() const; 93 | 94 | //============================================================= 95 | 96 | /** Set the audio buffer for this AudioFile by copying samples from another buffer. 97 | * @Returns true if the buffer was copied successfully. 98 | */ 99 | bool setAudioBuffer (AudioBuffer& newBuffer); 100 | 101 | /** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve 102 | * the existing audio, adding zeros to any new channels or new samples in a given channel. 103 | */ 104 | void setAudioBufferSize (int numChannels, int numSamples); 105 | 106 | /** Sets the number of samples per channel in the audio buffer. This will try to preserve 107 | * the existing audio, adding zeros to new samples in a given channel if the number of samples is increased. 108 | */ 109 | void setNumSamplesPerChannel (int numSamples); 110 | 111 | /** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */ 112 | void setNumChannels (int numChannels); 113 | 114 | /** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */ 115 | void setBitDepth (int numBitsPerSample); 116 | 117 | /** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */ 118 | void setSampleRate (uint32_t newSampleRate); 119 | 120 | //============================================================= 121 | /** A vector of vectors holding the audio samples for the AudioFile. You can 122 | * access the samples by channel and then by sample index, i.e: 123 | * 124 | * samples[channel][sampleIndex] 125 | */ 126 | AudioBuffer samples; 127 | 128 | private: 129 | 130 | //============================================================= 131 | enum class Endianness 132 | { 133 | LittleEndian, 134 | BigEndian 135 | }; 136 | 137 | //============================================================= 138 | AudioFileFormat determineAudioFileFormat (std::vector& fileData); 139 | bool decodeWaveFile (std::vector& fileData); 140 | bool decodeAiffFile (std::vector& fileData); 141 | 142 | //============================================================= 143 | bool saveToWaveFile (std::string filePath); 144 | bool saveToAiffFile (std::string filePath); 145 | 146 | //============================================================= 147 | void clearAudioBuffer(); 148 | 149 | //============================================================= 150 | int32_t fourBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); 151 | int16_t twoBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); 152 | int getIndexOfString (std::vector& source, std::string s); 153 | T sixteenBitIntToSample (int16_t sample); 154 | uint32_t getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex); 155 | bool tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2); 156 | void addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate); 157 | 158 | //============================================================= 159 | void addStringToFileData (std::vector& fileData, std::string s); 160 | void addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian); 161 | void addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian); 162 | 163 | //============================================================= 164 | bool writeDataToFile (std::vector& fileData, std::string filePath); 165 | 166 | //============================================================= 167 | AudioFileFormat audioFileFormat; 168 | uint32_t sampleRate; 169 | int bitDepth; 170 | }; 171 | 172 | #endif /* AudioFile_h */ 173 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/audio_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 12 | #define COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | //#include "rtc_base/checks.h" 21 | #include "checks.h" 22 | 23 | namespace webrtc { 24 | 25 | typedef std::numeric_limits limits_int16; 26 | 27 | // The conversion functions use the following naming convention: 28 | // S16: int16_t [-32768, 32767] 29 | // Float: float [-1.0, 1.0] 30 | // FloatS16: float [-32768.0, 32767.0] 31 | // Dbfs: float [-20.0*log(10, 32768), 0] = [-90.3, 0] 32 | // The ratio conversion functions use this naming convention: 33 | // Ratio: float (0, +inf) 34 | // Db: float (-inf, +inf) 35 | static inline int16_t FloatToS16(float v) { 36 | if (v > 0) 37 | return v >= 1 ? limits_int16::max() 38 | : static_cast(v * limits_int16::max() + 0.5f); 39 | return v <= -1 ? limits_int16::min() 40 | : static_cast(-v * limits_int16::min() - 0.5f); 41 | } 42 | 43 | static inline float S16ToFloat(int16_t v) { 44 | static const float kMaxInt16Inverse = 1.f / limits_int16::max(); 45 | static const float kMinInt16Inverse = 1.f / limits_int16::min(); 46 | return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); 47 | } 48 | 49 | static inline int16_t FloatS16ToS16(float v) { 50 | static const float kMaxRound = limits_int16::max() - 0.5f; 51 | static const float kMinRound = limits_int16::min() + 0.5f; 52 | if (v > 0) 53 | return v >= kMaxRound ? limits_int16::max() 54 | : static_cast(v + 0.5f); 55 | return v <= kMinRound ? limits_int16::min() : static_cast(v - 0.5f); 56 | } 57 | 58 | static inline float FloatToFloatS16(float v) { 59 | return v * (v > 0 ? limits_int16::max() : -limits_int16::min()); 60 | } 61 | 62 | static inline float FloatS16ToFloat(float v) { 63 | static const float kMaxInt16Inverse = 1.f / limits_int16::max(); 64 | static const float kMinInt16Inverse = 1.f / limits_int16::min(); 65 | return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); 66 | } 67 | 68 | void FloatToS16(const float* src, size_t size, int16_t* dest); 69 | void S16ToFloat(const int16_t* src, size_t size, float* dest); 70 | void FloatS16ToS16(const float* src, size_t size, int16_t* dest); 71 | void FloatToFloatS16(const float* src, size_t size, float* dest); 72 | void FloatS16ToFloat(const float* src, size_t size, float* dest); 73 | 74 | inline float DbToRatio(float v) { 75 | return std::pow(10.0f, v / 20.0f); 76 | } 77 | 78 | inline float DbfsToFloatS16(float v) { 79 | static constexpr float kMaximumAbsFloatS16 = -limits_int16::min(); 80 | return DbToRatio(v) * kMaximumAbsFloatS16; 81 | } 82 | 83 | inline float FloatS16ToDbfs(float v) { 84 | RTC_DCHECK_GE(v, 0); 85 | 86 | // kMinDbfs is equal to -20.0 * log10(-limits_int16::min()) 87 | static constexpr float kMinDbfs = -90.30899869919436f; 88 | if (v <= 1.0f) { 89 | return kMinDbfs; 90 | } 91 | // Equal to 20 * log10(v / (-limits_int16::min())) 92 | return 20.0f * std::log10(v) + kMinDbfs; 93 | } 94 | 95 | // Copy audio from |src| channels to |dest| channels unless |src| and |dest| 96 | // point to the same address. |src| and |dest| must have the same number of 97 | // channels, and there must be sufficient space allocated in |dest|. 98 | template 99 | void CopyAudioIfNeeded(const T* const* src, 100 | int num_frames, 101 | int num_channels, 102 | T* const* dest) { 103 | for (int i = 0; i < num_channels; ++i) { 104 | if (src[i] != dest[i]) { 105 | std::copy(src[i], src[i] + num_frames, dest[i]); 106 | } 107 | } 108 | } 109 | 110 | // Deinterleave audio from |interleaved| to the channel buffers pointed to 111 | // by |deinterleaved|. There must be sufficient space allocated in the 112 | // |deinterleaved| buffers (|num_channel| buffers with |samples_per_channel| 113 | // per buffer). 114 | template 115 | void Deinterleave(const T* interleaved, 116 | size_t samples_per_channel, 117 | size_t num_channels, 118 | T* const* deinterleaved) { 119 | for (size_t i = 0; i < num_channels; ++i) { 120 | T* channel = deinterleaved[i]; 121 | size_t interleaved_idx = i; 122 | for (size_t j = 0; j < samples_per_channel; ++j) { 123 | channel[j] = interleaved[interleaved_idx]; 124 | interleaved_idx += num_channels; 125 | } 126 | } 127 | } 128 | 129 | // Interleave audio from the channel buffers pointed to by |deinterleaved| to 130 | // |interleaved|. There must be sufficient space allocated in |interleaved| 131 | // (|samples_per_channel| * |num_channels|). 132 | template 133 | void Interleave(const T* const* deinterleaved, 134 | size_t samples_per_channel, 135 | size_t num_channels, 136 | T* interleaved) { 137 | for (size_t i = 0; i < num_channels; ++i) { 138 | const T* channel = deinterleaved[i]; 139 | size_t interleaved_idx = i; 140 | for (size_t j = 0; j < samples_per_channel; ++j) { 141 | interleaved[interleaved_idx] = channel[j]; 142 | interleaved_idx += num_channels; 143 | } 144 | } 145 | } 146 | 147 | // Copies audio from a single channel buffer pointed to by |mono| to each 148 | // channel of |interleaved|. There must be sufficient space allocated in 149 | // |interleaved| (|samples_per_channel| * |num_channels|). 150 | template 151 | void UpmixMonoToInterleaved(const T* mono, 152 | int num_frames, 153 | int num_channels, 154 | T* interleaved) { 155 | int interleaved_idx = 0; 156 | for (int i = 0; i < num_frames; ++i) { 157 | for (int j = 0; j < num_channels; ++j) { 158 | interleaved[interleaved_idx++] = mono[i]; 159 | } 160 | } 161 | } 162 | 163 | template 164 | void DownmixToMono(const T* const* input_channels, 165 | size_t num_frames, 166 | int num_channels, 167 | T* out) { 168 | for (size_t i = 0; i < num_frames; ++i) { 169 | Intermediate value = input_channels[0][i]; 170 | for (int j = 1; j < num_channels; ++j) { 171 | value += input_channels[j][i]; 172 | } 173 | out[i] = value / num_channels; 174 | } 175 | } 176 | 177 | // Downmixes an interleaved multichannel signal to a single channel by averaging 178 | // all channels. 179 | template 180 | void DownmixInterleavedToMonoImpl(const T* interleaved, 181 | size_t num_frames, 182 | int num_channels, 183 | T* deinterleaved) { 184 | RTC_DCHECK_GT(num_channels, 0); 185 | RTC_DCHECK_GT(num_frames, 0); 186 | 187 | const T* const end = interleaved + num_frames * num_channels; 188 | 189 | while (interleaved < end) { 190 | const T* const frame_end = interleaved + num_channels; 191 | 192 | Intermediate value = *interleaved++; 193 | while (interleaved < frame_end) { 194 | value += *interleaved++; 195 | } 196 | 197 | *deinterleaved++ = value / num_channels; 198 | } 199 | } 200 | 201 | template 202 | void DownmixInterleavedToMono(const T* interleaved, 203 | size_t num_frames, 204 | int num_channels, 205 | T* deinterleaved); 206 | 207 | template <> 208 | void DownmixInterleavedToMono(const int16_t* interleaved, 209 | size_t num_frames, 210 | int num_channels, 211 | int16_t* deinterleaved); 212 | 213 | } // namespace webrtc 214 | 215 | #endif // COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 216 | -------------------------------------------------------------------------------- /WebRtc_official/include/audio_processing/audio_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 12 | #define COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | //#include "rtc_base/checks.h" 21 | #include "checks.h" 22 | 23 | namespace webrtc { 24 | 25 | typedef std::numeric_limits limits_int16; 26 | 27 | // The conversion functions use the following naming convention: 28 | // S16: int16_t [-32768, 32767] 29 | // Float: float [-1.0, 1.0] 30 | // FloatS16: float [-32768.0, 32767.0] 31 | // Dbfs: float [-20.0*log(10, 32768), 0] = [-90.3, 0] 32 | // The ratio conversion functions use this naming convention: 33 | // Ratio: float (0, +inf) 34 | // Db: float (-inf, +inf) 35 | static inline int16_t FloatToS16(float v) { 36 | if (v > 0) 37 | return v >= 1 ? limits_int16::max() 38 | : static_cast(v * limits_int16::max() + 0.5f); 39 | return v <= -1 ? limits_int16::min() 40 | : static_cast(-v * limits_int16::min() - 0.5f); 41 | } 42 | 43 | static inline float S16ToFloat(int16_t v) { 44 | static const float kMaxInt16Inverse = 1.f / limits_int16::max(); 45 | static const float kMinInt16Inverse = 1.f / limits_int16::min(); 46 | return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); 47 | } 48 | 49 | static inline int16_t FloatS16ToS16(float v) { 50 | static const float kMaxRound = limits_int16::max() - 0.5f; 51 | static const float kMinRound = limits_int16::min() + 0.5f; 52 | if (v > 0) 53 | return v >= kMaxRound ? limits_int16::max() 54 | : static_cast(v + 0.5f); 55 | return v <= kMinRound ? limits_int16::min() : static_cast(v - 0.5f); 56 | } 57 | 58 | static inline float FloatToFloatS16(float v) { 59 | return v * (v > 0 ? limits_int16::max() : -limits_int16::min()); 60 | } 61 | 62 | static inline float FloatS16ToFloat(float v) { 63 | static const float kMaxInt16Inverse = 1.f / limits_int16::max(); 64 | static const float kMinInt16Inverse = 1.f / limits_int16::min(); 65 | return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); 66 | } 67 | 68 | void FloatToS16(const float* src, size_t size, int16_t* dest); 69 | void S16ToFloat(const int16_t* src, size_t size, float* dest); 70 | void FloatS16ToS16(const float* src, size_t size, int16_t* dest); 71 | void FloatToFloatS16(const float* src, size_t size, float* dest); 72 | void FloatS16ToFloat(const float* src, size_t size, float* dest); 73 | 74 | inline float DbToRatio(float v) { 75 | return std::pow(10.0f, v / 20.0f); 76 | } 77 | 78 | inline float DbfsToFloatS16(float v) { 79 | static constexpr float kMaximumAbsFloatS16 = -limits_int16::min(); 80 | return DbToRatio(v) * kMaximumAbsFloatS16; 81 | } 82 | 83 | inline float FloatS16ToDbfs(float v) { 84 | RTC_DCHECK_GE(v, 0); 85 | 86 | // kMinDbfs is equal to -20.0 * log10(-limits_int16::min()) 87 | static constexpr float kMinDbfs = -90.30899869919436f; 88 | if (v <= 1.0f) { 89 | return kMinDbfs; 90 | } 91 | // Equal to 20 * log10(v / (-limits_int16::min())) 92 | return 20.0f * std::log10(v) + kMinDbfs; 93 | } 94 | 95 | // Copy audio from |src| channels to |dest| channels unless |src| and |dest| 96 | // point to the same address. |src| and |dest| must have the same number of 97 | // channels, and there must be sufficient space allocated in |dest|. 98 | template 99 | void CopyAudioIfNeeded(const T* const* src, 100 | int num_frames, 101 | int num_channels, 102 | T* const* dest) { 103 | for (int i = 0; i < num_channels; ++i) { 104 | if (src[i] != dest[i]) { 105 | std::copy(src[i], src[i] + num_frames, dest[i]); 106 | } 107 | } 108 | } 109 | 110 | // Deinterleave audio from |interleaved| to the channel buffers pointed to 111 | // by |deinterleaved|. There must be sufficient space allocated in the 112 | // |deinterleaved| buffers (|num_channel| buffers with |samples_per_channel| 113 | // per buffer). 114 | template 115 | void Deinterleave(const T* interleaved, 116 | size_t samples_per_channel, 117 | size_t num_channels, 118 | T* const* deinterleaved) { 119 | for (size_t i = 0; i < num_channels; ++i) { 120 | T* channel = deinterleaved[i]; 121 | size_t interleaved_idx = i; 122 | for (size_t j = 0; j < samples_per_channel; ++j) { 123 | channel[j] = interleaved[interleaved_idx]; 124 | interleaved_idx += num_channels; 125 | } 126 | } 127 | } 128 | 129 | // Interleave audio from the channel buffers pointed to by |deinterleaved| to 130 | // |interleaved|. There must be sufficient space allocated in |interleaved| 131 | // (|samples_per_channel| * |num_channels|). 132 | template 133 | void Interleave(const T* const* deinterleaved, 134 | size_t samples_per_channel, 135 | size_t num_channels, 136 | T* interleaved) { 137 | for (size_t i = 0; i < num_channels; ++i) { 138 | const T* channel = deinterleaved[i]; 139 | size_t interleaved_idx = i; 140 | for (size_t j = 0; j < samples_per_channel; ++j) { 141 | interleaved[interleaved_idx] = channel[j]; 142 | interleaved_idx += num_channels; 143 | } 144 | } 145 | } 146 | 147 | // Copies audio from a single channel buffer pointed to by |mono| to each 148 | // channel of |interleaved|. There must be sufficient space allocated in 149 | // |interleaved| (|samples_per_channel| * |num_channels|). 150 | template 151 | void UpmixMonoToInterleaved(const T* mono, 152 | int num_frames, 153 | int num_channels, 154 | T* interleaved) { 155 | int interleaved_idx = 0; 156 | for (int i = 0; i < num_frames; ++i) { 157 | for (int j = 0; j < num_channels; ++j) { 158 | interleaved[interleaved_idx++] = mono[i]; 159 | } 160 | } 161 | } 162 | 163 | template 164 | void DownmixToMono(const T* const* input_channels, 165 | size_t num_frames, 166 | int num_channels, 167 | T* out) { 168 | for (size_t i = 0; i < num_frames; ++i) { 169 | Intermediate value = input_channels[0][i]; 170 | for (int j = 1; j < num_channels; ++j) { 171 | value += input_channels[j][i]; 172 | } 173 | out[i] = value / num_channels; 174 | } 175 | } 176 | 177 | // Downmixes an interleaved multichannel signal to a single channel by averaging 178 | // all channels. 179 | template 180 | void DownmixInterleavedToMonoImpl(const T* interleaved, 181 | size_t num_frames, 182 | int num_channels, 183 | T* deinterleaved) { 184 | RTC_DCHECK_GT(num_channels, 0); 185 | RTC_DCHECK_GT(num_frames, 0); 186 | 187 | const T* const end = interleaved + num_frames * num_channels; 188 | 189 | while (interleaved < end) { 190 | const T* const frame_end = interleaved + num_channels; 191 | 192 | Intermediate value = *interleaved++; 193 | while (interleaved < frame_end) { 194 | value += *interleaved++; 195 | } 196 | 197 | *deinterleaved++ = value / num_channels; 198 | } 199 | } 200 | 201 | template 202 | void DownmixInterleavedToMono(const T* interleaved, 203 | size_t num_frames, 204 | int num_channels, 205 | T* deinterleaved); 206 | 207 | template <> 208 | void DownmixInterleavedToMono(const int16_t* interleaved, 209 | size_t num_frames, 210 | int num_channels, 211 | int16_t* deinterleaved); 212 | 213 | } // namespace webrtc 214 | 215 | #endif // COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_ 216 | -------------------------------------------------------------------------------- /my_splitting_filter/splitting_filter/splitting_filter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | /* 12 | * This file contains the splitting filter functions. 13 | * 14 | */ 15 | 16 | //#include "rtc_base/checks.h" 17 | //#include "common_audio/signal_processing/include/signal_processing_library.h" 18 | #include "checks.h" 19 | #include "signal_processing_library.h" 20 | 21 | // Maximum number of samples in a low/high-band frame. 22 | enum 23 | { 24 | kMaxBandFrameLength = 320 // 10 ms at 64 kHz. 25 | }; 26 | 27 | // QMF filter coefficients in Q16. 28 | static const uint16_t WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; 29 | static const uint16_t WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; 30 | 31 | /////////////////////////////////////////////////////////////////////////////////////////////// 32 | // WebRtcSpl_AllPassQMF(...) 33 | // 34 | // Allpass filter used by the analysis and synthesis parts of the QMF filter. 35 | // 36 | // Input: 37 | // - in_data : Input data sequence (Q10) 38 | // - data_length : Length of data sequence (>2) 39 | // - filter_coefficients : Filter coefficients (length 3, Q16) 40 | // 41 | // Input & Output: 42 | // - filter_state : Filter state (length 6, Q10). 43 | // 44 | // Output: 45 | // - out_data : Output data sequence (Q10), length equal to 46 | // |data_length| 47 | // 48 | 49 | void WebRtcSpl_AllPassQMF(int32_t* in_data, size_t data_length, 50 | int32_t* out_data, const uint16_t* filter_coefficients, 51 | int32_t* filter_state) 52 | { 53 | // The procedure is to filter the input with three first order all pass filters 54 | // (cascade operations). 55 | // 56 | // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 57 | // y[n] = ----------- ----------- ----------- x[n] 58 | // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 59 | // 60 | // The input vector |filter_coefficients| includes these three filter coefficients. 61 | // The filter state contains the in_data state, in_data[-1], followed by 62 | // the out_data state, out_data[-1]. This is repeated for each cascade. 63 | // The first cascade filter will filter the |in_data| and store the output in 64 | // |out_data|. The second will the take the |out_data| as input and make an 65 | // intermediate storage in |in_data|, to save memory. The third, and final, cascade 66 | // filter operation takes the |in_data| (which is the output from the previous cascade 67 | // filter) and store the output in |out_data|. 68 | // Note that the input vector values are changed during the process. 69 | size_t k; 70 | int32_t diff; 71 | // First all-pass cascade; filter from in_data to out_data. 72 | 73 | // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at 74 | // vector position n. Then the final output will be y[n] = y_3[n] 75 | 76 | // First loop, use the states stored in memory. 77 | // "diff" should be safe from wrap around since max values are 2^25 78 | // diff = (x[0] - y_1[-1]) 79 | diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]); 80 | // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1]) 81 | out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]); 82 | 83 | // For the remaining loops, use previous values. 84 | for (k = 1; k < data_length; k++) 85 | { 86 | // diff = (x[n] - y_1[n-1]) 87 | diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); 88 | // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1]) 89 | out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]); 90 | } 91 | 92 | // Update states. 93 | filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time 94 | filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time 95 | 96 | // Second all-pass cascade; filter from out_data to in_data. 97 | // diff = (y_1[0] - y_2[-1]) 98 | diff = WebRtcSpl_SubSatW32(out_data[0], filter_state[3]); 99 | // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) 100 | in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]); 101 | for (k = 1; k < data_length; k++) 102 | { 103 | // diff = (y_1[n] - y_2[n-1]) 104 | diff = WebRtcSpl_SubSatW32(out_data[k], in_data[k - 1]); 105 | // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) 106 | in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]); 107 | } 108 | 109 | filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time 110 | filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time 111 | 112 | // Third all-pass cascade; filter from in_data to out_data. 113 | // diff = (y_2[0] - y[-1]) 114 | diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[5]); 115 | // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1]) 116 | out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]); 117 | for (k = 1; k < data_length; k++) 118 | { 119 | // diff = (y_2[n] - y[n-1]) 120 | diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); 121 | // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) 122 | out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]); 123 | } 124 | filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time 125 | filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time 126 | } 127 | 128 | void WebRtcSpl_AnalysisQMF(const int16_t* in_data, size_t in_data_length, 129 | int16_t* low_band, int16_t* high_band, 130 | int32_t* filter_state1, int32_t* filter_state2) 131 | { 132 | size_t i; 133 | int16_t k; 134 | int32_t tmp; 135 | int32_t half_in1[kMaxBandFrameLength]; 136 | int32_t half_in2[kMaxBandFrameLength]; 137 | int32_t filter1[kMaxBandFrameLength]; 138 | int32_t filter2[kMaxBandFrameLength]; 139 | const size_t band_length = in_data_length / 2; 140 | RTC_DCHECK_EQ(0, in_data_length % 2); 141 | RTC_DCHECK_LE(band_length, kMaxBandFrameLength); 142 | 143 | // Split even and odd samples. Also shift them to Q10. 144 | for (i = 0, k = 0; i < band_length; i++, k += 2) 145 | { 146 | half_in2[i] = ((int32_t)in_data[k]) * (1 << 10); 147 | half_in1[i] = ((int32_t)in_data[k + 1]) * (1 << 10); 148 | } 149 | 150 | // All pass filter even and odd samples, independently. 151 | WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, 152 | WebRtcSpl_kAllPassFilter1, filter_state1); 153 | WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, 154 | WebRtcSpl_kAllPassFilter2, filter_state2); 155 | 156 | // Take the sum and difference of filtered version of odd and even 157 | // branches to get upper & lower band. 158 | for (i = 0; i < band_length; i++) 159 | { 160 | tmp = (filter1[i] + filter2[i] + 1024) >> 11; 161 | low_band[i] = WebRtcSpl_SatW32ToW16(tmp); 162 | 163 | tmp = (filter1[i] - filter2[i] + 1024) >> 11; 164 | high_band[i] = WebRtcSpl_SatW32ToW16(tmp); 165 | } 166 | } 167 | 168 | void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band, 169 | size_t band_length, int16_t* out_data, 170 | int32_t* filter_state1, int32_t* filter_state2) 171 | { 172 | int32_t tmp; 173 | int32_t half_in1[kMaxBandFrameLength]; 174 | int32_t half_in2[kMaxBandFrameLength]; 175 | int32_t filter1[kMaxBandFrameLength]; 176 | int32_t filter2[kMaxBandFrameLength]; 177 | size_t i; 178 | int16_t k; 179 | RTC_DCHECK_LE(band_length, kMaxBandFrameLength); 180 | 181 | // Obtain the sum and difference channels out of upper and lower-band channels. 182 | // Also shift to Q10 domain. 183 | for (i = 0; i < band_length; i++) 184 | { 185 | tmp = (int32_t)low_band[i] + (int32_t)high_band[i]; 186 | half_in1[i] = tmp * (1 << 10); 187 | tmp = (int32_t)low_band[i] - (int32_t)high_band[i]; 188 | half_in2[i] = tmp * (1 << 10); 189 | } 190 | 191 | // all-pass filter the sum and difference channels 192 | WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, 193 | WebRtcSpl_kAllPassFilter2, filter_state1); 194 | WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, 195 | WebRtcSpl_kAllPassFilter1, filter_state2); 196 | 197 | // The filtered signals are even and odd samples of the output. Combine 198 | // them. The signals are Q10 should shift them back to Q0 and take care of 199 | // saturation. 200 | for (i = 0, k = 0; i < band_length; i++) 201 | { 202 | tmp = (filter2[i] + 512) >> 10; 203 | out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); 204 | 205 | tmp = (filter1[i] + 512) >> 10; 206 | out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /WebRtc_official/include/splitting_filter/splitting_filter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | /* 12 | * This file contains the splitting filter functions. 13 | * 14 | */ 15 | 16 | //#include "rtc_base/checks.h" 17 | //#include "common_audio/signal_processing/include/signal_processing_library.h" 18 | #include "checks.h" 19 | #include "signal_processing_library.h" 20 | 21 | // Maximum number of samples in a low/high-band frame. 22 | enum 23 | { 24 | kMaxBandFrameLength = 320 // 10 ms at 64 kHz. 25 | }; 26 | 27 | // QMF filter coefficients in Q16. 28 | static const uint16_t WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; 29 | static const uint16_t WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; 30 | 31 | /////////////////////////////////////////////////////////////////////////////////////////////// 32 | // WebRtcSpl_AllPassQMF(...) 33 | // 34 | // Allpass filter used by the analysis and synthesis parts of the QMF filter. 35 | // 36 | // Input: 37 | // - in_data : Input data sequence (Q10) 38 | // - data_length : Length of data sequence (>2) 39 | // - filter_coefficients : Filter coefficients (length 3, Q16) 40 | // 41 | // Input & Output: 42 | // - filter_state : Filter state (length 6, Q10). 43 | // 44 | // Output: 45 | // - out_data : Output data sequence (Q10), length equal to 46 | // |data_length| 47 | // 48 | 49 | void WebRtcSpl_AllPassQMF(int32_t* in_data, size_t data_length, 50 | int32_t* out_data, const uint16_t* filter_coefficients, 51 | int32_t* filter_state) 52 | { 53 | // The procedure is to filter the input with three first order all pass filters 54 | // (cascade operations). 55 | // 56 | // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 57 | // y[n] = ----------- ----------- ----------- x[n] 58 | // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 59 | // 60 | // The input vector |filter_coefficients| includes these three filter coefficients. 61 | // The filter state contains the in_data state, in_data[-1], followed by 62 | // the out_data state, out_data[-1]. This is repeated for each cascade. 63 | // The first cascade filter will filter the |in_data| and store the output in 64 | // |out_data|. The second will the take the |out_data| as input and make an 65 | // intermediate storage in |in_data|, to save memory. The third, and final, cascade 66 | // filter operation takes the |in_data| (which is the output from the previous cascade 67 | // filter) and store the output in |out_data|. 68 | // Note that the input vector values are changed during the process. 69 | size_t k; 70 | int32_t diff; 71 | // First all-pass cascade; filter from in_data to out_data. 72 | 73 | // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at 74 | // vector position n. Then the final output will be y[n] = y_3[n] 75 | 76 | // First loop, use the states stored in memory. 77 | // "diff" should be safe from wrap around since max values are 2^25 78 | // diff = (x[0] - y_1[-1]) 79 | diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]); 80 | // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1]) 81 | out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]); 82 | 83 | // For the remaining loops, use previous values. 84 | for (k = 1; k < data_length; k++) 85 | { 86 | // diff = (x[n] - y_1[n-1]) 87 | diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); 88 | // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1]) 89 | out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]); 90 | } 91 | 92 | // Update states. 93 | filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time 94 | filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time 95 | 96 | // Second all-pass cascade; filter from out_data to in_data. 97 | // diff = (y_1[0] - y_2[-1]) 98 | diff = WebRtcSpl_SubSatW32(out_data[0], filter_state[3]); 99 | // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) 100 | in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]); 101 | for (k = 1; k < data_length; k++) 102 | { 103 | // diff = (y_1[n] - y_2[n-1]) 104 | diff = WebRtcSpl_SubSatW32(out_data[k], in_data[k - 1]); 105 | // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) 106 | in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]); 107 | } 108 | 109 | filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time 110 | filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time 111 | 112 | // Third all-pass cascade; filter from in_data to out_data. 113 | // diff = (y_2[0] - y[-1]) 114 | diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[5]); 115 | // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1]) 116 | out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]); 117 | for (k = 1; k < data_length; k++) 118 | { 119 | // diff = (y_2[n] - y[n-1]) 120 | diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); 121 | // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) 122 | out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]); 123 | } 124 | filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time 125 | filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time 126 | } 127 | 128 | void WebRtcSpl_AnalysisQMF(const int16_t* in_data, size_t in_data_length, 129 | int16_t* low_band, int16_t* high_band, 130 | int32_t* filter_state1, int32_t* filter_state2) 131 | { 132 | size_t i; 133 | int16_t k; 134 | int32_t tmp; 135 | int32_t half_in1[kMaxBandFrameLength]; 136 | int32_t half_in2[kMaxBandFrameLength]; 137 | int32_t filter1[kMaxBandFrameLength]; 138 | int32_t filter2[kMaxBandFrameLength]; 139 | const size_t band_length = in_data_length / 2; 140 | RTC_DCHECK_EQ(0, in_data_length % 2); 141 | RTC_DCHECK_LE(band_length, kMaxBandFrameLength); 142 | 143 | // Split even and odd samples. Also shift them to Q10. 144 | for (i = 0, k = 0; i < band_length; i++, k += 2) 145 | { 146 | half_in2[i] = ((int32_t)in_data[k]) * (1 << 10); 147 | half_in1[i] = ((int32_t)in_data[k + 1]) * (1 << 10); 148 | } 149 | 150 | // All pass filter even and odd samples, independently. 151 | WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, 152 | WebRtcSpl_kAllPassFilter1, filter_state1); 153 | WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, 154 | WebRtcSpl_kAllPassFilter2, filter_state2); 155 | 156 | // Take the sum and difference of filtered version of odd and even 157 | // branches to get upper & lower band. 158 | for (i = 0; i < band_length; i++) 159 | { 160 | tmp = (filter1[i] + filter2[i] + 1024) >> 11; 161 | low_band[i] = WebRtcSpl_SatW32ToW16(tmp); 162 | 163 | tmp = (filter1[i] - filter2[i] + 1024) >> 11; 164 | high_band[i] = WebRtcSpl_SatW32ToW16(tmp); 165 | } 166 | } 167 | 168 | void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band, 169 | size_t band_length, int16_t* out_data, 170 | int32_t* filter_state1, int32_t* filter_state2) 171 | { 172 | int32_t tmp; 173 | int32_t half_in1[kMaxBandFrameLength]; 174 | int32_t half_in2[kMaxBandFrameLength]; 175 | int32_t filter1[kMaxBandFrameLength]; 176 | int32_t filter2[kMaxBandFrameLength]; 177 | size_t i; 178 | int16_t k; 179 | RTC_DCHECK_LE(band_length, kMaxBandFrameLength); 180 | 181 | // Obtain the sum and difference channels out of upper and lower-band channels. 182 | // Also shift to Q10 domain. 183 | for (i = 0; i < band_length; i++) 184 | { 185 | tmp = (int32_t)low_band[i] + (int32_t)high_band[i]; 186 | half_in1[i] = tmp * (1 << 10); 187 | tmp = (int32_t)low_band[i] - (int32_t)high_band[i]; 188 | half_in2[i] = tmp * (1 << 10); 189 | } 190 | 191 | // all-pass filter the sum and difference channels 192 | WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, 193 | WebRtcSpl_kAllPassFilter2, filter_state1); 194 | WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, 195 | WebRtcSpl_kAllPassFilter1, filter_state2); 196 | 197 | // The filtered signals are even and odd samples of the output. Combine 198 | // them. The signals are Q10 should shift them back to Q0 and take care of 199 | // saturation. 200 | for (i = 0, k = 0; i < band_length; i++) 201 | { 202 | tmp = (filter2[i] + 512) >> 10; 203 | out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); 204 | 205 | tmp = (filter1[i] + 512) >> 10; 206 | out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); 207 | } 208 | 209 | } 210 | --------------------------------------------------------------------------------