diff --git a/Makefile.am b/Makefile.am index 633cdec..a0377c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src +SUBDIRS = webrtc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = webrtc-audio-processing.pc diff --git a/configure.ac b/configure.ac index f4fa7a7..5f0fe25 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Revision changelog (version - date, svn rev. from upstream that was merged) # 0.1 - 21 Oct 2011, r789 AC_INIT([webrtc-audio-processing], [0.1]) -AM_INIT_AUTOMAKE([dist-xz tar-ustar]) +AM_INIT_AUTOMAKE([dist-xz subdir-objects tar-ustar]) AC_SUBST(LIBWEBRTC_AUDIO_PROCESSING_VERSION_INFO, [0:0:0]) @@ -24,26 +24,24 @@ AS_CASE(["x${with_ns_mode}"], [NS_FIXED=0]) AM_CONDITIONAL(NS_FIXED, [test "x${NS_FIXED}" = "x1"]) -COMMON_CFLAGS="-DNDEBUG -I\$(srcdir)/interface -I\$(srcdir)/main/interface -I\$(top_srcdir)/src -I\$(top_srcdir)/src/modules/interface" -COMMON_CXXFLAGS="-DNDEBUG -I\$(srcdir)/interface -I\$(srcdir)/main/interface -I\$(top_srcdir)/src -I\$(top_srcdir)/src/modules/interface" +COMMON_CFLAGS="-DNDEBUG -I\$(top_srcdir)" +COMMON_CXXFLAGS="-std=c++11 -DNDEBUG -I\$(top_srcdir)" AC_SUBST([COMMON_CFLAGS]) AC_SUBST([COMMON_CXXFLAGS]) AC_CONFIG_FILES([ webrtc-audio-processing.pc Makefile -src/Makefile -src/common_audio/Makefile -src/common_audio/signal_processing_library/Makefile -src/common_audio/vad/Makefile -src/system_wrappers/Makefile -src/modules/Makefile -src/modules/audio_processing/Makefile -src/modules/audio_processing/utility/Makefile -src/modules/audio_processing/ns/Makefile -src/modules/audio_processing/aec/Makefile -src/modules/audio_processing/aecm/Makefile -src/modules/audio_processing/agc/Makefile +webrtc/Makefile +webrtc/common_audio/Makefile +webrtc/system_wrappers/Makefile +webrtc/modules/Makefile +webrtc/modules/audio_processing/Makefile +webrtc/modules/audio_processing/utility/Makefile +webrtc/modules/audio_processing/ns/Makefile +webrtc/modules/audio_processing/aec/Makefile +webrtc/modules/audio_processing/aecm/Makefile +webrtc/modules/audio_processing/agc/Makefile ]) AC_OUTPUT diff --git a/src/common_audio/Makefile.am b/src/common_audio/Makefile.am deleted file mode 100644 index 64b2598..0000000 --- a/src/common_audio/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = signal_processing_library vad diff --git a/src/common_audio/signal_processing_library/Makefile.am b/src/common_audio/signal_processing_library/Makefile.am deleted file mode 100644 index 2402ef4..0000000 --- a/src/common_audio/signal_processing_library/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -noinst_LTLIBRARIES = libspl.la - -libspl_la_SOURCES = main/interface/signal_processing_library.h \ - main/interface/spl_inl.h \ - main/source/auto_corr_to_refl_coef.c \ - main/source/auto_correlation.c \ - main/source/complex_fft.c \ - main/source/complex_ifft.c \ - main/source/complex_bit_reverse.c \ - main/source/copy_set_operations.c \ - main/source/cos_table.c \ - main/source/cross_correlation.c \ - main/source/division_operations.c \ - main/source/dot_product_with_scale.c \ - main/source/downsample_fast.c \ - main/source/energy.c \ - main/source/filter_ar.c \ - main/source/filter_ar_fast_q12.c \ - main/source/filter_ma_fast_q12.c \ - main/source/get_hanning_window.c \ - main/source/get_scaling_square.c \ - main/source/hanning_table.c \ - main/source/ilbc_specific_functions.c \ - main/source/levinson_durbin.c \ - main/source/lpc_to_refl_coef.c \ - main/source/min_max_operations.c \ - main/source/randn_table.c \ - main/source/randomization_functions.c \ - main/source/refl_coef_to_lpc.c \ - main/source/resample.c \ - main/source/resample_48khz.c \ - main/source/resample_by_2.c \ - main/source/resample_by_2_internal.c \ - main/source/resample_by_2_internal.h \ - main/source/resample_fractional.c \ - main/source/sin_table.c \ - main/source/sin_table_1024.c \ - main/source/spl_sqrt.c \ - main/source/spl_sqrt_floor.c \ - main/source/spl_version.c \ - main/source/splitting_filter.c \ - main/source/sqrt_of_one_minus_x_squared.c \ - main/source/vector_scaling_operations.c -libspl_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS) diff --git a/src/common_audio/signal_processing_library/main/interface/spl_inl.h b/src/common_audio/signal_processing_library/main/interface/spl_inl.h deleted file mode 100644 index 23b3209..0000000 --- a/src/common_audio/signal_processing_library/main/interface/spl_inl.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// This header file includes the inline functions in -// the fix point signal processing library. - -#ifndef WEBRTC_SPL_SPL_INL_H_ -#define WEBRTC_SPL_SPL_INL_H_ - -#ifdef WEBRTC_ARCH_ARM_V7A -#include "spl_inl_armv7.h" -#else - -static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) { - WebRtc_Word16 out16 = (WebRtc_Word16) value32; - - if (value32 > 32767) - out16 = 32767; - else if (value32 < -32768) - out16 = -32768; - - return out16; -} - -static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, - WebRtc_Word16 b) { - return WebRtcSpl_SatW32ToW16((WebRtc_Word32) a + (WebRtc_Word32) b); -} - -static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sum; - - // perform long addition - l_sum = l_var1 + l_var2; - - // check for under or overflow - if (WEBRTC_SPL_IS_NEG(l_var1)) { - if (WEBRTC_SPL_IS_NEG(l_var2) && !WEBRTC_SPL_IS_NEG(l_sum)) { - l_sum = (WebRtc_Word32)0x80000000; - } - } else { - if (!WEBRTC_SPL_IS_NEG(l_var2) && WEBRTC_SPL_IS_NEG(l_sum)) { - l_sum = (WebRtc_Word32)0x7FFFFFFF; - } - } - - return l_sum; -} - -static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, - WebRtc_Word16 var2) { - return WebRtcSpl_SatW32ToW16((WebRtc_Word32) var1 - (WebRtc_Word32) var2); -} - -static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_diff; - - // perform subtraction - l_diff = l_var1 - l_var2; - - // check for underflow - if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0)) - l_diff = (WebRtc_Word32)0x80000000; - // check for overflow - if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0)) - l_diff = (WebRtc_Word32)0x7FFFFFFF; - - return l_diff; -} - -static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) { - int bits; - - if (0xFFFF0000 & n) { - bits = 16; - } else { - bits = 0; - } - if (0x0000FF00 & (n >> bits)) bits += 8; - if (0x000000F0 & (n >> bits)) bits += 4; - if (0x0000000C & (n >> bits)) bits += 2; - if (0x00000002 & (n >> bits)) bits += 1; - if (0x00000001 & (n >> bits)) bits += 1; - - return bits; -} - -static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) { - int zeros; - - if (a <= 0) a ^= 0xFFFFFFFF; - - if (!(0xFFFF8000 & a)) { - zeros = 16; - } else { - zeros = 0; - } - if (!(0xFF800000 & (a << zeros))) zeros += 8; - if (!(0xF8000000 & (a << zeros))) zeros += 4; - if (!(0xE0000000 & (a << zeros))) zeros += 2; - if (!(0xC0000000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) { - int zeros; - - if (a == 0) return 0; - - if (!(0xFFFF0000 & a)) { - zeros = 16; - } else { - zeros = 0; - } - if (!(0xFF000000 & (a << zeros))) zeros += 8; - if (!(0xF0000000 & (a << zeros))) zeros += 4; - if (!(0xC0000000 & (a << zeros))) zeros += 2; - if (!(0x80000000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) { - int zeros; - - if (a <= 0) a ^= 0xFFFF; - - if (!(0xFF80 & a)) { - zeros = 8; - } else { - zeros = 0; - } - if (!(0xF800 & (a << zeros))) zeros += 4; - if (!(0xE000 & (a << zeros))) zeros += 2; - if (!(0xC000 & (a << zeros))) zeros += 1; - - return zeros; -} - -static __inline int32_t WebRtc_MulAccumW16(int16_t a, - int16_t b, - int32_t c) { - return (a * b + c); -} - -#endif // WEBRTC_ARCH_ARM_V7A - -#endif // WEBRTC_SPL_SPL_INL_H_ diff --git a/src/common_audio/signal_processing_library/main/interface/spl_inl_armv7.h b/src/common_audio/signal_processing_library/main/interface/spl_inl_armv7.h deleted file mode 100644 index 689c2ba..0000000 --- a/src/common_audio/signal_processing_library/main/interface/spl_inl_armv7.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// This header file includes the inline functions for ARM processors in -// the fix point signal processing library. - -#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_ -#define WEBRTC_SPL_SPL_INL_ARMV7_H_ - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, - WebRtc_Word32 b) { - WebRtc_Word32 tmp; - __asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a, - WebRtc_Word16 b, - WebRtc_Word32 c) { - WebRtc_Word32 tmp; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a)); - __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI(WebRtc_Word32 a, - WebRtc_Word32 b) { - WebRtc_Word32 tmp; - __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); - return tmp; -} - -static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a, - WebRtc_Word16 b) { - WebRtc_Word32 tmp; - __asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); - return tmp; -} - -static __inline int32_t WebRtc_MulAccumW16(int16_t a, - int16_t b, - int32_t c) { - int32_t tmp = 0; - __asm__("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c)); - return tmp; -} - -static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, - WebRtc_Word16 b) { - WebRtc_Word32 s_sum; - - __asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); - - return (WebRtc_Word16) s_sum; -} - -static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sum; - - __asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); - - return l_sum; -} - -static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, - WebRtc_Word16 var2) { - WebRtc_Word32 s_sub; - - __asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); - - return (WebRtc_Word16)s_sub; -} - -static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, - WebRtc_Word32 l_var2) { - WebRtc_Word32 l_sub; - - __asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); - - return l_sub; -} - -static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) { - WebRtc_Word32 tmp; - - __asm__("clz %0, %1":"=r"(tmp):"r"(n)); - - return (WebRtc_Word16)(32 - tmp); -} - -static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) { - WebRtc_Word32 tmp; - - if (a <= 0) a ^= 0xFFFFFFFF; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp - 1; -} - -static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) { - int tmp; - - if (a == 0) return 0; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp; -} - -static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) { - WebRtc_Word32 tmp; - - if (a <= 0) a ^= 0xFFFFFFFF; - - __asm__("clz %0, %1":"=r"(tmp):"r"(a)); - - return tmp - 17; -} - -static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) { - WebRtc_Word16 out16; - - __asm__("ssat %r0, #16, %r1" : "=r"(out16) : "r"(value32)); - - return out16; -} -#endif // WEBRTC_SPL_SPL_INL_ARMV7_H_ diff --git a/src/common_audio/signal_processing_library/main/source/auto_correlation.c b/src/common_audio/signal_processing_library/main/source/auto_correlation.c deleted file mode 100644 index a00fde4..0000000 --- a/src/common_audio/signal_processing_library/main/source/auto_correlation.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_AutoCorrelation(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector, - int in_vector_length, - int order, - WebRtc_Word32* result, - int* scale) -{ - WebRtc_Word32 sum; - int i, j; - WebRtc_Word16 smax; // Sample max - G_CONST WebRtc_Word16* xptr1; - G_CONST WebRtc_Word16* xptr2; - WebRtc_Word32* resultptr; - int scaling = 0; - -#ifdef _ARM_OPT_ -#pragma message("NOTE: _ARM_OPT_ optimizations are used") - WebRtc_Word16 loops4; -#endif - - if (order < 0) - order = in_vector_length; - - // Find the max. sample - smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length); - - // In order to avoid overflow when computing the sum we should scale the samples so that - // (in_vector_length * smax * smax) will not overflow. - - if (smax == 0) - { - scaling = 0; - } else - { - int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop - int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax - - if (t > nbits) - { - scaling = 0; - } else - { - scaling = nbits - t; - } - - } - - resultptr = result; - - // Perform the actual correlation calculation - for (i = 0; i < order + 1; i++) - { - int loops = (in_vector_length - i); - sum = 0; - xptr1 = in_vector; - xptr2 = &in_vector[i]; -#ifndef _ARM_OPT_ - for (j = loops; j > 0; j--) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling); - } -#else - loops4 = (loops >> 2) << 2; - - if (scaling == 0) - { - for (j = 0; j < loops4; j = j + 4) - { - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - } - - for (j = loops4; j < loops; j++) - { - sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); - xptr1++; - xptr2++; - } - } - else - { - for (j = 0; j < loops4; j = j + 4) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - } - - for (j = loops4; j < loops; j++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); - xptr1++; - xptr2++; - } - } - -#endif - *resultptr++ = sum; - } - - *scale = scaling; - - return order + 1; -} diff --git a/src/common_audio/signal_processing_library/main/source/complex_bit_reverse.c b/src/common_audio/signal_processing_library/main/source/complex_bit_reverse.c deleted file mode 100644 index 85c76f8..0000000 --- a/src/common_audio/signal_processing_library/main/source/complex_bit_reverse.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ComplexBitReverse(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages) -{ - int mr, nn, n, l, m; - WebRtc_Word16 tr, ti; - - n = 1 << stages; - - mr = 0; - nn = n - 1; - - // decimation in time - re-order data - for (m = 1; m <= nn; ++m) - { - l = n; - do - { - l >>= 1; - } while (mr + l > nn); - mr = (mr & (l - 1)) + l; - - if (mr <= m) - continue; - - tr = frfi[2 * m]; - frfi[2 * m] = frfi[2 * mr]; - frfi[2 * mr] = tr; - - ti = frfi[2 * m + 1]; - frfi[2 * m + 1] = frfi[2 * mr + 1]; - frfi[2 * mr + 1] = ti; - } -} diff --git a/src/common_audio/signal_processing_library/main/source/complex_fft.c b/src/common_audio/signal_processing_library/main/source/complex_fft.c deleted file mode 100644 index bcaa076..0000000 --- a/src/common_audio/signal_processing_library/main/source/complex_fft.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ComplexFFT(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define CFFTSFT 14 -#define CFFTRND 1 -#define CFFTRND2 16384 - -int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode) -{ - int i, j, l, k, istep, n, m; - WebRtc_Word16 wr, wi; - WebRtc_Word32 tr32, ti32, qr32, qi32; - - /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[], - * and should not be changed depending on the input parameter 'stages' - */ - n = 1 << stages; - if (n > 1024) - return -1; - - l = 1; - k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change - depending on the input parameter 'stages' */ - - if (mode == 0) - { - // mode==0: Low-complexity and Low-accuracy mode - while (l < n) - { - istep = l << 1; - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = WebRtcSpl_kSinTable1024[j + 256]; - wi = -WebRtcSpl_kSinTable1024[j]; - - for (i = m; i < n; i += istep) - { - j = i + l; - - tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15); - - ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15); - - qr32 = (WebRtc_Word32)frfi[2 * i]; - qi32 = (WebRtc_Word32)frfi[2 * i + 1]; - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1); - } - } - - --k; - l = istep; - - } - - } else - { - // mode==1: High-complexity and High-accuracy mode - while (l < n) - { - istep = l << 1; - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = WebRtcSpl_kSinTable1024[j + 256]; - wi = -WebRtcSpl_kSinTable1024[j]; - -#ifdef WEBRTC_ARCH_ARM_V7A - WebRtc_Word32 wri; - WebRtc_Word32 frfi_r; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : - "r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi)); -#endif - - for (i = m; i < n; i += istep) - { - j = i + l; - -#ifdef WEBRTC_ARCH_ARM_V7A - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) : - "r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1])); - __asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) : - "r"(wri), "r"(frfi_r), "r"(CFFTRND)); - __asm__("smladx %0, %1, %2, %3" : "=r"(ti32) : - "r"(wri), "r"(frfi_r), "r"(CFFTRND)); - -#else - tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND; - - ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND; -#endif - - tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT); - ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT); - - qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT; - qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT; - - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT); - } - } - - --k; - l = istep; - } - } - return 0; -} diff --git a/src/common_audio/signal_processing_library/main/source/complex_ifft.c b/src/common_audio/signal_processing_library/main/source/complex_ifft.c deleted file mode 100644 index c2e4b4f..0000000 --- a/src/common_audio/signal_processing_library/main/source/complex_ifft.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_ComplexIFFT(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define CIFFTSFT 14 -#define CIFFTRND 1 - -int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode) -{ - int i, j, l, k, istep, n, m, scale, shift; - WebRtc_Word16 wr, wi; - WebRtc_Word32 tr32, ti32, qr32, qi32; - WebRtc_Word32 tmp32, round2; - - /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[], - * and should not be changed depending on the input parameter 'stages' - */ - n = 1 << stages; - if (n > 1024) - return -1; - - scale = 0; - - l = 1; - k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change - depending on the input parameter 'stages' */ - - while (l < n) - { - // variable scaling, depending upon data - shift = 0; - round2 = 8192; - - tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n); - if (tmp32 > 13573) - { - shift++; - scale++; - round2 <<= 1; - } - if (tmp32 > 27146) - { - shift++; - scale++; - round2 <<= 1; - } - - istep = l << 1; - - if (mode == 0) - { - // mode==0: Low-complexity and Low-accuracy mode - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = WebRtcSpl_kSinTable1024[j + 256]; - wi = WebRtcSpl_kSinTable1024[j]; - - for (i = m; i < n; i += istep) - { - j = i + l; - - tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0) - - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15); - - ti32 = WEBRTC_SPL_RSHIFT_W32( - (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0) - + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15); - - qr32 = (WebRtc_Word32)frfi[2 * i]; - qi32 = (WebRtc_Word32)frfi[2 * i + 1]; - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift); - } - } - } else - { - // mode==1: High-complexity and High-accuracy mode - - for (m = 0; m < l; ++m) - { - j = m << k; - - /* The 256-value is a constant given as 1/4 of the size of - * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input - * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 - */ - wr = WebRtcSpl_kSinTable1024[j + 256]; - wi = WebRtcSpl_kSinTable1024[j]; - -#ifdef WEBRTC_ARCH_ARM_V7A - WebRtc_Word32 wri; - WebRtc_Word32 frfi_r; - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : - "r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi)); -#endif - - for (i = m; i < n; i += istep) - { - j = i + l; - -#ifdef WEBRTC_ARCH_ARM_V7A - __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) : - "r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1])); - __asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) : - "r"(wri), "r"(frfi_r), "r"(CIFFTRND)); - __asm__("smladx %0, %1, %2, %3" : "=r"(ti32) : - "r"(wri), "r"(frfi_r), "r"(CIFFTRND)); -#else - - tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) - - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND; - - ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) - + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND; -#endif - tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT); - ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT); - - qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT; - qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT; - - frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2), - shift+CIFFTSFT); - frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 - ti32 + round2), shift + CIFFTSFT); - frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2), - shift + CIFFTSFT); - frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( - (qi32 + ti32 + round2), shift + CIFFTSFT); - } - } - - } - --k; - l = istep; - } - return scale; -} diff --git a/src/common_audio/signal_processing_library/main/source/copy_set_operations.c b/src/common_audio/signal_processing_library/main/source/copy_set_operations.c deleted file mode 100644 index 8247337..0000000 --- a/src/common_audio/signal_processing_library/main/source/copy_set_operations.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the implementation of functions - * WebRtcSpl_MemSetW16() - * WebRtcSpl_MemSetW32() - * WebRtcSpl_MemCpyReversedOrder() - * WebRtcSpl_CopyFromEndW16() - * WebRtcSpl_ZerosArrayW16() - * WebRtcSpl_ZerosArrayW32() - * WebRtcSpl_OnesArrayW16() - * WebRtcSpl_OnesArrayW32() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include -#include "signal_processing_library.h" - - -void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length) -{ - int j; - WebRtc_Word16 *arrptr = ptr; - - for (j = length; j > 0; j--) - { - *arrptr++ = set_value; - } -} - -void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length) -{ - int j; - WebRtc_Word32 *arrptr = ptr; - - for (j = length; j > 0; j--) - { - *arrptr++ = set_value; - } -} - -void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length) -{ - int j; - WebRtc_Word16* destPtr = dest; - WebRtc_Word16* sourcePtr = source; - - for (j = 0; j < length; j++) - { - *destPtr-- = *sourcePtr++; - } -} - -WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in, - WebRtc_Word16 length, - WebRtc_Word16 samples, - WebRtc_Word16 *vector_out) -{ - // Copy the last of the input vector to vector_out - WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples); - - return samples; -} - -WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtcSpl_MemSetW16(vector, 0, length); - return length; -} - -WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtcSpl_MemSetW32(vector, 0, length); - return length; -} - -WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 i; - WebRtc_Word16 *tmpvec = vector; - for (i = 0; i < length; i++) - { - *tmpvec++ = 1; - } - return length; -} - -WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 i; - WebRtc_Word32 *tmpvec = vector; - for (i = 0; i < length; i++) - { - *tmpvec++ = 1; - } - return length; -} diff --git a/src/common_audio/signal_processing_library/main/source/cos_table.c b/src/common_audio/signal_processing_library/main/source/cos_table.c deleted file mode 100644 index 7dba4b0..0000000 --- a/src/common_audio/signal_processing_library/main/source/cos_table.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the 360 degree cos table. - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word16 WebRtcSpl_kCosTable[] = { - 8192, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112, - 8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834, - 7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362, - 7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710, - 6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892, - 5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930, - 4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845, - 3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667, - 2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422, - 1281, 1140, 998, 856, 713, 571, 428, 285, 142, - 0, -142, -285, -428, -571, -713, -856, -998, -1140, - -1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395, - -2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591, - -3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698, - -4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690, - -5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542, - -6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233, - -7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745, - -7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067, - -8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190, - -8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112, - -8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834, - -7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362, - -7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710, - -6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892, - -5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930, - -4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845, - -3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667, - -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, - -1281, -1140, -998, -856, -713, -571, -428, -285, -142, - 0, 142, 285, 428, 571, 713, 856, 998, 1140, - 1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395, - 2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591, - 3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698, - 4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690, - 5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542, - 6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233, - 7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745, - 7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067, - 8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190 -}; diff --git a/src/common_audio/signal_processing_library/main/source/cross_correlation.c b/src/common_audio/signal_processing_library/main/source/cross_correlation.c deleted file mode 100644 index 1133d09..0000000 --- a/src/common_audio/signal_processing_library/main/source/cross_correlation.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_CrossCorrelation(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1, - WebRtc_Word16* seq2, WebRtc_Word16 dim_seq, - WebRtc_Word16 dim_cross_correlation, - WebRtc_Word16 right_shifts, - WebRtc_Word16 step_seq2) -{ - int i, j; - WebRtc_Word16* seq1Ptr; - WebRtc_Word16* seq2Ptr; - WebRtc_Word32* CrossCorrPtr; - -#ifdef _XSCALE_OPT_ - -#ifdef _WIN32 -#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)") -#endif - - __int64 macc40; - - int iseq1[250]; - int iseq2[250]; - int iseq3[250]; - int * iseq1Ptr; - int * iseq2Ptr; - int * iseq3Ptr; - int len, i_len; - - seq1Ptr = seq1; - iseq1Ptr = iseq1; - for(i = 0; i < ((dim_seq + 1) >> 1); i++) - { - *iseq1Ptr = (unsigned short)*seq1Ptr++; - *iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16; - - } - - if(dim_seq%2) - { - *(iseq1Ptr-1) &= 0x0000ffff; - } - *iseq1Ptr = 0; - iseq1Ptr++; - *iseq1Ptr = 0; - iseq1Ptr++; - *iseq1Ptr = 0; - - if(step_seq2 < 0) - { - seq2Ptr = seq2 - dim_cross_correlation + 1; - CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1]; - } - else - { - seq2Ptr = seq2; - CrossCorrPtr = cross_correlation; - } - - len = dim_seq + dim_cross_correlation - 1; - i_len = (len + 1) >> 1; - iseq2Ptr = iseq2; - - iseq3Ptr = iseq3; - for(i = 0; i < i_len; i++) - { - *iseq2Ptr = (unsigned short)*seq2Ptr++; - *iseq3Ptr = (unsigned short)*seq2Ptr; - *iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16; - *iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16; - } - - if(len % 2) - { - iseq2[i_len - 1] &= 0x0000ffff; - iseq3[i_len - 1] = 0; - } - else - iseq3[i_len - 1] &= 0x0000ffff; - - iseq2[i_len] = 0; - iseq3[i_len] = 0; - iseq2[i_len + 1] = 0; - iseq3[i_len + 1] = 0; - iseq2[i_len + 2] = 0; - iseq3[i_len + 2] = 0; - - // Set pointer to start value - iseq2Ptr = iseq2; - iseq3Ptr = iseq3; - - i_len = (dim_seq + 7) >> 3; - for (i = 0; i < dim_cross_correlation; i++) - { - - iseq1Ptr = iseq1; - - macc40 = 0; - - _WriteCoProcessor(macc40, 0); - - if((i & 1)) - { - iseq3Ptr = iseq3 + (i >> 1); - for (j = i_len; j > 0; j--) - { - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); - } - } - else - { - iseq2Ptr = iseq2 + (i >> 1); - for (j = i_len; j > 0; j--) - { - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); - } - - } - - macc40 = _ReadCoProcessor(0); - *CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts); - CrossCorrPtr += step_seq2; - } -#else // #ifdef _XSCALE_OPT_ -#ifdef _ARM_OPT_ - WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3; -#endif - - CrossCorrPtr = cross_correlation; - - for (i = 0; i < dim_cross_correlation; i++) - { - // Set the pointer to the static vector, set the pointer to the sliding vector - // and initialize cross_correlation - seq1Ptr = seq1; - seq2Ptr = seq2 + (step_seq2 * i); - (*CrossCorrPtr) = 0; - -#ifndef _ARM_OPT_ -#ifdef _WIN32 -#pragma message("NOTE: default implementation is used") -#endif - // Perform the cross correlation - for (j = 0; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts); - seq1Ptr++; - seq2Ptr++; - } -#else -#ifdef _WIN32 -#pragma message("NOTE: _ARM_OPT_ optimizations are used") -#endif - if (right_shifts == 0) - { - // Perform the optimized cross correlation - for (j = 0; j < dim_seq8; j = j + 8) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - } - - for (j = dim_seq8; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); - seq1Ptr++; - seq2Ptr++; - } - } - else // right_shifts != 0 - - { - // Perform the optimized cross correlation - for (j = 0; j < dim_seq8; j = j + 8) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - } - - for (j = dim_seq8; j < dim_seq; j++) - { - (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), - right_shifts); - seq1Ptr++; - seq2Ptr++; - } - } -#endif - CrossCorrPtr++; - } -#endif -} diff --git a/src/common_audio/signal_processing_library/main/source/division_operations.c b/src/common_audio/signal_processing_library/main/source/division_operations.c deleted file mode 100644 index b143373..0000000 --- a/src/common_audio/signal_processing_library/main/source/division_operations.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the divisions - * WebRtcSpl_DivU32U16() - * WebRtcSpl_DivW32W16() - * WebRtcSpl_DivW32W16ResW16() - * WebRtcSpl_DivResultInQ31() - * WebRtcSpl_DivW32HiLow() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_UWord32)(num / den); - } else - { - return (WebRtc_UWord32)0xFFFFFFFF; - } -} - -WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_Word32)(num / den); - } else - { - return (WebRtc_Word32)0x7FFFFFFF; - } -} - -WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den) -{ - // Guard against division with 0 - if (den != 0) - { - return (WebRtc_Word16)(num / den); - } else - { - return (WebRtc_Word16)0x7FFF; - } -} - -WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den) -{ - WebRtc_Word32 L_num = num; - WebRtc_Word32 L_den = den; - WebRtc_Word32 div = 0; - int k = 31; - int change_sign = 0; - - if (num == 0) - return 0; - - if (num < 0) - { - change_sign++; - L_num = -num; - } - if (den < 0) - { - change_sign++; - L_den = -den; - } - while (k--) - { - div <<= 1; - L_num <<= 1; - if (L_num >= L_den) - { - L_num -= L_den; - div++; - } - } - if (change_sign == 1) - { - div = -div; - } - return div; -} - -WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, - WebRtc_Word16 den_low) -{ - WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low; - WebRtc_Word32 tmpW32; - - approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi); - // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) - - // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) - tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1) - + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1); - // tmpW32 = den * approx - - tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) - - // Store tmpW32 in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // tmpW32 = 1/den in Q29 - tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx) - >> 15)) << 1); - - // 1/den in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Store num in hi and low format - num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16); - num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1); - - // num * (1/den) by 32 bit multiplication (result in Q28) - - tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low) - >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15)); - - // Put result in Q31 (convert from Q28) - tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); - - return tmpW32; -} diff --git a/src/common_audio/signal_processing_library/main/source/dot_product_with_scale.c b/src/common_audio/signal_processing_library/main/source/dot_product_with_scale.c deleted file mode 100644 index 6e085fd..0000000 --- a/src/common_audio/signal_processing_library/main/source/dot_product_with_scale.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_DotProductWithScale(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2, - int length, int scaling) -{ - WebRtc_Word32 sum; - int i; -#ifdef _ARM_OPT_ -#pragma message("NOTE: _ARM_OPT_ optimizations are used") - WebRtc_Word16 len4 = (length >> 2) << 2; -#endif - - sum = 0; - -#ifndef _ARM_OPT_ - for (i = 0; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling); - } -#else - if (scaling == 0) - { - for (i = 0; i < len4; i = i + 4) - { - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - } - - for (i = len4; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); - vector1++; - vector2++; - } - } - else - { - for (i = 0; i < len4; i = i + 4) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - } - - for (i = len4; i < length; i++) - { - sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); - vector1++; - vector2++; - } - } -#endif - - return sum; -} diff --git a/src/common_audio/signal_processing_library/main/source/downsample_fast.c b/src/common_audio/signal_processing_library/main/source/downsample_fast.c deleted file mode 100644 index cce463c..0000000 --- a/src/common_audio/signal_processing_library/main/source/downsample_fast.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_DownsampleFast(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length, - WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length, - WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor, - WebRtc_Word16 delay) -{ - WebRtc_Word32 o; - int i, j; - - WebRtc_Word16 *downsampled_ptr = out_ptr; - WebRtc_Word16 *b_ptr; - WebRtc_Word16 *x_ptr; - WebRtc_Word16 endpos = delay - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1; - - if (in_length < endpos) - { - return -1; - } - - for (i = delay; i < endpos; i += factor) - { - b_ptr = &B[0]; - x_ptr = &in_ptr[i]; - - o = (WebRtc_Word32)2048; // Round val - - for (j = 0; j < B_length; j++) - { - o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--); - } - - o = WEBRTC_SPL_RSHIFT_W32(o, 12); - - // If output is higher than 32768, saturate it. Same with negative side - - *downsampled_ptr++ = WebRtcSpl_SatW32ToW16(o); - } - - return 0; -} diff --git a/src/common_audio/signal_processing_library/main/source/filter_ar.c b/src/common_audio/signal_processing_library/main/source/filter_ar.c deleted file mode 100644 index 24e83a6..0000000 --- a/src/common_audio/signal_processing_library/main/source/filter_ar.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_FilterAR(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a, - int a_length, - G_CONST WebRtc_Word16* x, - int x_length, - WebRtc_Word16* state, - int state_length, - WebRtc_Word16* state_low, - int state_low_length, - WebRtc_Word16* filtered, - WebRtc_Word16* filtered_low, - int filtered_low_length) -{ - WebRtc_Word32 o; - WebRtc_Word32 oLOW; - int i, j, stop; - G_CONST WebRtc_Word16* x_ptr = &x[0]; - WebRtc_Word16* filteredFINAL_ptr = filtered; - WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low; - - for (i = 0; i < x_length; i++) - { - // Calculate filtered[i] and filtered_low[i] - G_CONST WebRtc_Word16* a_ptr = &a[1]; - WebRtc_Word16* filtered_ptr = &filtered[i - 1]; - WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1]; - WebRtc_Word16* state_ptr = &state[state_length - 1]; - WebRtc_Word16* state_low_ptr = &state_low[state_length - 1]; - - o = (WebRtc_Word32)(*x_ptr++) << 12; - oLOW = (WebRtc_Word32)0; - - stop = (i < a_length) ? i + 1 : a_length; - for (j = 1; j < stop; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--); - oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--); - } - for (j = i + 1; j < a_length; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--); - oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--); - } - - o += (oLOW >> 12); - *filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); - *filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++) - << 12)); - } - - // Save the filter state - if (x_length >= state_length) - { - WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state); - WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low); - } else - { - for (i = 0; i < state_length - x_length; i++) - { - state[i] = state[i + x_length]; - state_low[i] = state_low[i + x_length]; - } - for (i = 0; i < x_length; i++) - { - state[state_length - x_length + i] = filtered[i]; - state[state_length - x_length + i] = filtered_low[i]; - } - } - - return x_length; -} diff --git a/src/common_audio/signal_processing_library/main/source/filter_ar_fast_q12.c b/src/common_audio/signal_processing_library/main/source/filter_ar_fast_q12.c deleted file mode 100644 index 6184da3..0000000 --- a/src/common_audio/signal_processing_library/main/source/filter_ar_fast_q12.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_FilterARFastQ12(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A, - WebRtc_Word16 A_length, WebRtc_Word16 length) -{ - WebRtc_Word32 o; - int i, j; - - WebRtc_Word16 *x_ptr = &in[0]; - WebRtc_Word16 *filtered_ptr = &out[0]; - - for (i = 0; i < length; i++) - { - // Calculate filtered[i] - G_CONST WebRtc_Word16 *a_ptr = &A[0]; - WebRtc_Word16 *state_ptr = &out[i - 1]; - - o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++); - - for (j = 1; j < A_length; j++) - { - o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--); - } - - // Saturate the output - o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728); - - *filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); - } - - return; -} diff --git a/src/common_audio/signal_processing_library/main/source/get_hanning_window.c b/src/common_audio/signal_processing_library/main/source/get_hanning_window.c deleted file mode 100644 index 2845c83..0000000 --- a/src/common_audio/signal_processing_library/main/source/get_hanning_window.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_GetHanningWindow(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size) -{ - int jj; - WebRtc_Word16 *vptr1; - - WebRtc_Word32 index; - WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000); - - factor = WebRtcSpl_DivW32W16(factor, size); - if (size < 513) - index = (WebRtc_Word32)-0x200000; - else - index = (WebRtc_Word32)-0x100000; - vptr1 = v; - - for (jj = 0; jj < size; jj++) - { - index += factor; - (*vptr1++) = WebRtcSpl_kHanningTable[index >> 22]; - } - -} diff --git a/src/common_audio/signal_processing_library/main/source/ilbc_specific_functions.c b/src/common_audio/signal_processing_library/main/source/ilbc_specific_functions.c deleted file mode 100644 index 5a9e577..0000000 --- a/src/common_audio/signal_processing_library/main/source/ilbc_specific_functions.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the iLBC specific functions - * WebRtcSpl_ScaleAndAddVectorsWithRound() - * WebRtcSpl_ReverseOrderMultArrayElements() - * WebRtcSpl_ElementwiseVectorMult() - * WebRtcSpl_AddVectorsAndShift() - * WebRtcSpl_AddAffineVectorToVector() - * WebRtcSpl_AffineTransformVector() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1, - WebRtc_Word16 *vector2, WebRtc_Word16 scale2, - WebRtc_Word16 right_shifts, WebRtc_Word16 *out, - WebRtc_Word16 vector_length) -{ - int i; - WebRtc_Word16 roundVal; - roundVal = 1 << right_shifts; - roundVal = roundVal >> 1; - for (i = 0; i < vector_length; i++) - { - out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1) - + WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts); - } -} - -void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, - G_CONST WebRtc_Word16 *win, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *inptr = in; - G_CONST WebRtc_Word16 *winptr = win; - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, - *winptr--, right_shifts); - } -} - -void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, - G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *inptr = in; - G_CONST WebRtc_Word16 *winptr = win; - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, - *winptr++, right_shifts); - } -} - -void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1, - G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts) -{ - int i; - WebRtc_Word16 *outptr = out; - G_CONST WebRtc_Word16 *in1ptr = in1; - G_CONST WebRtc_Word16 *in2ptr = in2; - for (i = vector_length; i > 0; i--) - { - (*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts); - } -} - -void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in, - WebRtc_Word16 gain, WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, int vector_length) -{ - WebRtc_Word16 *inPtr; - WebRtc_Word16 *outPtr; - int i; - - inPtr = in; - outPtr = out; - for (i = 0; i < vector_length; i++) - { - (*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) - + (WebRtc_Word32)add_constant) >> right_shifts); - } -} - -void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in, - WebRtc_Word16 gain, WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, int vector_length) -{ - WebRtc_Word16 *inPtr; - WebRtc_Word16 *outPtr; - int i; - - inPtr = in; - outPtr = out; - for (i = 0; i < vector_length; i++) - { - (*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) - + (WebRtc_Word32)add_constant) >> right_shifts); - } -} diff --git a/src/common_audio/signal_processing_library/main/source/levinson_durbin.c b/src/common_audio/signal_processing_library/main/source/levinson_durbin.c deleted file mode 100644 index 4e11cdb..0000000 --- a/src/common_audio/signal_processing_library/main/source/levinson_durbin.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_LevinsonDurbin(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define SPL_LEVINSON_MAXORDER 20 - -WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32 *R, WebRtc_Word16 *A, WebRtc_Word16 *K, - WebRtc_Word16 order) -{ - WebRtc_Word16 i, j; - // Auto-correlation coefficients in high precision - WebRtc_Word16 R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1]; - // LPC coefficients in high precision - WebRtc_Word16 A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1]; - // LPC coefficients for next iteration - WebRtc_Word16 A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1]; - // Reflection coefficient in high precision - WebRtc_Word16 K_hi, K_low; - // Prediction gain Alpha in high precision and with scale factor - WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp; - WebRtc_Word16 tmp_hi, tmp_low; - WebRtc_Word32 temp1W32, temp2W32, temp3W32; - WebRtc_Word16 norm; - - // Normalize the autocorrelation R[0]...R[order+1] - - norm = WebRtcSpl_NormW32(R[0]); - - for (i = order; i >= 0; i--) - { - temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm); - // Put R in hi and low format - R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1); - } - - // K = A[1] = -R[1] / R[0] - - temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31 - temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1] - temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31 - // Put back the sign on R[1] - if (temp2W32 > 0) - { - temp1W32 = -temp1W32; - } - - // Put K in hi and low format - K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); - - // Store first reflection coefficient - K[0] = K_hi; - - temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27 - - // Put A[1] in hi and low format - A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1); - - // Alpha = R[0] * (1-K^2) - - temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) - << 1); // temp1W32 = k^2 in Q31 - - temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 - temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31 - - // Store temp1W32 = 1 - K[0]*K[0] on hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Calculate Alpha in Q31 - temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) - + (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15) - + (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1); - - // Normalize Alpha and put it in hi and low format - - Alpha_exp = WebRtcSpl_NormW32(temp1W32); - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); - Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); - - // Perform the iterative calculations in the Levinson-Durbin algorithm - - for (i = 2; i <= order; i++) - { - /* ---- - temp1W32 = R[i] + > R[j]*A[i-j] - / - ---- - j=1..i-1 - */ - - temp1W32 = 0; - - for (j = 1; j < i; j++) - { - // temp1W32 is in Q31 - temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1) - + (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15) - + (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1)); - } - - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4); - temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1)); - - // K = -temp1W32 / Alpha - temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32) - temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha - - // Put the sign of temp1W32 back again - if (temp1W32 > 0) - { - temp3W32 = -temp3W32; - } - - // Use the Alpha shifts from earlier to de-normalize - norm = WebRtcSpl_NormW32(temp3W32); - if ((Alpha_exp <= norm) || (temp3W32 == 0)) - { - temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp); - } else - { - if (temp3W32 > 0) - { - temp3W32 = (WebRtc_Word32)0x7fffffffL; - } else - { - temp3W32 = (WebRtc_Word32)0x80000000L; - } - } - - // Put K on hi and low format - K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); - K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); - - // Store Reflection coefficient in Q15 - K[i - 1] = K_hi; - - // Test for unstable filter. - // If unstable return 0 and let the user decide what to do in that case - - if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750) - { - return 0; // Unstable filter - } - - /* - Compute updated LPC coefficient: Anew[i] - Anew[j]= A[j] + K*A[i-j] for j=1..i-1 - Anew[i]= K - */ - - for (j = 1; j < i; j++) - { - // temp1W32 = A[j] in Q27 - temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1); - - // temp1W32 += K*A[i-j] in Q27 - temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) - + (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15) - + (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1); - - // Put Anew in hi and low format - A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1); - } - - // temp3W32 = K in Q27 (Convert from Q31 to Q27) - temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4); - - // Store Anew in hi and low format - A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); - A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1); - - // Alpha = Alpha * (1-K^2) - - temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) - + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31 - - temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 - temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K in Q31 - - // Convert 1- K^2 in hi and low format - tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); - - // Calculate Alpha = Alpha * (1-K^2) in Q31 - temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) - + (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15) - + (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1); - - // Normalize Alpha and store it on hi and low format - - norm = WebRtcSpl_NormW32(temp1W32); - temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); - - Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); - Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); - - // Update the total normalization of Alpha - Alpha_exp = Alpha_exp + norm; - - // Update A[] - - for (j = 1; j <= i; j++) - { - A_hi[j] = A_upd_hi[j]; - A_low[j] = A_upd_low[j]; - } - } - - /* - Set A[0] to 1.0 and store the A[i] i=1...order in Q12 - (Convert from Q27 and use rounding) - */ - - A[0] = 4096; - - for (i = 1; i <= order; i++) - { - // temp1W32 in Q27 - temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16) - + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1); - // Round and store upper word - A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16); - } - return 1; // Stable filters -} diff --git a/src/common_audio/signal_processing_library/main/source/min_max_operations.c b/src/common_audio/signal_processing_library/main/source/min_max_operations.c deleted file mode 100644 index 57eaff7..0000000 --- a/src/common_audio/signal_processing_library/main/source/min_max_operations.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the implementation of functions - * WebRtcSpl_MaxAbsValueW16() - * WebRtcSpl_MaxAbsIndexW16() - * WebRtcSpl_MaxAbsValueW32() - * WebRtcSpl_MaxValueW16() - * WebRtcSpl_MaxIndexW16() - * WebRtcSpl_MaxValueW32() - * WebRtcSpl_MaxIndexW32() - * WebRtcSpl_MinValueW16() - * WebRtcSpl_MinIndexW16() - * WebRtcSpl_MinValueW32() - * WebRtcSpl_MinIndexW32() - * - * The description header can be found in signal_processing_library.h. - * - */ - -#include "signal_processing_library.h" - -#if !(defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON)) - -// Maximum absolute value of word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax = 0; - WebRtc_Word32 absVal; - WebRtc_Word16 totMax; - int i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - for (i = 0; i < length; i++) - { - absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); - if (absVal > tempMax) - { - tempMax = absVal; - } - tmpvector++; - } - totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX); - return totMax; -} - -#endif - -// Index of maximum absolute value in a word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 absTemp; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = WEBRTC_SPL_ABS_W16(*tmpvector); - tmpvector++; - for (i = 1; i < length; i++) - { - absTemp = WEBRTC_SPL_ABS_W16(*tmpvector); - tmpvector++; - if (absTemp > tempMax) - { - tempMax = absTemp; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Maximum absolute value of word32 vector. -WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_UWord32 tempMax = 0; - WebRtc_UWord32 absVal; - WebRtc_Word32 retval; - int i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - for (i = 0; i < length; i++) - { - absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); - if (absVal > tempMax) - { - tempMax = absVal; - } - tmpvector++; - } - retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX)); - return retval; -} - -// Maximum value of word16 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - tempMax = vector[i]; - } - return tempMax; -} -#else -#pragma message(">> WebRtcSpl_MaxValueW16 is excluded from this build") -#endif - -// Index of maximum value in a word16 vector. -WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMax; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - { - tempMax = vector[i]; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Maximum value of word32 vector. -#ifndef XSCALE_OPT -WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax; - WebRtc_Word16 i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - tempMax = vector[i]; - } - return tempMax; -} -#else -#pragma message(">> WebRtcSpl_MaxValueW32 is excluded from this build") -#endif - -// Index of maximum value in a word32 vector. -WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMax; - WebRtc_Word16 tempMaxIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word32 *tmpvector = vector; - - tempMax = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ > tempMax) - { - tempMax = vector[i]; - tempMaxIndex = i; - } - } - return tempMaxIndex; -} - -// Minimum value of word16 vector. -WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMin; - WebRtc_Word16 i; - G_CONST WebRtc_Word16 *tmpvector = vector; - - // Find the minimum value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - tempMin = (vector[i]); - } - return tempMin; -} - -// Index of minimum value in a word16 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) -{ - WebRtc_Word16 tempMin; - WebRtc_Word16 tempMinIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word16* tmpvector = vector; - - // Find index of smallest value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - { - tempMin = vector[i]; - tempMinIndex = i; - } - } - return tempMinIndex; -} -#else -#pragma message(">> WebRtcSpl_MinIndexW16 is excluded from this build") -#endif - -// Minimum value of word32 vector. -WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMin; - WebRtc_Word16 i; - G_CONST WebRtc_Word32 *tmpvector = vector; - - // Find the minimum value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - tempMin = (vector[i]); - } - return tempMin; -} - -// Index of minimum value in a word32 vector. -#ifndef XSCALE_OPT -WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) -{ - WebRtc_Word32 tempMin; - WebRtc_Word16 tempMinIndex = 0; - WebRtc_Word16 i = 0; - G_CONST WebRtc_Word32 *tmpvector = vector; - - // Find index of smallest value - tempMin = *tmpvector++; - for (i = 1; i < length; i++) - { - if (*tmpvector++ < tempMin) - { - tempMin = vector[i]; - tempMinIndex = i; - } - } - return tempMinIndex; -} -#else -#pragma message(">> WebRtcSpl_MinIndexW32 is excluded from this build") -#endif diff --git a/src/common_audio/signal_processing_library/main/source/min_max_operations_neon.c b/src/common_audio/signal_processing_library/main/source/min_max_operations_neon.c deleted file mode 100644 index 158bcc1..0000000 --- a/src/common_audio/signal_processing_library/main/source/min_max_operations_neon.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#if (defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON)) - -#include - -#include "signal_processing_library.h" - -// Maximum absolute value of word16 vector. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector, - WebRtc_Word16 length) { - WebRtc_Word32 temp_max = 0; - WebRtc_Word32 abs_val; - WebRtc_Word16 tot_max; - int i; - - __asm__("vmov.i16 d25, #0" : : : "d25"); - - for (i = 0; i < length - 7; i += 8) { - __asm__("vld1.16 {d26, d27}, [%0]" : : "r"(&vector[i]) : "q13"); - __asm__("vabs.s16 q13, q13" : : : "q13"); - __asm__("vpmax.s16 d26, d27" : : : "q13"); - __asm__("vpmax.s16 d25, d26" : : : "d25", "d26"); - } - __asm__("vpmax.s16 d25, d25" : : : "d25"); - __asm__("vpmax.s16 d25, d25" : : : "d25"); - __asm__("vmov.s16 %0, d25[0]" : "=r"(temp_max): : "d25"); - - for (; i < length; i++) { - abs_val = WEBRTC_SPL_ABS_W32((vector[i])); - if (abs_val > temp_max) { - temp_max = abs_val; - } - } - tot_max = (WebRtc_Word16)WEBRTC_SPL_MIN(temp_max, WEBRTC_SPL_WORD16_MAX); - return tot_max; -} - -#endif diff --git a/src/common_audio/signal_processing_library/main/source/randomization_functions.c b/src/common_audio/signal_processing_library/main/source/randomization_functions.c deleted file mode 100644 index 6bc87c7..0000000 --- a/src/common_audio/signal_processing_library/main/source/randomization_functions.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the randomization functions - * WebRtcSpl_IncreaseSeed() - * WebRtcSpl_RandU() - * WebRtcSpl_RandN() - * WebRtcSpl_RandUArray() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed) -{ - seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1); - return seed[0]; -} - -WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32 *seed) -{ - return (WebRtc_Word16)(WebRtcSpl_IncreaseSeed(seed) >> 16); -} - -WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32 *seed) -{ - return WebRtcSpl_kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23]; -} - -// Creates an array of uniformly distributed variables -WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, - WebRtc_Word16 vector_length, - WebRtc_UWord32* seed) -{ - int i; - for (i = 0; i < vector_length; i++) - { - vector[i] = WebRtcSpl_RandU(seed); - } - return vector_length; -} diff --git a/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.h b/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.h deleted file mode 100644 index b6ac9f0..0000000 --- a/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file contains some internal resampling functions. - * - */ - -#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ -#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ - -#include "typedefs.h" - -/******************************************************************* - * resample_by_2_fast.c - * Functions for internal use in the other resample functions - ******************************************************************/ -void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state); - -void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, - WebRtc_Word32 *out, WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, - WebRtc_Word32 *out, WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state); - -void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, - WebRtc_Word16 *out, WebRtc_Word32 *state); - -void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, - WebRtc_Word32* out, WebRtc_Word32* state); - -void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state); - -#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ diff --git a/src/common_audio/signal_processing_library/main/source/sin_table.c b/src/common_audio/signal_processing_library/main/source/sin_table.c deleted file mode 100644 index ea44666..0000000 --- a/src/common_audio/signal_processing_library/main/source/sin_table.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the 360 degree sine table. - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word16 WebRtcSpl_kSinTable[] = { - 0, 142, 285, 428, 571, 713, 856, 998, 1140, - 1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395, - 2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591, - 3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698, - 4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690, - 5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542, - 6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233, - 7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745, - 7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067, - 8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190, - 8191, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112, - 8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834, - 7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362, - 7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710, - 6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892, - 5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930, - 4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845, - 3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667, - 2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422, - 1281, 1140, 998, 856, 713, 571, 428, 285, 142, - 0, -142, -285, -428, -571, -713, -856, -998, -1140, - -1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395, - -2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591, - -3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698, - -4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690, - -5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542, - -6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233, - -7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745, - -7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067, - -8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190, - -8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112, - -8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834, - -7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362, - -7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710, - -6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892, - -5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930, - -4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845, - -3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667, - -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, - -1281, -1140, -998, -856, -713, -571, -428, -285, -142 -}; diff --git a/src/common_audio/signal_processing_library/main/source/sin_table_1024.c b/src/common_audio/signal_processing_library/main/source/sin_table_1024.c deleted file mode 100644 index a2007f9..0000000 --- a/src/common_audio/signal_processing_library/main/source/sin_table_1024.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the 1024 point sine table. - * - */ - -#include "signal_processing_library.h" - -WebRtc_Word16 WebRtcSpl_kSinTable1024[] = -{ - 0, 201, 402, 603, 804, 1005, 1206, 1406, - 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, - 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, - 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, - 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, - 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, - 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, - 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, - 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, - 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, - 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, - 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, - 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, - 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, - 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, - 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, - 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, - 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, - 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, - 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, - 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, - 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, - 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, - 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, - 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, - 30851, 30918, 30984, 31049, - 31113, 31175, 31236, 31297, - 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, - 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, - 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, - 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, - 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, - 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, - 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, - 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, - 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, - 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, - 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, - 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, - 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, - 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, - 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, - 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, - 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, - 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, - 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, - 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, - 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, - 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, - 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, - 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, - 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, - 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, - 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, - 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, - 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, - 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, - 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, - 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, - 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, - 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, - 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, - 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, - 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, - 1607, 1406, 1206, 1005, 804, 603, 402, 201, - 0, -201, -402, -603, -804, -1005, -1206, -1406, - -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, - -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, - -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, - -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, - -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, - -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, - -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, - -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, - -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, - -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, - -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, - -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, - -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, - -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, - -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, - -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, - -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, - -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, - -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, - -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, - -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, - -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, - -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, - -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, - -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, - -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, - -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, - -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, - -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, - -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, - -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, - -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, - -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, - -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, - -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, - -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, - -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, - -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, - -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, - -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, - -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, - -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, - -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, - -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, - -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, - -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, - -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, - -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, - -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, - -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, - -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, - -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, - -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, - -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, - -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, - -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, - -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, - -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, - -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, - -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, - -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, - -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, - -1607, -1406, -1206, -1005, -804, -603, -402, -201, -}; diff --git a/src/common_audio/signal_processing_library/main/source/spl.gypi b/src/common_audio/signal_processing_library/main/source/spl.gypi deleted file mode 100644 index eea6142..0000000 --- a/src/common_audio/signal_processing_library/main/source/spl.gypi +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'targets': [ - { - 'target_name': 'spl', - 'type': '<(library)', - 'include_dirs': [ - '../interface', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../interface', - ], - }, - 'sources': [ - '../interface/signal_processing_library.h', - '../interface/spl_inl.h', - 'auto_corr_to_refl_coef.c', - 'auto_correlation.c', - 'complex_fft.c', - 'complex_ifft.c', - 'complex_bit_reverse.c', - 'copy_set_operations.c', - 'cos_table.c', - 'cross_correlation.c', - 'division_operations.c', - 'dot_product_with_scale.c', - 'downsample_fast.c', - 'energy.c', - 'filter_ar.c', - 'filter_ar_fast_q12.c', - 'filter_ma_fast_q12.c', - 'get_hanning_window.c', - 'get_scaling_square.c', - 'hanning_table.c', - 'ilbc_specific_functions.c', - 'levinson_durbin.c', - 'lpc_to_refl_coef.c', - 'min_max_operations.c', - 'randn_table.c', - 'randomization_functions.c', - 'refl_coef_to_lpc.c', - 'resample.c', - 'resample_48khz.c', - 'resample_by_2.c', - 'resample_by_2_internal.c', - 'resample_by_2_internal.h', - 'resample_fractional.c', - 'sin_table.c', - 'sin_table_1024.c', - 'spl_sqrt.c', - 'spl_sqrt_floor.c', - 'spl_version.c', - 'splitting_filter.c', - 'sqrt_of_one_minus_x_squared.c', - 'vector_scaling_operations.c', - ], - }, - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/common_audio/signal_processing_library/main/source/spl_sqrt_floor.c b/src/common_audio/signal_processing_library/main/source/spl_sqrt_floor.c deleted file mode 100644 index aa36459..0000000 --- a/src/common_audio/signal_processing_library/main/source/spl_sqrt_floor.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the function WebRtcSpl_SqrtFloor(). - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -#define WEBRTC_SPL_SQRT_ITER(N) \ - try1 = root + (1 << (N)); \ - if (value >= try1 << (N)) \ - { \ - value -= try1 << (N); \ - root |= 2 << (N); \ - } - -// (out) Square root of input parameter -WebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value) -{ - // new routine for performance, 4 cycles/bit in ARM - // output precision is 16 bits - - WebRtc_Word32 root = 0, try1; - - WEBRTC_SPL_SQRT_ITER (15); - WEBRTC_SPL_SQRT_ITER (14); - WEBRTC_SPL_SQRT_ITER (13); - WEBRTC_SPL_SQRT_ITER (12); - WEBRTC_SPL_SQRT_ITER (11); - WEBRTC_SPL_SQRT_ITER (10); - WEBRTC_SPL_SQRT_ITER ( 9); - WEBRTC_SPL_SQRT_ITER ( 8); - WEBRTC_SPL_SQRT_ITER ( 7); - WEBRTC_SPL_SQRT_ITER ( 6); - WEBRTC_SPL_SQRT_ITER ( 5); - WEBRTC_SPL_SQRT_ITER ( 4); - WEBRTC_SPL_SQRT_ITER ( 3); - WEBRTC_SPL_SQRT_ITER ( 2); - WEBRTC_SPL_SQRT_ITER ( 1); - WEBRTC_SPL_SQRT_ITER ( 0); - - return root >> 1; -} diff --git a/src/common_audio/signal_processing_library/main/source/spl_version.c b/src/common_audio/signal_processing_library/main/source/spl_version.c deleted file mode 100644 index 936925e..0000000 --- a/src/common_audio/signal_processing_library/main/source/spl_version.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the function WebRtcSpl_get_version(). - * The description header can be found in signal_processing_library.h - * - */ - -#include -#include "signal_processing_library.h" - -WebRtc_Word16 WebRtcSpl_get_version(char* version, WebRtc_Word16 length_in_bytes) -{ - strncpy(version, "1.2.0", length_in_bytes); - return 0; -} diff --git a/src/common_audio/signal_processing_library/main/source/vector_scaling_operations.c b/src/common_audio/signal_processing_library/main/source/vector_scaling_operations.c deleted file mode 100644 index 20d239c..0000000 --- a/src/common_audio/signal_processing_library/main/source/vector_scaling_operations.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains implementations of the functions - * WebRtcSpl_VectorBitShiftW16() - * WebRtcSpl_VectorBitShiftW32() - * WebRtcSpl_VectorBitShiftW32ToW16() - * WebRtcSpl_ScaleVector() - * WebRtcSpl_ScaleVectorWithSat() - * WebRtcSpl_ScaleAndAddVectors() - * - * The description header can be found in signal_processing_library.h - * - */ - -#include "signal_processing_library.h" - -void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16 *res, - WebRtc_Word16 length, - G_CONST WebRtc_Word16 *in, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts > 0) - { - for (i = length; i > 0; i--) - { - (*res++) = ((*in++) >> right_shifts); - } - } else - { - for (i = length; i > 0; i--) - { - (*res++) = ((*in++) << (-right_shifts)); - } - } -} - -void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32 *out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32 *in_vector, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts > 0) - { - for (i = vector_length; i > 0; i--) - { - (*out_vector++) = ((*in_vector++) >> right_shifts); - } - } else - { - for (i = vector_length; i > 0; i--) - { - (*out_vector++) = ((*in_vector++) << (-right_shifts)); - } - } -} - -void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16 *res, - WebRtc_Word16 length, - G_CONST WebRtc_Word32 *in, - WebRtc_Word16 right_shifts) -{ - int i; - - if (right_shifts >= 0) - { - for (i = length; i > 0; i--) - { - (*res++) = (WebRtc_Word16)((*in++) >> right_shifts); - } - } else - { - WebRtc_Word16 left_shifts = -right_shifts; - for (i = length; i > 0; i--) - { - (*res++) = (WebRtc_Word16)((*in++) << left_shifts); - } - } -} - -void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, - WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, - WebRtc_Word16 right_shifts) -{ - // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts - int i; - G_CONST WebRtc_Word16 *inptr; - WebRtc_Word16 *outptr; - - inptr = in_vector; - outptr = out_vector; - - for (i = 0; i < in_vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); - } -} - -void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, - WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, - WebRtc_Word16 right_shifts) -{ - // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts - int i; - WebRtc_Word32 tmpW32; - G_CONST WebRtc_Word16 *inptr; - WebRtc_Word16 *outptr; - - inptr = in_vector; - outptr = out_vector; - - for (i = 0; i < in_vector_length; i++) - { - tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); - (*outptr++) = WebRtcSpl_SatW32ToW16(tmpW32); - } -} - -void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16 *in1, WebRtc_Word16 gain1, int shift1, - G_CONST WebRtc_Word16 *in2, WebRtc_Word16 gain2, int shift2, - WebRtc_Word16 *out, int vector_length) -{ - // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2 - int i; - G_CONST WebRtc_Word16 *in1ptr; - G_CONST WebRtc_Word16 *in2ptr; - WebRtc_Word16 *outptr; - - in1ptr = in1; - in2ptr = in2; - outptr = out; - - for (i = 0; i < vector_length; i++) - { - (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2); - } -} diff --git a/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_1024_8.c b/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_1024_8.c deleted file mode 100644 index b587380..0000000 --- a/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_1024_8.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the Q14 radix-8 tables used in ARM9e optimizations. - * - */ - -extern const int s_Q14S_8; -const int s_Q14S_8 = 1024; -extern const unsigned short t_Q14S_8[2032]; -const unsigned short t_Q14S_8[2032] = { - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , - 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , - 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , - 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , - 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , - 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , - 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , - 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , - 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , - 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , - 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , - 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , - 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , - 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , - 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , - 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , - 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b , - 0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 , - 0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e , - 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , - 0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 , - 0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 , - 0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 , - 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , - 0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 , - 0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 , - 0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 , - 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , - 0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 , - 0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c , - 0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 , - 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , - 0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e , - 0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 , - 0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 , - 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , - 0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 , - 0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a , - 0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 , - 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , - 0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef , - 0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 , - 0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 , - 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , - 0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 , - 0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b , - 0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 , - 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , - 0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd , - 0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 , - 0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 , - 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , - 0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d , - 0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f , - 0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b , - 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , - 0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 , - 0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb , - 0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff , - 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , - 0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 , - 0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 , - 0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 , - 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , - 0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 , - 0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf , - 0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 , - 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , - 0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d , - 0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 , - 0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 , - 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , - 0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b , - 0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 , - 0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 , - 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , - 0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 , - 0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 , - 0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 , - 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , - 0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f , - 0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce , - 0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe , - 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , - 0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 , - 0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d , - 0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a , - 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , - 0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 , - 0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef , - 0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 , - 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , - 0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 , - 0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 , - 0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca , - 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , - 0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b , - 0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 , - 0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e , - 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , - 0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 , - 0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e , - 0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 , - 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , - 0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 , - 0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f , - 0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf , - 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , - 0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d , - 0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed , - 0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 , - 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , - 0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 , - 0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a , - 0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 , - 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , - 0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 , - 0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 , - 0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f , - 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , - 0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b , - 0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df , - 0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 , - 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , - 0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 , - 0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c , - 0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 , - 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , - 0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 , - 0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 , - 0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 , - 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , - 0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d , - 0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a , - 0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b , - 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , - 0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d , - 0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e , - 0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 , - 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , - 0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 , - 0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c , - 0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b , - 0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 , - 0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 , - 0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 , - 0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 , - 0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e , - 0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa , - 0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 , - 0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 , - 0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b , - 0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 , - 0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c , - 0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 , - 0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca , - 0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee , - 0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 , - 0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 , - 0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 , - 0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 , - 0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 , - 0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab , - 0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 , - 0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db , - 0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef , - 0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 , - 0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 , - 0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 , - 0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b , - 0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 , - 0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a , - 0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d , - 0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d , - 0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b , - 0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 , - 0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c , - 0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 , - 0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 , - 0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe , - 0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 , - 0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce , - 0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 , - 0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f , - 0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a , - 0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 , - 0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 , - 0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 , - 0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf , - 0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 , - 0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 , - 0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 , - 0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 , - 0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 , - 0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 , - 0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 , - 0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e , - 0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 , - 0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 , - 0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b , - 0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 , - 0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 , - 0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd , - 0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 , - 0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 , - 0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 , - 0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa , - 0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d , - 0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda , - 0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 , - 0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 , - 0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 , - 0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b , - 0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf , - 0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc , - 0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 , - 0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 , - 0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 , - 0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd , - 0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 , - 0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d , - 0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 , - 0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 , - 0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 , - 0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb , - 0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec , - 0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 , - 0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff , - 0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 , - 0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb , - 0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 , - 0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 , - 0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc , - 0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 , - 0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 , - 0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b , - 0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 , - 0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f , - 0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 , - 0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d , - 0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c , - 0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 , - 0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 , - 0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 , - 0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 , - 0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 , - 0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 , - 0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd , - 0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 , - 0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 , - 0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab , - 0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 , - 0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 , - 0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b , - 0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 , - 0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 , - 0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e , - 0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 , - 0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 , - 0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 , - 0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff , - 0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 , - 0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 , - 0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef , - 0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 , - 0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 , - 0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 , - 0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 , - 0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 , - 0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a , - 0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 , - 0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 , - 0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 , - 0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb , - 0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a , - 0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 , - 0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c , - 0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 , - 0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 , - 0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e , - 0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 , - 0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e , - 0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 , - 0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 , - 0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 , - 0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c , - 0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 , - 0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 , - 0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c , - 0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d , - 0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b , - 0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 , - 0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 , - 0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 , - 0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee , - 0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 , - 0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 , - 0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 , - 0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 , - 0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 , - 0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b , - 0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 , - 0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf , - 0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 , - 0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e , - 0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 , - 0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 , - 0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e , - 0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 , - 0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 , - 0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 , - 0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b , - 0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e , - 0xbf38,0x00c9 ,0xbf9c,0x0065 }; - - -extern const int s_Q14R_8; -const int s_Q14R_8 = 1024; -extern const unsigned short t_Q14R_8[2032]; -const unsigned short t_Q14R_8[2032] = { - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , - 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , - 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , - 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , - 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , - 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , - 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , - 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , - 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , - 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , - 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , - 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , - 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , - 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , - 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , - 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , - 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , - 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , - 0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b , - 0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 , - 0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e , - 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , - 0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 , - 0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 , - 0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 , - 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , - 0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 , - 0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 , - 0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 , - 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , - 0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 , - 0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c , - 0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 , - 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , - 0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e , - 0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 , - 0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 , - 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , - 0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 , - 0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a , - 0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 , - 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , - 0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef , - 0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 , - 0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 , - 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , - 0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 , - 0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b , - 0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 , - 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , - 0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd , - 0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 , - 0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 , - 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , - 0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d , - 0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f , - 0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b , - 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , - 0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 , - 0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb , - 0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff , - 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , - 0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 , - 0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 , - 0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 , - 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , - 0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 , - 0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf , - 0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 , - 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , - 0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d , - 0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 , - 0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 , - 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , - 0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b , - 0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 , - 0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 , - 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , - 0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 , - 0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 , - 0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 , - 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , - 0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f , - 0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce , - 0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe , - 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , - 0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 , - 0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d , - 0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a , - 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , - 0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 , - 0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef , - 0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 , - 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , - 0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 , - 0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 , - 0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca , - 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , - 0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b , - 0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 , - 0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e , - 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , - 0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 , - 0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e , - 0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 , - 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , - 0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 , - 0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f , - 0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf , - 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , - 0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d , - 0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed , - 0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 , - 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , - 0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 , - 0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a , - 0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 , - 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , - 0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 , - 0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 , - 0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f , - 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , - 0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b , - 0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df , - 0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 , - 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , - 0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 , - 0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c , - 0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 , - 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , - 0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 , - 0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 , - 0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 , - 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , - 0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d , - 0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a , - 0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b , - 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , - 0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d , - 0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e , - 0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 , - 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , - 0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 , - 0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c , - 0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b , - 0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 , - 0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 , - 0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 , - 0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 , - 0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e , - 0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa , - 0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 , - 0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 , - 0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b , - 0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 , - 0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c , - 0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 , - 0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca , - 0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee , - 0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 , - 0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 , - 0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 , - 0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 , - 0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 , - 0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab , - 0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 , - 0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db , - 0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef , - 0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 , - 0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 , - 0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 , - 0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b , - 0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 , - 0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a , - 0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d , - 0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d , - 0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b , - 0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 , - 0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c , - 0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 , - 0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 , - 0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe , - 0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 , - 0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce , - 0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 , - 0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f , - 0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a , - 0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 , - 0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 , - 0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 , - 0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf , - 0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 , - 0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 , - 0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 , - 0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 , - 0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 , - 0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 , - 0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 , - 0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e , - 0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 , - 0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 , - 0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b , - 0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 , - 0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 , - 0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd , - 0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 , - 0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 , - 0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 , - 0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa , - 0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d , - 0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda , - 0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 , - 0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 , - 0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 , - 0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b , - 0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf , - 0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc , - 0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 , - 0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 , - 0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 , - 0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd , - 0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 , - 0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d , - 0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 , - 0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 , - 0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 , - 0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb , - 0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec , - 0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 , - 0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff , - 0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 , - 0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb , - 0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 , - 0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 , - 0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc , - 0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 , - 0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 , - 0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b , - 0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 , - 0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f , - 0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 , - 0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d , - 0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c , - 0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 , - 0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 , - 0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 , - 0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 , - 0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 , - 0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 , - 0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd , - 0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 , - 0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 , - 0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab , - 0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 , - 0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 , - 0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b , - 0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 , - 0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 , - 0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e , - 0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 , - 0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 , - 0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 , - 0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff , - 0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 , - 0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 , - 0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef , - 0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 , - 0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 , - 0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 , - 0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 , - 0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 , - 0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a , - 0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 , - 0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 , - 0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 , - 0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb , - 0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a , - 0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 , - 0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c , - 0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 , - 0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 , - 0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e , - 0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 , - 0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e , - 0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 , - 0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 , - 0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 , - 0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c , - 0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 , - 0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 , - 0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c , - 0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d , - 0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b , - 0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 , - 0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 , - 0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 , - 0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee , - 0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 , - 0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 , - 0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 , - 0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 , - 0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 , - 0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b , - 0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 , - 0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf , - 0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 , - 0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e , - 0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 , - 0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 , - 0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e , - 0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 , - 0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 , - 0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 , - 0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b , - 0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e , - 0xc001,0x00c9 ,0xc000,0x0065 }; diff --git a/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_rad.c b/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_rad.c deleted file mode 100644 index 13fbd9f..0000000 --- a/src/common_audio/signal_processing_library/main/source/webrtc_fft_t_rad.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the Q14 radix-2 tables used in ARM9E optimization routines. - * - */ - -extern const unsigned short t_Q14S_rad8[2]; -const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 }; - -//extern const int t_Q30S_rad8[2]; -//const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd }; - -extern const unsigned short t_Q14R_rad8[2]; -const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 }; - -//extern const int t_Q30R_rad8[2]; -//const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd }; diff --git a/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.cc b/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.cc deleted file mode 100644 index e4348eb..0000000 --- a/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.cc +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file contains the SPL unit_test. - * - */ - -#include "unit_test.h" -#include "signal_processing_library.h" - -class SplEnvironment : public ::testing::Environment { - public: - virtual void SetUp() { - } - virtual void TearDown() { - } -}; - -SplTest::SplTest() -{ -} - -void SplTest::SetUp() { -} - -void SplTest::TearDown() { -} - -TEST_F(SplTest, MacroTest) { - // Macros with inputs. - int A = 10; - int B = 21; - int a = -3; - int b = WEBRTC_SPL_WORD32_MAX; - int nr = 2; - int d_ptr1 = 0; - int d_ptr2 = 0; - - EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B)); - EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B)); - - EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a)); - EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a)); - EXPECT_EQ(0, WEBRTC_SPL_GET_BYTE(&B, nr)); - WEBRTC_SPL_SET_BYTE(&d_ptr2, 1, nr); - EXPECT_EQ(65536, d_ptr2); - - EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B)); - EXPECT_EQ(-2147483645, WEBRTC_SPL_MUL(a, b)); - EXPECT_EQ(-2147483645, WEBRTC_SPL_UMUL(a, b)); - b = WEBRTC_SPL_WORD16_MAX >> 1; - EXPECT_EQ(65535, WEBRTC_SPL_UMUL_RSFT16(a, b)); - EXPECT_EQ(1073627139, WEBRTC_SPL_UMUL_16_16(a, b)); - EXPECT_EQ(16382, WEBRTC_SPL_UMUL_16_16_RSFT16(a, b)); - EXPECT_EQ(-49149, WEBRTC_SPL_UMUL_32_16(a, b)); - EXPECT_EQ(65535, WEBRTC_SPL_UMUL_32_16_RSFT16(a, b)); - EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b)); - - a = b; - b = -3; - EXPECT_EQ(-5461, WEBRTC_SPL_DIV(a, b)); - EXPECT_EQ(0, WEBRTC_SPL_UDIV(a, b)); - - EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b)); - EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b)); - EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b)); - EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b)); - - int a32 = WEBRTC_SPL_WORD32_MAX; - int a32a = (WEBRTC_SPL_WORD32_MAX >> 16); - int a32b = (WEBRTC_SPL_WORD32_MAX & 0x0000ffff); - EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, A)); - EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, A)); - - EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b)); - EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2)); - - EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2)); - EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b)); - - EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W32(a, b)); - EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B)); - EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A)); - EXPECT_EQ(-49149, WEBRTC_SPL_MUL_32_16(a, b)); - - EXPECT_EQ(16386, WEBRTC_SPL_SUB_SAT_W32(a, b)); - EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W16(a, b)); - EXPECT_EQ(16386, WEBRTC_SPL_SUB_SAT_W16(a, b)); - - EXPECT_TRUE(WEBRTC_SPL_IS_NEG(b)); - - // Shifting with negative numbers allowed - // Positive means left shift - EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W16(a, 1)); - EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, 1)); - - // Shifting with negative numbers not allowed - // We cannot do casting here due to signed/unsigned problem - EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W16(a, 1)); - EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W16(a, 1)); - EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W32(a, 1)); - EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1)); - - EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_U16(a, 1)); - EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_U16(a, 1)); - EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_U32(a, 1)); - EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_U32(a, 1)); - - EXPECT_EQ(1470, WEBRTC_SPL_RAND(A)); -} - -TEST_F(SplTest, InlineTest) { - - WebRtc_Word16 a = 121; - WebRtc_Word16 b = -17; - WebRtc_Word32 A = 111121; - WebRtc_Word32 B = -1711; - char bVersion[8]; - - EXPECT_EQ(104, WebRtcSpl_AddSatW16(a, b)); - EXPECT_EQ(138, WebRtcSpl_SubSatW16(a, b)); - - EXPECT_EQ(109410, WebRtcSpl_AddSatW32(A, B)); - EXPECT_EQ(112832, WebRtcSpl_SubSatW32(A, B)); - - EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(A)); - EXPECT_EQ(14, WebRtcSpl_NormW32(A)); - EXPECT_EQ(4, WebRtcSpl_NormW16(B)); - EXPECT_EQ(15, WebRtcSpl_NormU32(A)); - - EXPECT_EQ(0, WebRtcSpl_get_version(bVersion, 8)); -} - -TEST_F(SplTest, MathOperationsTest) { - - int A = 117; - WebRtc_Word32 num = 117; - WebRtc_Word32 den = -5; - WebRtc_UWord16 denU = 5; - EXPECT_EQ(10, WebRtcSpl_Sqrt(A)); - EXPECT_EQ(10, WebRtcSpl_SqrtFloor(A)); - - - EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num)); - EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (WebRtc_Word16)den)); - EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (WebRtc_Word16)den)); - EXPECT_EQ(23, WebRtcSpl_DivU32U16(num, denU)); - EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256)); -} - -TEST_F(SplTest, BasicArrayOperationsTest) { - - - const int kVectorSize = 4; - int B[] = {4, 12, 133, 1100}; - int Bs[] = {2, 6, 66, 550}; - WebRtc_UWord8 b8[kVectorSize]; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; - - WebRtc_UWord8 bTmp8[kVectorSize]; - WebRtc_Word16 bTmp16[kVectorSize]; - WebRtc_Word32 bTmp32[kVectorSize]; - - WebRtcSpl_MemSetW16(b16, 3, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(3, b16[kk]); - } - EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW16(b16, kVectorSize)); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(0, b16[kk]); - } - EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW16(b16, kVectorSize)); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(1, b16[kk]); - } - WebRtcSpl_MemSetW32(b32, 3, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(3, b32[kk]); - } - EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW32(b32, kVectorSize)); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(0, b32[kk]); - } - EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW32(b32, kVectorSize)); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(1, b32[kk]); - } - for (int kk = 0; kk < kVectorSize; ++kk) { - bTmp8[kk] = (WebRtc_Word8)kk; - bTmp16[kk] = (WebRtc_Word16)kk; - bTmp32[kk] = (WebRtc_Word32)kk; - } - WEBRTC_SPL_MEMCPY_W8(b8, bTmp8, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(b8[kk], bTmp8[kk]); - } - WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(b16[kk], bTmp16[kk]); - } -// WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize); -// for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(b32[kk], bTmp32[kk]); -// } - EXPECT_EQ(2, WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16)); - for (int kk = 0; kk < 2; ++kk) { - EXPECT_EQ(kk+2, bTmp16[kk]); - } - - for (int kk = 0; kk < kVectorSize; ++kk) { - b32[kk] = B[kk]; - b16[kk] = (WebRtc_Word16)B[kk]; - } - WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((B[kk]>>1), bTmp16[kk]); - } - WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((B[kk]>>1), bTmp16[kk]); - } - WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((B[kk]>>1), bTmp32[kk]); - } - - WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(b16[3-kk], bTmp16[kk]); - } - -} - -TEST_F(SplTest, MinMaxOperationsTest) { - - - const int kVectorSize = 4; - int B[] = {4, 12, 133, -1100}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; - - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = B[kk]; - b32[kk] = B[kk]; - } - - EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW16(b16, kVectorSize)); - EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW32(b32, kVectorSize)); - EXPECT_EQ(133, WebRtcSpl_MaxValueW16(b16, kVectorSize)); - EXPECT_EQ(133, WebRtcSpl_MaxValueW32(b32, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MaxAbsIndexW16(b16, kVectorSize)); - EXPECT_EQ(2, WebRtcSpl_MaxIndexW16(b16, kVectorSize)); - EXPECT_EQ(2, WebRtcSpl_MaxIndexW32(b32, kVectorSize)); - - EXPECT_EQ(-1100, WebRtcSpl_MinValueW16(b16, kVectorSize)); - EXPECT_EQ(-1100, WebRtcSpl_MinValueW32(b32, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MinIndexW16(b16, kVectorSize)); - EXPECT_EQ(3, WebRtcSpl_MinIndexW32(b32, kVectorSize)); - - EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1)); - -} - -TEST_F(SplTest, VectorOperationsTest) { - - - const int kVectorSize = 4; - int B[] = {4, 12, 133, 1100}; - WebRtc_Word16 a16[kVectorSize]; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; - WebRtc_Word16 bTmp16[kVectorSize]; - - for (int kk = 0; kk < kVectorSize; ++kk) { - a16[kk] = B[kk]; - b16[kk] = B[kk]; - } - - WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((B[kk]*3+7)>>2, bTmp16[kk]); - } - WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((B[kk]*3+B[kk]*2+2)>>2, bTmp16[kk]); - } - - WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]); - } - - WebRtcSpl_CrossCorrelation(b32, b16, bTmp16, kVectorSize, 2, 2, 0); - for (int kk = 0; kk < 2; ++kk) { - EXPECT_EQ(614236, b32[kk]); - } -// EXPECT_EQ(, WebRtcSpl_DotProduct(b16, bTmp16, 4)); - EXPECT_EQ(306962, WebRtcSpl_DotProductWithScale(b16, b16, kVectorSize, 2)); - - WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]); - } - WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]); - } - WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(((a16[kk]*13)>>2)+((b16[kk]*7)>>2), bTmp16[kk]); - } - - WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(B[kk] >> 1, bTmp16[kk]); - } - WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((a16[kk]*b16[3-kk])>>2, bTmp16[kk]); - } - WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ((a16[kk]*b16[kk])>>6, bTmp16[kk]); - } - - WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16); - for (int kk = 0; kk < kVectorSize - 1; ++kk) { - EXPECT_EQ(32767, bTmp16[kk]); - } - EXPECT_EQ(32749, bTmp16[kVectorSize - 1]); -} - -TEST_F(SplTest, EstimatorsTest) { - - - const int kVectorSize = 4; - int B[] = {4, 12, 133, 1100}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; - WebRtc_Word16 bTmp16[kVectorSize]; - - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = B[kk]; - b32[kk] = B[kk]; - } - - EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(b32, b16, bTmp16, 2)); - -} - -TEST_F(SplTest, FilterTest) { - - - const int kVectorSize = 4; - WebRtc_Word16 A[] = {1, 2, 33, 100}; - WebRtc_Word16 A5[] = {1, 2, 33, 100, -5}; - WebRtc_Word16 B[] = {4, 12, 133, 110}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word16 bTmp16[kVectorSize]; - WebRtc_Word16 bTmp16Low[kVectorSize]; - WebRtc_Word16 bState[kVectorSize]; - WebRtc_Word16 bStateLow[kVectorSize]; - - WebRtcSpl_ZerosArrayW16(bState, kVectorSize); - WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize); - - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = A[kk]; - } - - // MA filters - WebRtcSpl_FilterMAFastQ12(b16, bTmp16, B, kVectorSize, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { - //EXPECT_EQ(aTmp16[kk], bTmp16[kk]); - } - // AR filters - WebRtcSpl_FilterARFastQ12(b16, bTmp16, A, kVectorSize, kVectorSize); - for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); - } - EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5, - 5, - b16, - kVectorSize, - bState, - kVectorSize, - bStateLow, - kVectorSize, - bTmp16, - bTmp16Low, - kVectorSize)); - -} - -TEST_F(SplTest, RandTest) { - - - const int kVectorSize = 4; - WebRtc_Word16 BU[] = {3653, 12446, 8525, 30691}; - WebRtc_Word16 BN[] = {3459, -11689, -258, -3738}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_UWord32 bSeed = 100000; - - EXPECT_EQ(464449057, WebRtcSpl_IncreaseSeed(&bSeed)); - EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed)); - EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed)); - EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed)); - for (int kk = 0; kk < kVectorSize; ++kk) { - EXPECT_EQ(BU[kk], b16[kk]); - } -} - -TEST_F(SplTest, SignalProcessingTest) { - - - const int kVectorSize = 4; - int A[] = {1, 2, 33, 100}; - WebRtc_Word16 b16[kVectorSize]; - WebRtc_Word32 b32[kVectorSize]; - - WebRtc_Word16 bTmp16[kVectorSize]; - WebRtc_Word32 bTmp32[kVectorSize]; - - int bScale = 0; - - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = A[kk]; - b32[kk] = A[kk]; - } - - EXPECT_EQ(2, WebRtcSpl_AutoCorrelation(b16, kVectorSize, 1, bTmp32, &bScale)); - WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16); -// for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); -// } - WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16); -// for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(a16[kk], b16[kk]); -// } - WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16); -// for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); -// } - WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize); -// for (int kk = 0; kk < kVectorSize; ++kk) { -// EXPECT_EQ(aTmp16[kk], bTmp16[kk]); -// } - - for (int kk = 0; kk < kVectorSize; ++kk) { - b16[kk] = A[kk]; - } - EXPECT_EQ(11094 , WebRtcSpl_Energy(b16, kVectorSize, &bScale)); - EXPECT_EQ(0, bScale); -} - -TEST_F(SplTest, FFTTest) { - - - WebRtc_Word16 B[] = {1, 2, 33, 100, - 2, 3, 34, 101, - 3, 4, 35, 102, - 4, 5, 36, 103}; - - EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1)); -// for (int kk = 0; kk < 16; ++kk) { -// EXPECT_EQ(A[kk], B[kk]); -// } - EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1)); -// for (int kk = 0; kk < 16; ++kk) { -// EXPECT_EQ(A[kk], B[kk]); -// } - WebRtcSpl_ComplexBitReverse(B, 3); - for (int kk = 0; kk < 16; ++kk) { - //EXPECT_EQ(A[kk], B[kk]); - } -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - SplEnvironment* env = new SplEnvironment; - ::testing::AddGlobalTestEnvironment(env); - - return RUN_ALL_TESTS(); -} diff --git a/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.h b/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.h deleted file mode 100644 index d7babe7..0000000 --- a/src/common_audio/signal_processing_library/main/test/unit_test/unit_test.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This header file contains the function WebRtcSpl_CopyFromBeginU8(). - * The description header can be found in signal_processing_library.h - * - */ - -#ifndef WEBRTC_SPL_UNIT_TEST_H_ -#define WEBRTC_SPL_UNIT_TEST_H_ - -#include - -class SplTest: public ::testing::Test -{ -protected: - SplTest(); - virtual void SetUp(); - virtual void TearDown(); -}; - -#endif // WEBRTC_SPL_UNIT_TEST_H_ diff --git a/src/common_audio/vad/Makefile.am b/src/common_audio/vad/Makefile.am deleted file mode 100644 index deab054..0000000 --- a/src/common_audio/vad/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -noinst_LTLIBRARIES = libvad.la - -libvad_la_SOURCES = main/interface/webrtc_vad.h \ - main/source/webrtc_vad.c \ - main/source/vad_core.c \ - main/source/vad_core.h \ - main/source/vad_defines.h \ - main/source/vad_filterbank.c \ - main/source/vad_filterbank.h \ - main/source/vad_gmm.c \ - main/source/vad_gmm.h \ - main/source/vad_sp.c \ - main/source/vad_sp.h -libvad_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS) \ - -I$(top_srcdir)/src/common_audio/signal_processing_library/main/interface diff --git a/src/common_audio/vad/main/interface/webrtc_vad.h b/src/common_audio/vad/main/interface/webrtc_vad.h deleted file mode 100644 index 6e3eb74..0000000 --- a/src/common_audio/vad/main/interface/webrtc_vad.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the VAD API calls. Specific function calls are given below. - */ - -#ifndef WEBRTC_VAD_WEBRTC_VAD_H_ -#define WEBRTC_VAD_WEBRTC_VAD_H_ - -#include "typedefs.h" - -typedef struct WebRtcVadInst VadInst; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/**************************************************************************** - * WebRtcVad_get_version(...) - * - * This function returns the version number of the code. - * - * Output: - * - version : Pointer to a buffer where the version info will - * be stored. - * Input: - * - size_bytes : Size of the buffer. - * - */ -WebRtc_Word16 WebRtcVad_get_version(char *version, size_t size_bytes); - -/**************************************************************************** - * WebRtcVad_AssignSize(...) - * - * This functions get the size needed for storing the instance for encoder - * and decoder, respectively - * - * Input/Output: - * - size_in_bytes : Pointer to integer where the size is returned - * - * Return value : 0 - */ -WebRtc_Word16 WebRtcVad_AssignSize(int *size_in_bytes); - -/**************************************************************************** - * WebRtcVad_Assign(...) - * - * This functions Assigns memory for the instances. - * - * Input: - * - vad_inst_addr : Address to where to assign memory - * Output: - * - vad_inst : Pointer to the instance that should be created - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_Assign(VadInst **vad_inst, void *vad_inst_addr); - -/**************************************************************************** - * WebRtcVad_Create(...) - * - * This function creates an instance to the VAD structure - * - * Input: - * - vad_inst : Pointer to VAD instance that should be created - * - * Output: - * - vad_inst : Pointer to created VAD instance - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_Create(VadInst **vad_inst); - -/**************************************************************************** - * WebRtcVad_Free(...) - * - * This function frees the dynamic memory of a specified VAD instance - * - * Input: - * - vad_inst : Pointer to VAD instance that should be freed - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_Free(VadInst *vad_inst); - -/**************************************************************************** - * WebRtcVad_Init(...) - * - * This function initializes a VAD instance - * - * Input: - * - vad_inst : Instance that should be initialized - * - * Output: - * - vad_inst : Initialized instance - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_Init(VadInst *vad_inst); - -/**************************************************************************** - * WebRtcVad_set_mode(...) - * - * This function initializes a VAD instance - * - * Input: - * - vad_inst : VAD instance - * - mode : Aggressiveness setting (0, 1, 2, or 3) - * - * Output: - * - vad_inst : Initialized instance - * - * Return value : 0 - Ok - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_set_mode(VadInst *vad_inst, WebRtc_Word16 mode); - -/**************************************************************************** - * WebRtcVad_Process(...) - * - * This functions does a VAD for the inserted speech frame - * - * Input - * - vad_inst : VAD Instance. Needs to be initiated before call. - * - fs : sampling frequency (Hz): 8000, 16000, or 32000 - * - speech_frame : Pointer to speech frame buffer - * - frame_length : Length of speech frame buffer in number of samples - * - * Output: - * - vad_inst : Updated VAD instance - * - * Return value : 1 - Active Voice - * 0 - Non-active Voice - * -1 - Error - */ -WebRtc_Word16 WebRtcVad_Process(VadInst *vad_inst, - WebRtc_Word16 fs, - WebRtc_Word16 *speech_frame, - WebRtc_Word16 frame_length); - -#ifdef __cplusplus -} -#endif - -#endif // WEBRTC_VAD_WEBRTC_VAD_H_ diff --git a/src/common_audio/vad/main/source/vad.gypi b/src/common_audio/vad/main/source/vad.gypi deleted file mode 100644 index 442d8a9..0000000 --- a/src/common_audio/vad/main/source/vad.gypi +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'targets': [ - { - 'target_name': 'vad', - 'type': '<(library)', - 'dependencies': [ - 'spl', - ], - 'include_dirs': [ - '../interface', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../interface', - ], - }, - 'sources': [ - '../interface/webrtc_vad.h', - 'webrtc_vad.c', - 'vad_core.c', - 'vad_core.h', - 'vad_defines.h', - 'vad_filterbank.c', - 'vad_filterbank.h', - 'vad_gmm.c', - 'vad_gmm.h', - 'vad_sp.c', - 'vad_sp.h', - ], - }, - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/common_audio/vad/main/source/vad_core.c b/src/common_audio/vad/main/source/vad_core.c deleted file mode 100644 index e05c296..0000000 --- a/src/common_audio/vad/main/source/vad_core.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the implementation of the core functionality in VAD. - * For function description, see vad_core.h. - */ - -#include "vad_core.h" - -#include "signal_processing_library.h" -#include "typedefs.h" -#include "vad_defines.h" -#include "vad_filterbank.h" -#include "vad_gmm.h" -#include "vad_sp.h" - -// Spectrum Weighting -static const WebRtc_Word16 kSpectrumWeight[6] = { 6, 8, 10, 12, 14, 16 }; -static const WebRtc_Word16 kNoiseUpdateConst = 655; // Q15 -static const WebRtc_Word16 kSpeechUpdateConst = 6554; // Q15 -static const WebRtc_Word16 kBackEta = 154; // Q8 -// Minimum difference between the two models, Q5 -static const WebRtc_Word16 kMinimumDifference[6] = { - 544, 544, 576, 576, 576, 576 }; -// Upper limit of mean value for speech model, Q7 -static const WebRtc_Word16 kMaximumSpeech[6] = { - 11392, 11392, 11520, 11520, 11520, 11520 }; -// Minimum value for mean value -static const WebRtc_Word16 kMinimumMean[2] = { 640, 768 }; -// Upper limit of mean value for noise model, Q7 -static const WebRtc_Word16 kMaximumNoise[6] = { - 9216, 9088, 8960, 8832, 8704, 8576 }; -// Start values for the Gaussian models, Q7 -// Weights for the two Gaussians for the six channels (noise) -static const WebRtc_Word16 kNoiseDataWeights[12] = { - 34, 62, 72, 66, 53, 25, 94, 66, 56, 62, 75, 103 }; -// Weights for the two Gaussians for the six channels (speech) -static const WebRtc_Word16 kSpeechDataWeights[12] = { - 48, 82, 45, 87, 50, 47, 80, 46, 83, 41, 78, 81 }; -// Means for the two Gaussians for the six channels (noise) -static const WebRtc_Word16 kNoiseDataMeans[12] = { - 6738, 4892, 7065, 6715, 6771, 3369, 7646, 3863, 7820, 7266, 5020, 4362 }; -// Means for the two Gaussians for the six channels (speech) -static const WebRtc_Word16 kSpeechDataMeans[12] = { - 8306, 10085, 10078, 11823, 11843, 6309, 9473, 9571, 10879, 7581, 8180, 7483 -}; -// Stds for the two Gaussians for the six channels (noise) -static const WebRtc_Word16 kNoiseDataStds[12] = { - 378, 1064, 493, 582, 688, 593, 474, 697, 475, 688, 421, 455 }; -// Stds for the two Gaussians for the six channels (speech) -static const WebRtc_Word16 kSpeechDataStds[12] = { - 555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540, 1079, 850 }; - -static const int kInitCheck = 42; - -// Initialize VAD -int WebRtcVad_InitCore(VadInstT *inst, short mode) -{ - int i; - - // Initialization of struct - inst->vad = 1; - inst->frame_counter = 0; - inst->over_hang = 0; - inst->num_of_speech = 0; - - // Initialization of downsampling filter state - inst->downsampling_filter_states[0] = 0; - inst->downsampling_filter_states[1] = 0; - inst->downsampling_filter_states[2] = 0; - inst->downsampling_filter_states[3] = 0; - - // Read initial PDF parameters - for (i = 0; i < NUM_TABLE_VALUES; i++) - { - inst->noise_means[i] = kNoiseDataMeans[i]; - inst->speech_means[i] = kSpeechDataMeans[i]; - inst->noise_stds[i] = kNoiseDataStds[i]; - inst->speech_stds[i] = kSpeechDataStds[i]; - } - - // Index and Minimum value vectors are initialized - for (i = 0; i < 16 * NUM_CHANNELS; i++) - { - inst->low_value_vector[i] = 10000; - inst->index_vector[i] = 0; - } - - for (i = 0; i < 5; i++) - { - inst->upper_state[i] = 0; - inst->lower_state[i] = 0; - } - - for (i = 0; i < 4; i++) - { - inst->hp_filter_state[i] = 0; - } - - // Init mean value memory, for FindMin function - inst->mean_value[0] = 1600; - inst->mean_value[1] = 1600; - inst->mean_value[2] = 1600; - inst->mean_value[3] = 1600; - inst->mean_value[4] = 1600; - inst->mean_value[5] = 1600; - - if (mode == 0) - { - // Quality mode - inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_Q; - inst->individual[1] = INDIVIDUAL_20MS_Q; - inst->individual[2] = INDIVIDUAL_30MS_Q; - - inst->total[0] = TOTAL_10MS_Q; - inst->total[1] = TOTAL_20MS_Q; - inst->total[2] = TOTAL_30MS_Q; - } else if (mode == 1) - { - // Low bitrate mode - inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_LBR; - inst->individual[1] = INDIVIDUAL_20MS_LBR; - inst->individual[2] = INDIVIDUAL_30MS_LBR; - - inst->total[0] = TOTAL_10MS_LBR; - inst->total[1] = TOTAL_20MS_LBR; - inst->total[2] = TOTAL_30MS_LBR; - } else if (mode == 2) - { - // Aggressive mode - inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_AGG; - inst->individual[1] = INDIVIDUAL_20MS_AGG; - inst->individual[2] = INDIVIDUAL_30MS_AGG; - - inst->total[0] = TOTAL_10MS_AGG; - inst->total[1] = TOTAL_20MS_AGG; - inst->total[2] = TOTAL_30MS_AGG; - } else - { - // Very aggressive mode - inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_VAG; - inst->individual[1] = INDIVIDUAL_20MS_VAG; - inst->individual[2] = INDIVIDUAL_30MS_VAG; - - inst->total[0] = TOTAL_10MS_VAG; - inst->total[1] = TOTAL_20MS_VAG; - inst->total[2] = TOTAL_30MS_VAG; - } - - inst->init_flag = kInitCheck; - - return 0; -} - -// Set aggressiveness mode -int WebRtcVad_set_mode_core(VadInstT *inst, short mode) -{ - - if (mode == 0) - { - // Quality mode - inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_Q; - inst->individual[1] = INDIVIDUAL_20MS_Q; - inst->individual[2] = INDIVIDUAL_30MS_Q; - - inst->total[0] = TOTAL_10MS_Q; - inst->total[1] = TOTAL_20MS_Q; - inst->total[2] = TOTAL_30MS_Q; - } else if (mode == 1) - { - // Low bitrate mode - inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_LBR; - inst->individual[1] = INDIVIDUAL_20MS_LBR; - inst->individual[2] = INDIVIDUAL_30MS_LBR; - - inst->total[0] = TOTAL_10MS_LBR; - inst->total[1] = TOTAL_20MS_LBR; - inst->total[2] = TOTAL_30MS_LBR; - } else if (mode == 2) - { - // Aggressive mode - inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_AGG; - inst->individual[1] = INDIVIDUAL_20MS_AGG; - inst->individual[2] = INDIVIDUAL_30MS_AGG; - - inst->total[0] = TOTAL_10MS_AGG; - inst->total[1] = TOTAL_20MS_AGG; - inst->total[2] = TOTAL_30MS_AGG; - } else if (mode == 3) - { - // Very aggressive mode - inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst - inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst - inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst - inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst - inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst - inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst - - inst->individual[0] = INDIVIDUAL_10MS_VAG; - inst->individual[1] = INDIVIDUAL_20MS_VAG; - inst->individual[2] = INDIVIDUAL_30MS_VAG; - - inst->total[0] = TOTAL_10MS_VAG; - inst->total[1] = TOTAL_20MS_VAG; - inst->total[2] = TOTAL_30MS_VAG; - } else - { - return -1; - } - - return 0; -} - -// Calculate VAD decision by first extracting feature values and then calculate -// probability for both speech and background noise. - -WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT *inst, WebRtc_Word16 *speech_frame, - int frame_length) -{ - WebRtc_Word16 len, vad; - WebRtc_Word16 speechWB[480]; // Downsampled speech frame: 960 samples (30ms in SWB) - WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) - - - // Downsample signal 32->16->8 before doing VAD - WebRtcVad_Downsampling(speech_frame, speechWB, &(inst->downsampling_filter_states[2]), - frame_length); - len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1); - - WebRtcVad_Downsampling(speechWB, speechNB, inst->downsampling_filter_states, len); - len = WEBRTC_SPL_RSHIFT_W16(len, 1); - - // Do VAD on an 8 kHz signal - vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); - - return vad; -} - -WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT *inst, WebRtc_Word16 *speech_frame, - int frame_length) -{ - WebRtc_Word16 len, vad; - WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) - - // Wideband: Downsample signal before doing VAD - WebRtcVad_Downsampling(speech_frame, speechNB, inst->downsampling_filter_states, - frame_length); - - len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1); - vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); - - return vad; -} - -WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT *inst, WebRtc_Word16 *speech_frame, - int frame_length) -{ - WebRtc_Word16 feature_vector[NUM_CHANNELS], total_power; - - // Get power in the bands - total_power = WebRtcVad_get_features(inst, speech_frame, frame_length, feature_vector); - - // Make a VAD - inst->vad = WebRtcVad_GmmProbability(inst, feature_vector, total_power, frame_length); - - return inst->vad; -} - -// Calculate probability for both speech and background noise, and perform a -// hypothesis-test. -WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT *inst, WebRtc_Word16 *feature_vector, - WebRtc_Word16 total_power, int frame_length) -{ - int n, k; - WebRtc_Word16 backval; - WebRtc_Word16 h0, h1; - WebRtc_Word16 ratvec, xval; - WebRtc_Word16 vadflag; - WebRtc_Word16 shifts0, shifts1; - WebRtc_Word16 tmp16, tmp16_1, tmp16_2; - WebRtc_Word16 diff, nr, pos; - WebRtc_Word16 nmk, nmk2, nmk3, smk, smk2, nsk, ssk; - WebRtc_Word16 delt, ndelt; - WebRtc_Word16 maxspe, maxmu; - WebRtc_Word16 deltaN[NUM_TABLE_VALUES], deltaS[NUM_TABLE_VALUES]; - WebRtc_Word16 ngprvec[NUM_TABLE_VALUES], sgprvec[NUM_TABLE_VALUES]; - WebRtc_Word32 h0test, h1test; - WebRtc_Word32 tmp32_1, tmp32_2; - WebRtc_Word32 dotVal; - WebRtc_Word32 nmid, smid; - WebRtc_Word32 probn[NUM_MODELS], probs[NUM_MODELS]; - WebRtc_Word16 *nmean1ptr, *nmean2ptr, *smean1ptr, *smean2ptr, *nstd1ptr, *nstd2ptr, - *sstd1ptr, *sstd2ptr; - WebRtc_Word16 overhead1, overhead2, individualTest, totalTest; - - // Set the thresholds to different values based on frame length - if (frame_length == 80) - { - // 80 input samples - overhead1 = inst->over_hang_max_1[0]; - overhead2 = inst->over_hang_max_2[0]; - individualTest = inst->individual[0]; - totalTest = inst->total[0]; - } else if (frame_length == 160) - { - // 160 input samples - overhead1 = inst->over_hang_max_1[1]; - overhead2 = inst->over_hang_max_2[1]; - individualTest = inst->individual[1]; - totalTest = inst->total[1]; - } else - { - // 240 input samples - overhead1 = inst->over_hang_max_1[2]; - overhead2 = inst->over_hang_max_2[2]; - individualTest = inst->individual[2]; - totalTest = inst->total[2]; - } - - if (total_power > MIN_ENERGY) - { // If signal present at all - - // Set pointers to the gaussian parameters - nmean1ptr = &inst->noise_means[0]; - nmean2ptr = &inst->noise_means[NUM_CHANNELS]; - smean1ptr = &inst->speech_means[0]; - smean2ptr = &inst->speech_means[NUM_CHANNELS]; - nstd1ptr = &inst->noise_stds[0]; - nstd2ptr = &inst->noise_stds[NUM_CHANNELS]; - sstd1ptr = &inst->speech_stds[0]; - sstd2ptr = &inst->speech_stds[NUM_CHANNELS]; - - vadflag = 0; - dotVal = 0; - for (n = 0; n < NUM_CHANNELS; n++) - { // For all channels - - pos = WEBRTC_SPL_LSHIFT_W16(n, 1); - xval = feature_vector[n]; - - // Probability for Noise, Q7 * Q20 = Q27 - tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean1ptr++, *nstd1ptr++, - &deltaN[pos]); - probn[0] = (WebRtc_Word32)(kNoiseDataWeights[n] * tmp32_1); - tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean2ptr++, *nstd2ptr++, - &deltaN[pos + 1]); - probn[1] = (WebRtc_Word32)(kNoiseDataWeights[n + NUM_CHANNELS] * tmp32_1); - h0test = probn[0] + probn[1]; // Q27 - h0 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h0test, 12); // Q15 - - // Probability for Speech - tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean1ptr++, *sstd1ptr++, - &deltaS[pos]); - probs[0] = (WebRtc_Word32)(kSpeechDataWeights[n] * tmp32_1); - tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean2ptr++, *sstd2ptr++, - &deltaS[pos + 1]); - probs[1] = (WebRtc_Word32)(kSpeechDataWeights[n + NUM_CHANNELS] * tmp32_1); - h1test = probs[0] + probs[1]; // Q27 - h1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h1test, 12); // Q15 - - // Get likelihood ratio. Approximate log2(H1/H0) with shifts0 - shifts1 - shifts0 = WebRtcSpl_NormW32(h0test); - shifts1 = WebRtcSpl_NormW32(h1test); - - if ((h0test > 0) && (h1test > 0)) - { - ratvec = shifts0 - shifts1; - } else if (h1test > 0) - { - ratvec = 31 - shifts1; - } else if (h0test > 0) - { - ratvec = shifts0 - 31; - } else - { - ratvec = 0; - } - - // VAD decision with spectrum weighting - dotVal += WEBRTC_SPL_MUL_16_16(ratvec, kSpectrumWeight[n]); - - // Individual channel test - if ((ratvec << 2) > individualTest) - { - vadflag = 1; - } - - // Probabilities used when updating model - if (h0 > 0) - { - tmp32_1 = probn[0] & 0xFFFFF000; // Q27 - tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2); // Q29 - ngprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h0); - ngprvec[pos + 1] = 16384 - ngprvec[pos]; - } else - { - ngprvec[pos] = 16384; - ngprvec[pos + 1] = 0; - } - - // Probabilities used when updating model - if (h1 > 0) - { - tmp32_1 = probs[0] & 0xFFFFF000; - tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2); - sgprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h1); - sgprvec[pos + 1] = 16384 - sgprvec[pos]; - } else - { - sgprvec[pos] = 0; - sgprvec[pos + 1] = 0; - } - } - - // Overall test - if (dotVal >= totalTest) - { - vadflag |= 1; - } - - // Set pointers to the means and standard deviations. - nmean1ptr = &inst->noise_means[0]; - smean1ptr = &inst->speech_means[0]; - nstd1ptr = &inst->noise_stds[0]; - sstd1ptr = &inst->speech_stds[0]; - - maxspe = 12800; - - // Update the model's parameters - for (n = 0; n < NUM_CHANNELS; n++) - { - - pos = WEBRTC_SPL_LSHIFT_W16(n, 1); - - // Get min value in past which is used for long term correction - backval = WebRtcVad_FindMinimum(inst, feature_vector[n], n); // Q4 - - // Compute the "global" mean, that is the sum of the two means weighted - nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr); // Q7 * Q7 - nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS], - *(nmean1ptr+NUM_CHANNELS)); - tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 6); // Q8 - - for (k = 0; k < NUM_MODELS; k++) - { - - nr = pos + k; - - nmean2ptr = nmean1ptr + k * NUM_CHANNELS; - smean2ptr = smean1ptr + k * NUM_CHANNELS; - nstd2ptr = nstd1ptr + k * NUM_CHANNELS; - sstd2ptr = sstd1ptr + k * NUM_CHANNELS; - nmk = *nmean2ptr; - smk = *smean2ptr; - nsk = *nstd2ptr; - ssk = *sstd2ptr; - - // Update noise mean vector if the frame consists of noise only - nmk2 = nmk; - if (!vadflag) - { - // deltaN = (x-mu)/sigma^2 - // ngprvec[k] = probn[k]/(probn[0] + probn[1]) - - delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ngprvec[nr], - deltaN[nr], 11); // Q14*Q11 - nmk2 = nmk + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt, - kNoiseUpdateConst, - 22); // Q7+(Q14*Q15>>22) - } - - // Long term correction of the noise mean - ndelt = WEBRTC_SPL_LSHIFT_W16(backval, 4); - ndelt -= tmp16_1; // Q8 - Q8 - nmk3 = nmk2 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ndelt, - kBackEta, - 9); // Q7+(Q8*Q8)>>9 - - // Control that the noise mean does not drift to much - tmp16 = WEBRTC_SPL_LSHIFT_W16(k+5, 7); - if (nmk3 < tmp16) - nmk3 = tmp16; - tmp16 = WEBRTC_SPL_LSHIFT_W16(72+k-n, 7); - if (nmk3 > tmp16) - nmk3 = tmp16; - *nmean2ptr = nmk3; - - if (vadflag) - { - // Update speech mean vector: - // deltaS = (x-mu)/sigma^2 - // sgprvec[k] = probn[k]/(probn[0] + probn[1]) - - delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sgprvec[nr], - deltaS[nr], - 11); // (Q14*Q11)>>11=Q14 - tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt, - kSpeechUpdateConst, - 21) + 1; - smk2 = smk + (tmp16 >> 1); // Q7 + (Q14 * Q15 >> 22) - - // Control that the speech mean does not drift to much - maxmu = maxspe + 640; - if (smk2 < kMinimumMean[k]) - smk2 = kMinimumMean[k]; - if (smk2 > maxmu) - smk2 = maxmu; - - *smean2ptr = smk2; - - // (Q7>>3) = Q4 - tmp16 = WEBRTC_SPL_RSHIFT_W16((smk + 4), 3); - - tmp16 = feature_vector[n] - tmp16; // Q4 - tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaS[nr], tmp16, 3); - tmp32_2 = tmp32_1 - (WebRtc_Word32)4096; // Q12 - tmp16 = WEBRTC_SPL_RSHIFT_W16((sgprvec[nr]), 2); - tmp32_1 = (WebRtc_Word32)(tmp16 * tmp32_2);// (Q15>>3)*(Q14>>2)=Q12*Q12=Q24 - - tmp32_2 = WEBRTC_SPL_RSHIFT_W32(tmp32_1, 4); // Q20 - - // 0.1 * Q20 / Q7 = Q13 - if (tmp32_2 > 0) - tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, ssk * 10); - else - { - tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_2, ssk * 10); - tmp16 = -tmp16; - } - // divide by 4 giving an update factor of 0.025 - tmp16 += 128; // Rounding - ssk += WEBRTC_SPL_RSHIFT_W16(tmp16, 8); - // Division with 8 plus Q7 - if (ssk < MIN_STD) - ssk = MIN_STD; - *sstd2ptr = ssk; - } else - { - // Update GMM variance vectors - // deltaN * (feature_vector[n] - nmk) - 1, Q11 * Q4 - tmp16 = feature_vector[n] - WEBRTC_SPL_RSHIFT_W16(nmk, 3); - - // (Q15>>3) * (Q14>>2) = Q12 * Q12 = Q24 - tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaN[nr], tmp16, 3) - 4096; - tmp16 = WEBRTC_SPL_RSHIFT_W16((ngprvec[nr]+2), 2); - tmp32_2 = (WebRtc_Word32)(tmp16 * tmp32_1); - tmp32_1 = WEBRTC_SPL_RSHIFT_W32(tmp32_2, 14); - // Q20 * approx 0.001 (2^-10=0.0009766) - - // Q20 / Q7 = Q13 - tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk); - if (tmp32_1 > 0) - tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk); - else - { - tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_1, nsk); - tmp16 = -tmp16; - } - tmp16 += 32; // Rounding - nsk += WEBRTC_SPL_RSHIFT_W16(tmp16, 6); - - if (nsk < MIN_STD) - nsk = MIN_STD; - - *nstd2ptr = nsk; - } - } - - // Separate models if they are too close - nmid in Q14 - nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr); - nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS], *nmean2ptr); - - // smid in Q14 - smid = WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n], *smean1ptr); - smid += WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n+NUM_CHANNELS], *smean2ptr); - - // diff = "global" speech mean - "global" noise mean - diff = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 9); - tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 9); - diff -= tmp16; - - if (diff < kMinimumDifference[n]) - { - - tmp16 = kMinimumDifference[n] - diff; // Q5 - - // tmp16_1 = ~0.8 * (kMinimumDifference - diff) in Q7 - // tmp16_2 = ~0.2 * (kMinimumDifference - diff) in Q7 - tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(13, tmp16, 2); - tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, tmp16, 2); - - // First Gauss, speech model - tmp16 = tmp16_1 + *smean1ptr; - *smean1ptr = tmp16; - smid = WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n]); - - // Second Gauss, speech model - tmp16 = tmp16_1 + *smean2ptr; - *smean2ptr = tmp16; - smid += WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n+NUM_CHANNELS]); - - // First Gauss, noise model - tmp16 = *nmean1ptr - tmp16_2; - *nmean1ptr = tmp16; - - nmid = WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n]); - - // Second Gauss, noise model - tmp16 = *nmean2ptr - tmp16_2; - *nmean2ptr = tmp16; - nmid += WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n+NUM_CHANNELS]); - } - - // Control that the speech & noise means do not drift to much - maxspe = kMaximumSpeech[n]; - tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 7); - if (tmp16_2 > maxspe) - { // Upper limit of speech model - tmp16_2 -= maxspe; - - *smean1ptr -= tmp16_2; - *smean2ptr -= tmp16_2; - } - - tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 7); - if (tmp16_2 > kMaximumNoise[n]) - { - tmp16_2 -= kMaximumNoise[n]; - - *nmean1ptr -= tmp16_2; - *nmean2ptr -= tmp16_2; - } - - nmean1ptr++; - smean1ptr++; - nstd1ptr++; - sstd1ptr++; - } - inst->frame_counter++; - } else - { - vadflag = 0; - } - - // Hangover smoothing - if (!vadflag) - { - if (inst->over_hang > 0) - { - vadflag = 2 + inst->over_hang; - inst->over_hang = inst->over_hang - 1; - } - inst->num_of_speech = 0; - } else - { - inst->num_of_speech = inst->num_of_speech + 1; - if (inst->num_of_speech > NSP_MAX) - { - inst->num_of_speech = NSP_MAX; - inst->over_hang = overhead2; - } else - inst->over_hang = overhead1; - } - return vadflag; -} diff --git a/src/common_audio/vad/main/source/vad_core.h b/src/common_audio/vad/main/source/vad_core.h deleted file mode 100644 index 544caf5..0000000 --- a/src/common_audio/vad/main/source/vad_core.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the descriptions of the core VAD calls. - */ - -#ifndef WEBRTC_VAD_CORE_H_ -#define WEBRTC_VAD_CORE_H_ - -#include "typedefs.h" -#include "vad_defines.h" - -typedef struct VadInstT_ -{ - - WebRtc_Word16 vad; - WebRtc_Word32 downsampling_filter_states[4]; - WebRtc_Word16 noise_means[NUM_TABLE_VALUES]; - WebRtc_Word16 speech_means[NUM_TABLE_VALUES]; - WebRtc_Word16 noise_stds[NUM_TABLE_VALUES]; - WebRtc_Word16 speech_stds[NUM_TABLE_VALUES]; - WebRtc_Word32 frame_counter; - WebRtc_Word16 over_hang; // Over Hang - WebRtc_Word16 num_of_speech; - WebRtc_Word16 index_vector[16 * NUM_CHANNELS]; - WebRtc_Word16 low_value_vector[16 * NUM_CHANNELS]; - WebRtc_Word16 mean_value[NUM_CHANNELS]; - WebRtc_Word16 upper_state[5]; - WebRtc_Word16 lower_state[5]; - WebRtc_Word16 hp_filter_state[4]; - WebRtc_Word16 over_hang_max_1[3]; - WebRtc_Word16 over_hang_max_2[3]; - WebRtc_Word16 individual[3]; - WebRtc_Word16 total[3]; - - short init_flag; - -} VadInstT; - -/**************************************************************************** - * WebRtcVad_InitCore(...) - * - * This function initializes a VAD instance - * - * Input: - * - inst : Instance that should be initialized - * - mode : Aggressiveness degree - * 0 (High quality) - 3 (Highly aggressive) - * - * Output: - * - inst : Initialized instance - * - * Return value : 0 - Ok - * -1 - Error - */ -int WebRtcVad_InitCore(VadInstT* inst, short mode); - -/**************************************************************************** - * WebRtcVad_set_mode_core(...) - * - * This function changes the VAD settings - * - * Input: - * - inst : VAD instance - * - mode : Aggressiveness degree - * 0 (High quality) - 3 (Highly aggressive) - * - * Output: - * - inst : Changed instance - * - * Return value : 0 - Ok - * -1 - Error - */ - -int WebRtcVad_set_mode_core(VadInstT* inst, short mode); - -/**************************************************************************** - * WebRtcVad_CalcVad32khz(...) - * WebRtcVad_CalcVad16khz(...) - * WebRtcVad_CalcVad8khz(...) - * - * Calculate probability for active speech and make VAD decision. - * - * Input: - * - inst : Instance that should be initialized - * - speech_frame : Input speech frame - * - frame_length : Number of input samples - * - * Output: - * - inst : Updated filter states etc. - * - * Return value : VAD decision - * 0 - No active speech - * 1-6 - Active speech - */ -WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT* inst, WebRtc_Word16* speech_frame, - int frame_length); -WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT* inst, WebRtc_Word16* speech_frame, - int frame_length); -WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT* inst, WebRtc_Word16* speech_frame, - int frame_length); - -/**************************************************************************** - * WebRtcVad_GmmProbability(...) - * - * This function calculates the probabilities for background noise and - * speech using Gaussian Mixture Models. A hypothesis-test is performed to decide - * which type of signal is most probable. - * - * Input: - * - inst : Pointer to VAD instance - * - feature_vector : Feature vector = log10(energy in frequency band) - * - total_power : Total power in frame. - * - frame_length : Number of input samples - * - * Output: - * VAD decision : 0 - noise, 1 - speech - * - */ -WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT* inst, WebRtc_Word16* feature_vector, - WebRtc_Word16 total_power, int frame_length); - -#endif // WEBRTC_VAD_CORE_H_ diff --git a/src/common_audio/vad/main/source/vad_filterbank.c b/src/common_audio/vad/main/source/vad_filterbank.c deleted file mode 100644 index 9bd4443..0000000 --- a/src/common_audio/vad/main/source/vad_filterbank.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the implementation of the internal filterbank associated functions. - * For function description, see vad_filterbank.h. - */ - -#include "vad_filterbank.h" - -#include "signal_processing_library.h" -#include "typedefs.h" -#include "vad_defines.h" - -// Constant 160*log10(2) in Q9 -static const WebRtc_Word16 kLogConst = 24660; -// Coefficients used by WebRtcVad_HpOutput, Q14 -static const WebRtc_Word16 kHpZeroCoefs[3] = {6631, -13262, 6631}; -static const WebRtc_Word16 kHpPoleCoefs[3] = {16384, -7756, 5620}; -// Allpass filter coefficients, upper and lower, in Q15 -// Upper: 0.64, Lower: 0.17 -static const WebRtc_Word16 kAllPassCoefsQ15[2] = {20972, 5571}; -// Adjustment for division with two in WebRtcVad_SplitFilter -static const WebRtc_Word16 kOffsetVector[6] = {368, 368, 272, 176, 176, 176}; - -void WebRtcVad_HpOutput(WebRtc_Word16 *in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16 *out_vector, - WebRtc_Word16 *filter_state) -{ - WebRtc_Word16 i, *pi, *outPtr; - WebRtc_Word32 tmpW32; - - pi = &in_vector[0]; - outPtr = &out_vector[0]; - - // The sum of the absolute values of the impulse response: - // The zero/pole-filter has a max amplification of a single sample of: 1.4546 - // Impulse response: 0.4047 -0.6179 -0.0266 0.1993 0.1035 -0.0194 - // The all-zero section has a max amplification of a single sample of: 1.6189 - // Impulse response: 0.4047 -0.8094 0.4047 0 0 0 - // The all-pole section has a max amplification of a single sample of: 1.9931 - // Impulse response: 1.0000 0.4734 -0.1189 -0.2187 -0.0627 0.04532 - - for (i = 0; i < in_vector_length; i++) - { - // all-zero section (filter coefficients in Q14) - tmpW32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[0], (*pi)); - tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[1], filter_state[0]); - tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[2], filter_state[1]); // Q14 - filter_state[1] = filter_state[0]; - filter_state[0] = *pi++; - - // all-pole section - tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[1], filter_state[2]); // Q14 - tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[2], filter_state[3]); - filter_state[3] = filter_state[2]; - filter_state[2] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32 (tmpW32, 14); - *outPtr++ = filter_state[2]; - } -} - -void WebRtcVad_Allpass(WebRtc_Word16 *in_vector, - WebRtc_Word16 *out_vector, - WebRtc_Word16 filter_coefficients, - int vector_length, - WebRtc_Word16 *filter_state) -{ - // The filter can only cause overflow (in the w16 output variable) - // if more than 4 consecutive input numbers are of maximum value and - // has the the same sign as the impulse responses first taps. - // First 6 taps of the impulse response: 0.6399 0.5905 -0.3779 - // 0.2418 -0.1547 0.0990 - - int n; - WebRtc_Word16 tmp16; - WebRtc_Word32 tmp32, in32, state32; - - state32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*filter_state)), 16); // Q31 - - for (n = 0; n < vector_length; n++) - { - - tmp32 = state32 + WEBRTC_SPL_MUL_16_16(filter_coefficients, (*in_vector)); - tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16); - *out_vector++ = tmp16; - in32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*in_vector)), 14); - state32 = in32 - WEBRTC_SPL_MUL_16_16(filter_coefficients, tmp16); - state32 = WEBRTC_SPL_LSHIFT_W32(state32, 1); - in_vector += 2; - } - - *filter_state = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(state32, 16); -} - -void WebRtcVad_SplitFilter(WebRtc_Word16 *in_vector, - WebRtc_Word16 *out_vector_hp, - WebRtc_Word16 *out_vector_lp, - WebRtc_Word16 *upper_state, - WebRtc_Word16 *lower_state, - int in_vector_length) -{ - WebRtc_Word16 tmpOut; - int k, halflen; - - // Downsampling by 2 and get two branches - halflen = WEBRTC_SPL_RSHIFT_W16(in_vector_length, 1); - - // All-pass filtering upper branch - WebRtcVad_Allpass(&in_vector[0], out_vector_hp, kAllPassCoefsQ15[0], halflen, upper_state); - - // All-pass filtering lower branch - WebRtcVad_Allpass(&in_vector[1], out_vector_lp, kAllPassCoefsQ15[1], halflen, lower_state); - - // Make LP and HP signals - for (k = 0; k < halflen; k++) - { - tmpOut = *out_vector_hp; - *out_vector_hp++ -= *out_vector_lp; - *out_vector_lp++ += tmpOut; - } -} - -WebRtc_Word16 WebRtcVad_get_features(VadInstT *inst, - WebRtc_Word16 *in_vector, - int frame_size, - WebRtc_Word16 *out_vector) -{ - int curlen, filtno; - WebRtc_Word16 vecHP1[120], vecLP1[120]; - WebRtc_Word16 vecHP2[60], vecLP2[60]; - WebRtc_Word16 *ptin; - WebRtc_Word16 *hptout, *lptout; - WebRtc_Word16 power = 0; - - // Split at 2000 Hz and downsample - filtno = 0; - ptin = in_vector; - hptout = vecHP1; - lptout = vecLP1; - curlen = frame_size; - WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], - &inst->lower_state[filtno], curlen); - - // Split at 3000 Hz and downsample - filtno = 1; - ptin = vecHP1; - hptout = vecHP2; - lptout = vecLP2; - curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1); - - WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], - &inst->lower_state[filtno], curlen); - - // Energy in 3000 Hz - 4000 Hz - curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); - WebRtcVad_LogOfEnergy(vecHP2, &out_vector[5], &power, kOffsetVector[5], curlen); - - // Energy in 2000 Hz - 3000 Hz - WebRtcVad_LogOfEnergy(vecLP2, &out_vector[4], &power, kOffsetVector[4], curlen); - - // Split at 1000 Hz and downsample - filtno = 2; - ptin = vecLP1; - hptout = vecHP2; - lptout = vecLP2; - curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1); - WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], - &inst->lower_state[filtno], curlen); - - // Energy in 1000 Hz - 2000 Hz - curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); - WebRtcVad_LogOfEnergy(vecHP2, &out_vector[3], &power, kOffsetVector[3], curlen); - - // Split at 500 Hz - filtno = 3; - ptin = vecLP2; - hptout = vecHP1; - lptout = vecLP1; - - WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], - &inst->lower_state[filtno], curlen); - - // Energy in 500 Hz - 1000 Hz - curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); - WebRtcVad_LogOfEnergy(vecHP1, &out_vector[2], &power, kOffsetVector[2], curlen); - // Split at 250 Hz - filtno = 4; - ptin = vecLP1; - hptout = vecHP2; - lptout = vecLP2; - - WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], - &inst->lower_state[filtno], curlen); - - // Energy in 250 Hz - 500 Hz - curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); - WebRtcVad_LogOfEnergy(vecHP2, &out_vector[1], &power, kOffsetVector[1], curlen); - - // Remove DC and LFs - WebRtcVad_HpOutput(vecLP2, curlen, vecHP1, inst->hp_filter_state); - - // Power in 80 Hz - 250 Hz - WebRtcVad_LogOfEnergy(vecHP1, &out_vector[0], &power, kOffsetVector[0], curlen); - - return power; -} - -void WebRtcVad_LogOfEnergy(WebRtc_Word16 *vector, - WebRtc_Word16 *enerlogval, - WebRtc_Word16 *power, - WebRtc_Word16 offset, - int vector_length) -{ - WebRtc_Word16 enerSum = 0; - WebRtc_Word16 zeros, frac, log2; - WebRtc_Word32 energy; - - int shfts = 0, shfts2; - - energy = WebRtcSpl_Energy(vector, vector_length, &shfts); - - if (energy > 0) - { - - shfts2 = 16 - WebRtcSpl_NormW32(energy); - shfts += shfts2; - // "shfts" is the total number of right shifts that has been done to enerSum. - enerSum = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(energy, -shfts2); - - // Find: - // 160*log10(enerSum*2^shfts) = 160*log10(2)*log2(enerSum*2^shfts) = - // 160*log10(2)*(log2(enerSum) + log2(2^shfts)) = - // 160*log10(2)*(log2(enerSum) + shfts) - - zeros = WebRtcSpl_NormU32(enerSum); - frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_Word32)(enerSum) << zeros) - & 0x7FFFFFFF) >> 21); - log2 = (WebRtc_Word16)(((31 - zeros) << 10) + frac); - - *enerlogval = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kLogConst, log2, 19) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(shfts, kLogConst, 9); - - if (*enerlogval < 0) - { - *enerlogval = 0; - } - } else - { - *enerlogval = 0; - shfts = -15; - enerSum = 0; - } - - *enerlogval += offset; - - // Total power in frame - if (*power <= MIN_ENERGY) - { - if (shfts > 0) - { - *power += MIN_ENERGY + 1; - } else if (WEBRTC_SPL_SHIFT_W16(enerSum, shfts) > MIN_ENERGY) - { - *power += MIN_ENERGY + 1; - } else - { - *power += WEBRTC_SPL_SHIFT_W16(enerSum, shfts); - } - } -} diff --git a/src/common_audio/vad/main/source/vad_filterbank.h b/src/common_audio/vad/main/source/vad_filterbank.h deleted file mode 100644 index a5507ea..0000000 --- a/src/common_audio/vad/main/source/vad_filterbank.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the description of the internal VAD call - * WebRtcVad_GaussianProbability. - */ - -#ifndef WEBRTC_VAD_FILTERBANK_H_ -#define WEBRTC_VAD_FILTERBANK_H_ - -#include "vad_core.h" - -/**************************************************************************** - * WebRtcVad_HpOutput(...) - * - * This function removes DC from the lowest frequency band - * - * Input: - * - in_vector : Samples in the frequency interval 0 - 250 Hz - * - in_vector_length : Length of input and output vector - * - filter_state : Current state of the filter - * - * Output: - * - out_vector : Samples in the frequency interval 80 - 250 Hz - * - filter_state : Updated state of the filter - * - */ -void WebRtcVad_HpOutput(WebRtc_Word16* in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16* out_vector, - WebRtc_Word16* filter_state); - -/**************************************************************************** - * WebRtcVad_Allpass(...) - * - * This function is used when before splitting a speech file into - * different frequency bands - * - * Note! Do NOT let the arrays in_vector and out_vector correspond to the same address. - * - * Input: - * - in_vector : (Q0) - * - filter_coefficients : (Q15) - * - vector_length : Length of input and output vector - * - filter_state : Current state of the filter (Q(-1)) - * - * Output: - * - out_vector : Output speech signal (Q(-1)) - * - filter_state : Updated state of the filter (Q(-1)) - * - */ -void WebRtcVad_Allpass(WebRtc_Word16* in_vector, - WebRtc_Word16* outw16, - WebRtc_Word16 filter_coefficients, - int vector_length, - WebRtc_Word16* filter_state); - -/**************************************************************************** - * WebRtcVad_SplitFilter(...) - * - * This function is used when before splitting a speech file into - * different frequency bands - * - * Input: - * - in_vector : Input signal to be split into two frequency bands. - * - upper_state : Current state of the upper filter - * - lower_state : Current state of the lower filter - * - in_vector_length : Length of input vector - * - * Output: - * - out_vector_hp : Upper half of the spectrum - * - out_vector_lp : Lower half of the spectrum - * - upper_state : Updated state of the upper filter - * - lower_state : Updated state of the lower filter - * - */ -void WebRtcVad_SplitFilter(WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector_hp, - WebRtc_Word16* out_vector_lp, - WebRtc_Word16* upper_state, - WebRtc_Word16* lower_state, - int in_vector_length); - -/**************************************************************************** - * WebRtcVad_get_features(...) - * - * This function is used to get the logarithm of the power of each of the - * 6 frequency bands used by the VAD: - * 80 Hz - 250 Hz - * 250 Hz - 500 Hz - * 500 Hz - 1000 Hz - * 1000 Hz - 2000 Hz - * 2000 Hz - 3000 Hz - * 3000 Hz - 4000 Hz - * - * Input: - * - inst : Pointer to VAD instance - * - in_vector : Input speech signal - * - frame_size : Frame size, in number of samples - * - * Output: - * - out_vector : 10*log10(power in each freq. band), Q4 - * - * Return: total power in the signal (NOTE! This value is not exact since it - * is only used in a comparison. - */ -WebRtc_Word16 WebRtcVad_get_features(VadInstT* inst, - WebRtc_Word16* in_vector, - int frame_size, - WebRtc_Word16* out_vector); - -/**************************************************************************** - * WebRtcVad_LogOfEnergy(...) - * - * This function is used to get the logarithm of the power of one frequency band. - * - * Input: - * - vector : Input speech samples for one frequency band - * - offset : Offset value for the current frequency band - * - vector_length : Length of input vector - * - * Output: - * - enerlogval : 10*log10(energy); - * - power : Update total power in speech frame. NOTE! This value - * is not exact since it is only used in a comparison. - * - */ -void WebRtcVad_LogOfEnergy(WebRtc_Word16* vector, - WebRtc_Word16* enerlogval, - WebRtc_Word16* power, - WebRtc_Word16 offset, - int vector_length); - -#endif // WEBRTC_VAD_FILTERBANK_H_ diff --git a/src/common_audio/vad/main/source/vad_gmm.c b/src/common_audio/vad/main/source/vad_gmm.c deleted file mode 100644 index 0865261..0000000 --- a/src/common_audio/vad/main/source/vad_gmm.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the implementation of the internal VAD call - * WebRtcVad_GaussianProbability. For function description, see vad_gmm.h. - */ - -#include "vad_gmm.h" - -#include "signal_processing_library.h" -#include "typedefs.h" - -static const WebRtc_Word32 kCompVar = 22005; -// Constant log2(exp(1)) in Q12 -static const WebRtc_Word16 kLog10Const = 5909; - -WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample, - WebRtc_Word16 mean, - WebRtc_Word16 std, - WebRtc_Word16 *delta) -{ - WebRtc_Word16 tmp16, tmpDiv, tmpDiv2, expVal, tmp16_1, tmp16_2; - WebRtc_Word32 tmp32, y32; - - // Calculate tmpDiv=1/std, in Q10 - tmp32 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W16(std,1) + (WebRtc_Word32)131072; // 1 in Q17 - tmpDiv = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32, std); // Q17/Q7 = Q10 - - // Calculate tmpDiv2=1/std^2, in Q14 - tmp16 = WEBRTC_SPL_RSHIFT_W16(tmpDiv, 2); // From Q10 to Q8 - tmpDiv2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 2); // (Q8 * Q8)>>2 = Q14 - - tmp16 = WEBRTC_SPL_LSHIFT_W16(in_sample, 3); // Q7 - tmp16 = tmp16 - mean; // Q7 - Q7 = Q7 - - // To be used later, when updating noise/speech model - // delta = (x-m)/std^2, in Q11 - *delta = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmpDiv2, tmp16, 10); //(Q14*Q7)>>10 = Q11 - - // Calculate tmp32=(x-m)^2/(2*std^2), in Q10 - tmp32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT(*delta, tmp16, 9); // One shift for /2 - - // Calculate expVal ~= exp(-(x-m)^2/(2*std^2)) ~= exp2(-log2(exp(1))*tmp32) - if (tmp32 < kCompVar) - { - // Calculate tmp16 = log2(exp(1))*tmp32 , in Q10 - tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)tmp32, - kLog10Const, 12); - tmp16 = -tmp16; - tmp16_2 = (WebRtc_Word16)(0x0400 | (tmp16 & 0x03FF)); - tmp16_1 = (WebRtc_Word16)(tmp16 ^ 0xFFFF); - tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(tmp16_1, 10); - tmp16 += 1; - // Calculate expVal=log2(-tmp32), in Q10 - expVal = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)tmp16_2, tmp16); - - } else - { - expVal = 0; - } - - // Calculate y32=(1/std)*exp(-(x-m)^2/(2*std^2)), in Q20 - y32 = WEBRTC_SPL_MUL_16_16(tmpDiv, expVal); // Q10 * Q10 = Q20 - - return y32; // Q20 -} diff --git a/src/common_audio/vad/main/source/vad_gmm.h b/src/common_audio/vad/main/source/vad_gmm.h deleted file mode 100644 index e0747fb..0000000 --- a/src/common_audio/vad/main/source/vad_gmm.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the description of the internal VAD call - * WebRtcVad_GaussianProbability. - */ - -#ifndef WEBRTC_VAD_GMM_H_ -#define WEBRTC_VAD_GMM_H_ - -#include "typedefs.h" - -/**************************************************************************** - * WebRtcVad_GaussianProbability(...) - * - * This function calculates the probability for the value 'in_sample', given that in_sample - * comes from a normal distribution with mean 'mean' and standard deviation 'std'. - * - * Input: - * - in_sample : Input sample in Q4 - * - mean : mean value in the statistical model, Q7 - * - std : standard deviation, Q7 - * - * Output: - * - * - delta : Value used when updating the model, Q11 - * - * Return: - * - out : out = 1/std * exp(-(x-m)^2/(2*std^2)); - * Probability for x. - * - */ -WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample, - WebRtc_Word16 mean, - WebRtc_Word16 std, - WebRtc_Word16 *delta); - -#endif // WEBRTC_VAD_GMM_H_ diff --git a/src/common_audio/vad/main/source/vad_sp.c b/src/common_audio/vad/main/source/vad_sp.c deleted file mode 100644 index 620ab97..0000000 --- a/src/common_audio/vad/main/source/vad_sp.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the implementation of the VAD internal calls for - * Downsampling and FindMinimum. - * For function call descriptions; See vad_sp.h. - */ - -#include "vad_sp.h" - -#include "signal_processing_library.h" -#include "typedefs.h" -#include "vad_defines.h" - -// Allpass filter coefficients, upper and lower, in Q13 -// Upper: 0.64, Lower: 0.17 -static const WebRtc_Word16 kAllPassCoefsQ13[2] = {5243, 1392}; // Q13 - -// Downsampling filter based on the splitting filter and the allpass functions -// in vad_filterbank.c -void WebRtcVad_Downsampling(WebRtc_Word16* signal_in, - WebRtc_Word16* signal_out, - WebRtc_Word32* filter_state, - int inlen) -{ - WebRtc_Word16 tmp16_1, tmp16_2; - WebRtc_Word32 tmp32_1, tmp32_2; - int n, halflen; - - // Downsampling by 2 and get two branches - halflen = WEBRTC_SPL_RSHIFT_W16(inlen, 1); - - tmp32_1 = filter_state[0]; - tmp32_2 = filter_state[1]; - - // Filter coefficients in Q13, filter state in Q0 - for (n = 0; n < halflen; n++) - { - // All-pass filtering upper branch - tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_1, 1) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), - *signal_in, 14); - *signal_out = tmp16_1; - tmp32_1 = (WebRtc_Word32)(*signal_in++) - - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), tmp16_1, 12); - - // All-pass filtering lower branch - tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_2, 1) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), - *signal_in, 14); - *signal_out++ += tmp16_2; - tmp32_2 = (WebRtc_Word32)(*signal_in++) - - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), tmp16_2, 12); - } - filter_state[0] = tmp32_1; - filter_state[1] = tmp32_2; -} - -WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst, - WebRtc_Word16 x, - int n) -{ - int i, j, k, II = -1, offset; - WebRtc_Word16 meanV, alpha; - WebRtc_Word32 tmp32, tmp32_1; - WebRtc_Word16 *valptr, *idxptr, *p1, *p2, *p3; - - // Offset to beginning of the 16 minimum values in memory - offset = WEBRTC_SPL_LSHIFT_W16(n, 4); - - // Pointer to memory for the 16 minimum values and the age of each value - idxptr = &inst->index_vector[offset]; - valptr = &inst->low_value_vector[offset]; - - // Each value in low_value_vector is getting 1 loop older. - // Update age of each value in indexVal, and remove old values. - for (i = 0; i < 16; i++) - { - p3 = idxptr + i; - if (*p3 != 100) - { - *p3 += 1; - } else - { - p1 = valptr + i + 1; - p2 = p3 + 1; - for (j = i; j < 16; j++) - { - *(valptr + j) = *p1++; - *(idxptr + j) = *p2++; - } - *(idxptr + 15) = 101; - *(valptr + 15) = 10000; - } - } - - // Check if x smaller than any of the values in low_value_vector. - // If so, find position. - if (x < *(valptr + 7)) - { - if (x < *(valptr + 3)) - { - if (x < *(valptr + 1)) - { - if (x < *valptr) - { - II = 0; - } else - { - II = 1; - } - } else if (x < *(valptr + 2)) - { - II = 2; - } else - { - II = 3; - } - } else if (x < *(valptr + 5)) - { - if (x < *(valptr + 4)) - { - II = 4; - } else - { - II = 5; - } - } else if (x < *(valptr + 6)) - { - II = 6; - } else - { - II = 7; - } - } else if (x < *(valptr + 15)) - { - if (x < *(valptr + 11)) - { - if (x < *(valptr + 9)) - { - if (x < *(valptr + 8)) - { - II = 8; - } else - { - II = 9; - } - } else if (x < *(valptr + 10)) - { - II = 10; - } else - { - II = 11; - } - } else if (x < *(valptr + 13)) - { - if (x < *(valptr + 12)) - { - II = 12; - } else - { - II = 13; - } - } else if (x < *(valptr + 14)) - { - II = 14; - } else - { - II = 15; - } - } - - // Put new min value on right position and shift bigger values up - if (II > -1) - { - for (i = 15; i > II; i--) - { - k = i - 1; - *(valptr + i) = *(valptr + k); - *(idxptr + i) = *(idxptr + k); - } - *(valptr + II) = x; - *(idxptr + II) = 1; - } - - meanV = 0; - if ((inst->frame_counter) > 4) - { - j = 5; - } else - { - j = inst->frame_counter; - } - - if (j > 2) - { - meanV = *(valptr + 2); - } else if (j > 0) - { - meanV = *valptr; - } else - { - meanV = 1600; - } - - if (inst->frame_counter > 0) - { - if (meanV < inst->mean_value[n]) - { - alpha = (WebRtc_Word16)ALPHA1; // 0.2 in Q15 - } else - { - alpha = (WebRtc_Word16)ALPHA2; // 0.99 in Q15 - } - } else - { - alpha = 0; - } - - tmp32 = WEBRTC_SPL_MUL_16_16((alpha+1), inst->mean_value[n]); - tmp32_1 = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX - alpha, meanV); - tmp32 += tmp32_1; - tmp32 += 16384; - inst->mean_value[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 15); - - return inst->mean_value[n]; -} diff --git a/src/common_audio/vad/main/source/vad_sp.h b/src/common_audio/vad/main/source/vad_sp.h deleted file mode 100644 index ae15c11..0000000 --- a/src/common_audio/vad/main/source/vad_sp.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the VAD internal calls for Downsampling and FindMinimum. - * Specific function calls are given below. - */ - -#ifndef WEBRTC_VAD_SP_H_ -#define WEBRTC_VAD_SP_H_ - -#include "vad_core.h" - -/**************************************************************************** - * WebRtcVad_Downsampling(...) - * - * Downsamples the signal a factor 2, eg. 32->16 or 16->8 - * - * Input: - * - signal_in : Input signal - * - in_length : Length of input signal in samples - * - * Input & Output: - * - filter_state : Filter state for first all-pass filters - * - * Output: - * - signal_out : Downsampled signal (of length len/2) - */ -void WebRtcVad_Downsampling(WebRtc_Word16* signal_in, - WebRtc_Word16* signal_out, - WebRtc_Word32* filter_state, - int in_length); - -/**************************************************************************** - * WebRtcVad_FindMinimum(...) - * - * Find the five lowest values of x in 100 frames long window. Return a mean - * value of these five values. - * - * Input: - * - feature_value : Feature value - * - channel : Channel number - * - * Input & Output: - * - inst : State information - * - * Output: - * return value : Weighted minimum value for a moving window. - */ -WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst, WebRtc_Word16 feature_value, int channel); - -#endif // WEBRTC_VAD_SP_H_ diff --git a/src/common_audio/vad/main/source/webrtc_vad.c b/src/common_audio/vad/main/source/webrtc_vad.c deleted file mode 100644 index dcfbda1..0000000 --- a/src/common_audio/vad/main/source/webrtc_vad.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the VAD API calls. For a specific function call description, - * see webrtc_vad.h - */ - -#include -#include - -#include "webrtc_vad.h" -#include "vad_core.h" - -static const int kInitCheck = 42; - -WebRtc_Word16 WebRtcVad_get_version(char *version, size_t size_bytes) -{ - const char my_version[] = "VAD 1.2.0"; - - if (version == NULL) - { - return -1; - } - - if (size_bytes < sizeof(my_version)) - { - return -1; - } - - memcpy(version, my_version, sizeof(my_version)); - return 0; -} - -WebRtc_Word16 WebRtcVad_AssignSize(int *size_in_bytes) -{ - *size_in_bytes = sizeof(VadInstT) * 2 / sizeof(WebRtc_Word16); - return 0; -} - -WebRtc_Word16 WebRtcVad_Assign(VadInst **vad_inst, void *vad_inst_addr) -{ - - if (vad_inst == NULL) - { - return -1; - } - - if (vad_inst_addr != NULL) - { - *vad_inst = (VadInst*)vad_inst_addr; - return 0; - } else - { - return -1; - } -} - -WebRtc_Word16 WebRtcVad_Create(VadInst **vad_inst) -{ - - VadInstT *vad_ptr = NULL; - - if (vad_inst == NULL) - { - return -1; - } - - *vad_inst = NULL; - - vad_ptr = (VadInstT *)malloc(sizeof(VadInstT)); - *vad_inst = (VadInst *)vad_ptr; - - if (vad_ptr == NULL) - { - return -1; - } - - vad_ptr->init_flag = 0; - - return 0; -} - -WebRtc_Word16 WebRtcVad_Free(VadInst *vad_inst) -{ - - if (vad_inst == NULL) - { - return -1; - } - - free(vad_inst); - return 0; -} - -WebRtc_Word16 WebRtcVad_Init(VadInst *vad_inst) -{ - short mode = 0; // Default high quality - - if (vad_inst == NULL) - { - return -1; - } - - return WebRtcVad_InitCore((VadInstT*)vad_inst, mode); -} - -WebRtc_Word16 WebRtcVad_set_mode(VadInst *vad_inst, WebRtc_Word16 mode) -{ - VadInstT* vad_ptr; - - if (vad_inst == NULL) - { - return -1; - } - - vad_ptr = (VadInstT*)vad_inst; - if (vad_ptr->init_flag != kInitCheck) - { - return -1; - } - - return WebRtcVad_set_mode_core((VadInstT*)vad_inst, mode); -} - -WebRtc_Word16 WebRtcVad_Process(VadInst *vad_inst, - WebRtc_Word16 fs, - WebRtc_Word16 *speech_frame, - WebRtc_Word16 frame_length) -{ - WebRtc_Word16 vad; - VadInstT* vad_ptr; - - if (vad_inst == NULL) - { - return -1; - } - - vad_ptr = (VadInstT*)vad_inst; - if (vad_ptr->init_flag != kInitCheck) - { - return -1; - } - - if (speech_frame == NULL) - { - return -1; - } - - if (fs == 32000) - { - if ((frame_length != 320) && (frame_length != 640) && (frame_length != 960)) - { - return -1; - } - vad = WebRtcVad_CalcVad32khz((VadInstT*)vad_inst, speech_frame, frame_length); - - } else if (fs == 16000) - { - if ((frame_length != 160) && (frame_length != 320) && (frame_length != 480)) - { - return -1; - } - vad = WebRtcVad_CalcVad16khz((VadInstT*)vad_inst, speech_frame, frame_length); - - } else if (fs == 8000) - { - if ((frame_length != 80) && (frame_length != 160) && (frame_length != 240)) - { - return -1; - } - vad = WebRtcVad_CalcVad8khz((VadInstT*)vad_inst, speech_frame, frame_length); - - } else - { - return -1; // Not a supported sampling frequency - } - - if (vad > 0) - { - return 1; - } else if (vad == 0) - { - return 0; - } else - { - return -1; - } -} diff --git a/src/common_audio/vad/main/test/unit_test/unit_test.cc b/src/common_audio/vad/main/test/unit_test/unit_test.cc deleted file mode 100644 index 8ac793e..0000000 --- a/src/common_audio/vad/main/test/unit_test/unit_test.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes the implementation of the VAD unit tests. - */ - -#include -#include "unit_test.h" -#include "webrtc_vad.h" - - -class VadEnvironment : public ::testing::Environment { - public: - virtual void SetUp() { - } - - virtual void TearDown() { - } -}; - -VadTest::VadTest() -{ -} - -void VadTest::SetUp() { -} - -void VadTest::TearDown() { -} - -TEST_F(VadTest, ApiTest) { - VadInst *vad_inst; - int i, j, k; - short zeros[960]; - short speech[960]; - char version[32]; - - // Valid test cases - int fs[3] = {8000, 16000, 32000}; - int nMode[4] = {0, 1, 2, 3}; - int framelen[3][3] = {{80, 160, 240}, - {160, 320, 480}, {320, 640, 960}} ; - int vad_counter = 0; - - memset(zeros, 0, sizeof(short) * 960); - memset(speech, 1, sizeof(short) * 960); - speech[13] = 1374; - speech[73] = -3747; - - - - // WebRtcVad_get_version() - WebRtcVad_get_version(version); - //printf("API Test for %s\n", version); - - // Null instance tests - EXPECT_EQ(-1, WebRtcVad_Create(NULL)); - EXPECT_EQ(-1, WebRtcVad_Init(NULL)); - EXPECT_EQ(-1, WebRtcVad_Assign(NULL, NULL)); - EXPECT_EQ(-1, WebRtcVad_Free(NULL)); - EXPECT_EQ(-1, WebRtcVad_set_mode(NULL, nMode[0])); - EXPECT_EQ(-1, WebRtcVad_Process(NULL, fs[0], speech, framelen[0][0])); - - - EXPECT_EQ(WebRtcVad_Create(&vad_inst), 0); - - // Not initialized tests - EXPECT_EQ(-1, WebRtcVad_Process(vad_inst, fs[0], speech, framelen[0][0])); - EXPECT_EQ(-1, WebRtcVad_set_mode(vad_inst, nMode[0])); - - // WebRtcVad_Init() tests - EXPECT_EQ(WebRtcVad_Init(vad_inst), 0); - - // WebRtcVad_set_mode() tests - EXPECT_EQ(-1, WebRtcVad_set_mode(vad_inst, -1)); - EXPECT_EQ(-1, WebRtcVad_set_mode(vad_inst, 4)); - - for (i = 0; i < sizeof(nMode)/sizeof(nMode[0]); i++) { - EXPECT_EQ(WebRtcVad_set_mode(vad_inst, nMode[i]), 0); - } - - // WebRtcVad_Process() tests - EXPECT_EQ(-1, WebRtcVad_Process(vad_inst, fs[0], NULL, framelen[0][0])); - EXPECT_EQ(-1, WebRtcVad_Process(vad_inst, 12000, speech, framelen[0][0])); - EXPECT_EQ(-1, WebRtcVad_Process(vad_inst, fs[0], speech, framelen[1][1])); - EXPECT_EQ(WebRtcVad_Process(vad_inst, fs[0], zeros, framelen[0][0]), 0); - for (i = 0; i < sizeof(fs)/sizeof(fs[0]); i++) { - for (j = 0; j < sizeof(framelen[0])/sizeof(framelen[0][0]); j++) { - for (k = 0; k < sizeof(nMode)/sizeof(nMode[0]); k++) { - EXPECT_EQ(WebRtcVad_set_mode(vad_inst, nMode[k]), 0); -// printf("%d\n", WebRtcVad_Process(vad_inst, fs[i], speech, framelen[i][j])); - if (vad_counter < 9) - { - EXPECT_EQ(WebRtcVad_Process(vad_inst, fs[i], speech, framelen[i][j]), 1); - } else - { - EXPECT_EQ(WebRtcVad_Process(vad_inst, fs[i], speech, framelen[i][j]), 0); - } - vad_counter++; - } - } - } - - EXPECT_EQ(0, WebRtcVad_Free(vad_inst)); - -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - VadEnvironment* env = new VadEnvironment; - ::testing::AddGlobalTestEnvironment(env); - - return RUN_ALL_TESTS(); -} diff --git a/src/common_audio/vad/main/test/unit_test/unit_test.h b/src/common_audio/vad/main/test/unit_test/unit_test.h deleted file mode 100644 index 62dac11..0000000 --- a/src/common_audio/vad/main/test/unit_test/unit_test.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes the declaration of the VAD unit test. - */ - -#ifndef WEBRTC_VAD_UNIT_TEST_H_ -#define WEBRTC_VAD_UNIT_TEST_H_ - -#include - -class VadTest : public ::testing::Test { - protected: - VadTest(); - virtual void SetUp(); - virtual void TearDown(); -}; - -#endif // WEBRTC_VAD_UNIT_TEST_H_ diff --git a/src/common_types.h b/src/common_types.h deleted file mode 100644 index a3c12d9..0000000 --- a/src/common_types.h +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_COMMON_TYPES_H -#define WEBRTC_COMMON_TYPES_H - -#include "typedefs.h" - -#ifdef WEBRTC_EXPORT - #define WEBRTC_DLLEXPORT _declspec(dllexport) -#elif WEBRTC_DLL - #define WEBRTC_DLLEXPORT _declspec(dllimport) -#else - #define WEBRTC_DLLEXPORT -#endif - -#ifndef NULL - #define NULL 0 -#endif - -namespace webrtc { - -class InStream -{ -public: - virtual int Read(void *buf,int len) = 0; - virtual int Rewind() {return -1;} - virtual ~InStream() {} -protected: - InStream() {} -}; - -class OutStream -{ -public: - virtual bool Write(const void *buf,int len) = 0; - virtual int Rewind() {return -1;} - virtual ~OutStream() {} -protected: - OutStream() {} -}; - -enum TraceModule -{ - // not a module, triggered from the engine code - kTraceVoice = 0x0001, - // not a module, triggered from the engine code - kTraceVideo = 0x0002, - // not a module, triggered from the utility code - kTraceUtility = 0x0003, - kTraceRtpRtcp = 0x0004, - kTraceTransport = 0x0005, - kTraceSrtp = 0x0006, - kTraceAudioCoding = 0x0007, - kTraceAudioMixerServer = 0x0008, - kTraceAudioMixerClient = 0x0009, - kTraceFile = 0x000a, - kTraceAudioProcessing = 0x000b, - kTraceVideoCoding = 0x0010, - kTraceVideoMixer = 0x0011, - kTraceAudioDevice = 0x0012, - kTraceVideoRenderer = 0x0014, - kTraceVideoCapture = 0x0015, - kTraceVideoPreocessing = 0x0016 -}; - -enum TraceLevel -{ - kTraceNone = 0x0000, // no trace - kTraceStateInfo = 0x0001, - kTraceWarning = 0x0002, - kTraceError = 0x0004, - kTraceCritical = 0x0008, - kTraceApiCall = 0x0010, - kTraceDefault = 0x00ff, - - kTraceModuleCall = 0x0020, - kTraceMemory = 0x0100, // memory info - kTraceTimer = 0x0200, // timing info - kTraceStream = 0x0400, // "continuous" stream of data - - // used for debug purposes - kTraceDebug = 0x0800, // debug - kTraceInfo = 0x1000, // debug info - - kTraceAll = 0xffff -}; - -// External Trace API -class TraceCallback -{ -public: - virtual void Print(const TraceLevel level, - const char *traceString, - const int length) = 0; -protected: - virtual ~TraceCallback() {} - TraceCallback() {} -}; - - -enum FileFormats -{ - kFileFormatWavFile = 1, - kFileFormatCompressedFile = 2, - kFileFormatAviFile = 3, - kFileFormatPreencodedFile = 4, - kFileFormatPcm16kHzFile = 7, - kFileFormatPcm8kHzFile = 8, - kFileFormatPcm32kHzFile = 9 -}; - - -enum ProcessingTypes -{ - kPlaybackPerChannel = 0, - kPlaybackAllChannelsMixed, - kRecordingPerChannel, - kRecordingAllChannelsMixed -}; - -// Encryption enums -enum CipherTypes -{ - kCipherNull = 0, - kCipherAes128CounterMode = 1 -}; - -enum AuthenticationTypes -{ - kAuthNull = 0, - kAuthHmacSha1 = 3 -}; - -enum SecurityLevels -{ - kNoProtection = 0, - kEncryption = 1, - kAuthentication = 2, - kEncryptionAndAuthentication = 3 -}; - -class Encryption -{ -public: - virtual void encrypt( - int channel_no, - unsigned char* in_data, - unsigned char* out_data, - int bytes_in, - int* bytes_out) = 0; - - virtual void decrypt( - int channel_no, - unsigned char* in_data, - unsigned char* out_data, - int bytes_in, - int* bytes_out) = 0; - - virtual void encrypt_rtcp( - int channel_no, - unsigned char* in_data, - unsigned char* out_data, - int bytes_in, - int* bytes_out) = 0; - - virtual void decrypt_rtcp( - int channel_no, - unsigned char* in_data, - unsigned char* out_data, - int bytes_in, - int* bytes_out) = 0; - -protected: - virtual ~Encryption() {} - Encryption() {} -}; - -// External transport callback interface -class Transport -{ -public: - virtual int SendPacket(int channel, const void *data, int len) = 0; - virtual int SendRTCPPacket(int channel, const void *data, int len) = 0; - -protected: - virtual ~Transport() {} - Transport() {} -}; - -// ================================================================== -// Voice specific types -// ================================================================== - -// Each codec supported can be described by this structure. -struct CodecInst -{ - int pltype; - char plname[32]; - int plfreq; - int pacsize; - int channels; - int rate; -}; - -enum FrameType -{ - kFrameEmpty = 0, - kAudioFrameSpeech = 1, - kAudioFrameCN = 2, - kVideoFrameKey = 3, // independent frame - kVideoFrameDelta = 4, // depends on the previus frame - kVideoFrameGolden = 5, // depends on a old known previus frame - kVideoFrameAltRef = 6 -}; - -// RTP -enum {kRtpCsrcSize = 15}; // RFC 3550 page 13 - -enum RTPDirections -{ - kRtpIncoming = 0, - kRtpOutgoing -}; - -enum PayloadFrequencies -{ - kFreq8000Hz = 8000, - kFreq16000Hz = 16000, - kFreq32000Hz = 32000 -}; - -enum VadModes // degree of bandwidth reduction -{ - kVadConventional = 0, // lowest reduction - kVadAggressiveLow, - kVadAggressiveMid, - kVadAggressiveHigh // highest reduction -}; - -struct NetworkStatistics // NETEQ statistics -{ - // current jitter buffer size in ms - WebRtc_UWord16 currentBufferSize; - // preferred (optimal) buffer size in ms - WebRtc_UWord16 preferredBufferSize; - // loss rate (network + late) in percent (in Q14) - WebRtc_UWord16 currentPacketLossRate; - // late loss rate in percent (in Q14) - WebRtc_UWord16 currentDiscardRate; - // fraction (of original stream) of synthesized speech inserted through - // expansion (in Q14) - WebRtc_UWord16 currentExpandRate; - // fraction of synthesized speech inserted through pre-emptive expansion - // (in Q14) - WebRtc_UWord16 currentPreemptiveRate; - // fraction of data removed through acceleration (in Q14) - WebRtc_UWord16 currentAccelerateRate; -}; - -struct JitterStatistics -{ - // smallest Jitter Buffer size during call in ms - WebRtc_UWord32 jbMinSize; - // largest Jitter Buffer size during call in ms - WebRtc_UWord32 jbMaxSize; - // the average JB size, measured over time - ms - WebRtc_UWord32 jbAvgSize; - // number of times the Jitter Buffer changed (using Accelerate or - // Pre-emptive Expand) - WebRtc_UWord32 jbChangeCount; - // amount (in ms) of audio data received late - WebRtc_UWord32 lateLossMs; - // milliseconds removed to reduce jitter buffer size - WebRtc_UWord32 accelerateMs; - // milliseconds discarded through buffer flushing - WebRtc_UWord32 flushedMs; - // milliseconds of generated silence - WebRtc_UWord32 generatedSilentMs; - // milliseconds of synthetic audio data (non-background noise) - WebRtc_UWord32 interpolatedVoiceMs; - // milliseconds of synthetic audio data (background noise level) - WebRtc_UWord32 interpolatedSilentMs; - // count of tiny expansions in output audio - WebRtc_UWord32 countExpandMoreThan120ms; - // count of small expansions in output audio - WebRtc_UWord32 countExpandMoreThan250ms; - // count of medium expansions in output audio - WebRtc_UWord32 countExpandMoreThan500ms; - // count of long expansions in output audio - WebRtc_UWord32 countExpandMoreThan2000ms; - // duration of longest audio drop-out - WebRtc_UWord32 longestExpandDurationMs; - // count of times we got small network outage (inter-arrival time in - // [500, 1000) ms) - WebRtc_UWord32 countIAT500ms; - // count of times we got medium network outage (inter-arrival time in - // [1000, 2000) ms) - WebRtc_UWord32 countIAT1000ms; - // count of times we got large network outage (inter-arrival time >= - // 2000 ms) - WebRtc_UWord32 countIAT2000ms; - // longest packet inter-arrival time in ms - WebRtc_UWord32 longestIATms; - // min time incoming Packet "waited" to be played - WebRtc_UWord32 minPacketDelayMs; - // max time incoming Packet "waited" to be played - WebRtc_UWord32 maxPacketDelayMs; - // avg time incoming Packet "waited" to be played - WebRtc_UWord32 avgPacketDelayMs; -}; - -typedef struct -{ - int min; // minumum - int max; // maximum - int average; // average -} StatVal; - -typedef struct // All levels are reported in dBm0 -{ - StatVal speech_rx; // long-term speech levels on receiving side - StatVal speech_tx; // long-term speech levels on transmitting side - StatVal noise_rx; // long-term noise/silence levels on receiving side - StatVal noise_tx; // long-term noise/silence levels on transmitting side -} LevelStatistics; - -typedef struct // All levels are reported in dB -{ - StatVal erl; // Echo Return Loss - StatVal erle; // Echo Return Loss Enhancement - StatVal rerl; // RERL = ERL + ERLE - // Echo suppression inside EC at the point just before its NLP - StatVal a_nlp; -} EchoStatistics; - -enum TelephoneEventDetectionMethods -{ - kInBand = 0, - kOutOfBand = 1, - kInAndOutOfBand = 2 -}; - -enum NsModes // type of Noise Suppression -{ - kNsUnchanged = 0, // previously set mode - kNsDefault, // platform default - kNsConference, // conferencing default - kNsLowSuppression, // lowest suppression - kNsModerateSuppression, - kNsHighSuppression, - kNsVeryHighSuppression, // highest suppression -}; - -enum AgcModes // type of Automatic Gain Control -{ - kAgcUnchanged = 0, // previously set mode - kAgcDefault, // platform default - // adaptive mode for use when analog volume control exists (e.g. for - // PC softphone) - kAgcAdaptiveAnalog, - // scaling takes place in the digital domain (e.g. for conference servers - // and embedded devices) - kAgcAdaptiveDigital, - // can be used on embedded devices where the the capture signal is level - // is predictable - kAgcFixedDigital -}; - -// EC modes -enum EcModes // type of Echo Control -{ - kEcUnchanged = 0, // previously set mode - kEcDefault, // platform default - kEcConference, // conferencing default (aggressive AEC) - kEcAec, // Acoustic Echo Cancellation - kEcAecm, // AEC mobile -}; - -// AECM modes -enum AecmModes // mode of AECM -{ - kAecmQuietEarpieceOrHeadset = 0, - // Quiet earpiece or headset use - kAecmEarpiece, // most earpiece use - kAecmLoudEarpiece, // Loud earpiece or quiet speakerphone use - kAecmSpeakerphone, // most speakerphone use (default) - kAecmLoudSpeakerphone // Loud speakerphone -}; - -// AGC configuration -typedef struct -{ - unsigned short targetLeveldBOv; - unsigned short digitalCompressionGaindB; - bool limiterEnable; -} AgcConfig; // AGC configuration parameters - -enum StereoChannel -{ - kStereoLeft = 0, - kStereoRight, - kStereoBoth -}; - -// Audio device layers -enum AudioLayers -{ - kAudioPlatformDefault = 0, - kAudioWindowsWave = 1, - kAudioWindowsCore = 2, - kAudioLinuxAlsa = 3, - kAudioLinuxPulse = 4 -}; - -enum NetEqModes // NetEQ playout configurations -{ - // Optimized trade-off between low delay and jitter robustness for two-way - // communication. - kNetEqDefault = 0, - // Improved jitter robustness at the cost of increased delay. Can be - // used in one-way communication. - kNetEqStreaming = 1, - // Optimzed for decodability of fax signals rather than for perceived audio - // quality. - kNetEqFax = 2, -}; - -enum NetEqBgnModes // NetEQ Background Noise (BGN) configurations -{ - // BGN is always on and will be generated when the incoming RTP stream - // stops (default). - kBgnOn = 0, - // The BGN is faded to zero (complete silence) after a few seconds. - kBgnFade = 1, - // BGN is not used at all. Silence is produced after speech extrapolation - // has faded. - kBgnOff = 2, -}; - -enum OnHoldModes // On Hold direction -{ - kHoldSendAndPlay = 0, // Put both sending and playing in on-hold state. - kHoldSendOnly, // Put only sending in on-hold state. - kHoldPlayOnly // Put only playing in on-hold state. -}; - -enum AmrMode -{ - kRfc3267BwEfficient = 0, - kRfc3267OctetAligned = 1, - kRfc3267FileStorage = 2, -}; - -// ================================================================== -// Video specific types -// ================================================================== - -// Raw video types -enum RawVideoType -{ - kVideoI420 = 0, - kVideoYV12 = 1, - kVideoYUY2 = 2, - kVideoUYVY = 3, - kVideoIYUV = 4, - kVideoARGB = 5, - kVideoRGB24 = 6, - kVideoRGB565 = 7, - kVideoARGB4444 = 8, - kVideoARGB1555 = 9, - kVideoMJPEG = 10, - kVideoNV12 = 11, - kVideoNV21 = 12, - kVideoUnknown = 99 -}; - -// Video codec -enum { kConfigParameterSize = 128}; -enum { kPayloadNameSize = 32}; -enum { kMaxSimulcastStreams = 4}; - -// H.263 specific -struct VideoCodecH263 -{ - char quality; -}; - -// H.264 specific -enum H264Packetization -{ - kH264SingleMode = 0, - kH264NonInterleavedMode = 1 -}; - -enum VideoCodecComplexity -{ - kComplexityNormal = 0, - kComplexityHigh = 1, - kComplexityHigher = 2, - kComplexityMax = 3 -}; - -enum VideoCodecProfile -{ - kProfileBase = 0x00, - kProfileMain = 0x01 -}; - -struct VideoCodecH264 -{ - H264Packetization packetization; - VideoCodecComplexity complexity; - VideoCodecProfile profile; - char level; - char quality; - - bool useFMO; - - unsigned char configParameters[kConfigParameterSize]; - unsigned char configParametersSize; -}; - -// VP8 specific -struct VideoCodecVP8 -{ - bool pictureLossIndicationOn; - bool feedbackModeOn; - VideoCodecComplexity complexity; - unsigned char numberOfTemporalLayers; -}; - -// MPEG-4 specific -struct VideoCodecMPEG4 -{ - unsigned char configParameters[kConfigParameterSize]; - unsigned char configParametersSize; - char level; -}; - -// Unknown specific -struct VideoCodecGeneric -{ -}; - -// Video codec types -enum VideoCodecType -{ - kVideoCodecH263, - kVideoCodecH264, - kVideoCodecVP8, - kVideoCodecMPEG4, - kVideoCodecI420, - kVideoCodecRED, - kVideoCodecULPFEC, - kVideoCodecUnknown -}; - -union VideoCodecUnion -{ - VideoCodecH263 H263; - VideoCodecH264 H264; - VideoCodecVP8 VP8; - VideoCodecMPEG4 MPEG4; - VideoCodecGeneric Generic; -}; - -/* -* Simulcast is when the same stream is encoded multiple times with different -* settings such as resolution. -*/ -struct SimulcastStream -{ - unsigned short width; - unsigned short height; - unsigned char numberOfTemporalLayers; - unsigned int maxBitrate; - unsigned int qpMax; // minimum quality -}; - -// Common video codec properties -struct VideoCodec -{ - VideoCodecType codecType; - char plName[kPayloadNameSize]; - unsigned char plType; - - unsigned short width; - unsigned short height; - - unsigned int startBitrate; - unsigned int maxBitrate; - unsigned int minBitrate; - unsigned char maxFramerate; - - VideoCodecUnion codecSpecific; - - unsigned int qpMax; - unsigned char numberOfSimulcastStreams; - SimulcastStream simulcastStream[kMaxSimulcastStreams]; -}; -} // namespace webrtc -#endif // WEBRTC_COMMON_TYPES_H diff --git a/src/system_wrappers/OWNERS b/src/system_wrappers/OWNERS deleted file mode 100644 index 4091a93..0000000 --- a/src/system_wrappers/OWNERS +++ /dev/null @@ -1,7 +0,0 @@ -henrike@webrtc.org -pwestin@webrtc.org -perkj@webrtc.org -henrika@webrtc.org -henrikg@webrtc.org -mflodman@webrtc.org -niklas.enbom@webrtc.org \ No newline at end of file diff --git a/src/system_wrappers/interface/critical_section_wrapper.h b/src/system_wrappers/interface/critical_section_wrapper.h deleted file mode 100644 index ad31497..0000000 --- a/src/system_wrappers/interface/critical_section_wrapper.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ -#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ - -// If the critical section is heavily contended it may be beneficial to use -// read/write locks instead. - -#include "common_types.h" - -namespace webrtc { -class CriticalSectionWrapper -{ -public: - // Factory method, constructor disabled - static CriticalSectionWrapper* CreateCriticalSection(); - - virtual ~CriticalSectionWrapper() {} - - // Tries to grab lock, beginning of a critical section. Will wait for the - // lock to become available if the grab failed. - virtual void Enter() = 0; - - // Returns a grabbed lock, end of critical section. - virtual void Leave() = 0; -}; - -// RAII extension of the critical section. Prevents Enter/Leave missmatches and -// provides more compact critical section syntax. -class CriticalSectionScoped -{ -public: - CriticalSectionScoped(CriticalSectionWrapper& critsec) - : - _ptrCritSec(&critsec) - { - _ptrCritSec->Enter(); - } - - ~CriticalSectionScoped() - { - if (_ptrCritSec) - { - Leave(); - } - } - -private: - void Leave() - { - _ptrCritSec->Leave(); - _ptrCritSec = 0; - } - - CriticalSectionWrapper* _ptrCritSec; -}; -} // namespace webrtc -#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ diff --git a/src/typedefs.h b/src/typedefs.h deleted file mode 100644 index ba87309..0000000 --- a/src/typedefs.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file contains platform-specific typedefs and defines. - -#ifndef WEBRTC_TYPEDEFS_H_ -#define WEBRTC_TYPEDEFS_H_ - -// Reserved words definitions -// TODO(andrew): Look at removing these. -#define WEBRTC_EXTERN extern -#define G_CONST const -#define WEBRTC_INLINE extern __inline - -// Define WebRTC preprocessor identifiers based on the current build platform. -// TODO(andrew): Clean these up. We can probably remove everything in this -// block. -// - TARGET_MAC_INTEL and TARGET_MAC aren't used anywhere. -// - In the few places where TARGET_PC is used, it should be replaced by -// something more specific. -// - Do we really support PowerPC? Probably not. Remove WEBRTC_MAC_INTEL -// from build/common.gypi as well. -#if defined(WIN32) - // Windows & Windows Mobile. - #if !defined(WEBRTC_TARGET_PC) - #define WEBRTC_TARGET_PC - #endif -#elif defined(__APPLE__) - // Mac OS X. - #if defined(__LITTLE_ENDIAN__ ) - #if !defined(WEBRTC_TARGET_MAC_INTEL) - #define WEBRTC_TARGET_MAC_INTEL - #endif - #else - #if !defined(WEBRTC_TARGET_MAC) - #define WEBRTC_TARGET_MAC - #endif - #endif -#else - // Linux etc. - #if !defined(WEBRTC_TARGET_PC) - #define WEBRTC_TARGET_PC - #endif -#endif - -// Derived from Chromium's build/build_config.h -// Processor architecture detection. For more info on what's defined, see: -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx -// http://www.agner.org/optimize/calling_conventions.pdf -// or with gcc, run: "echo | gcc -E -dM -" -// TODO(andrew): replace WEBRTC_LITTLE_ENDIAN with WEBRTC_ARCH_LITTLE_ENDIAN? -#if defined(_M_X64) || defined(__x86_64__) -#define WEBRTC_ARCH_X86_FAMILY -#define WEBRTC_ARCH_X86_64 -#define WEBRTC_ARCH_64_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(_M_IX86) || defined(__i386__) -#define WEBRTC_ARCH_X86_FAMILY -#define WEBRTC_ARCH_X86 -#define WEBRTC_ARCH_32_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#elif defined(__ARMEL__) -// TODO(andrew): We'd prefer to control platform defines here, but this is -// currently provided by the Android makefiles. Commented to avoid duplicate -// definition warnings. -//#define WEBRTC_ARCH_ARM -// TODO(andrew): Chromium uses the following two defines. Should we switch? -//#define WEBRTC_ARCH_ARM_FAMILY -//#define WEBRTC_ARCH_ARMEL -#define WEBRTC_ARCH_32_BITS -#define WEBRTC_ARCH_LITTLE_ENDIAN -#else -#error Please add support for your architecture in typedefs.h -#endif - -#if defined(__SSE2__) || defined(_MSC_VER) -#define WEBRTC_USE_SSE2 -#endif - -#if defined(WEBRTC_TARGET_PC) - -#if !defined(_MSC_VER) - #include -#else - // Define C99 equivalent types. - // Since MSVC doesn't include these headers, we have to write our own - // version to provide a compatibility layer between MSVC and the WebRTC - // headers. - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef signed long long int64_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - typedef unsigned long long uint64_t; -#endif - -#if defined(WIN32) - typedef __int64 WebRtc_Word64; - typedef unsigned __int64 WebRtc_UWord64; -#else - typedef int64_t WebRtc_Word64; - typedef uint64_t WebRtc_UWord64; -#endif - typedef int32_t WebRtc_Word32; - typedef uint32_t WebRtc_UWord32; - typedef int16_t WebRtc_Word16; - typedef uint16_t WebRtc_UWord16; - typedef char WebRtc_Word8; - typedef uint8_t WebRtc_UWord8; - - // Define endian for the platform - #define WEBRTC_LITTLE_ENDIAN - -#elif defined(WEBRTC_TARGET_MAC_INTEL) - #include - - typedef int64_t WebRtc_Word64; - typedef uint64_t WebRtc_UWord64; - typedef int32_t WebRtc_Word32; - typedef uint32_t WebRtc_UWord32; - typedef int16_t WebRtc_Word16; - typedef char WebRtc_Word8; - typedef uint16_t WebRtc_UWord16; - typedef uint8_t WebRtc_UWord8; - - // Define endian for the platform - #define WEBRTC_LITTLE_ENDIAN - -#else - #error "No platform defined for WebRTC type definitions (typedefs.h)" -#endif - -#endif // WEBRTC_TYPEDEFS_H_ diff --git a/src/Makefile.am b/webrtc/Makefile.am similarity index 100% rename from src/Makefile.am rename to webrtc/Makefile.am diff --git a/webrtc/base/checks.h b/webrtc/base/checks.h new file mode 100644 index 0000000..98e896a --- /dev/null +++ b/webrtc/base/checks.h @@ -0,0 +1,227 @@ +/* + * Copyright 2006 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_CHECKS_H_ +#define WEBRTC_BASE_CHECKS_H_ + +#include +#include + +#include "webrtc/typedefs.h" + +// The macros here print a message to stderr and abort under various +// conditions. All will accept additional stream messages. For example: +// RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar."; +// +// - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't, +// it's better to terminate the process than to continue. During development, +// the reason that it's better to terminate might simply be that the error +// handling code isn't in place yet; in production, the reason might be that +// the author of the code truly believes that x will always be true, but that +// she recognizes that if she is wrong, abrupt and unpleasant process +// termination is still better than carrying on with the assumption violated. +// +// RTC_CHECK always evaluates its argument, so it's OK for x to have side +// effects. +// +// - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always +// true---except that x will only be evaluated in debug builds; in production +// builds, x is simply assumed to be true. This is useful if evaluating x is +// expensive and the expected cost of failing to detect the violated +// assumption is acceptable. You should not handle cases where a production +// build fails to spot a violated condition, even those that would result in +// crashes. If the code needs to cope with the error, make it cope, but don't +// call RTC_DCHECK; if the condition really can't occur, but you'd sleep +// better at night knowing that the process will suicide instead of carrying +// on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK. +// +// RTC_DCHECK only evaluates its argument in debug builds, so if x has visible +// side effects, you need to write e.g. +// bool w = x; RTC_DCHECK(w); +// +// - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are +// specialized variants of RTC_CHECK and RTC_DCHECK that print prettier +// messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and +// RTC_DCHECK. +// +// - FATAL() aborts unconditionally. +// +// TODO(ajm): Ideally, checks.h would be combined with logging.h, but +// consolidation with system_wrappers/logging.h should happen first. + +namespace rtc { + +// Helper macro which avoids evaluating the arguments to a stream if +// the condition doesn't hold. +#define RTC_LAZY_STREAM(stream, condition) \ + !(condition) ? static_cast(0) : rtc::FatalMessageVoidify() & (stream) + +// The actual stream used isn't important. We reference condition in the code +// but don't evaluate it; this is to avoid "unused variable" warnings (we do so +// in a particularly convoluted way with an extra ?: because that appears to be +// the simplest construct that keeps Visual Studio from complaining about +// condition being unused). +#define RTC_EAT_STREAM_PARAMETERS(condition) \ + (true ? true : !(condition)) \ + ? static_cast(0) \ + : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream() + +// RTC_CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. +// +// We make sure RTC_CHECK et al. always evaluates their arguments, as +// doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom. +#define RTC_CHECK(condition) \ + RTC_LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), \ + !(condition)) \ + << "Check failed: " #condition << std::endl << "# " + +// Helper macro for binary operators. +// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below. +// +// TODO(akalin): Rewrite this so that constructs like if (...) +// RTC_CHECK_EQ(...) else { ... } work properly. +#define RTC_CHECK_OP(name, op, val1, val2) \ + if (std::string* _result = \ + rtc::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ + rtc::FatalMessage(__FILE__, __LINE__, _result).stream() + +// Build the error message string. This is separate from the "Impl" +// function template because it is not performance critical and so can +// be out of line, while the "Impl" code should be inline. Caller +// takes ownership of the returned string. +template +std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { + std::ostringstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + std::string* msg = new std::string(ss.str()); + return msg; +} + +// MSVC doesn't like complex extern templates and DLLs. +#if !defined(COMPILER_MSVC) +// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated +// in logging.cc. +extern template std::string* MakeCheckOpString( + const int&, const int&, const char* names); +extern template +std::string* MakeCheckOpString( + const unsigned long&, const unsigned long&, const char* names); +extern template +std::string* MakeCheckOpString( + const unsigned long&, const unsigned int&, const char* names); +extern template +std::string* MakeCheckOpString( + const unsigned int&, const unsigned long&, const char* names); +extern template +std::string* MakeCheckOpString( + const std::string&, const std::string&, const char* name); +#endif + +// Helper functions for RTC_CHECK_OP macro. +// The (int, int) specialization works around the issue that the compiler +// will not instantiate the template version of the function on values of +// unnamed enum type - see comment below. +#define DEFINE_RTC_CHECK_OP_IMPL(name, op) \ + template \ + inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ + const char* names) { \ + if (v1 op v2) \ + return NULL; \ + else \ + return rtc::MakeCheckOpString(v1, v2, names); \ + } \ + inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ + if (v1 op v2) \ + return NULL; \ + else \ + return rtc::MakeCheckOpString(v1, v2, names); \ + } +DEFINE_RTC_CHECK_OP_IMPL(EQ, ==) +DEFINE_RTC_CHECK_OP_IMPL(NE, !=) +DEFINE_RTC_CHECK_OP_IMPL(LE, <=) +DEFINE_RTC_CHECK_OP_IMPL(LT, < ) +DEFINE_RTC_CHECK_OP_IMPL(GE, >=) +DEFINE_RTC_CHECK_OP_IMPL(GT, > ) +#undef DEFINE_RTC_CHECK_OP_IMPL + +#define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(EQ, ==, val1, val2) +#define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(NE, !=, val1, val2) +#define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(LE, <=, val1, val2) +#define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(LT, < , val1, val2) +#define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(GE, >=, val1, val2) +#define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(GT, > , val1, val2) + +// The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates +// code in debug builds. It does reference the condition parameter in all cases, +// though, so callers won't risk getting warnings about unused variables. +#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) +#define RTC_DCHECK(condition) RTC_CHECK(condition) +#define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2) +#define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2) +#define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2) +#define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2) +#define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2) +#define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2) +#else +#define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition) +#define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) == (v2)) +#define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) != (v2)) +#define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) <= (v2)) +#define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) < (v2)) +#define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) >= (v2)) +#define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) > (v2)) +#endif + +// This is identical to LogMessageVoidify but in name. +class FatalMessageVoidify { + public: + FatalMessageVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(std::ostream&) { } +}; + +#define RTC_UNREACHABLE_CODE_HIT false +#define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT) + +#define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream() +// TODO(ajm): Consider adding RTC_NOTIMPLEMENTED macro when +// base/logging.h and system_wrappers/logging.h are consolidated such that we +// can match the Chromium behavior. + +// Like a stripped-down LogMessage from logging.h, except that it aborts. +class FatalMessage { + public: + FatalMessage(const char* file, int line); + // Used for RTC_CHECK_EQ(), etc. Takes ownership of the given string. + FatalMessage(const char* file, int line, std::string* result); + NO_RETURN ~FatalMessage(); + + std::ostream& stream() { return stream_; } + + private: + void Init(const char* file, int line); + + std::ostringstream stream_; +}; + +// Performs the integer division a/b and returns the result. CHECKs that the +// remainder is zero. +template +inline T CheckedDivExact(T a, T b) { + RTC_CHECK_EQ(a % b, static_cast(0)); + return a / b; +} + +} // namespace rtc + +#endif // WEBRTC_BASE_CHECKS_H_ diff --git a/webrtc/base/constructormagic.h b/webrtc/base/constructormagic.h new file mode 100644 index 0000000..6ef7826 --- /dev/null +++ b/webrtc/base/constructormagic.h @@ -0,0 +1,34 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_CONSTRUCTORMAGIC_H_ +#define WEBRTC_BASE_CONSTRUCTORMAGIC_H_ + +// Put this in the declarations for a class to be unassignable. +#define RTC_DISALLOW_ASSIGN(TypeName) \ + void operator=(const TypeName&) = delete + +// A macro to disallow the copy constructor and operator= functions. This should +// be used in the declarations for a class. +#define RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + RTC_DISALLOW_ASSIGN(TypeName) + +// A macro to disallow all the implicit constructors, namely the default +// constructor, copy constructor and operator= functions. +// +// This should be used in the declarations for a class that wants to prevent +// anyone from instantiating it. This is especially useful for classes +// containing only static methods. +#define RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName() = delete; \ + RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) + +#endif // WEBRTC_BASE_CONSTRUCTORMAGIC_H_ diff --git a/webrtc/base/scoped_ptr.h b/webrtc/base/scoped_ptr.h new file mode 100644 index 0000000..203a001 --- /dev/null +++ b/webrtc/base/scoped_ptr.h @@ -0,0 +1,636 @@ +/* + * Copyright 2012 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Borrowed from Chromium's src/base/memory/scoped_ptr.h. + +// Scopers help you manage ownership of a pointer, helping you easily manage a +// pointer within a scope, and automatically destroying the pointer at the end +// of a scope. There are two main classes you will use, which correspond to the +// operators new/delete and new[]/delete[]. +// +// Example usage (scoped_ptr): +// { +// scoped_ptr foo(new Foo("wee")); +// } // foo goes out of scope, releasing the pointer with it. +// +// { +// scoped_ptr foo; // No pointer managed. +// foo.reset(new Foo("wee")); // Now a pointer is managed. +// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. +// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. +// foo->Method(); // Foo::Method() called. +// foo.get()->Method(); // Foo::Method() called. +// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer +// // manages a pointer. +// foo.reset(new Foo("wee4")); // foo manages a pointer again. +// foo.reset(); // Foo("wee4") destroyed, foo no longer +// // manages a pointer. +// } // foo wasn't managing a pointer, so nothing was destroyed. +// +// Example usage (scoped_ptr): +// { +// scoped_ptr foo(new Foo[100]); +// foo.get()->Method(); // Foo::Method on the 0th element. +// foo[10].Method(); // Foo::Method on the 10th element. +// } +// +// These scopers also implement part of the functionality of C++11 unique_ptr +// in that they are "movable but not copyable." You can use the scopers in +// the parameter and return types of functions to signify ownership transfer +// in to and out of a function. When calling a function that has a scoper +// as the argument type, it must be called with the result of an analogous +// scoper's Pass() function or another function that generates a temporary; +// passing by copy will NOT work. Here is an example using scoped_ptr: +// +// void TakesOwnership(scoped_ptr arg) { +// // Do something with arg +// } +// scoped_ptr CreateFoo() { +// // No need for calling Pass() because we are constructing a temporary +// // for the return value. +// return scoped_ptr(new Foo("new")); +// } +// scoped_ptr PassThru(scoped_ptr arg) { +// return arg.Pass(); +// } +// +// { +// scoped_ptr ptr(new Foo("yay")); // ptr manages Foo("yay"). +// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). +// scoped_ptr ptr2 = CreateFoo(); // ptr2 owns the return Foo. +// scoped_ptr ptr3 = // ptr3 now owns what was in ptr2. +// PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr. +// } +// +// Notice that if you do not call Pass() when returning from PassThru(), or +// when invoking TakesOwnership(), the code will not compile because scopers +// are not copyable; they only implement move semantics which require calling +// the Pass() function to signify a destructive transfer of state. CreateFoo() +// is different though because we are constructing a temporary on the return +// line and thus can avoid needing to call Pass(). +// +// Pass() properly handles upcast in initialization, i.e. you can use a +// scoped_ptr to initialize a scoped_ptr: +// +// scoped_ptr foo(new Foo()); +// scoped_ptr parent(foo.Pass()); +// +// PassAs<>() should be used to upcast return value in return statement: +// +// scoped_ptr CreateFoo() { +// scoped_ptr result(new FooChild()); +// return result.PassAs(); +// } +// +// Note that PassAs<>() is implemented only for scoped_ptr, but not for +// scoped_ptr. This is because casting array pointers may not be safe. + +#ifndef WEBRTC_BASE_SCOPED_PTR_H__ +#define WEBRTC_BASE_SCOPED_PTR_H__ + +// This is an implementation designed to match the anticipated future TR2 +// implementation of the scoped_ptr class. + +#include +#include +#include + +#include // For std::swap(). + +#include "webrtc/base/constructormagic.h" +#include "webrtc/base/template_util.h" +#include "webrtc/typedefs.h" + +namespace rtc { + +// Function object which deletes its parameter, which must be a pointer. +// If C is an array type, invokes 'delete[]' on the parameter; otherwise, +// invokes 'delete'. The default deleter for scoped_ptr. +template +struct DefaultDeleter { + DefaultDeleter() {} + template DefaultDeleter(const DefaultDeleter& other) { + // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor + // if U* is implicitly convertible to T* and U is not an array type. + // + // Correct implementation should use SFINAE to disable this + // constructor. However, since there are no other 1-argument constructors, + // using a static_assert based on is_convertible<> and requiring + // complete types is simpler and will cause compile failures for equivalent + // misuses. + // + // Note, the is_convertible check also ensures that U is not an + // array. T is guaranteed to be a non-array, so any U* where U is an array + // cannot convert to T*. + enum { T_must_be_complete = sizeof(T) }; + enum { U_must_be_complete = sizeof(U) }; + static_assert(rtc::is_convertible::value, + "U* must implicitly convert to T*"); + } + inline void operator()(T* ptr) const { + enum { type_must_be_complete = sizeof(T) }; + delete ptr; + } +}; + +// Specialization of DefaultDeleter for array types. +template +struct DefaultDeleter { + inline void operator()(T* ptr) const { + enum { type_must_be_complete = sizeof(T) }; + delete[] ptr; + } + + private: + // Disable this operator for any U != T because it is undefined to execute + // an array delete when the static type of the array mismatches the dynamic + // type. + // + // References: + // C++98 [expr.delete]p3 + // http://cplusplus.github.com/LWG/lwg-defects.html#938 + template void operator()(U* array) const; +}; + +template +struct DefaultDeleter { + // Never allow someone to declare something like scoped_ptr. + static_assert(sizeof(T) == -1, "do not use array with size as type"); +}; + +// Function object which invokes 'free' on its parameter, which must be +// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: +// +// scoped_ptr foo_ptr( +// static_cast(malloc(sizeof(int)))); +struct FreeDeleter { + inline void operator()(void* ptr) const { + free(ptr); + } +}; + +namespace internal { + +template +struct ShouldAbortOnSelfReset { + template + static rtc::internal::NoType Test(const typename U::AllowSelfReset*); + + template + static rtc::internal::YesType Test(...); + + static const bool value = + sizeof(Test(0)) == sizeof(rtc::internal::YesType); +}; + +// Minimal implementation of the core logic of scoped_ptr, suitable for +// reuse in both scoped_ptr and its specializations. +template +class scoped_ptr_impl { + public: + explicit scoped_ptr_impl(T* p) : data_(p) {} + + // Initializer for deleters that have data parameters. + scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} + + // Templated constructor that destructively takes the value from another + // scoped_ptr_impl. + template + scoped_ptr_impl(scoped_ptr_impl* other) + : data_(other->release(), other->get_deleter()) { + // We do not support move-only deleters. We could modify our move + // emulation to have rtc::subtle::move() and rtc::subtle::forward() + // functions that are imperfect emulations of their C++11 equivalents, + // but until there's a requirement, just assume deleters are copyable. + } + + template + void TakeState(scoped_ptr_impl* other) { + // See comment in templated constructor above regarding lack of support + // for move-only deleters. + reset(other->release()); + get_deleter() = other->get_deleter(); + } + + ~scoped_ptr_impl() { + if (data_.ptr != nullptr) { + // Not using get_deleter() saves one function call in non-optimized + // builds. + static_cast(data_)(data_.ptr); + } + } + + void reset(T* p) { + // This is a self-reset, which is no longer allowed for default deleters: + // https://crbug.com/162971 + assert(!ShouldAbortOnSelfReset::value || p == nullptr || p != data_.ptr); + + // Note that running data_.ptr = p can lead to undefined behavior if + // get_deleter()(get()) deletes this. In order to prevent this, reset() + // should update the stored pointer before deleting its old value. + // + // However, changing reset() to use that behavior may cause current code to + // break in unexpected ways. If the destruction of the owned object + // dereferences the scoped_ptr when it is destroyed by a call to reset(), + // then it will incorrectly dispatch calls to |p| rather than the original + // value of |data_.ptr|. + // + // During the transition period, set the stored pointer to nullptr while + // deleting the object. Eventually, this safety check will be removed to + // prevent the scenario initially described from occurring and + // http://crbug.com/176091 can be closed. + T* old = data_.ptr; + data_.ptr = nullptr; + if (old != nullptr) + static_cast(data_)(old); + data_.ptr = p; + } + + T* get() const { return data_.ptr; } + + D& get_deleter() { return data_; } + const D& get_deleter() const { return data_; } + + void swap(scoped_ptr_impl& p2) { + // Standard swap idiom: 'using std::swap' ensures that std::swap is + // present in the overload set, but we call swap unqualified so that + // any more-specific overloads can be used, if available. + using std::swap; + swap(static_cast(data_), static_cast(p2.data_)); + swap(data_.ptr, p2.data_.ptr); + } + + T* release() { + T* old_ptr = data_.ptr; + data_.ptr = nullptr; + return old_ptr; + } + + T** accept() { + reset(nullptr); + return &(data_.ptr); + } + + T** use() { + return &(data_.ptr); + } + + private: + // Needed to allow type-converting constructor. + template friend class scoped_ptr_impl; + + // Use the empty base class optimization to allow us to have a D + // member, while avoiding any space overhead for it when D is an + // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good + // discussion of this technique. + struct Data : public D { + explicit Data(T* ptr_in) : ptr(ptr_in) {} + Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} + T* ptr; + }; + + Data data_; + + RTC_DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); +}; + +} // namespace internal + +// A scoped_ptr is like a T*, except that the destructor of scoped_ptr +// automatically deletes the pointer it holds (if any). +// That is, scoped_ptr owns the T object that it points to. +// Like a T*, a scoped_ptr may hold either nullptr or a pointer to a T +// object. Also like T*, scoped_ptr is thread-compatible, and once you +// dereference it, you get the thread safety guarantees of T. +// +// The size of scoped_ptr is small. On most compilers, when using the +// DefaultDeleter, sizeof(scoped_ptr) == sizeof(T*). Custom deleters will +// increase the size proportional to whatever state they need to have. See +// comments inside scoped_ptr_impl<> for details. +// +// Current implementation targets having a strict subset of C++11's +// unique_ptr<> features. Known deficiencies include not supporting move-only +// deleters, function pointers as deleters, and deleters with reference +// types. +template > +class scoped_ptr { + + // TODO(ajm): If we ever import RefCountedBase, this check needs to be + // enabled. + //static_assert(rtc::internal::IsNotRefCounted::value, + // "T is refcounted type and needs scoped refptr"); + + public: + // The element and deleter types. + typedef T element_type; + typedef D deleter_type; + + // Constructor. Defaults to initializing with nullptr. + scoped_ptr() : impl_(nullptr) {} + + // Constructor. Takes ownership of p. + explicit scoped_ptr(element_type* p) : impl_(p) {} + + // Constructor. Allows initialization of a stateful deleter. + scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} + + // Constructor. Allows construction from a nullptr. + scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} + + // Constructor. Allows construction from a scoped_ptr rvalue for a + // convertible type and deleter. + // + // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct + // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor + // has different post-conditions if D is a reference type. Since this + // implementation does not support deleters with reference type, + // we do not need a separate move constructor allowing us to avoid one + // use of SFINAE. You only need to care about this if you modify the + // implementation of scoped_ptr. + template + scoped_ptr(scoped_ptr&& other) + : impl_(&other.impl_) { + static_assert(!rtc::is_array::value, "U cannot be an array"); + } + + // operator=. Allows assignment from a scoped_ptr rvalue for a convertible + // type and deleter. + // + // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from + // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated + // form has different requirements on for move-only Deleters. Since this + // implementation does not support move-only Deleters, we do not need a + // separate move assignment operator allowing us to avoid one use of SFINAE. + // You only need to care about this if you modify the implementation of + // scoped_ptr. + template + scoped_ptr& operator=(scoped_ptr&& rhs) { + static_assert(!rtc::is_array::value, "U cannot be an array"); + impl_.TakeState(&rhs.impl_); + return *this; + } + + // operator=. Allows assignment from a nullptr. Deletes the currently owned + // object, if any. + scoped_ptr& operator=(decltype(nullptr)) { + reset(); + return *this; + } + + // Deleted copy constructor and copy assignment, to make the type move-only. + scoped_ptr(const scoped_ptr& other) = delete; + scoped_ptr& operator=(const scoped_ptr& other) = delete; + + // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).) + scoped_ptr&& Pass() { return static_cast(*this); } + + // Reset. Deletes the currently owned object, if any. + // Then takes ownership of a new object, if given. + void reset(element_type* p = nullptr) { impl_.reset(p); } + + // Accessors to get the owned object. + // operator* and operator-> will assert() if there is no current object. + element_type& operator*() const { + assert(impl_.get() != nullptr); + return *impl_.get(); + } + element_type* operator->() const { + assert(impl_.get() != nullptr); + return impl_.get(); + } + element_type* get() const { return impl_.get(); } + + // Access to the deleter. + deleter_type& get_deleter() { return impl_.get_deleter(); } + const deleter_type& get_deleter() const { return impl_.get_deleter(); } + + // Allow scoped_ptr to be used in boolean expressions, but not + // implicitly convertible to a real bool (which is dangerous). + // + // Note that this trick is only safe when the == and != operators + // are declared explicitly, as otherwise "scoped_ptr1 == + // scoped_ptr2" will compile but do the wrong thing (i.e., convert + // to Testable and then do the comparison). + private: + typedef rtc::internal::scoped_ptr_impl + scoped_ptr::*Testable; + + public: + operator Testable() const { + return impl_.get() ? &scoped_ptr::impl_ : nullptr; + } + + // Comparison operators. + // These return whether two scoped_ptr refer to the same object, not just to + // two different but equal objects. + bool operator==(const element_type* p) const { return impl_.get() == p; } + bool operator!=(const element_type* p) const { return impl_.get() != p; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + impl_.swap(p2.impl_); + } + + // Release a pointer. + // The return value is the current pointer held by this object. If this object + // holds a nullptr, the return value is nullptr. After this operation, this + // object will hold a nullptr, and will not own the object any more. + element_type* release() WARN_UNUSED_RESULT { + return impl_.release(); + } + + // Delete the currently held pointer and return a pointer + // to allow overwriting of the current pointer address. + element_type** accept() WARN_UNUSED_RESULT { + return impl_.accept(); + } + + // Return a pointer to the current pointer address. + element_type** use() WARN_UNUSED_RESULT { + return impl_.use(); + } + + private: + // Needed to reach into |impl_| in the constructor. + template friend class scoped_ptr; + rtc::internal::scoped_ptr_impl impl_; + + // Forbidden for API compatibility with std::unique_ptr. + explicit scoped_ptr(int disallow_construction_from_null); + + // Forbid comparison of scoped_ptr types. If U != T, it totally + // doesn't make sense, and if U == T, it still doesn't make sense + // because you should never have the same object owned by two different + // scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; +}; + +template +class scoped_ptr { + public: + // The element and deleter types. + typedef T element_type; + typedef D deleter_type; + + // Constructor. Defaults to initializing with nullptr. + scoped_ptr() : impl_(nullptr) {} + + // Constructor. Stores the given array. Note that the argument's type + // must exactly match T*. In particular: + // - it cannot be a pointer to a type derived from T, because it is + // inherently unsafe in the general case to access an array through a + // pointer whose dynamic type does not match its static type (eg., if + // T and the derived types had different sizes access would be + // incorrectly calculated). Deletion is also always undefined + // (C++98 [expr.delete]p3). If you're doing this, fix your code. + // - it cannot be const-qualified differently from T per unique_ptr spec + // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting + // to work around this may use implicit_cast(). + // However, because of the first bullet in this comment, users MUST + // NOT use implicit_cast() to upcast the static type of the array. + explicit scoped_ptr(element_type* array) : impl_(array) {} + + // Constructor. Allows construction from a nullptr. + scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} + + // Constructor. Allows construction from a scoped_ptr rvalue. + scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} + + // operator=. Allows assignment from a scoped_ptr rvalue. + scoped_ptr& operator=(scoped_ptr&& rhs) { + impl_.TakeState(&rhs.impl_); + return *this; + } + + // operator=. Allows assignment from a nullptr. Deletes the currently owned + // array, if any. + scoped_ptr& operator=(decltype(nullptr)) { + reset(); + return *this; + } + + // Deleted copy constructor and copy assignment, to make the type move-only. + scoped_ptr(const scoped_ptr& other) = delete; + scoped_ptr& operator=(const scoped_ptr& other) = delete; + + // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).) + scoped_ptr&& Pass() { return static_cast(*this); } + + // Reset. Deletes the currently owned array, if any. + // Then takes ownership of a new object, if given. + void reset(element_type* array = nullptr) { impl_.reset(array); } + + // Accessors to get the owned array. + element_type& operator[](size_t i) const { + assert(impl_.get() != nullptr); + return impl_.get()[i]; + } + element_type* get() const { return impl_.get(); } + + // Access to the deleter. + deleter_type& get_deleter() { return impl_.get_deleter(); } + const deleter_type& get_deleter() const { return impl_.get_deleter(); } + + // Allow scoped_ptr to be used in boolean expressions, but not + // implicitly convertible to a real bool (which is dangerous). + private: + typedef rtc::internal::scoped_ptr_impl + scoped_ptr::*Testable; + + public: + operator Testable() const { + return impl_.get() ? &scoped_ptr::impl_ : nullptr; + } + + // Comparison operators. + // These return whether two scoped_ptr refer to the same object, not just to + // two different but equal objects. + bool operator==(element_type* array) const { return impl_.get() == array; } + bool operator!=(element_type* array) const { return impl_.get() != array; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + impl_.swap(p2.impl_); + } + + // Release a pointer. + // The return value is the current pointer held by this object. If this object + // holds a nullptr, the return value is nullptr. After this operation, this + // object will hold a nullptr, and will not own the object any more. + element_type* release() WARN_UNUSED_RESULT { + return impl_.release(); + } + + // Delete the currently held pointer and return a pointer + // to allow overwriting of the current pointer address. + element_type** accept() WARN_UNUSED_RESULT { + return impl_.accept(); + } + + // Return a pointer to the current pointer address. + element_type** use() WARN_UNUSED_RESULT { + return impl_.use(); + } + + private: + // Force element_type to be a complete type. + enum { type_must_be_complete = sizeof(element_type) }; + + // Actually hold the data. + rtc::internal::scoped_ptr_impl impl_; + + // Disable initialization from any type other than element_type*, by + // providing a constructor that matches such an initialization, but is + // private and has no definition. This is disabled because it is not safe to + // call delete[] on an array whose static type does not match its dynamic + // type. + template explicit scoped_ptr(U* array); + explicit scoped_ptr(int disallow_construction_from_null); + + // Disable reset() from any type other than element_type*, for the same + // reasons as the constructor above. + template void reset(U* array); + void reset(int disallow_reset_from_null); + + // Forbid comparison of scoped_ptr types. If U != T, it totally + // doesn't make sense, and if U == T, it still doesn't make sense + // because you should never have the same object owned by two different + // scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; +}; + +template +void swap(rtc::scoped_ptr& p1, rtc::scoped_ptr& p2) { + p1.swap(p2); +} + +} // namespace rtc + +template +bool operator==(T* p1, const rtc::scoped_ptr& p2) { + return p1 == p2.get(); +} + +template +bool operator!=(T* p1, const rtc::scoped_ptr& p2) { + return p1 != p2.get(); +} + +// A function to convert T* into scoped_ptr +// Doing e.g. make_scoped_ptr(new FooBarBaz(arg)) is a shorter notation +// for scoped_ptr >(new FooBarBaz(arg)) +template +rtc::scoped_ptr rtc_make_scoped_ptr(T* ptr) { + return rtc::scoped_ptr(ptr); +} + +#endif // #ifndef WEBRTC_BASE_SCOPED_PTR_H__ diff --git a/webrtc/base/template_util.h b/webrtc/base/template_util.h new file mode 100644 index 0000000..86e541d --- /dev/null +++ b/webrtc/base/template_util.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Borrowed from Chromium's src/base/template_util.h. + +#ifndef WEBRTC_BASE_TEMPLATE_UTIL_H_ +#define WEBRTC_BASE_TEMPLATE_UTIL_H_ + +#include // For size_t. + +namespace rtc { + +// Template definitions from tr1. + +template +struct integral_constant { + static const T value = v; + typedef T value_type; + typedef integral_constant type; +}; + +template const T integral_constant::value; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template struct is_pointer : false_type {}; +template struct is_pointer : true_type {}; + +template struct is_same : public false_type {}; +template struct is_same : true_type {}; + +template struct is_array : public false_type {}; +template struct is_array : public true_type {}; +template struct is_array : public true_type {}; + +template struct is_non_const_reference : false_type {}; +template struct is_non_const_reference : true_type {}; +template struct is_non_const_reference : false_type {}; + +template struct is_void : false_type {}; +template <> struct is_void : true_type {}; + +namespace internal { + +// Types YesType and NoType are guaranteed such that sizeof(YesType) < +// sizeof(NoType). +typedef char YesType; + +struct NoType { + YesType dummy[2]; +}; + +// This class is an implementation detail for is_convertible, and you +// don't need to know how it works to use is_convertible. For those +// who care: we declare two different functions, one whose argument is +// of type To and one with a variadic argument list. We give them +// return types of different size, so we can use sizeof to trick the +// compiler into telling us which function it would have chosen if we +// had called it with an argument of type From. See Alexandrescu's +// _Modern C++ Design_ for more details on this sort of trick. + +struct ConvertHelper { + template + static YesType Test(To); + + template + static NoType Test(...); + + template + static From& Create(); +}; + +// Used to determine if a type is a struct/union/class. Inspired by Boost's +// is_class type_trait implementation. +struct IsClassHelper { + template + static YesType Test(void(C::*)(void)); + + template + static NoType Test(...); +}; + +} // namespace internal + +// Inherits from true_type if From is convertible to To, false_type otherwise. +// +// Note that if the type is convertible, this will be a true_type REGARDLESS +// of whether or not the conversion would emit a warning. +template +struct is_convertible + : integral_constant( + internal::ConvertHelper::Create())) == + sizeof(internal::YesType)> { +}; + +template +struct is_class + : integral_constant(0)) == + sizeof(internal::YesType)> { +}; + +} // namespace rtc + +#endif // WEBRTC_BASE_TEMPLATE_UTIL_H_ diff --git a/webrtc/common_audio/BUILD.gn b/webrtc/common_audio/BUILD.gn new file mode 100644 index 0000000..b01b318 --- /dev/null +++ b/webrtc/common_audio/BUILD.gn @@ -0,0 +1,243 @@ +# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("//build/config/arm.gni") +import("../build/webrtc.gni") + +config("common_audio_config") { + include_dirs = [ + "resampler/include", + "signal_processing/include", + "vad/include", + ] +} + +source_set("common_audio") { + sources = [ + "audio_converter.cc", + "audio_converter.h", + "audio_ring_buffer.cc", + "audio_ring_buffer.h", + "audio_util.cc", + "blocker.cc", + "blocker.h", + "channel_buffer.cc", + "channel_buffer.h", + "fft4g.c", + "fft4g.h", + "fir_filter.cc", + "fir_filter.h", + "fir_filter_neon.h", + "fir_filter_sse.h", + "include/audio_util.h", + "lapped_transform.cc", + "lapped_transform.h", + "real_fourier.cc", + "real_fourier.h", + "real_fourier_ooura.cc", + "real_fourier_ooura.h", + "resampler/include/push_resampler.h", + "resampler/include/resampler.h", + "resampler/push_resampler.cc", + "resampler/push_sinc_resampler.cc", + "resampler/push_sinc_resampler.h", + "resampler/resampler.cc", + "resampler/sinc_resampler.cc", + "resampler/sinc_resampler.h", + "ring_buffer.c", + "ring_buffer.h", + "signal_processing/auto_corr_to_refl_coef.c", + "signal_processing/auto_correlation.c", + "signal_processing/complex_fft_tables.h", + "signal_processing/copy_set_operations.c", + "signal_processing/cross_correlation.c", + "signal_processing/division_operations.c", + "signal_processing/dot_product_with_scale.c", + "signal_processing/downsample_fast.c", + "signal_processing/energy.c", + "signal_processing/filter_ar.c", + "signal_processing/filter_ma_fast_q12.c", + "signal_processing/get_hanning_window.c", + "signal_processing/get_scaling_square.c", + "signal_processing/ilbc_specific_functions.c", + "signal_processing/include/real_fft.h", + "signal_processing/include/signal_processing_library.h", + "signal_processing/include/spl_inl.h", + "signal_processing/levinson_durbin.c", + "signal_processing/lpc_to_refl_coef.c", + "signal_processing/min_max_operations.c", + "signal_processing/randomization_functions.c", + "signal_processing/real_fft.c", + "signal_processing/refl_coef_to_lpc.c", + "signal_processing/resample.c", + "signal_processing/resample_48khz.c", + "signal_processing/resample_by_2.c", + "signal_processing/resample_by_2_internal.c", + "signal_processing/resample_by_2_internal.h", + "signal_processing/resample_fractional.c", + "signal_processing/spl_init.c", + "signal_processing/spl_sqrt.c", + "signal_processing/splitting_filter.c", + "signal_processing/sqrt_of_one_minus_x_squared.c", + "signal_processing/vector_scaling_operations.c", + "sparse_fir_filter.cc", + "sparse_fir_filter.h", + "vad/include/vad.h", + "vad/include/webrtc_vad.h", + "vad/vad.cc", + "vad/vad_core.c", + "vad/vad_core.h", + "vad/vad_filterbank.c", + "vad/vad_filterbank.h", + "vad/vad_gmm.c", + "vad/vad_gmm.h", + "vad/vad_sp.c", + "vad/vad_sp.h", + "vad/webrtc_vad.c", + "wav_file.cc", + "wav_file.h", + "wav_header.cc", + "wav_header.h", + "window_generator.cc", + "window_generator.h", + ] + + deps = [ + "../system_wrappers", + ] + + defines = [] + if (rtc_use_openmax_dl) { + sources += [ + "real_fourier_openmax.cc", + "real_fourier_openmax.h", + ] + defines += [ "RTC_USE_OPENMAX_DL" ] + if (rtc_build_openmax_dl) { + deps += [ "//third_party/openmax_dl/dl" ] + } + } + + if (current_cpu == "arm") { + sources += [ + "signal_processing/complex_bit_reverse_arm.S", + "signal_processing/spl_sqrt_floor_arm.S", + ] + + if (arm_version >= 7) { + sources += [ "signal_processing/filter_ar_fast_q12_armv7.S" ] + } else { + sources += [ "signal_processing/filter_ar_fast_q12.c" ] + } + } + + if (rtc_build_with_neon) { + deps += [ ":common_audio_neon" ] + } + + if (current_cpu == "mipsel") { + sources += [ + "signal_processing/complex_bit_reverse_mips.c", + "signal_processing/complex_fft_mips.c", + "signal_processing/cross_correlation_mips.c", + "signal_processing/downsample_fast_mips.c", + "signal_processing/filter_ar_fast_q12_mips.c", + "signal_processing/include/spl_inl_mips.h", + "signal_processing/min_max_operations_mips.c", + "signal_processing/resample_by_2_mips.c", + "signal_processing/spl_sqrt_floor_mips.c", + ] + if (mips_dsp_rev > 0) { + sources += [ "signal_processing/vector_scaling_operations_mips.c" ] + } + } else { + sources += [ "signal_processing/complex_fft.c" ] + } + + if (current_cpu != "arm" && current_cpu != "mipsel") { + sources += [ + "signal_processing/complex_bit_reverse.c", + "signal_processing/filter_ar_fast_q12.c", + "signal_processing/spl_sqrt_floor.c", + ] + } + + if (is_win) { + cflags = [ "/wd4334" ] # Ignore warning on shift operator promotion. + } + + configs += [ "..:common_config" ] + + public_configs = [ + "..:common_inherited_config", + ":common_audio_config", + ] + + if (is_clang) { + # Suppress warnings from Chrome's Clang plugins. + # See http://code.google.com/p/webrtc/issues/detail?id=163 for details. + configs -= [ "//build/config/clang:find_bad_constructs" ] + } + + if (current_cpu == "x86" || current_cpu == "x64") { + deps += [ ":common_audio_sse2" ] + } +} + +if (current_cpu == "x86" || current_cpu == "x64") { + source_set("common_audio_sse2") { + sources = [ + "fir_filter_sse.cc", + "resampler/sinc_resampler_sse.cc", + ] + + if (is_posix) { + cflags = [ "-msse2" ] + } + + configs += [ "..:common_inherited_config" ] + + if (is_clang) { + # Suppress warnings from Chrome's Clang plugins. + # See http://code.google.com/p/webrtc/issues/detail?id=163 for details. + configs -= [ "//build/config/clang:find_bad_constructs" ] + } + } +} + +if (rtc_build_with_neon) { + source_set("common_audio_neon") { + sources = [ + "fir_filter_neon.cc", + "resampler/sinc_resampler_neon.cc", + "signal_processing/cross_correlation_neon.c", + "signal_processing/downsample_fast_neon.c", + "signal_processing/min_max_operations_neon.c", + ] + + if (current_cpu != "arm64") { + # Enable compilation for the NEON instruction set. This is needed + # since //build/config/arm.gni only enables NEON for iOS, not Android. + # This provides the same functionality as webrtc/build/arm_neon.gypi. + configs -= [ "//build/config/compiler:compiler_arm_fpu" ] + cflags = [ "-mfpu=neon" ] + } + + # Disable LTO on NEON targets due to compiler bug. + # TODO(fdegans): Enable this. See crbug.com/408997. + if (rtc_use_lto) { + cflags -= [ + "-flto", + "-ffat-lto-objects", + ] + } + + configs += [ "..:common_config" ] + public_configs = [ "..:common_inherited_config" ] + } +} diff --git a/webrtc/common_audio/Makefile.am b/webrtc/common_audio/Makefile.am new file mode 100644 index 0000000..3c9fcce --- /dev/null +++ b/webrtc/common_audio/Makefile.am @@ -0,0 +1,74 @@ +noinst_LTLIBRARIES = libcommon_audio.la + +libcommon_audio_la_SOURCES = signal_processing/include/real_fft.h \ + signal_processing/include/signal_processing_library.h \ + signal_processing/include/spl_inl.h \ + signal_processing/include/spl_inl_armv7.h \ + signal_processing/include/spl_inl_mips.h \ + signal_processing/auto_corr_to_refl_coef.c \ + signal_processing/auto_correlation.c \ + signal_processing/complex_bit_reverse.c \ + signal_processing/complex_fft.c \ + signal_processing/complex_fft_tables.h \ + signal_processing/copy_set_operations.c \ + signal_processing/cross_correlation.c \ + signal_processing/division_operations.c \ + signal_processing/dot_product_with_scale.c \ + signal_processing/downsample_fast.c \ + signal_processing/energy.c \ + signal_processing/filter_ar.c \ + signal_processing/filter_ar_fast_q12.c \ + signal_processing/filter_ma_fast_q12.c \ + signal_processing/get_hanning_window.c \ + signal_processing/get_scaling_square.c \ + signal_processing/ilbc_specific_functions.c \ + signal_processing/levinson_durbin.c \ + signal_processing/lpc_to_refl_coef.c \ + signal_processing/min_max_operations.c \ + signal_processing/randomization_functions.c \ + signal_processing/real_fft.c \ + signal_processing/refl_coef_to_lpc.c \ + signal_processing/resample.c \ + signal_processing/resample_48khz.c \ + signal_processing/resample_by_2.c \ + signal_processing/resample_by_2_internal.c \ + signal_processing/resample_by_2_internal.h \ + signal_processing/resample_fractional.c \ + signal_processing/spl_init.c \ + signal_processing/spl_sqrt.c \ + signal_processing/spl_sqrt_floor.c \ + signal_processing/splitting_filter.c \ + signal_processing/sqrt_of_one_minus_x_squared.c \ + signal_processing/vector_scaling_operations.c \ + vad/include/vad.h \ + vad/include/webrtc_vad.h \ + vad/vad.cc \ + vad/vad_core.c \ + vad/vad_core.h \ + vad/vad_filterbank.c \ + vad/vad_filterbank.h \ + vad/vad_gmm.c \ + vad/vad_gmm.h \ + vad/vad_sp.c \ + vad/vad_sp.h \ + vad/webrtc_vad.c + +libcommon_audio_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS) +libcommon_audio_la_CXXFLAGS = $(AM_CXXFLAGS) $(COMMON_CXXFLAGS) + +# FIXME: +# if ARM - signal_processing/complex_bit_reverse_arm.S +# signal_processing/spl_sqrt_floor_arm.S +# ARM7 - signal_processing/filter_ar_fast_q12_armv7.S +# NEON - signal_processing/cross_correlation_neon.c +# signal_processing/downsample_fast_neon.c +# signal_processing/min_max_operations_neon.c +# if MIPS - signal_processing/complex_bit_reverse_mips.c +# signal_processing/complex_fft_mips.c +# signal_processing/cross_correlation_mips.c +# signal_processing/downsample_fast_mips.c +# signal_processing/filter_ar_fast_q12_mips.c +# signal_processing/min_max_operations_mips.c +# signal_processing/resample_by_2_mips.c +# signal_processing/spl_sqrt_floor_mips.c +# signal_processing/vector_scaling_operations_mips.c diff --git a/src/common_audio/signal_processing_library/main/source/auto_corr_to_refl_coef.c b/webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c similarity index 70% rename from src/common_audio/signal_processing_library/main/source/auto_corr_to_refl_coef.c rename to webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c index b7e8858..f99dd62 100644 --- a/src/common_audio/signal_processing_library/main/source/auto_corr_to_refl_coef.c +++ b/webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c @@ -15,15 +15,15 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K) +void WebRtcSpl_AutoCorrToReflCoef(const int32_t *R, int use_order, int16_t *K) { int i, n; - WebRtc_Word16 tmp; - G_CONST WebRtc_Word32 *rptr; - WebRtc_Word32 L_num, L_den; - WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER], + int16_t tmp; + const int32_t *rptr; + int32_t L_num, L_den; + int16_t *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER], P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER]; // Initialize loop and pointers. @@ -36,13 +36,13 @@ void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRt // First loop; n=0. Determine shifting. tmp = WebRtcSpl_NormW32(*R); - *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); + *acfptr = (int16_t)((*rptr++ << tmp) >> 16); *pptr++ = *acfptr++; // Initialize ACF, P and W. for (i = 1; i <= use_order; i++) { - *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); + *acfptr = (int16_t)((*rptr++ << tmp) >> 16); *wptr++ = *acfptr; *pptr++ = *acfptr++; } @@ -87,16 +87,16 @@ void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRt // Schur recursion. pptr = P; wptr = w1ptr; - tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15); - *pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp ); + tmp = (int16_t)(((int32_t)*p1ptr * (int32_t)*K + 16384) >> 15); + *pptr = WebRtcSpl_AddSatW16(*pptr, tmp); pptr++; for (i = 1; i <= use_order - n; i++) { - tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15); - *pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp ); + tmp = (int16_t)(((int32_t)*wptr * (int32_t)*K + 16384) >> 15); + *pptr = WebRtcSpl_AddSatW16(*(pptr + 1), tmp); pptr++; - tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15); - *wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp ); + tmp = (int16_t)(((int32_t)*pptr * (int32_t)*K + 16384) >> 15); + *wptr = WebRtcSpl_AddSatW16(*wptr, tmp); wptr++; } } diff --git a/webrtc/common_audio/signal_processing/auto_correlation.c b/webrtc/common_audio/signal_processing/auto_correlation.c new file mode 100644 index 0000000..fda4fff --- /dev/null +++ b/webrtc/common_audio/signal_processing/auto_correlation.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#include + +size_t WebRtcSpl_AutoCorrelation(const int16_t* in_vector, + size_t in_vector_length, + size_t order, + int32_t* result, + int* scale) { + int32_t sum = 0; + size_t i = 0, j = 0; + int16_t smax = 0; + int scaling = 0; + + assert(order <= in_vector_length); + + // Find the maximum absolute value of the samples. + smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length); + + // In order to avoid overflow when computing the sum we should scale the + // samples so that (in_vector_length * smax * smax) will not overflow. + if (smax == 0) { + scaling = 0; + } else { + // Number of bits in the sum loop. + int nbits = WebRtcSpl_GetSizeInBits((uint32_t)in_vector_length); + // Number of bits to normalize smax. + int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); + + if (t > nbits) { + scaling = 0; + } else { + scaling = nbits - t; + } + } + + // Perform the actual correlation calculation. + for (i = 0; i < order + 1; i++) { + sum = 0; + /* Unroll the loop to improve performance. */ + for (j = 0; i + j + 3 < in_vector_length; j += 4) { + sum += (in_vector[j + 0] * in_vector[i + j + 0]) >> scaling; + sum += (in_vector[j + 1] * in_vector[i + j + 1]) >> scaling; + sum += (in_vector[j + 2] * in_vector[i + j + 2]) >> scaling; + sum += (in_vector[j + 3] * in_vector[i + j + 3]) >> scaling; + } + for (; j < in_vector_length - i; j++) { + sum += (in_vector[j] * in_vector[i + j]) >> scaling; + } + *result++ = sum; + } + + *scale = scaling; + return order + 1; +} diff --git a/webrtc/common_audio/signal_processing/complex_bit_reverse.c b/webrtc/common_audio/signal_processing/complex_bit_reverse.c new file mode 100644 index 0000000..c8bd2dc --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_bit_reverse.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +/* Tables for data buffer indexes that are bit reversed and thus need to be + * swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap + * operations, while index_7[{1, 3, 5, ...}] are for the right side of the + * operation. Same for index_8. + */ + +/* Indexes for the case of stages == 7. */ +static const int16_t index_7[112] = { + 1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104, + 12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52, + 23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98, + 37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70, + 51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69, + 81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125, + 103, 115, 111, 123 +}; + +/* Indexes for the case of stages == 8. */ +static const int16_t index_8[240] = { + 1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80, + 11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20, + 40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184, + 30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41, + 148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76, + 51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62, + 124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82, + 75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87, + 234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101, + 166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142, + 115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131, + 193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201, + 149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171, + 213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227, + 203, 211, 207, 243, 215, 235, 223, 251, 239, 247 +}; + +void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) { + /* For any specific value of stages, we know exactly the indexes that are + * bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of + * stages are 7 and 8, so we use tables to save unnecessary iterations and + * calculations for these two cases. + */ + if (stages == 7 || stages == 8) { + int m = 0; + int length = 112; + const int16_t* index = index_7; + + if (stages == 8) { + length = 240; + index = index_8; + } + + /* Decimation in time. Swap the elements with bit-reversed indexes. */ + for (m = 0; m < length; m += 2) { + /* We declare a int32_t* type pointer, to load both the 16-bit real + * and imaginary elements from complex_data in one instruction, reducing + * complexity. + */ + int32_t* complex_data_ptr = (int32_t*)complex_data; + int32_t temp = 0; + + temp = complex_data_ptr[index[m]]; /* Real and imaginary */ + complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]]; + complex_data_ptr[index[m + 1]] = temp; + } + } + else { + int m = 0, mr = 0, l = 0; + int n = 1 << stages; + int nn = n - 1; + + /* Decimation in time - re-order data */ + for (m = 1; m <= nn; ++m) { + int32_t* complex_data_ptr = (int32_t*)complex_data; + int32_t temp = 0; + + /* Find out indexes that are bit-reversed. */ + l = n; + do { + l >>= 1; + } while (l > nn - mr); + mr = (mr & (l - 1)) + l; + + if (mr <= m) { + continue; + } + + /* Swap the elements with bit-reversed indexes. + * This is similar to the loop in the stages == 7 or 8 cases. + */ + temp = complex_data_ptr[m]; /* Real and imaginary */ + complex_data_ptr[m] = complex_data_ptr[mr]; + complex_data_ptr[mr] = temp; + } + } +} diff --git a/webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S b/webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S new file mode 100644 index 0000000..e7f8a81 --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S @@ -0,0 +1,119 @@ +@ +@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. +@ +@ Use of this source code is governed by a BSD-style license +@ that can be found in the LICENSE file in the root of the source +@ tree. An additional intellectual property rights grant can be found +@ in the file PATENTS. All contributing project authors may +@ be found in the AUTHORS file in the root of the source tree. +@ + +@ This file contains the function WebRtcSpl_ComplexBitReverse(), optimized +@ for ARMv5 platforms. +@ Reference C code is in file complex_bit_reverse.c. Bit-exact. + +#include "webrtc/system_wrappers/interface/asm_defines.h" + +GLOBAL_FUNCTION WebRtcSpl_ComplexBitReverse +.align 2 +DEFINE_FUNCTION WebRtcSpl_ComplexBitReverse + push {r4-r7} + + cmp r1, #7 + adr r3, index_7 @ Table pointer. + mov r4, #112 @ Number of interations. + beq PRE_LOOP_STAGES_7_OR_8 + + cmp r1, #8 + adr r3, index_8 @ Table pointer. + mov r4, #240 @ Number of interations. + beq PRE_LOOP_STAGES_7_OR_8 + + mov r3, #1 @ Initialize m. + mov r1, r3, asl r1 @ n = 1 << stages; + subs r6, r1, #1 @ nn = n - 1; + ble END + + mov r5, r0 @ &complex_data + mov r4, #0 @ ml + +LOOP_GENERIC: + rsb r12, r4, r6 @ l > nn - mr + mov r2, r1 @ n + +LOOP_SHIFT: + asr r2, #1 @ l >>= 1; + cmp r2, r12 + bgt LOOP_SHIFT + + sub r12, r2, #1 + and r4, r12, r4 + add r4, r2 @ mr = (mr & (l - 1)) + l; + cmp r4, r3 @ mr <= m ? + ble UPDATE_REGISTERS + + mov r12, r4, asl #2 + ldr r7, [r5, #4] @ complex_data[2 * m, 2 * m + 1]. + @ Offset 4 due to m incrementing from 1. + ldr r2, [r0, r12] @ complex_data[2 * mr, 2 * mr + 1]. + str r7, [r0, r12] + str r2, [r5, #4] + +UPDATE_REGISTERS: + add r3, r3, #1 + add r5, #4 + cmp r3, r1 + bne LOOP_GENERIC + + b END + +PRE_LOOP_STAGES_7_OR_8: + add r4, r3, r4, asl #1 + +LOOP_STAGES_7_OR_8: + ldrsh r2, [r3], #2 @ index[m] + ldrsh r5, [r3], #2 @ index[m + 1] + ldr r1, [r0, r2] @ complex_data[index[m], index[m] + 1] + ldr r12, [r0, r5] @ complex_data[index[m + 1], index[m + 1] + 1] + cmp r3, r4 + str r1, [r0, r5] + str r12, [r0, r2] + bne LOOP_STAGES_7_OR_8 + +END: + pop {r4-r7} + bx lr + +@ The index tables. Note the values are doubles of the actual indexes for 16-bit +@ elements, different from the generic C code. It actually provides byte offsets +@ for the indexes. + +.align 2 +index_7: @ Indexes for stages == 7. + .short 4, 256, 8, 128, 12, 384, 16, 64, 20, 320, 24, 192, 28, 448, 36, 288 + .short 40, 160, 44, 416, 48, 96, 52, 352, 56, 224, 60, 480, 68, 272, 72, 144 + .short 76, 400, 84, 336, 88, 208, 92, 464, 100, 304, 104, 176, 108, 432, 116 + .short 368, 120, 240, 124, 496, 132, 264, 140, 392, 148, 328, 152, 200, 156 + .short 456, 164, 296, 172, 424, 180, 360, 184, 232, 188, 488, 196, 280, 204 + .short 408, 212, 344, 220, 472, 228, 312, 236, 440, 244, 376, 252, 504, 268 + .short 388, 276, 324, 284, 452, 300, 420, 308, 356, 316, 484, 332, 404, 348 + .short 468, 364, 436, 380, 500, 412, 460, 444, 492 + +index_8: @ Indexes for stages == 8. + .short 4, 512, 8, 256, 12, 768, 16, 128, 20, 640, 24, 384, 28, 896, 32, 64 + .short 36, 576, 40, 320, 44, 832, 48, 192, 52, 704, 56, 448, 60, 960, 68, 544 + .short 72, 288, 76, 800, 80, 160, 84, 672, 88, 416, 92, 928, 100, 608, 104 + .short 352, 108, 864, 112, 224, 116, 736, 120, 480, 124, 992, 132, 528, 136 + .short 272, 140, 784, 148, 656, 152, 400, 156, 912, 164, 592, 168, 336, 172 + .short 848, 176, 208, 180, 720, 184, 464, 188, 976, 196, 560, 200, 304, 204 + .short 816, 212, 688, 216, 432, 220, 944, 228, 624, 232, 368, 236, 880, 244 + .short 752, 248, 496, 252, 1008, 260, 520, 268, 776, 276, 648, 280, 392, 284 + .short 904, 292, 584, 296, 328, 300, 840, 308, 712, 312, 456, 316, 968, 324 + .short 552, 332, 808, 340, 680, 344, 424, 348, 936, 356, 616, 364, 872, 372 + .short 744, 376, 488, 380, 1000, 388, 536, 396, 792, 404, 664, 412, 920, 420 + .short 600, 428, 856, 436, 728, 440, 472, 444, 984, 452, 568, 460, 824, 468 + .short 696, 476, 952, 484, 632, 492, 888, 500, 760, 508, 1016, 524, 772, 532 + .short 644, 540, 900, 548, 580, 556, 836, 564, 708, 572, 964, 588, 804, 596 + .short 676, 604, 932, 620, 868, 628, 740, 636, 996, 652, 788, 668, 916, 684 + .short 852, 692, 724, 700, 980, 716, 820, 732, 948, 748, 884, 764, 1012, 796 + .short 908, 812, 844, 828, 972, 860, 940, 892, 1004, 956, 988 diff --git a/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c b/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c new file mode 100644 index 0000000..583fe4f --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +static int16_t coefTable_7[] = { + 4, 256, 8, 128, 12, 384, 16, 64, + 20, 320, 24, 192, 28, 448, 36, 288, + 40, 160, 44, 416, 48, 96, 52, 352, + 56, 224, 60, 480, 68, 272, 72, 144, + 76, 400, 84, 336, 88, 208, 92, 464, + 100, 304, 104, 176, 108, 432, 116, 368, + 120, 240, 124, 496, 132, 264, 140, 392, + 148, 328, 152, 200, 156, 456, 164, 296, + 172, 424, 180, 360, 184, 232, 188, 488, + 196, 280, 204, 408, 212, 344, 220, 472, + 228, 312, 236, 440, 244, 376, 252, 504, + 268, 388, 276, 324, 284, 452, 300, 420, + 308, 356, 316, 484, 332, 404, 348, 468, + 364, 436, 380, 500, 412, 460, 444, 492 +}; + +static int16_t coefTable_8[] = { + 4, 512, 8, 256, 12, 768, 16, 128, + 20, 640, 24, 384, 28, 896, 32, 64, + 36, 576, 40, 320, 44, 832, 48, 192, + 52, 704, 56, 448, 60, 960, 68, 544, + 72, 288, 76, 800, 80, 160, 84, 672, + 88, 416, 92, 928, 100, 608, 104, 352, + 108, 864, 112, 224, 116, 736, 120, 480, + 124, 992, 132, 528, 136, 272, 140, 784, + 148, 656, 152, 400, 156, 912, 164, 592, + 168, 336, 172, 848, 176, 208, 180, 720, + 184, 464, 188, 976, 196, 560, 200, 304, + 204, 816, 212, 688, 216, 432, 220, 944, + 228, 624, 232, 368, 236, 880, 244, 752, + 248, 496, 252, 1008, 260, 520, 268, 776, + 276, 648, 280, 392, 284, 904, 292, 584, + 296, 328, 300, 840, 308, 712, 312, 456, + 316, 968, 324, 552, 332, 808, 340, 680, + 344, 424, 348, 936, 356, 616, 364, 872, + 372, 744, 376, 488, 380, 1000, 388, 536, + 396, 792, 404, 664, 412, 920, 420, 600, + 428, 856, 436, 728, 440, 472, 444, 984, + 452, 568, 460, 824, 468, 696, 476, 952, + 484, 632, 492, 888, 500, 760, 508, 1016, + 524, 772, 532, 644, 540, 900, 548, 580, + 556, 836, 564, 708, 572, 964, 588, 804, + 596, 676, 604, 932, 620, 868, 628, 740, + 636, 996, 652, 788, 668, 916, 684, 852, + 692, 724, 700, 980, 716, 820, 732, 948, + 748, 884, 764, 1012, 796, 908, 812, 844, + 828, 972, 860, 940, 892, 1004, 956, 988 +}; + +void WebRtcSpl_ComplexBitReverse(int16_t frfi[], int stages) { + int l; + int16_t tr, ti; + int32_t tmp1, tmp2, tmp3, tmp4; + int32_t* ptr_i; + int32_t* ptr_j; + + if (stages == 8) { + int16_t* pcoeftable_8 = coefTable_8; + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[l], $zero, 120 \n\t" + "1: \n\t" + "addiu %[l], %[l], -4 \n\t" + "lh %[tr], 0(%[pcoeftable_8]) \n\t" + "lh %[ti], 2(%[pcoeftable_8]) \n\t" + "lh %[tmp3], 4(%[pcoeftable_8]) \n\t" + "lh %[tmp4], 6(%[pcoeftable_8]) \n\t" + "addu %[ptr_i], %[frfi], %[tr] \n\t" + "addu %[ptr_j], %[frfi], %[ti] \n\t" + "addu %[tr], %[frfi], %[tmp3] \n\t" + "addu %[ti], %[frfi], %[tmp4] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "lh %[tmp1], 8(%[pcoeftable_8]) \n\t" + "lh %[tmp2], 10(%[pcoeftable_8]) \n\t" + "lh %[tr], 12(%[pcoeftable_8]) \n\t" + "lh %[ti], 14(%[pcoeftable_8]) \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[frfi], %[tmp2] \n\t" + "addu %[tr], %[frfi], %[tr] \n\t" + "addu %[ti], %[frfi], %[ti] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "bgtz %[l], 1b \n\t" + " addiu %[pcoeftable_8], %[pcoeftable_8], 16 \n\t" + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i), + [ptr_j] "=&r" (ptr_j), [tr] "=&r" (tr), [l] "=&r" (l), + [tmp3] "=&r" (tmp3), [pcoeftable_8] "+r" (pcoeftable_8), + [ti] "=&r" (ti), [tmp4] "=&r" (tmp4) + : [frfi] "r" (frfi) + : "memory" + ); + } else if (stages == 7) { + int16_t* pcoeftable_7 = coefTable_7; + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[l], $zero, 56 \n\t" + "1: \n\t" + "addiu %[l], %[l], -4 \n\t" + "lh %[tr], 0(%[pcoeftable_7]) \n\t" + "lh %[ti], 2(%[pcoeftable_7]) \n\t" + "lh %[tmp3], 4(%[pcoeftable_7]) \n\t" + "lh %[tmp4], 6(%[pcoeftable_7]) \n\t" + "addu %[ptr_i], %[frfi], %[tr] \n\t" + "addu %[ptr_j], %[frfi], %[ti] \n\t" + "addu %[tr], %[frfi], %[tmp3] \n\t" + "addu %[ti], %[frfi], %[tmp4] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "lh %[tmp1], 8(%[pcoeftable_7]) \n\t" + "lh %[tmp2], 10(%[pcoeftable_7]) \n\t" + "lh %[tr], 12(%[pcoeftable_7]) \n\t" + "lh %[ti], 14(%[pcoeftable_7]) \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[frfi], %[tmp2] \n\t" + "addu %[tr], %[frfi], %[tr] \n\t" + "addu %[ti], %[frfi], %[ti] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "bgtz %[l], 1b \n\t" + " addiu %[pcoeftable_7], %[pcoeftable_7], 16 \n\t" + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i), + [ptr_j] "=&r" (ptr_j), [ti] "=&r" (ti), [tr] "=&r" (tr), + [l] "=&r" (l), [pcoeftable_7] "+r" (pcoeftable_7), + [tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4) + : [frfi] "r" (frfi) + : "memory" + ); + } +} diff --git a/webrtc/common_audio/signal_processing/complex_fft.c b/webrtc/common_audio/signal_processing/complex_fft.c new file mode 100644 index 0000000..97ebacc --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_fft.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_ComplexFFT(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "webrtc/common_audio/signal_processing/complex_fft_tables.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#define CFFTSFT 14 +#define CFFTRND 1 +#define CFFTRND2 16384 + +#define CIFFTSFT 14 +#define CIFFTRND 1 + + +int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) +{ + int i, j, l, k, istep, n, m; + int16_t wr, wi; + int32_t tr32, ti32, qr32, qi32; + + /* The 1024-value is a constant given from the size of kSinTable1024[], + * and should not be changed depending on the input parameter 'stages' + */ + n = 1 << stages; + if (n > 1024) + return -1; + + l = 1; + k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change + depending on the input parameter 'stages' */ + + if (mode == 0) + { + // mode==0: Low-complexity and Low-accuracy mode + while (l < n) + { + istep = l << 1; + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = kSinTable1024[j + 256]; + wi = -kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15; + + ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15; + + qr32 = (int32_t)frfi[2 * i]; + qi32 = (int32_t)frfi[2 * i + 1]; + frfi[2 * j] = (int16_t)((qr32 - tr32) >> 1); + frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> 1); + frfi[2 * i] = (int16_t)((qr32 + tr32) >> 1); + frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> 1); + } + } + + --k; + l = istep; + + } + + } else + { + // mode==1: High-complexity and High-accuracy mode + while (l < n) + { + istep = l << 1; + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = kSinTable1024[j + 256]; + wi = -kSinTable1024[j]; + +#ifdef WEBRTC_ARCH_ARM_V7 + int32_t wri = 0; + __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : + "r"((int32_t)wr), "r"((int32_t)wi)); +#endif + + for (i = m; i < n; i += istep) + { + j = i + l; + +#ifdef WEBRTC_ARCH_ARM_V7 + register int32_t frfi_r; + __asm __volatile( + "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd]," + " lsl #16\n\t" + "smlsd %[tr32], %[wri], %[frfi_r], %[cfftrnd]\n\t" + "smladx %[ti32], %[wri], %[frfi_r], %[cfftrnd]\n\t" + :[frfi_r]"=&r"(frfi_r), + [tr32]"=&r"(tr32), + [ti32]"=r"(ti32) + :[frfi_even]"r"((int32_t)frfi[2*j]), + [frfi_odd]"r"((int32_t)frfi[2*j +1]), + [wri]"r"(wri), + [cfftrnd]"r"(CFFTRND)); +#else + tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CFFTRND; + + ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CFFTRND; +#endif + + tr32 >>= 15 - CFFTSFT; + ti32 >>= 15 - CFFTSFT; + + qr32 = ((int32_t)frfi[2 * i]) << CFFTSFT; + qi32 = ((int32_t)frfi[2 * i + 1]) << CFFTSFT; + + frfi[2 * j] = (int16_t)( + (qr32 - tr32 + CFFTRND2) >> (1 + CFFTSFT)); + frfi[2 * j + 1] = (int16_t)( + (qi32 - ti32 + CFFTRND2) >> (1 + CFFTSFT)); + frfi[2 * i] = (int16_t)( + (qr32 + tr32 + CFFTRND2) >> (1 + CFFTSFT)); + frfi[2 * i + 1] = (int16_t)( + (qi32 + ti32 + CFFTRND2) >> (1 + CFFTSFT)); + } + } + + --k; + l = istep; + } + } + return 0; +} + +int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) +{ + size_t i, j, l, istep, n, m; + int k, scale, shift; + int16_t wr, wi; + int32_t tr32, ti32, qr32, qi32; + int32_t tmp32, round2; + + /* The 1024-value is a constant given from the size of kSinTable1024[], + * and should not be changed depending on the input parameter 'stages' + */ + n = 1 << stages; + if (n > 1024) + return -1; + + scale = 0; + + l = 1; + k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change + depending on the input parameter 'stages' */ + + while (l < n) + { + // variable scaling, depending upon data + shift = 0; + round2 = 8192; + + tmp32 = WebRtcSpl_MaxAbsValueW16(frfi, 2 * n); + if (tmp32 > 13573) + { + shift++; + scale++; + round2 <<= 1; + } + if (tmp32 > 27146) + { + shift++; + scale++; + round2 <<= 1; + } + + istep = l << 1; + + if (mode == 0) + { + // mode==0: Low-complexity and Low-accuracy mode + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = kSinTable1024[j + 256]; + wi = kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15; + + ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15; + + qr32 = (int32_t)frfi[2 * i]; + qi32 = (int32_t)frfi[2 * i + 1]; + frfi[2 * j] = (int16_t)((qr32 - tr32) >> shift); + frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> shift); + frfi[2 * i] = (int16_t)((qr32 + tr32) >> shift); + frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> shift); + } + } + } else + { + // mode==1: High-complexity and High-accuracy mode + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = kSinTable1024[j + 256]; + wi = kSinTable1024[j]; + +#ifdef WEBRTC_ARCH_ARM_V7 + int32_t wri = 0; + __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) : + "r"((int32_t)wr), "r"((int32_t)wi)); +#endif + + for (i = m; i < n; i += istep) + { + j = i + l; + +#ifdef WEBRTC_ARCH_ARM_V7 + register int32_t frfi_r; + __asm __volatile( + "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t" + "smlsd %[tr32], %[wri], %[frfi_r], %[cifftrnd]\n\t" + "smladx %[ti32], %[wri], %[frfi_r], %[cifftrnd]\n\t" + :[frfi_r]"=&r"(frfi_r), + [tr32]"=&r"(tr32), + [ti32]"=r"(ti32) + :[frfi_even]"r"((int32_t)frfi[2*j]), + [frfi_odd]"r"((int32_t)frfi[2*j +1]), + [wri]"r"(wri), + [cifftrnd]"r"(CIFFTRND) + ); +#else + + tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CIFFTRND; + + ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CIFFTRND; +#endif + tr32 >>= 15 - CIFFTSFT; + ti32 >>= 15 - CIFFTSFT; + + qr32 = ((int32_t)frfi[2 * i]) << CIFFTSFT; + qi32 = ((int32_t)frfi[2 * i + 1]) << CIFFTSFT; + + frfi[2 * j] = (int16_t)( + (qr32 - tr32 + round2) >> (shift + CIFFTSFT)); + frfi[2 * j + 1] = (int16_t)( + (qi32 - ti32 + round2) >> (shift + CIFFTSFT)); + frfi[2 * i] = (int16_t)( + (qr32 + tr32 + round2) >> (shift + CIFFTSFT)); + frfi[2 * i + 1] = (int16_t)( + (qi32 + ti32 + round2) >> (shift + CIFFTSFT)); + } + } + + } + --k; + l = istep; + } + return scale; +} diff --git a/webrtc/common_audio/signal_processing/complex_fft_mips.c b/webrtc/common_audio/signal_processing/complex_fft_mips.c new file mode 100644 index 0000000..34c4f23 --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_fft_mips.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include "webrtc/common_audio/signal_processing/complex_fft_tables.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#define CFFTSFT 14 +#define CFFTRND 1 +#define CFFTRND2 16384 + +#define CIFFTSFT 14 +#define CIFFTRND 1 + +int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) { + int i = 0; + int l = 0; + int k = 0; + int istep = 0; + int n = 0; + int m = 0; + int32_t wr = 0, wi = 0; + int32_t tmp1 = 0; + int32_t tmp2 = 0; + int32_t tmp3 = 0; + int32_t tmp4 = 0; + int32_t tmp5 = 0; + int32_t tmp6 = 0; + int32_t tmp = 0; + int16_t* ptr_j = NULL; + int16_t* ptr_i = NULL; + + n = 1 << stages; + if (n > 1024) { + return -1; + } + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "addiu %[k], $zero, 10 \n\t" + "addiu %[l], $zero, 1 \n\t" + "3: \n\t" + "sll %[istep], %[l], 1 \n\t" + "move %[m], $zero \n\t" + "sll %[tmp], %[l], 2 \n\t" + "move %[i], $zero \n\t" + "2: \n\t" +#if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addiu %[tmp2], %[tmp3], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t" + "lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t" + "addiu %[ptr_i], %[ptr_j], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lh %[wi], 0(%[ptr_j]) \n\t" + "lh %[wr], 0(%[ptr_i]) \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "1: \n\t" + "sll %[tmp1], %[i], 2 \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[ptr_i], %[tmp] \n\t" + "lh %[tmp6], 0(%[ptr_i]) \n\t" + "lh %[tmp5], 2(%[ptr_i]) \n\t" + "lh %[tmp3], 0(%[ptr_j]) \n\t" + "lh %[tmp4], 2(%[ptr_j]) \n\t" + "addu %[i], %[i], %[istep] \n\t" +#if defined(MIPS_DSP_R2_LE) + "mult %[wr], %[tmp3] \n\t" + "madd %[wi], %[tmp4] \n\t" + "mult $ac1, %[wr], %[tmp4] \n\t" + "msub $ac1, %[wi], %[tmp3] \n\t" + "mflo %[tmp1] \n\t" + "mflo %[tmp2], $ac1 \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "shra_r.w %[tmp1], %[tmp1], 1 \n\t" + "shra_r.w %[tmp2], %[tmp2], 1 \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "shra_r.w %[tmp1], %[tmp1], 15 \n\t" + "shra_r.w %[tmp6], %[tmp6], 15 \n\t" + "shra_r.w %[tmp4], %[tmp4], 15 \n\t" + "shra_r.w %[tmp5], %[tmp5], 15 \n\t" +#else // #if defined(MIPS_DSP_R2_LE) + "mul %[tmp2], %[wr], %[tmp4] \n\t" + "mul %[tmp1], %[wr], %[tmp3] \n\t" + "mul %[tmp4], %[wi], %[tmp4] \n\t" + "mul %[tmp3], %[wi], %[tmp3] \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "addiu %[tmp6], %[tmp6], 16384 \n\t" + "addiu %[tmp5], %[tmp5], 16384 \n\t" + "addu %[tmp1], %[tmp1], %[tmp4] \n\t" + "subu %[tmp2], %[tmp2], %[tmp3] \n\t" + "addiu %[tmp1], %[tmp1], 1 \n\t" + "addiu %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp1], %[tmp1], 1 \n\t" + "sra %[tmp2], %[tmp2], 1 \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "sra %[tmp4], %[tmp4], 15 \n\t" + "sra %[tmp1], %[tmp1], 15 \n\t" + "sra %[tmp6], %[tmp6], 15 \n\t" + "sra %[tmp5], %[tmp5], 15 \n\t" +#endif // #if defined(MIPS_DSP_R2_LE) + "sh %[tmp1], 0(%[ptr_i]) \n\t" + "sh %[tmp6], 2(%[ptr_i]) \n\t" + "sh %[tmp4], 0(%[ptr_j]) \n\t" + "blt %[i], %[n], 1b \n\t" + " sh %[tmp5], 2(%[ptr_j]) \n\t" + "blt %[m], %[l], 2b \n\t" + " addu %[i], $zero, %[m] \n\t" + "move %[l], %[istep] \n\t" + "blt %[l], %[n], 3b \n\t" + " addiu %[k], %[k], -1 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6), + [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [wi] "=&r" (wi), [wr] "=&r" (wr), + [m] "=&r" (m), [istep] "=&r" (istep), [l] "=&r" (l), [k] "=&r" (k), + [ptr_j] "=&r" (ptr_j), [tmp] "=&r" (tmp) + : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024) + : "hi", "lo", "memory" +#if defined(MIPS_DSP_R2_LE) + , "$ac1hi", "$ac1lo" +#endif // #if defined(MIPS_DSP_R2_LE) + ); + + return 0; +} + +int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) { + int i = 0, l = 0, k = 0; + int istep = 0, n = 0, m = 0; + int scale = 0, shift = 0; + int32_t wr = 0, wi = 0; + int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; + int32_t tmp5 = 0, tmp6 = 0, tmp = 0, tempMax = 0, round2 = 0; + int16_t* ptr_j = NULL; + int16_t* ptr_i = NULL; + + n = 1 << stages; + if (n > 1024) { + return -1; + } + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "addiu %[k], $zero, 10 \n\t" + "addiu %[l], $zero, 1 \n\t" + "move %[scale], $zero \n\t" + "3: \n\t" + "addiu %[shift], $zero, 14 \n\t" + "addiu %[round2], $zero, 8192 \n\t" + "move %[ptr_i], %[frfi] \n\t" + "move %[tempMax], $zero \n\t" + "addu %[i], %[n], %[n] \n\t" + "5: \n\t" + "lh %[tmp1], 0(%[ptr_i]) \n\t" + "lh %[tmp2], 2(%[ptr_i]) \n\t" + "lh %[tmp3], 4(%[ptr_i]) \n\t" + "lh %[tmp4], 6(%[ptr_i]) \n\t" +#if defined(MIPS_DSP_R1_LE) + "absq_s.w %[tmp1], %[tmp1] \n\t" + "absq_s.w %[tmp2], %[tmp2] \n\t" + "absq_s.w %[tmp3], %[tmp3] \n\t" + "absq_s.w %[tmp4], %[tmp4] \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp5], %[tmp1], $zero \n\t" + "subu %[tmp6], $zero, %[tmp1] \n\t" + "movn %[tmp1], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp2], $zero \n\t" + "subu %[tmp6], $zero, %[tmp2] \n\t" + "movn %[tmp2], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp3], $zero \n\t" + "subu %[tmp6], $zero, %[tmp3] \n\t" + "movn %[tmp3], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp4], $zero \n\t" + "subu %[tmp6], $zero, %[tmp4] \n\t" + "movn %[tmp4], %[tmp6], %[tmp5] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp5], %[tempMax], %[tmp1] \n\t" + "movn %[tempMax], %[tmp1], %[tmp5] \n\t" + "addiu %[i], %[i], -4 \n\t" + "slt %[tmp5], %[tempMax], %[tmp2] \n\t" + "movn %[tempMax], %[tmp2], %[tmp5] \n\t" + "slt %[tmp5], %[tempMax], %[tmp3] \n\t" + "movn %[tempMax], %[tmp3], %[tmp5] \n\t" + "slt %[tmp5], %[tempMax], %[tmp4] \n\t" + "movn %[tempMax], %[tmp4], %[tmp5] \n\t" + "bgtz %[i], 5b \n\t" + " addiu %[ptr_i], %[ptr_i], 8 \n\t" + "addiu %[tmp1], $zero, 13573 \n\t" + "addiu %[tmp2], $zero, 27146 \n\t" +#if !defined(MIPS32_R2_LE) + "sll %[tempMax], %[tempMax], 16 \n\t" + "sra %[tempMax], %[tempMax], 16 \n\t" +#else // #if !defined(MIPS32_R2_LE) + "seh %[tempMax] \n\t" +#endif // #if !defined(MIPS32_R2_LE) + "slt %[tmp1], %[tmp1], %[tempMax] \n\t" + "slt %[tmp2], %[tmp2], %[tempMax] \n\t" + "addu %[tmp1], %[tmp1], %[tmp2] \n\t" + "addu %[shift], %[shift], %[tmp1] \n\t" + "addu %[scale], %[scale], %[tmp1] \n\t" + "sllv %[round2], %[round2], %[tmp1] \n\t" + "sll %[istep], %[l], 1 \n\t" + "move %[m], $zero \n\t" + "sll %[tmp], %[l], 2 \n\t" + "2: \n\t" +#if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addiu %[tmp2], %[tmp3], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t" + "lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t" + "addiu %[ptr_i], %[ptr_j], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lh %[wi], 0(%[ptr_j]) \n\t" + "lh %[wr], 0(%[ptr_i]) \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "1: \n\t" + "sll %[tmp1], %[i], 2 \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[ptr_i], %[tmp] \n\t" + "lh %[tmp3], 0(%[ptr_j]) \n\t" + "lh %[tmp4], 2(%[ptr_j]) \n\t" + "lh %[tmp6], 0(%[ptr_i]) \n\t" + "lh %[tmp5], 2(%[ptr_i]) \n\t" + "addu %[i], %[i], %[istep] \n\t" +#if defined(MIPS_DSP_R2_LE) + "mult %[wr], %[tmp3] \n\t" + "msub %[wi], %[tmp4] \n\t" + "mult $ac1, %[wr], %[tmp4] \n\t" + "madd $ac1, %[wi], %[tmp3] \n\t" + "mflo %[tmp1] \n\t" + "mflo %[tmp2], $ac1 \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "shra_r.w %[tmp1], %[tmp1], 1 \n\t" + "shra_r.w %[tmp2], %[tmp2], 1 \n\t" + "addu %[tmp6], %[tmp6], %[round2] \n\t" + "addu %[tmp5], %[tmp5], %[round2] \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "srav %[tmp4], %[tmp4], %[shift] \n\t" + "srav %[tmp1], %[tmp1], %[shift] \n\t" + "srav %[tmp6], %[tmp6], %[shift] \n\t" + "srav %[tmp5], %[tmp5], %[shift] \n\t" +#else // #if defined(MIPS_DSP_R2_LE) + "mul %[tmp1], %[wr], %[tmp3] \n\t" + "mul %[tmp2], %[wr], %[tmp4] \n\t" + "mul %[tmp4], %[wi], %[tmp4] \n\t" + "mul %[tmp3], %[wi], %[tmp3] \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "sub %[tmp1], %[tmp1], %[tmp4] \n\t" + "addu %[tmp2], %[tmp2], %[tmp3] \n\t" + "addiu %[tmp1], %[tmp1], 1 \n\t" + "addiu %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp1], %[tmp1], 1 \n\t" + "addu %[tmp6], %[tmp6], %[round2] \n\t" + "addu %[tmp5], %[tmp5], %[round2] \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "sra %[tmp4], %[tmp4], %[shift] \n\t" + "sra %[tmp1], %[tmp1], %[shift] \n\t" + "sra %[tmp6], %[tmp6], %[shift] \n\t" + "sra %[tmp5], %[tmp5], %[shift] \n\t" +#endif // #if defined(MIPS_DSP_R2_LE) + "sh %[tmp1], 0(%[ptr_i]) \n\t" + "sh %[tmp6], 2(%[ptr_i]) \n\t" + "sh %[tmp4], 0(%[ptr_j]) \n\t" + "blt %[i], %[n], 1b \n\t" + " sh %[tmp5], 2(%[ptr_j]) \n\t" + "blt %[m], %[l], 2b \n\t" + " addu %[i], $zero, %[m] \n\t" + "move %[l], %[istep] \n\t" + "blt %[l], %[n], 3b \n\t" + " addiu %[k], %[k], -1 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6), + [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [m] "=&r" (m), [tmp] "=&r" (tmp), + [istep] "=&r" (istep), [wi] "=&r" (wi), [wr] "=&r" (wr), [l] "=&r" (l), + [k] "=&r" (k), [round2] "=&r" (round2), [ptr_j] "=&r" (ptr_j), + [shift] "=&r" (shift), [scale] "=&r" (scale), [tempMax] "=&r" (tempMax) + : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024) + : "hi", "lo", "memory" +#if defined(MIPS_DSP_R2_LE) + , "$ac1hi", "$ac1lo" +#endif // #if defined(MIPS_DSP_R2_LE) + ); + + return scale; + +} diff --git a/webrtc/common_audio/signal_processing/complex_fft_tables.h b/webrtc/common_audio/signal_processing/complex_fft_tables.h new file mode 100644 index 0000000..ca7b7fe --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_fft_tables.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ +#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ + +#include "webrtc/typedefs.h" + +static const int16_t kSinTable1024[] = { + 0, 201, 402, 603, 804, 1005, 1206, 1406, + 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, + 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, + 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, + 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, + 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, + 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, + 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, + 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, + 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, + 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, + 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, + 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, + 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, + 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, + 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, + 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, + 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, + 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, + 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, + 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, + 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, + 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, + 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, + 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, + 30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297, + 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, + 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, + 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, + 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, + 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, + 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, + 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, + 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, + 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, + 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, + 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, + 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, + 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, + 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, + 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, + 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, + 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, + 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, + 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, + 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, + 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, + 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, + 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, + 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, + 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, + 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, + 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, + 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, + 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, + 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, + 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, + 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, + 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, + 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, + 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, + 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, + 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, + 1607, 1406, 1206, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1206, -1406, + -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, + -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, + -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, + -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, + -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, + -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, + -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, + -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, + -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, + -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, + -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, + -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, + -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, + -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, + -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, + -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, + -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, + -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, + -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, + -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, + -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, + -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, + -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, + -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, + -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, + -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, + -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, + -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, + -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, + -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, + -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, + -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, + -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, + -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, + -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, + -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, + -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, + -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, + -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, + -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, + -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, + -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, + -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, + -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, + -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, + -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, + -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, + -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, + -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, + -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, + -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, + -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, + -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, + -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, + -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, + -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, + -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, + -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, + -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, + -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, + -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, + -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, + -1607, -1406, -1206, -1005, -804, -603, -402, -201 +}; + +#endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ diff --git a/webrtc/common_audio/signal_processing/copy_set_operations.c b/webrtc/common_audio/signal_processing/copy_set_operations.c new file mode 100644 index 0000000..9d7cf47 --- /dev/null +++ b/webrtc/common_audio/signal_processing/copy_set_operations.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the implementation of functions + * WebRtcSpl_MemSetW16() + * WebRtcSpl_MemSetW32() + * WebRtcSpl_MemCpyReversedOrder() + * WebRtcSpl_CopyFromEndW16() + * WebRtcSpl_ZerosArrayW16() + * WebRtcSpl_ZerosArrayW32() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + + +void WebRtcSpl_MemSetW16(int16_t *ptr, int16_t set_value, size_t length) +{ + size_t j; + int16_t *arrptr = ptr; + + for (j = length; j > 0; j--) + { + *arrptr++ = set_value; + } +} + +void WebRtcSpl_MemSetW32(int32_t *ptr, int32_t set_value, size_t length) +{ + size_t j; + int32_t *arrptr = ptr; + + for (j = length; j > 0; j--) + { + *arrptr++ = set_value; + } +} + +void WebRtcSpl_MemCpyReversedOrder(int16_t* dest, + int16_t* source, + size_t length) +{ + size_t j; + int16_t* destPtr = dest; + int16_t* sourcePtr = source; + + for (j = 0; j < length; j++) + { + *destPtr-- = *sourcePtr++; + } +} + +void WebRtcSpl_CopyFromEndW16(const int16_t *vector_in, + size_t length, + size_t samples, + int16_t *vector_out) +{ + // Copy the last of the input vector to vector_out + WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples); +} + +void WebRtcSpl_ZerosArrayW16(int16_t *vector, size_t length) +{ + WebRtcSpl_MemSetW16(vector, 0, length); +} + +void WebRtcSpl_ZerosArrayW32(int32_t *vector, size_t length) +{ + WebRtcSpl_MemSetW32(vector, 0, length); +} diff --git a/webrtc/common_audio/signal_processing/cross_correlation.c b/webrtc/common_audio/signal_processing/cross_correlation.c new file mode 100644 index 0000000..d7c9f2b --- /dev/null +++ b/webrtc/common_audio/signal_processing/cross_correlation.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +/* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */ +void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2) { + size_t i = 0, j = 0; + + for (i = 0; i < dim_cross_correlation; i++) { + int32_t corr = 0; + for (j = 0; j < dim_seq; j++) + corr += (seq1[j] * seq2[j]) >> right_shifts; + seq2 += step_seq2; + *cross_correlation++ = corr; + } +} diff --git a/webrtc/common_audio/signal_processing/cross_correlation_mips.c b/webrtc/common_audio/signal_processing/cross_correlation_mips.c new file mode 100644 index 0000000..b236402 --- /dev/null +++ b/webrtc/common_audio/signal_processing/cross_correlation_mips.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +void WebRtcSpl_CrossCorrelation_mips(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2) { + + int32_t t0 = 0, t1 = 0, t2 = 0, t3 = 0, sum = 0; + int16_t *pseq2 = NULL; + int16_t *pseq1 = NULL; + int16_t *pseq1_0 = (int16_t*)&seq1[0]; + int16_t *pseq2_0 = (int16_t*)&seq2[0]; + int k = 0; + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "sll %[step_seq2], %[step_seq2], 1 \n\t" + "andi %[t0], %[dim_seq], 1 \n\t" + "bgtz %[t0], 3f \n\t" + " nop \n\t" + "1: \n\t" + "move %[pseq1], %[pseq1_0] \n\t" + "move %[pseq2], %[pseq2_0] \n\t" + "sra %[k], %[dim_seq], 1 \n\t" + "addiu %[dim_cc], %[dim_cc], -1 \n\t" + "xor %[sum], %[sum], %[sum] \n\t" + "2: \n\t" + "lh %[t0], 0(%[pseq1]) \n\t" + "lh %[t1], 0(%[pseq2]) \n\t" + "lh %[t2], 2(%[pseq1]) \n\t" + "lh %[t3], 2(%[pseq2]) \n\t" + "mul %[t0], %[t0], %[t1] \n\t" + "addiu %[k], %[k], -1 \n\t" + "mul %[t2], %[t2], %[t3] \n\t" + "addiu %[pseq1], %[pseq1], 4 \n\t" + "addiu %[pseq2], %[pseq2], 4 \n\t" + "srav %[t0], %[t0], %[right_shifts] \n\t" + "addu %[sum], %[sum], %[t0] \n\t" + "srav %[t2], %[t2], %[right_shifts] \n\t" + "bgtz %[k], 2b \n\t" + " addu %[sum], %[sum], %[t2] \n\t" + "addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t" + "sw %[sum], 0(%[cc]) \n\t" + "bgtz %[dim_cc], 1b \n\t" + " addiu %[cc], %[cc], 4 \n\t" + "b 6f \n\t" + " nop \n\t" + "3: \n\t" + "move %[pseq1], %[pseq1_0] \n\t" + "move %[pseq2], %[pseq2_0] \n\t" + "sra %[k], %[dim_seq], 1 \n\t" + "addiu %[dim_cc], %[dim_cc], -1 \n\t" + "beqz %[k], 5f \n\t" + " xor %[sum], %[sum], %[sum] \n\t" + "4: \n\t" + "lh %[t0], 0(%[pseq1]) \n\t" + "lh %[t1], 0(%[pseq2]) \n\t" + "lh %[t2], 2(%[pseq1]) \n\t" + "lh %[t3], 2(%[pseq2]) \n\t" + "mul %[t0], %[t0], %[t1] \n\t" + "addiu %[k], %[k], -1 \n\t" + "mul %[t2], %[t2], %[t3] \n\t" + "addiu %[pseq1], %[pseq1], 4 \n\t" + "addiu %[pseq2], %[pseq2], 4 \n\t" + "srav %[t0], %[t0], %[right_shifts] \n\t" + "addu %[sum], %[sum], %[t0] \n\t" + "srav %[t2], %[t2], %[right_shifts] \n\t" + "bgtz %[k], 4b \n\t" + " addu %[sum], %[sum], %[t2] \n\t" + "5: \n\t" + "lh %[t0], 0(%[pseq1]) \n\t" + "lh %[t1], 0(%[pseq2]) \n\t" + "mul %[t0], %[t0], %[t1] \n\t" + "srav %[t0], %[t0], %[right_shifts] \n\t" + "addu %[sum], %[sum], %[t0] \n\t" + "addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t" + "sw %[sum], 0(%[cc]) \n\t" + "bgtz %[dim_cc], 3b \n\t" + " addiu %[cc], %[cc], 4 \n\t" + "6: \n\t" + ".set pop \n\t" + : [step_seq2] "+r" (step_seq2), [t0] "=&r" (t0), [t1] "=&r" (t1), + [t2] "=&r" (t2), [t3] "=&r" (t3), [pseq1] "=&r" (pseq1), + [pseq2] "=&r" (pseq2), [pseq1_0] "+r" (pseq1_0), [pseq2_0] "+r" (pseq2_0), + [k] "=&r" (k), [dim_cc] "+r" (dim_cross_correlation), [sum] "=&r" (sum), + [cc] "+r" (cross_correlation) + : [dim_seq] "r" (dim_seq), [right_shifts] "r" (right_shifts) + : "hi", "lo", "memory" + ); +} diff --git a/webrtc/common_audio/signal_processing/cross_correlation_neon.c b/webrtc/common_audio/signal_processing/cross_correlation_neon.c new file mode 100644 index 0000000..918b671 --- /dev/null +++ b/webrtc/common_audio/signal_processing/cross_correlation_neon.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#include + +static inline void DotProductWithScaleNeon(int32_t* cross_correlation, + const int16_t* vector1, + const int16_t* vector2, + size_t length, + int scaling) { + size_t i = 0; + size_t len1 = length >> 3; + size_t len2 = length & 7; + int64x2_t sum0 = vdupq_n_s64(0); + int64x2_t sum1 = vdupq_n_s64(0); + + for (i = len1; i > 0; i -= 1) { + int16x8_t seq1_16x8 = vld1q_s16(vector1); + int16x8_t seq2_16x8 = vld1q_s16(vector2); +#if defined(WEBRTC_ARCH_ARM64) + int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8), + vget_low_s16(seq2_16x8)); + int32x4_t tmp1 = vmull_high_s16(seq1_16x8, seq2_16x8); +#else + int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8), + vget_low_s16(seq2_16x8)); + int32x4_t tmp1 = vmull_s16(vget_high_s16(seq1_16x8), + vget_high_s16(seq2_16x8)); +#endif + sum0 = vpadalq_s32(sum0, tmp0); + sum1 = vpadalq_s32(sum1, tmp1); + vector1 += 8; + vector2 += 8; + } + + // Calculate the rest of the samples. + int64_t sum_res = 0; + for (i = len2; i > 0; i -= 1) { + sum_res += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + } + + sum0 = vaddq_s64(sum0, sum1); +#if defined(WEBRTC_ARCH_ARM64) + int64_t sum2 = vaddvq_s64(sum0); + *cross_correlation = (int32_t)((sum2 + sum_res) >> scaling); +#else + int64x1_t shift = vdup_n_s64(-scaling); + int64x1_t sum2 = vadd_s64(vget_low_s64(sum0), vget_high_s64(sum0)); + sum2 = vadd_s64(sum2, vdup_n_s64(sum_res)); + sum2 = vshl_s64(sum2, shift); + vst1_lane_s32(cross_correlation, vreinterpret_s32_s64(sum2), 0); +#endif +} + +/* NEON version of WebRtcSpl_CrossCorrelation() for ARM32/64 platforms. */ +void WebRtcSpl_CrossCorrelationNeon(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2) { + size_t i = 0; + + for (i = 0; i < dim_cross_correlation; i++) { + const int16_t* seq1_ptr = seq1; + const int16_t* seq2_ptr = seq2 + (step_seq2 * i); + + DotProductWithScaleNeon(cross_correlation, + seq1_ptr, + seq2_ptr, + dim_seq, + right_shifts); + cross_correlation++; + } +} diff --git a/webrtc/common_audio/signal_processing/division_operations.c b/webrtc/common_audio/signal_processing/division_operations.c new file mode 100644 index 0000000..eaa06a1 --- /dev/null +++ b/webrtc/common_audio/signal_processing/division_operations.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the divisions + * WebRtcSpl_DivU32U16() + * WebRtcSpl_DivW32W16() + * WebRtcSpl_DivW32W16ResW16() + * WebRtcSpl_DivResultInQ31() + * WebRtcSpl_DivW32HiLow() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den) +{ + // Guard against division with 0 + if (den != 0) + { + return (uint32_t)(num / den); + } else + { + return (uint32_t)0xFFFFFFFF; + } +} + +int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den) +{ + // Guard against division with 0 + if (den != 0) + { + return (int32_t)(num / den); + } else + { + return (int32_t)0x7FFFFFFF; + } +} + +int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den) +{ + // Guard against division with 0 + if (den != 0) + { + return (int16_t)(num / den); + } else + { + return (int16_t)0x7FFF; + } +} + +int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den) +{ + int32_t L_num = num; + int32_t L_den = den; + int32_t div = 0; + int k = 31; + int change_sign = 0; + + if (num == 0) + return 0; + + if (num < 0) + { + change_sign++; + L_num = -num; + } + if (den < 0) + { + change_sign++; + L_den = -den; + } + while (k--) + { + div <<= 1; + L_num <<= 1; + if (L_num >= L_den) + { + L_num -= L_den; + div++; + } + } + if (change_sign == 1) + { + div = -div; + } + return div; +} + +int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low) +{ + int16_t approx, tmp_hi, tmp_low, num_hi, num_low; + int32_t tmpW32; + + approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi); + // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) + + // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) + tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1); + // tmpW32 = den * approx + + tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) + + // Store tmpW32 in hi and low format + tmp_hi = (int16_t)(tmpW32 >> 16); + tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1); + + // tmpW32 = 1/den in Q29 + tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1; + + // 1/den in hi and low format + tmp_hi = (int16_t)(tmpW32 >> 16); + tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1); + + // Store num in hi and low format + num_hi = (int16_t)(num >> 16); + num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1); + + // num * (1/den) by 32 bit multiplication (result in Q28) + + tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) + + (num_low * tmp_hi >> 15); + + // Put result in Q31 (convert from Q28) + tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); + + return tmpW32; +} diff --git a/webrtc/common_audio/signal_processing/dot_product_with_scale.c b/webrtc/common_audio/signal_processing/dot_product_with_scale.c new file mode 100644 index 0000000..1302d62 --- /dev/null +++ b/webrtc/common_audio/signal_processing/dot_product_with_scale.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1, + const int16_t* vector2, + size_t length, + int scaling) { + int32_t sum = 0; + size_t i = 0; + + /* Unroll the loop to improve performance. */ + for (i = 0; i + 3 < length; i += 4) { + sum += (vector1[i + 0] * vector2[i + 0]) >> scaling; + sum += (vector1[i + 1] * vector2[i + 1]) >> scaling; + sum += (vector1[i + 2] * vector2[i + 2]) >> scaling; + sum += (vector1[i + 3] * vector2[i + 3]) >> scaling; + } + for (; i < length; i++) { + sum += (vector1[i] * vector2[i]) >> scaling; + } + + return sum; +} diff --git a/webrtc/common_audio/signal_processing/downsample_fast.c b/webrtc/common_audio/signal_processing/downsample_fast.c new file mode 100644 index 0000000..726a888 --- /dev/null +++ b/webrtc/common_audio/signal_processing/downsample_fast.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// TODO(Bjornv): Change the function parameter order to WebRTC code style. +// C version of WebRtcSpl_DownsampleFast() for generic platforms. +int WebRtcSpl_DownsampleFastC(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay) { + size_t i = 0; + size_t j = 0; + int32_t out_s32 = 0; + size_t endpos = delay + factor * (data_out_length - 1) + 1; + + // Return error if any of the running conditions doesn't meet. + if (data_out_length == 0 || coefficients_length == 0 + || data_in_length < endpos) { + return -1; + } + + for (i = delay; i < endpos; i += factor) { + out_s32 = 2048; // Round value, 0.5 in Q12. + + for (j = 0; j < coefficients_length; j++) { + out_s32 += coefficients[j] * data_in[i - j]; // Q12. + } + + out_s32 >>= 12; // Q0. + + // Saturate and store the output. + *data_out++ = WebRtcSpl_SatW32ToW16(out_s32); + } + + return 0; +} diff --git a/webrtc/common_audio/signal_processing/downsample_fast_mips.c b/webrtc/common_audio/signal_processing/downsample_fast_mips.c new file mode 100644 index 0000000..ac39401 --- /dev/null +++ b/webrtc/common_audio/signal_processing/downsample_fast_mips.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// Version of WebRtcSpl_DownsampleFast() for MIPS platforms. +int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay) { + int i; + int j; + int k; + int32_t out_s32 = 0; + size_t endpos = delay + factor * (data_out_length - 1) + 1; + + int32_t tmp1, tmp2, tmp3, tmp4, factor_2; + int16_t* p_coefficients; + int16_t* p_data_in; + int16_t* p_data_in_0 = (int16_t*)&data_in[delay]; + int16_t* p_coefficients_0 = (int16_t*)&coefficients[0]; +#if !defined(MIPS_DSP_R1_LE) + int32_t max_16 = 0x7FFF; + int32_t min_16 = 0xFFFF8000; +#endif // #if !defined(MIPS_DSP_R1_LE) + + // Return error if any of the running conditions doesn't meet. + if (data_out_length == 0 || coefficients_length == 0 + || data_in_length < endpos) { + return -1; + } +#if defined(MIPS_DSP_R2_LE) + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "subu %[i], %[endpos], %[delay] \n\t" + "sll %[factor_2], %[factor], 1 \n\t" + "1: \n\t" + "move %[p_data_in], %[p_data_in_0] \n\t" + "mult $zero, $zero \n\t" + "move %[p_coefs], %[p_coefs_0] \n\t" + "sra %[j], %[coef_length], 2 \n\t" + "beq %[j], $zero, 3f \n\t" + " andi %[k], %[coef_length], 3 \n\t" + "2: \n\t" + "lwl %[tmp1], 1(%[p_data_in]) \n\t" + "lwl %[tmp2], 3(%[p_coefs]) \n\t" + "lwl %[tmp3], -3(%[p_data_in]) \n\t" + "lwl %[tmp4], 7(%[p_coefs]) \n\t" + "lwr %[tmp1], -2(%[p_data_in]) \n\t" + "lwr %[tmp2], 0(%[p_coefs]) \n\t" + "lwr %[tmp3], -6(%[p_data_in]) \n\t" + "lwr %[tmp4], 4(%[p_coefs]) \n\t" + "packrl.ph %[tmp1], %[tmp1], %[tmp1] \n\t" + "packrl.ph %[tmp3], %[tmp3], %[tmp3] \n\t" + "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" + "dpa.w.ph $ac0, %[tmp3], %[tmp4] \n\t" + "addiu %[j], %[j], -1 \n\t" + "addiu %[p_data_in], %[p_data_in], -8 \n\t" + "bgtz %[j], 2b \n\t" + " addiu %[p_coefs], %[p_coefs], 8 \n\t" + "3: \n\t" + "beq %[k], $zero, 5f \n\t" + " nop \n\t" + "4: \n\t" + "lhu %[tmp1], 0(%[p_data_in]) \n\t" + "lhu %[tmp2], 0(%[p_coefs]) \n\t" + "addiu %[p_data_in], %[p_data_in], -2 \n\t" + "addiu %[k], %[k], -1 \n\t" + "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" + "bgtz %[k], 4b \n\t" + " addiu %[p_coefs], %[p_coefs], 2 \n\t" + "5: \n\t" + "extr_r.w %[out_s32], $ac0, 12 \n\t" + "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" + "subu %[i], %[i], %[factor] \n\t" + "shll_s.w %[out_s32], %[out_s32], 16 \n\t" + "sra %[out_s32], %[out_s32], 16 \n\t" + "sh %[out_s32], 0(%[data_out]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[data_out], %[data_out], 2 \n\t" + ".set pop \n\t" + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), + [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), + [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), + [i] "=&r" (i), [k] "=&r" (k) + : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), + [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), + [delay] "r" (delay), [factor] "r" (factor) + : "memory", "hi", "lo" + ); +#else // #if defined(MIPS_DSP_R2_LE) + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "sll %[factor_2], %[factor], 1 \n\t" + "subu %[i], %[endpos], %[delay] \n\t" + "1: \n\t" + "move %[p_data_in], %[p_data_in_0] \n\t" + "addiu %[out_s32], $zero, 2048 \n\t" + "move %[p_coefs], %[p_coefs_0] \n\t" + "sra %[j], %[coef_length], 1 \n\t" + "beq %[j], $zero, 3f \n\t" + " andi %[k], %[coef_length], 1 \n\t" + "2: \n\t" + "lh %[tmp1], 0(%[p_data_in]) \n\t" + "lh %[tmp2], 0(%[p_coefs]) \n\t" + "lh %[tmp3], -2(%[p_data_in]) \n\t" + "lh %[tmp4], 2(%[p_coefs]) \n\t" + "mul %[tmp1], %[tmp1], %[tmp2] \n\t" + "addiu %[p_coefs], %[p_coefs], 4 \n\t" + "mul %[tmp3], %[tmp3], %[tmp4] \n\t" + "addiu %[j], %[j], -1 \n\t" + "addiu %[p_data_in], %[p_data_in], -4 \n\t" + "addu %[tmp1], %[tmp1], %[tmp3] \n\t" + "bgtz %[j], 2b \n\t" + " addu %[out_s32], %[out_s32], %[tmp1] \n\t" + "3: \n\t" + "beq %[k], $zero, 4f \n\t" + " nop \n\t" + "lh %[tmp1], 0(%[p_data_in]) \n\t" + "lh %[tmp2], 0(%[p_coefs]) \n\t" + "mul %[tmp1], %[tmp1], %[tmp2] \n\t" + "addu %[out_s32], %[out_s32], %[tmp1] \n\t" + "4: \n\t" + "sra %[out_s32], %[out_s32], 12 \n\t" + "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[out_s32], %[out_s32], 16 \n\t" + "sra %[out_s32], %[out_s32], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp1], %[max_16], %[out_s32] \n\t" + "movn %[out_s32], %[max_16], %[tmp1] \n\t" + "slt %[tmp1], %[out_s32], %[min_16] \n\t" + "movn %[out_s32], %[min_16], %[tmp1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "subu %[i], %[i], %[factor] \n\t" + "sh %[out_s32], 0(%[data_out]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[data_out], %[data_out], 2 \n\t" + ".set pop \n\t" + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k), + [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), + [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), + [i] "=&r" (i) + : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), + [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), +#if !defined(MIPS_DSP_R1_LE) + [max_16] "r" (max_16), [min_16] "r" (min_16), +#endif // #if !defined(MIPS_DSP_R1_LE) + [delay] "r" (delay), [factor] "r" (factor) + : "memory", "hi", "lo" + ); +#endif // #if defined(MIPS_DSP_R2_LE) + return 0; +} diff --git a/webrtc/common_audio/signal_processing/downsample_fast_neon.c b/webrtc/common_audio/signal_processing/downsample_fast_neon.c new file mode 100644 index 0000000..58732da --- /dev/null +++ b/webrtc/common_audio/signal_processing/downsample_fast_neon.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#include + +// NEON intrinsics version of WebRtcSpl_DownsampleFast() +// for ARM 32-bit/64-bit platforms. +int WebRtcSpl_DownsampleFastNeon(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay) { + size_t i = 0; + size_t j = 0; + int32_t out_s32 = 0; + size_t endpos = delay + factor * (data_out_length - 1) + 1; + size_t res = data_out_length & 0x7; + size_t endpos1 = endpos - factor * res; + + // Return error if any of the running conditions doesn't meet. + if (data_out_length == 0 || coefficients_length == 0 + || data_in_length < endpos) { + return -1; + } + + // First part, unroll the loop 8 times, with 3 subcases + // (factor == 2, 4, others). + switch (factor) { + case 2: { + for (i = delay; i < endpos1; i += 16) { + // Round value, 0.5 in Q12. + int32x4_t out32x4_0 = vdupq_n_s32(2048); + int32x4_t out32x4_1 = vdupq_n_s32(2048); + +#if defined(WEBRTC_ARCH_ARM64) + // Unroll the loop 2 times. + for (j = 0; j < coefficients_length - 1; j += 2) { + int32x2_t coeff32 = vld1_dup_s32((int32_t*)&coefficients[j]); + int16x4_t coeff16x4 = vreinterpret_s16_s32(coeff32); + int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j - 1]); + + // Mul and accumulate low 64-bit data. + int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); + int16x4_t in16x4_1 = vget_low_s16(in16x8x2.val[1]); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 1); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_1, coeff16x4, 0); + + // Mul and accumulate high 64-bit data. + // TODO: vget_high_s16 need extra cost on ARM64. This could be + // replaced by vmlal_high_lane_s16. But for the interface of + // vmlal_high_lane_s16, there is a bug in gcc 4.9. + // This issue need to be tracked in the future. + int16x4_t in16x4_2 = vget_high_s16(in16x8x2.val[0]); + int16x4_t in16x4_3 = vget_high_s16(in16x8x2.val[1]); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_2, coeff16x4, 1); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_3, coeff16x4, 0); + } + + for (; j < coefficients_length; j++) { + int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); + int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j]); + + // Mul and accumulate low 64-bit data. + int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); + + // Mul and accumulate high 64-bit data. + // TODO: vget_high_s16 need extra cost on ARM64. This could be + // replaced by vmlal_high_lane_s16. But for the interface of + // vmlal_high_lane_s16, there is a bug in gcc 4.9. + // This issue need to be tracked in the future. + int16x4_t in16x4_1 = vget_high_s16(in16x8x2.val[0]); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); + } +#else + // On ARMv7, the loop unrolling 2 times results in performance + // regression. + for (j = 0; j < coefficients_length; j++) { + int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); + int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j]); + + // Mul and accumulate. + int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); + int16x4_t in16x4_1 = vget_high_s16(in16x8x2.val[0]); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); + } +#endif + + // Saturate and store the output. + int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); + int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); + vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); + data_out += 8; + } + break; + } + case 4: { + for (i = delay; i < endpos1; i += 32) { + // Round value, 0.5 in Q12. + int32x4_t out32x4_0 = vdupq_n_s32(2048); + int32x4_t out32x4_1 = vdupq_n_s32(2048); + + // Unroll the loop 4 times. + for (j = 0; j < coefficients_length - 3; j += 4) { + int16x4_t coeff16x4 = vld1_s16(&coefficients[j]); + int16x8x4_t in16x8x4 = vld4q_s16(&data_in[i - j - 3]); + + // Mul and accumulate low 64-bit data. + int16x4_t in16x4_0 = vget_low_s16(in16x8x4.val[0]); + int16x4_t in16x4_2 = vget_low_s16(in16x8x4.val[1]); + int16x4_t in16x4_4 = vget_low_s16(in16x8x4.val[2]); + int16x4_t in16x4_6 = vget_low_s16(in16x8x4.val[3]); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 3); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_2, coeff16x4, 2); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_4, coeff16x4, 1); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_6, coeff16x4, 0); + + // Mul and accumulate high 64-bit data. + // TODO: vget_high_s16 need extra cost on ARM64. This could be + // replaced by vmlal_high_lane_s16. But for the interface of + // vmlal_high_lane_s16, there is a bug in gcc 4.9. + // This issue need to be tracked in the future. + int16x4_t in16x4_1 = vget_high_s16(in16x8x4.val[0]); + int16x4_t in16x4_3 = vget_high_s16(in16x8x4.val[1]); + int16x4_t in16x4_5 = vget_high_s16(in16x8x4.val[2]); + int16x4_t in16x4_7 = vget_high_s16(in16x8x4.val[3]); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 3); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_3, coeff16x4, 2); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_5, coeff16x4, 1); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_7, coeff16x4, 0); + } + + for (; j < coefficients_length; j++) { + int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); + int16x8x4_t in16x8x4 = vld4q_s16(&data_in[i - j]); + + // Mul and accumulate low 64-bit data. + int16x4_t in16x4_0 = vget_low_s16(in16x8x4.val[0]); + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); + + // Mul and accumulate high 64-bit data. + // TODO: vget_high_s16 need extra cost on ARM64. This could be + // replaced by vmlal_high_lane_s16. But for the interface of + // vmlal_high_lane_s16, there is a bug in gcc 4.9. + // This issue need to be tracked in the future. + int16x4_t in16x4_1 = vget_high_s16(in16x8x4.val[0]); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); + } + + // Saturate and store the output. + int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); + int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); + vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); + data_out += 8; + } + break; + } + default: { + for (i = delay; i < endpos1; i += factor * 8) { + // Round value, 0.5 in Q12. + int32x4_t out32x4_0 = vdupq_n_s32(2048); + int32x4_t out32x4_1 = vdupq_n_s32(2048); + + for (j = 0; j < coefficients_length; j++) { + int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); + int16x4_t in16x4_0 = vld1_dup_s16(&data_in[i - j]); + in16x4_0 = vld1_lane_s16(&data_in[i + factor - j], in16x4_0, 1); + in16x4_0 = vld1_lane_s16(&data_in[i + factor * 2 - j], in16x4_0, 2); + in16x4_0 = vld1_lane_s16(&data_in[i + factor * 3 - j], in16x4_0, 3); + int16x4_t in16x4_1 = vld1_dup_s16(&data_in[i + factor * 4 - j]); + in16x4_1 = vld1_lane_s16(&data_in[i + factor * 5 - j], in16x4_1, 1); + in16x4_1 = vld1_lane_s16(&data_in[i + factor * 6 - j], in16x4_1, 2); + in16x4_1 = vld1_lane_s16(&data_in[i + factor * 7 - j], in16x4_1, 3); + + // Mul and accumulate. + out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); + out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); + } + + // Saturate and store the output. + int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); + int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); + vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); + data_out += 8; + } + break; + } + } + + // Second part, do the rest iterations (if any). + for (; i < endpos; i += factor) { + out_s32 = 2048; // Round value, 0.5 in Q12. + + for (j = 0; j < coefficients_length; j++) { + out_s32 = WebRtc_MulAccumW16(coefficients[j], data_in[i - j], out_s32); + } + + // Saturate and store the output. + out_s32 >>= 12; + *data_out++ = WebRtcSpl_SatW32ToW16(out_s32); + } + + return 0; +} diff --git a/src/common_audio/signal_processing_library/main/source/energy.c b/webrtc/common_audio/signal_processing/energy.c similarity index 57% rename from src/common_audio/signal_processing_library/main/source/energy.c rename to webrtc/common_audio/signal_processing/energy.c index e8fdf94..e83f1a6 100644 --- a/src/common_audio/signal_processing_library/main/source/energy.c +++ b/webrtc/common_audio/signal_processing/energy.c @@ -15,20 +15,23 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int vector_length, int* scale_factor) +int32_t WebRtcSpl_Energy(int16_t* vector, + size_t vector_length, + int* scale_factor) { - WebRtc_Word32 en = 0; - int i; - int scaling = WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); - int looptimes = vector_length; - WebRtc_Word16 *vectorptr = vector; + int32_t en = 0; + size_t i; + int scaling = + WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); + size_t looptimes = vector_length; + int16_t *vectorptr = vector; for (i = 0; i < looptimes; i++) { - en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling); - vectorptr++; + en += (*vectorptr * *vectorptr) >> scaling; + vectorptr++; } *scale_factor = scaling; diff --git a/webrtc/common_audio/signal_processing/filter_ar.c b/webrtc/common_audio/signal_processing/filter_ar.c new file mode 100644 index 0000000..dfbc4c2 --- /dev/null +++ b/webrtc/common_audio/signal_processing/filter_ar.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_FilterAR(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +size_t WebRtcSpl_FilterAR(const int16_t* a, + size_t a_length, + const int16_t* x, + size_t x_length, + int16_t* state, + size_t state_length, + int16_t* state_low, + size_t state_low_length, + int16_t* filtered, + int16_t* filtered_low, + size_t filtered_low_length) +{ + int32_t o; + int32_t oLOW; + size_t i, j, stop; + const int16_t* x_ptr = &x[0]; + int16_t* filteredFINAL_ptr = filtered; + int16_t* filteredFINAL_LOW_ptr = filtered_low; + + for (i = 0; i < x_length; i++) + { + // Calculate filtered[i] and filtered_low[i] + const int16_t* a_ptr = &a[1]; + int16_t* filtered_ptr = &filtered[i - 1]; + int16_t* filtered_low_ptr = &filtered_low[i - 1]; + int16_t* state_ptr = &state[state_length - 1]; + int16_t* state_low_ptr = &state_low[state_length - 1]; + + o = (int32_t)(*x_ptr++) << 12; + oLOW = (int32_t)0; + + stop = (i < a_length) ? i + 1 : a_length; + for (j = 1; j < stop; j++) + { + o -= *a_ptr * *filtered_ptr--; + oLOW -= *a_ptr++ * *filtered_low_ptr--; + } + for (j = i + 1; j < a_length; j++) + { + o -= *a_ptr * *state_ptr--; + oLOW -= *a_ptr++ * *state_low_ptr--; + } + + o += (oLOW >> 12); + *filteredFINAL_ptr = (int16_t)((o + (int32_t)2048) >> 12); + *filteredFINAL_LOW_ptr++ = (int16_t)(o - ((int32_t)(*filteredFINAL_ptr++) + << 12)); + } + + // Save the filter state + if (x_length >= state_length) + { + WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state); + WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low); + } else + { + for (i = 0; i < state_length - x_length; i++) + { + state[i] = state[i + x_length]; + state_low[i] = state_low[i + x_length]; + } + for (i = 0; i < x_length; i++) + { + state[state_length - x_length + i] = filtered[i]; + state[state_length - x_length + i] = filtered_low[i]; + } + } + + return x_length; +} diff --git a/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c b/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c new file mode 100644 index 0000000..70001a0 --- /dev/null +++ b/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// TODO(bjornv): Change the return type to report errors. + +void WebRtcSpl_FilterARFastQ12(const int16_t* data_in, + int16_t* data_out, + const int16_t* __restrict coefficients, + size_t coefficients_length, + size_t data_length) { + size_t i = 0; + size_t j = 0; + + assert(data_length > 0); + assert(coefficients_length > 1); + + for (i = 0; i < data_length; i++) { + int32_t output = 0; + int32_t sum = 0; + + for (j = coefficients_length - 1; j > 0; j--) { + sum += coefficients[j] * data_out[i - j]; + } + + output = coefficients[0] * data_in[i]; + output -= sum; + + // Saturate and store the output. + output = WEBRTC_SPL_SAT(134215679, output, -134217728); + data_out[i] = (int16_t)((output + 2048) >> 12); + } +} diff --git a/webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S new file mode 100644 index 0000000..76c8eee --- /dev/null +++ b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S @@ -0,0 +1,218 @@ +@ +@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. +@ +@ Use of this source code is governed by a BSD-style license +@ that can be found in the LICENSE file in the root of the source +@ tree. An additional intellectual property rights grant can be found +@ in the file PATENTS. All contributing project authors may +@ be found in the AUTHORS file in the root of the source tree. +@ + +@ This file contains the function WebRtcSpl_FilterARFastQ12(), optimized for +@ ARMv7 platform. The description header can be found in +@ signal_processing_library.h +@ +@ Output is bit-exact with the generic C code as in filter_ar_fast_q12.c, and +@ the reference C code at end of this file. + +@ Assumptions: +@ (1) data_length > 0 +@ (2) coefficients_length > 1 + +@ Register usage: +@ +@ r0: &data_in[i] +@ r1: &data_out[i], for result ouput +@ r2: &coefficients[0] +@ r3: coefficients_length +@ r4: Iteration counter for the outer loop. +@ r5: data_out[j] as multiplication inputs +@ r6: Calculated value for output data_out[]; interation counter for inner loop +@ r7: Partial sum of a filtering multiplication results +@ r8: Partial sum of a filtering multiplication results +@ r9: &data_out[], for filtering input; data_in[i] +@ r10: coefficients[j] +@ r11: Scratch +@ r12: &coefficients[j] + +#include "webrtc/system_wrappers/interface/asm_defines.h" + +GLOBAL_FUNCTION WebRtcSpl_FilterARFastQ12 +.align 2 +DEFINE_FUNCTION WebRtcSpl_FilterARFastQ12 + push {r4-r11} + + ldrsh r12, [sp, #32] @ data_length + subs r4, r12, #1 + beq ODD_LENGTH @ jump if data_length == 1 + +LOOP_LENGTH: + add r12, r2, r3, lsl #1 + sub r12, #4 @ &coefficients[coefficients_length - 2] + sub r9, r1, r3, lsl #1 + add r9, #2 @ &data_out[i - coefficients_length + 1] + ldr r5, [r9], #4 @ data_out[i - coefficients_length + {1,2}] + + mov r7, #0 @ sum1 + mov r8, #0 @ sum2 + subs r6, r3, #3 @ Iteration counter for inner loop. + beq ODD_A_LENGTH @ branch if coefficients_length == 3 + blt POST_LOOP_A_LENGTH @ branch if coefficients_length == 2 + +LOOP_A_LENGTH: + ldr r10, [r12], #-4 @ coefficients[j - 1], coefficients[j] + subs r6, #2 + smlatt r8, r10, r5, r8 @ sum2 += coefficients[j] * data_out[i - j + 1]; + smlatb r7, r10, r5, r7 @ sum1 += coefficients[j] * data_out[i - j]; + smlabt r7, r10, r5, r7 @ coefficients[j - 1] * data_out[i - j + 1]; + ldr r5, [r9], #4 @ data_out[i - j + 2], data_out[i - j + 3] + smlabb r8, r10, r5, r8 @ coefficients[j - 1] * data_out[i - j + 2]; + bgt LOOP_A_LENGTH + blt POST_LOOP_A_LENGTH + +ODD_A_LENGTH: + ldrsh r10, [r12, #2] @ Filter coefficients coefficients[2] + sub r12, #2 @ &coefficients[0] + smlabb r7, r10, r5, r7 @ sum1 += coefficients[2] * data_out[i - 2]; + smlabt r8, r10, r5, r8 @ sum2 += coefficients[2] * data_out[i - 1]; + ldr r5, [r9, #-2] @ data_out[i - 1], data_out[i] + +POST_LOOP_A_LENGTH: + ldr r10, [r12] @ coefficients[0], coefficients[1] + smlatb r7, r10, r5, r7 @ sum1 += coefficients[1] * data_out[i - 1]; + + ldr r9, [r0], #4 @ data_in[i], data_in[i + 1] + smulbb r6, r10, r9 @ output1 = coefficients[0] * data_in[i]; + sub r6, r7 @ output1 -= sum1; + + sbfx r11, r6, #12, #16 + ssat r7, #16, r6, asr #12 + cmp r7, r11 + addeq r6, r6, #2048 + ssat r6, #16, r6, asr #12 + strh r6, [r1], #2 @ Store data_out[i] + + smlatb r8, r10, r6, r8 @ sum2 += coefficients[1] * data_out[i]; + smulbt r6, r10, r9 @ output2 = coefficients[0] * data_in[i + 1]; + sub r6, r8 @ output1 -= sum1; + + sbfx r11, r6, #12, #16 + ssat r7, #16, r6, asr #12 + cmp r7, r11 + addeq r6, r6, #2048 + ssat r6, #16, r6, asr #12 + strh r6, [r1], #2 @ Store data_out[i + 1] + + subs r4, #2 + bgt LOOP_LENGTH + blt END @ For even data_length, it's done. Jump to END. + +@ Process i = data_length -1, for the case of an odd length. +ODD_LENGTH: + add r12, r2, r3, lsl #1 + sub r12, #4 @ &coefficients[coefficients_length - 2] + sub r9, r1, r3, lsl #1 + add r9, #2 @ &data_out[i - coefficients_length + 1] + mov r7, #0 @ sum1 + mov r8, #0 @ sum1 + subs r6, r3, #2 @ inner loop counter + beq EVEN_A_LENGTH @ branch if coefficients_length == 2 + +LOOP2_A_LENGTH: + ldr r10, [r12], #-4 @ coefficients[j - 1], coefficients[j] + ldr r5, [r9], #4 @ data_out[i - j], data_out[i - j + 1] + subs r6, #2 + smlatb r7, r10, r5, r7 @ sum1 += coefficients[j] * data_out[i - j]; + smlabt r8, r10, r5, r8 @ coefficients[j - 1] * data_out[i - j + 1]; + bgt LOOP2_A_LENGTH + addlt r12, #2 + blt POST_LOOP2_A_LENGTH + +EVEN_A_LENGTH: + ldrsh r10, [r12, #2] @ Filter coefficients coefficients[1] + ldrsh r5, [r9] @ data_out[i - 1] + smlabb r7, r10, r5, r7 @ sum1 += coefficients[1] * data_out[i - 1]; + +POST_LOOP2_A_LENGTH: + ldrsh r10, [r12] @ Filter coefficients coefficients[0] + ldrsh r9, [r0] @ data_in[i] + smulbb r6, r10, r9 @ output1 = coefficients[0] * data_in[i]; + sub r6, r7 @ output1 -= sum1; + sub r6, r8 @ output1 -= sum1; + sbfx r8, r6, #12, #16 + ssat r7, #16, r6, asr #12 + cmp r7, r8 + addeq r6, r6, #2048 + ssat r6, #16, r6, asr #12 + strh r6, [r1] @ Store the data_out[i] + +END: + pop {r4-r11} + bx lr + +@Reference C code: +@ +@void WebRtcSpl_FilterARFastQ12(int16_t* data_in, +@ int16_t* data_out, +@ int16_t* __restrict coefficients, +@ size_t coefficients_length, +@ size_t data_length) { +@ size_t i = 0; +@ size_t j = 0; +@ +@ assert(data_length > 0); +@ assert(coefficients_length > 1); +@ +@ for (i = 0; i < data_length - 1; i += 2) { +@ int32_t output1 = 0; +@ int32_t sum1 = 0; +@ int32_t output2 = 0; +@ int32_t sum2 = 0; +@ +@ for (j = coefficients_length - 1; j > 2; j -= 2) { +@ sum1 += coefficients[j] * data_out[i - j]; +@ sum1 += coefficients[j - 1] * data_out[i - j + 1]; +@ sum2 += coefficients[j] * data_out[i - j + 1]; +@ sum2 += coefficients[j - 1] * data_out[i - j + 2]; +@ } +@ +@ if (j == 2) { +@ sum1 += coefficients[2] * data_out[i - 2]; +@ sum2 += coefficients[2] * data_out[i - 1]; +@ } +@ +@ sum1 += coefficients[1] * data_out[i - 1]; +@ output1 = coefficients[0] * data_in[i]; +@ output1 -= sum1; +@ // Saturate and store the output. +@ output1 = WEBRTC_SPL_SAT(134215679, output1, -134217728); +@ data_out[i] = (int16_t)((output1 + 2048) >> 12); +@ +@ sum2 += coefficients[1] * data_out[i]; +@ output2 = coefficients[0] * data_in[i + 1]; +@ output2 -= sum2; +@ // Saturate and store the output. +@ output2 = WEBRTC_SPL_SAT(134215679, output2, -134217728); +@ data_out[i + 1] = (int16_t)((output2 + 2048) >> 12); +@ } +@ +@ if (i == data_length - 1) { +@ int32_t output1 = 0; +@ int32_t sum1 = 0; +@ +@ for (j = coefficients_length - 1; j > 1; j -= 2) { +@ sum1 += coefficients[j] * data_out[i - j]; +@ sum1 += coefficients[j - 1] * data_out[i - j + 1]; +@ } +@ +@ if (j == 1) { +@ sum1 += coefficients[1] * data_out[i - 1]; +@ } +@ +@ output1 = coefficients[0] * data_in[i]; +@ output1 -= sum1; +@ // Saturate and store the output. +@ output1 = WEBRTC_SPL_SAT(134215679, output1, -134217728); +@ data_out[i] = (int16_t)((output1 + 2048) >> 12); +@ } +@} diff --git a/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c new file mode 100644 index 0000000..0384701 --- /dev/null +++ b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +void WebRtcSpl_FilterARFastQ12(const int16_t* data_in, + int16_t* data_out, + const int16_t* __restrict coefficients, + size_t coefficients_length, + size_t data_length) { + int r0, r1, r2, r3; + int coef0, offset; + int i, j, k; + int coefptr, outptr, tmpout, inptr; +#if !defined(MIPS_DSP_R1_LE) + int max16 = 0x7FFF; + int min16 = 0xFFFF8000; +#endif // #if !defined(MIPS_DSP_R1_LE) + + assert(data_length > 0); + assert(coefficients_length > 1); + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[i], %[data_length], 0 \n\t" + "lh %[coef0], 0(%[coefficients]) \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" + "andi %[k], %[j], 1 \n\t" + "sll %[offset], %[j], 1 \n\t" + "subu %[outptr], %[data_out], %[offset] \n\t" + "addiu %[inptr], %[data_in], 0 \n\t" + "bgtz %[k], 3f \n\t" + " addu %[coefptr], %[coefficients], %[offset] \n\t" + "1: \n\t" + "lh %[r0], 0(%[inptr]) \n\t" + "addiu %[i], %[i], -1 \n\t" + "addiu %[tmpout], %[outptr], 0 \n\t" + "mult %[r0], %[coef0] \n\t" + "2: \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "lh %[r2], 2(%[tmpout]) \n\t" + "lh %[r3], -2(%[coefptr]) \n\t" + "addiu %[tmpout], %[tmpout], 4 \n\t" + "msub %[r0], %[r1] \n\t" + "msub %[r2], %[r3] \n\t" + "addiu %[j], %[j], -2 \n\t" + "bgtz %[j], 2b \n\t" + " addiu %[coefptr], %[coefptr], -4 \n\t" +#if defined(MIPS_DSP_R1_LE) + "extr_r.w %[r0], $ac0, 12 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "mflo %[r0] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "addu %[coefptr], %[coefficients], %[offset] \n\t" + "addiu %[inptr], %[inptr], 2 \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[r0], %[r0], 16 \n\t" + "sra %[r0], %[r0], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "addiu %[r0], %[r0], 2048 \n\t" + "sra %[r0], %[r0], 12 \n\t" + "slt %[r1], %[max16], %[r0] \n\t" + "movn %[r0], %[max16], %[r1] \n\t" + "slt %[r1], %[r0], %[min16] \n\t" + "movn %[r0], %[min16], %[r1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "sh %[r0], 0(%[tmpout]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[outptr], %[outptr], 2 \n\t" + "b 5f \n\t" + " nop \n\t" + "3: \n\t" + "lh %[r0], 0(%[inptr]) \n\t" + "addiu %[i], %[i], -1 \n\t" + "addiu %[tmpout], %[outptr], 0 \n\t" + "mult %[r0], %[coef0] \n\t" + "4: \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "lh %[r2], 2(%[tmpout]) \n\t" + "lh %[r3], -2(%[coefptr]) \n\t" + "addiu %[tmpout], %[tmpout], 4 \n\t" + "msub %[r0], %[r1] \n\t" + "msub %[r2], %[r3] \n\t" + "addiu %[j], %[j], -2 \n\t" + "bgtz %[j], 4b \n\t" + " addiu %[coefptr], %[coefptr], -4 \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "msub %[r0], %[r1] \n\t" +#if defined(MIPS_DSP_R1_LE) + "extr_r.w %[r0], $ac0, 12 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "mflo %[r0] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "addu %[coefptr], %[coefficients], %[offset] \n\t" + "addiu %[inptr], %[inptr], 2 \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[r0], %[r0], 16 \n\t" + "sra %[r0], %[r0], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "addiu %[r0], %[r0], 2048 \n\t" + "sra %[r0], %[r0], 12 \n\t" + "slt %[r1], %[max16], %[r0] \n\t" + "movn %[r0], %[max16], %[r1] \n\t" + "slt %[r1], %[r0], %[min16] \n\t" + "movn %[r0], %[min16], %[r1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "sh %[r0], 2(%[tmpout]) \n\t" + "bgtz %[i], 3b \n\t" + " addiu %[outptr], %[outptr], 2 \n\t" + "5: \n\t" + ".set pop \n\t" + : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0), + [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3), + [coef0] "=&r" (coef0), [offset] "=&r" (offset), + [outptr] "=&r" (outptr), [inptr] "=&r" (inptr), + [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout) + : [coefficients] "r" (coefficients), [data_length] "r" (data_length), + [coefficients_length] "r" (coefficients_length), +#if !defined(MIPS_DSP_R1_LE) + [max16] "r" (max16), [min16] "r" (min16), +#endif + [data_out] "r" (data_out), [data_in] "r" (data_in) + : "hi", "lo", "memory" + ); +} + diff --git a/src/common_audio/signal_processing_library/main/source/filter_ma_fast_q12.c b/webrtc/common_audio/signal_processing/filter_ma_fast_q12.c similarity index 55% rename from src/common_audio/signal_processing_library/main/source/filter_ma_fast_q12.c rename to webrtc/common_audio/signal_processing/filter_ma_fast_q12.c index 19ad9b1..f4d9a3d 100644 --- a/src/common_audio/signal_processing_library/main/source/filter_ma_fast_q12.c +++ b/webrtc/common_audio/signal_processing/filter_ma_fast_q12.c @@ -15,35 +15,31 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_ptr, - WebRtc_Word16* out_ptr, - WebRtc_Word16* B, - WebRtc_Word16 B_length, - WebRtc_Word16 length) +void WebRtcSpl_FilterMAFastQ12(const int16_t* in_ptr, + int16_t* out_ptr, + const int16_t* B, + size_t B_length, + size_t length) { - WebRtc_Word32 o; - int i, j; + size_t i, j; for (i = 0; i < length; i++) { - G_CONST WebRtc_Word16* b_ptr = &B[0]; - G_CONST WebRtc_Word16* x_ptr = &in_ptr[i]; - - o = (WebRtc_Word32)0; + int32_t o = 0; for (j = 0; j < B_length; j++) { - o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--); + o += B[j] * in_ptr[i - j]; } // If output is higher than 32768, saturate it. Same with negative side // 2^27 = 134217728, which corresponds to 32768 in Q12 // Saturate the output - o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728); + o = WEBRTC_SPL_SAT((int32_t)134215679, o, (int32_t)-134217728); - *out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); + *out_ptr++ = (int16_t)((o + (int32_t)2048) >> 12); } return; } diff --git a/src/common_audio/signal_processing_library/main/source/hanning_table.c b/webrtc/common_audio/signal_processing/get_hanning_window.c similarity index 77% rename from src/common_audio/signal_processing_library/main/source/hanning_table.c rename to webrtc/common_audio/signal_processing/get_hanning_window.c index 112d0e5..d83ac21 100644 --- a/src/common_audio/signal_processing_library/main/source/hanning_table.c +++ b/webrtc/common_audio/signal_processing/get_hanning_window.c @@ -10,14 +10,15 @@ /* - * This file contains the Hanning table with 256 entries. + * This file contains the function WebRtcSpl_GetHanningWindow(). + * The description header can be found in signal_processing_library.h * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" // Hanning table with 256 entries -WebRtc_Word16 WebRtcSpl_kHanningTable[] = { +static const int16_t kHanningTable[] = { 1, 2, 6, 10, 15, 22, 30, 39, 50, 62, 75, 89, 104, 121, 138, 157, 178, 199, 222, 246, 271, 297, 324, 353, @@ -51,3 +52,26 @@ WebRtc_Word16 WebRtcSpl_kHanningTable[] = { 16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345, 16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384 }; + +void WebRtcSpl_GetHanningWindow(int16_t *v, size_t size) +{ + size_t jj; + int16_t *vptr1; + + int32_t index; + int32_t factor = ((int32_t)0x40000000); + + factor = WebRtcSpl_DivW32W16(factor, (int16_t)size); + if (size < 513) + index = (int32_t)-0x200000; + else + index = (int32_t)-0x100000; + vptr1 = v; + + for (jj = 0; jj < size; jj++) + { + index += factor; + (*vptr1++) = kHanningTable[index >> 22]; + } + +} diff --git a/src/common_audio/signal_processing_library/main/source/get_scaling_square.c b/webrtc/common_audio/signal_processing/get_scaling_square.c similarity index 66% rename from src/common_audio/signal_processing_library/main/source/get_scaling_square.c rename to webrtc/common_audio/signal_processing/get_scaling_square.c index dccbf33..82e3c8b 100644 --- a/src/common_audio/signal_processing_library/main/source/get_scaling_square.c +++ b/webrtc/common_audio/signal_processing/get_scaling_square.c @@ -15,17 +15,19 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times) +int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector, + size_t in_vector_length, + size_t times) { - int nbits = WebRtcSpl_GetSizeInBits(times); - int i; - WebRtc_Word16 smax = -1; - WebRtc_Word16 sabs; - WebRtc_Word16 *sptr = in_vector; - int t; - int looptimes = in_vector_length; + int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t)times); + size_t i; + int16_t smax = -1; + int16_t sabs; + int16_t *sptr = in_vector; + int16_t t; + size_t looptimes = in_vector_length; for (i = looptimes; i > 0; i--) { diff --git a/webrtc/common_audio/signal_processing/ilbc_specific_functions.c b/webrtc/common_audio/signal_processing/ilbc_specific_functions.c new file mode 100644 index 0000000..301a922 --- /dev/null +++ b/webrtc/common_audio/signal_processing/ilbc_specific_functions.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the iLBC specific functions + * WebRtcSpl_ReverseOrderMultArrayElements() + * WebRtcSpl_ElementwiseVectorMult() + * WebRtcSpl_AddVectorsAndShift() + * WebRtcSpl_AddAffineVectorToVector() + * WebRtcSpl_AffineTransformVector() + * + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +void WebRtcSpl_ReverseOrderMultArrayElements(int16_t *out, const int16_t *in, + const int16_t *win, + size_t vector_length, + int16_t right_shifts) +{ + size_t i; + int16_t *outptr = out; + const int16_t *inptr = in; + const int16_t *winptr = win; + for (i = 0; i < vector_length; i++) + { + *outptr++ = (int16_t)((*inptr++ * *winptr--) >> right_shifts); + } +} + +void WebRtcSpl_ElementwiseVectorMult(int16_t *out, const int16_t *in, + const int16_t *win, size_t vector_length, + int16_t right_shifts) +{ + size_t i; + int16_t *outptr = out; + const int16_t *inptr = in; + const int16_t *winptr = win; + for (i = 0; i < vector_length; i++) + { + *outptr++ = (int16_t)((*inptr++ * *winptr++) >> right_shifts); + } +} + +void WebRtcSpl_AddVectorsAndShift(int16_t *out, const int16_t *in1, + const int16_t *in2, size_t vector_length, + int16_t right_shifts) +{ + size_t i; + int16_t *outptr = out; + const int16_t *in1ptr = in1; + const int16_t *in2ptr = in2; + for (i = vector_length; i > 0; i--) + { + (*outptr++) = (int16_t)(((*in1ptr++) + (*in2ptr++)) >> right_shifts); + } +} + +void WebRtcSpl_AddAffineVectorToVector(int16_t *out, int16_t *in, + int16_t gain, int32_t add_constant, + int16_t right_shifts, + size_t vector_length) +{ + size_t i; + + for (i = 0; i < vector_length; i++) + { + out[i] += (int16_t)((in[i] * gain + add_constant) >> right_shifts); + } +} + +void WebRtcSpl_AffineTransformVector(int16_t *out, int16_t *in, + int16_t gain, int32_t add_constant, + int16_t right_shifts, size_t vector_length) +{ + size_t i; + + for (i = 0; i < vector_length; i++) + { + out[i] = (int16_t)((in[i] * gain + add_constant) >> right_shifts); + } +} diff --git a/webrtc/common_audio/signal_processing/include/real_fft.h b/webrtc/common_audio/signal_processing/include/real_fft.h new file mode 100644 index 0000000..e7942f0 --- /dev/null +++ b/webrtc/common_audio/signal_processing/include/real_fft.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ +#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ + +#include "webrtc/typedefs.h" + +// For ComplexFFT(), the maximum fft order is 10; +// for OpenMax FFT in ARM, it is 12; +// WebRTC APM uses orders of only 7 and 8. +enum {kMaxFFTOrder = 10}; + +struct RealFFT; + +#ifdef __cplusplus +extern "C" { +#endif + +struct RealFFT* WebRtcSpl_CreateRealFFT(int order); +void WebRtcSpl_FreeRealFFT(struct RealFFT* self); + +// Compute an FFT for a real-valued signal of length of 2^order, +// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the +// specification structure, which must be initialized prior to calling the FFT +// function with WebRtcSpl_CreateRealFFT(). +// The relationship between the input and output sequences can +// be expressed in terms of the DFT, i.e.: +// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N) +// n=0,1,2,...N-1 +// N=2^order. +// The conjugate-symmetric output sequence is represented using a CCS vector, +// which is of length N+2, and is organized as follows: +// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1 +// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0 +// where R[n] and I[n], respectively, denote the real and imaginary components +// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length. +// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to +// the foldover frequency. +// +// Input Arguments: +// self - pointer to preallocated and initialized FFT specification structure. +// real_data_in - the input signal. For an ARM Neon platform, it must be +// aligned on a 32-byte boundary. +// +// Output Arguments: +// complex_data_out - the output complex signal with (2^order + 2) 16-bit +// elements. For an ARM Neon platform, it must be different +// from real_data_in, and aligned on a 32-byte boundary. +// +// Return Value: +// 0 - FFT calculation is successful. +// -1 - Error with bad arguments (NULL pointers). +int WebRtcSpl_RealForwardFFT(struct RealFFT* self, + const int16_t* real_data_in, + int16_t* complex_data_out); + +// Compute the inverse FFT for a conjugate-symmetric input sequence of length of +// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by +// the specification structure, which must be initialized prior to calling the +// FFT function with WebRtcSpl_CreateRealFFT(). +// For a transform of length M, the input sequence is represented using a packed +// CCS vector of length M+2, which is explained in the comments for +// WebRtcSpl_RealForwardFFTC above. +// +// Input Arguments: +// self - pointer to preallocated and initialized FFT specification structure. +// complex_data_in - the input complex signal with (2^order + 2) 16-bit +// elements. For an ARM Neon platform, it must be aligned on +// a 32-byte boundary. +// +// Output Arguments: +// real_data_out - the output real signal. For an ARM Neon platform, it must +// be different to complex_data_in, and aligned on a 32-byte +// boundary. +// +// Return Value: +// 0 or a positive number - a value that the elements in the |real_data_out| +// should be shifted left with in order to get +// correct physical values. +// -1 - Error with bad arguments (NULL pointers). +int WebRtcSpl_RealInverseFFT(struct RealFFT* self, + const int16_t* complex_data_in, + int16_t* real_data_out); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ diff --git a/src/common_audio/signal_processing_library/main/interface/signal_processing_library.h b/webrtc/common_audio/signal_processing/include/signal_processing_library.h similarity index 50% rename from src/common_audio/signal_processing_library/main/interface/signal_processing_library.h rename to webrtc/common_audio/signal_processing/include/signal_processing_library.h index 81c55b6..2e96883 100644 --- a/src/common_audio/signal_processing_library/main/interface/signal_processing_library.h +++ b/webrtc/common_audio/signal_processing/include/signal_processing_library.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -19,401 +19,729 @@ #define WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ #include -#include "typedefs.h" - -#ifdef ARM_WINM -#include // intrinsic file for windows mobile -#endif +#include "webrtc/typedefs.h" // Macros specific for the fixed point implementation #define WEBRTC_SPL_WORD16_MAX 32767 #define WEBRTC_SPL_WORD16_MIN -32768 -#define WEBRTC_SPL_WORD32_MAX (WebRtc_Word32)0x7fffffff -#define WEBRTC_SPL_WORD32_MIN (WebRtc_Word32)0x80000000 +#define WEBRTC_SPL_WORD32_MAX (int32_t)0x7fffffff +#define WEBRTC_SPL_WORD32_MIN (int32_t)0x80000000 #define WEBRTC_SPL_MAX_LPC_ORDER 14 -#define WEBRTC_SPL_MAX_SEED_USED 0x80000000L -#define WEBRTC_SPL_MIN(A, B) (A < B ? A : B) // Get min value -#define WEBRTC_SPL_MAX(A, B) (A > B ? A : B) // Get max value +#define WEBRTC_SPL_MIN(A, B) (A < B ? A : B) // Get min value +#define WEBRTC_SPL_MAX(A, B) (A > B ? A : B) // Get max value +// TODO(kma/bjorn): For the next two macros, investigate how to correct the code +// for inputs of a = WEBRTC_SPL_WORD16_MIN or WEBRTC_SPL_WORD32_MIN. #define WEBRTC_SPL_ABS_W16(a) \ - (((WebRtc_Word16)a >= 0) ? ((WebRtc_Word16)a) : -((WebRtc_Word16)a)) + (((int16_t)a >= 0) ? ((int16_t)a) : -((int16_t)a)) #define WEBRTC_SPL_ABS_W32(a) \ - (((WebRtc_Word32)a >= 0) ? ((WebRtc_Word32)a) : -((WebRtc_Word32)a)) - -#if (defined WEBRTC_TARGET_PC)||(defined __TARGET_XSCALE) -#define WEBRTC_SPL_GET_BYTE(a, nr) (((WebRtc_Word8 *)a)[nr]) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - (((WebRtc_Word8 *)d_ptr)[index] = (val)) -#elif defined WEBRTC_BIG_ENDIAN -#define WEBRTC_SPL_GET_BYTE(a, nr) \ - ((((WebRtc_Word16 *)a)[nr >> 1]) >> (((nr + 1) & 0x1) * 8) & 0x00ff) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - ((WebRtc_Word16 *)d_ptr)[index >> 1] = \ - ((((WebRtc_Word16 *)d_ptr)[index >> 1]) \ - & (0x00ff << (8 * ((index) & 0x1)))) | (val << (8 * ((index + 1) & 0x1))) -#else -#define WEBRTC_SPL_GET_BYTE(a,nr) \ - ((((WebRtc_Word16 *)(a))[(nr) >> 1]) >> (((nr) & 0x1) * 8) & 0x00ff) -#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ - ((WebRtc_Word16 *)(d_ptr))[(index) >> 1] = \ - ((((WebRtc_Word16 *)(d_ptr))[(index) >> 1]) \ - & (0x00ff << (8 * (((index) + 1) & 0x1)))) | \ - ((val) << (8 * ((index) & 0x1))) -#endif + (((int32_t)a >= 0) ? ((int32_t)a) : -((int32_t)a)) #define WEBRTC_SPL_MUL(a, b) \ - ((WebRtc_Word32) ((WebRtc_Word32)(a) * (WebRtc_Word32)(b))) + ((int32_t) ((int32_t)(a) * (int32_t)(b))) #define WEBRTC_SPL_UMUL(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b))) -#define WEBRTC_SPL_UMUL_RSFT16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b)) >> 16) -#define WEBRTC_SPL_UMUL_16_16(a, b) \ - ((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) -#define WEBRTC_SPL_UMUL_16_16_RSFT16(a, b) \ - (((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) >> 16) + ((uint32_t) ((uint32_t)(a) * (uint32_t)(b))) #define WEBRTC_SPL_UMUL_32_16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b))) -#define WEBRTC_SPL_UMUL_32_16_RSFT16(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b)) >> 16) + ((uint32_t) ((uint32_t)(a) * (uint16_t)(b))) #define WEBRTC_SPL_MUL_16_U16(a, b) \ - ((WebRtc_Word32)(WebRtc_Word16)(a) * (WebRtc_UWord16)(b)) -#define WEBRTC_SPL_DIV(a, b) \ - ((WebRtc_Word32) ((WebRtc_Word32)(a) / (WebRtc_Word32)(b))) -#define WEBRTC_SPL_UDIV(a, b) \ - ((WebRtc_UWord32) ((WebRtc_UWord32)(a) / (WebRtc_UWord32)(b))) + ((int32_t)(int16_t)(a) * (uint16_t)(b)) -#ifndef WEBRTC_ARCH_ARM_V7A +#ifndef WEBRTC_ARCH_ARM_V7 // For ARMv7 platforms, these are inline functions in spl_inl_armv7.h +#ifndef MIPS32_LE +// For MIPS platforms, these are inline functions in spl_inl_mips.h #define WEBRTC_SPL_MUL_16_16(a, b) \ - ((WebRtc_Word32) (((WebRtc_Word16)(a)) * ((WebRtc_Word16)(b)))) + ((int32_t) (((int16_t)(a)) * ((int16_t)(b)))) #define WEBRTC_SPL_MUL_16_32_RSFT16(a, b) \ (WEBRTC_SPL_MUL_16_16(a, b >> 16) \ + ((WEBRTC_SPL_MUL_16_16(a, (b & 0xffff) >> 1) + 0x4000) >> 15)) -#define WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, b32) \ - ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(a32a, b32) \ - + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32) >> 16))) -#define WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, b32) \ - ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(( \ - (WebRtc_Word16)(a32 >> 16)), b32) + \ - (WEBRTC_SPL_MUL_16_32_RSFT16(( \ - (WebRtc_Word16)((a32 & 0x0000FFFF) >> 1)), b32) >> 15))) +#endif #endif #define WEBRTC_SPL_MUL_16_32_RSFT11(a, b) \ ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 5) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x0200) >> 10)) + + (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x0200) >> 10)) #define WEBRTC_SPL_MUL_16_32_RSFT14(a, b) \ ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 2) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x1000) >> 13)) + + (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x1000) >> 13)) #define WEBRTC_SPL_MUL_16_32_RSFT15(a, b) \ ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 1) \ - + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x2000) >> 14)) - -#ifdef ARM_WINM -#define WEBRTC_SPL_MUL_16_16(a, b) \ - _SmulLo_SW_SL((WebRtc_Word16)(a), (WebRtc_Word16)(b)) -#endif + + (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x2000) >> 14)) #define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) \ (WEBRTC_SPL_MUL_16_16(a, b) >> (c)) #define WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, c) \ - ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) \ - (((WebRtc_Word32)1) << ((c) - 1)))) >> (c)) -#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b) \ - ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) (1 << 14))) >> 15) + ((WEBRTC_SPL_MUL_16_16(a, b) + ((int32_t) \ + (((int32_t)1) << ((c) - 1)))) >> (c)) // C + the 32 most significant bits of A * B #define WEBRTC_SPL_SCALEDIFF32(A, B, C) \ - (C + (B >> 16) * A + (((WebRtc_UWord32)(0x0000FFFF & B) * A) >> 16)) + (C + (B >> 16) * A + (((uint32_t)(0x0000FFFF & B) * A) >> 16)) -#define WEBRTC_SPL_ADD_SAT_W32(a, b) WebRtcSpl_AddSatW32(a, b) #define WEBRTC_SPL_SAT(a, b, c) (b > a ? a : b < c ? c : b) -#define WEBRTC_SPL_MUL_32_16(a, b) ((a) * (b)) -#define WEBRTC_SPL_SUB_SAT_W32(a, b) WebRtcSpl_SubSatW32(a, b) -#define WEBRTC_SPL_ADD_SAT_W16(a, b) WebRtcSpl_AddSatW16(a, b) -#define WEBRTC_SPL_SUB_SAT_W16(a, b) WebRtcSpl_SubSatW16(a, b) - -// We cannot do casting here due to signed/unsigned problem -#define WEBRTC_SPL_IS_NEG(a) ((a) & 0x80000000) // Shifting with negative numbers allowed // Positive means left shift -#define WEBRTC_SPL_SHIFT_W16(x, c) \ - (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) #define WEBRTC_SPL_SHIFT_W32(x, c) \ (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) // Shifting with negative numbers not allowed // We cannot do casting here due to signed/unsigned problem -#define WEBRTC_SPL_RSHIFT_W16(x, c) ((x) >> (c)) -#define WEBRTC_SPL_LSHIFT_W16(x, c) ((x) << (c)) -#define WEBRTC_SPL_RSHIFT_W32(x, c) ((x) >> (c)) #define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c)) -#define WEBRTC_SPL_RSHIFT_U16(x, c) ((WebRtc_UWord16)(x) >> (c)) -#define WEBRTC_SPL_LSHIFT_U16(x, c) ((WebRtc_UWord16)(x) << (c)) -#define WEBRTC_SPL_RSHIFT_U32(x, c) ((WebRtc_UWord32)(x) >> (c)) -#define WEBRTC_SPL_LSHIFT_U32(x, c) ((WebRtc_UWord32)(x) << (c)) - -#define WEBRTC_SPL_VNEW(t, n) (t *) malloc (sizeof (t) * (n)) -#define WEBRTC_SPL_FREE free +#define WEBRTC_SPL_RSHIFT_U32(x, c) ((uint32_t)(x) >> (c)) #define WEBRTC_SPL_RAND(a) \ - ((WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT((a), 18816, 7) & 0x00007fff)) + ((int16_t)((((int16_t)a * 18816) >> 7) & 0x00007fff)) #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif -#define WEBRTC_SPL_MEMCPY_W8(v1, v2, length) \ - memcpy(v1, v2, (length) * sizeof(char)) #define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \ - memcpy(v1, v2, (length) * sizeof(WebRtc_Word16)) - -#define WEBRTC_SPL_MEMMOVE_W16(v1, v2, length) \ - memmove(v1, v2, (length) * sizeof(WebRtc_Word16)) - -// Trigonometric tables used for quick lookup -// default declarations -extern WebRtc_Word16 WebRtcSpl_kCosTable[]; -extern WebRtc_Word16 WebRtcSpl_kSinTable[]; -extern WebRtc_Word16 WebRtcSpl_kSinTable1024[]; -// Hanning table -extern WebRtc_Word16 WebRtcSpl_kHanningTable[]; -// Random table -extern WebRtc_Word16 WebRtcSpl_kRandNTable[]; + memcpy(v1, v2, (length) * sizeof(int16_t)) // inline functions: -#include "spl_inl.h" +#include "webrtc/common_audio/signal_processing/include/spl_inl.h" -// Get SPL Version -WebRtc_Word16 WebRtcSpl_get_version(char* version, - WebRtc_Word16 length_in_bytes); +// Initialize SPL. Currently it contains only function pointer initialization. +// If the underlying platform is known to be ARM-Neon (WEBRTC_HAS_NEON defined), +// the pointers will be assigned to code optimized for Neon; otherwise +// if run-time Neon detection (WEBRTC_DETECT_NEON) is enabled, the pointers +// will be assigned to either Neon code or generic C code; otherwise, generic C +// code will be assigned. +// Note that this function MUST be called in any application that uses SPL +// functions. +void WebRtcSpl_Init(); -int WebRtcSpl_GetScalingSquare(WebRtc_Word16* in_vector, - int in_vector_length, - int times); +int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector, + size_t in_vector_length, + size_t times); // Copy and set operations. Implementation in copy_set_operations.c. // Descriptions at bottom of file. -void WebRtcSpl_MemSetW16(WebRtc_Word16* vector, - WebRtc_Word16 set_value, - int vector_length); -void WebRtcSpl_MemSetW32(WebRtc_Word32* vector, - WebRtc_Word32 set_value, - int vector_length); -void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - int vector_length); -WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16 samples, - WebRtc_Word16* out_vector); -WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16* vector, - WebRtc_Word16 vector_length); -WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32* vector, - WebRtc_Word16 vector_length); +void WebRtcSpl_MemSetW16(int16_t* vector, + int16_t set_value, + size_t vector_length); +void WebRtcSpl_MemSetW32(int32_t* vector, + int32_t set_value, + size_t vector_length); +void WebRtcSpl_MemCpyReversedOrder(int16_t* out_vector, + int16_t* in_vector, + size_t vector_length); +void WebRtcSpl_CopyFromEndW16(const int16_t* in_vector, + size_t in_vector_length, + size_t samples, + int16_t* out_vector); +void WebRtcSpl_ZerosArrayW16(int16_t* vector, + size_t vector_length); +void WebRtcSpl_ZerosArrayW32(int32_t* vector, + size_t vector_length); // End: Copy and set operations. -// Minimum and maximum operations. Implementation in min_max_operations.c. -// Descriptions at bottom of file. -WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16* vector, - WebRtc_Word16 length); -WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, - WebRtc_Word16 length); +// Minimum and maximum operation functions and their pointers. +// Implementation in min_max_operations.c. + +// Returns the largest absolute value in a signed 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Maximum absolute value in vector. +typedef int16_t (*MaxAbsValueW16)(const int16_t* vector, size_t length); +extern MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16; +int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, size_t length); +#endif +#if defined(MIPS32_LE) +int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, size_t length); +#endif + +// Returns the largest absolute value in a signed 32-bit vector. +// +// Input: +// - vector : 32-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Maximum absolute value in vector. +typedef int32_t (*MaxAbsValueW32)(const int32_t* vector, size_t length); +extern MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32; +int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int32_t WebRtcSpl_MaxAbsValueW32Neon(const int32_t* vector, size_t length); +#endif +#if defined(MIPS_DSP_R1_LE) +int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, size_t length); +#endif + +// Returns the maximum value of a 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Maximum sample value in |vector|. +typedef int16_t (*MaxValueW16)(const int16_t* vector, size_t length); +extern MaxValueW16 WebRtcSpl_MaxValueW16; +int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int16_t WebRtcSpl_MaxValueW16Neon(const int16_t* vector, size_t length); +#endif +#if defined(MIPS32_LE) +int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, size_t length); +#endif + +// Returns the maximum value of a 32-bit vector. +// +// Input: +// - vector : 32-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Maximum sample value in |vector|. +typedef int32_t (*MaxValueW32)(const int32_t* vector, size_t length); +extern MaxValueW32 WebRtcSpl_MaxValueW32; +int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int32_t WebRtcSpl_MaxValueW32Neon(const int32_t* vector, size_t length); +#endif +#if defined(MIPS32_LE) +int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, size_t length); +#endif + +// Returns the minimum value of a 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Minimum sample value in |vector|. +typedef int16_t (*MinValueW16)(const int16_t* vector, size_t length); +extern MinValueW16 WebRtcSpl_MinValueW16; +int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, size_t length); +#endif +#if defined(MIPS32_LE) +int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, size_t length); +#endif + +// Returns the minimum value of a 32-bit vector. +// +// Input: +// - vector : 32-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Minimum sample value in |vector|. +typedef int32_t (*MinValueW32)(const int32_t* vector, size_t length); +extern MinValueW32 WebRtcSpl_MinValueW32; +int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int32_t WebRtcSpl_MinValueW32Neon(const int32_t* vector, size_t length); +#endif +#if defined(MIPS32_LE) +int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, size_t length); +#endif + +// Returns the vector index to the largest absolute value of a 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Index to the maximum absolute value in vector. +// If there are multiple equal maxima, return the index of the +// first. -32768 will always have precedence over 32767 (despite +// -32768 presenting an int16 absolute value of 32767). +size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length); + +// Returns the vector index to the maximum sample value of a 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Index to the maximum value in vector (if multiple +// indexes have the maximum, return the first). +size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length); + +// Returns the vector index to the maximum sample value of a 32-bit vector. +// +// Input: +// - vector : 32-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Index to the maximum value in vector (if multiple +// indexes have the maximum, return the first). +size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length); + +// Returns the vector index to the minimum sample value of a 16-bit vector. +// +// Input: +// - vector : 16-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Index to the mimimum value in vector (if multiple +// indexes have the minimum, return the first). +size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length); + +// Returns the vector index to the minimum sample value of a 32-bit vector. +// +// Input: +// - vector : 32-bit input vector. +// - length : Number of samples in vector. +// +// Return value : Index to the mimimum value in vector (if multiple +// indexes have the minimum, return the first). +size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length); + // End: Minimum and maximum operations. + // Vector scaling operations. Implementation in vector_scaling_operations.c. // Description at bottom of file. -void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16 right_shifts); -void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32* in_vector, - WebRtc_Word16 right_shifts); -void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length, - G_CONST WebRtc_Word32* in_vector, - WebRtc_Word16 right_shifts); +void WebRtcSpl_VectorBitShiftW16(int16_t* out_vector, + size_t vector_length, + const int16_t* in_vector, + int16_t right_shifts); +void WebRtcSpl_VectorBitShiftW32(int32_t* out_vector, + size_t vector_length, + const int32_t* in_vector, + int16_t right_shifts); +void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out_vector, + size_t vector_length, + const int32_t* in_vector, + int right_shifts); +void WebRtcSpl_ScaleVector(const int16_t* in_vector, + int16_t* out_vector, + int16_t gain, + size_t vector_length, + int16_t right_shifts); +void WebRtcSpl_ScaleVectorWithSat(const int16_t* in_vector, + int16_t* out_vector, + int16_t gain, + size_t vector_length, + int16_t right_shifts); +void WebRtcSpl_ScaleAndAddVectors(const int16_t* in_vector1, + int16_t gain1, int right_shifts1, + const int16_t* in_vector2, + int16_t gain2, int right_shifts2, + int16_t* out_vector, + size_t vector_length); -void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16 gain, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16 gain, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16* in_vector1, - WebRtc_Word16 gain1, int right_shifts1, - G_CONST WebRtc_Word16* in_vector2, - WebRtc_Word16 gain2, int right_shifts2, - WebRtc_Word16* out_vector, - int vector_length); +// The functions (with related pointer) perform the vector operation: +// out_vector[k] = ((scale1 * in_vector1[k]) + (scale2 * in_vector2[k]) +// + round_value) >> right_shifts, +// where round_value = (1 << right_shifts) >> 1. +// +// Input: +// - in_vector1 : Input vector 1 +// - in_vector1_scale : Gain to be used for vector 1 +// - in_vector2 : Input vector 2 +// - in_vector2_scale : Gain to be used for vector 2 +// - right_shifts : Number of right bit shifts to be applied +// - length : Number of elements in the input vectors +// +// Output: +// - out_vector : Output vector +// Return value : 0 if OK, -1 if (in_vector1 == NULL +// || in_vector2 == NULL || out_vector == NULL +// || length <= 0 || right_shift < 0). +typedef int (*ScaleAndAddVectorsWithRound)(const int16_t* in_vector1, + int16_t in_vector1_scale, + const int16_t* in_vector2, + int16_t in_vector2_scale, + int right_shifts, + int16_t* out_vector, + size_t length); +extern ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound; +int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1, + int16_t in_vector1_scale, + const int16_t* in_vector2, + int16_t in_vector2_scale, + int right_shifts, + int16_t* out_vector, + size_t length); +#if defined(MIPS_DSP_R1_LE) +int WebRtcSpl_ScaleAndAddVectorsWithRound_mips(const int16_t* in_vector1, + int16_t in_vector1_scale, + const int16_t* in_vector2, + int16_t in_vector2_scale, + int right_shifts, + int16_t* out_vector, + size_t length); +#endif // End: Vector scaling operations. // iLBC specific functions. Implementations in ilbc_specific_functions.c. // Description at bottom of file. -void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16* in_vector1, - WebRtc_Word16 scale1, - WebRtc_Word16* in_vector2, - WebRtc_Word16 scale2, - WebRtc_Word16 right_shifts, - WebRtc_Word16* out_vector, - WebRtc_Word16 vector_length); -void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector, - G_CONST WebRtc_Word16* window, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector, - G_CONST WebRtc_Word16* window, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16* out_vector, - G_CONST WebRtc_Word16* in_vector1, - G_CONST WebRtc_Word16* in_vector2, - WebRtc_Word16 vector_length, - WebRtc_Word16 right_shifts); -void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - WebRtc_Word16 gain, - WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, - int vector_length); -void WebRtcSpl_AffineTransformVector(WebRtc_Word16* out_vector, - WebRtc_Word16* in_vector, - WebRtc_Word16 gain, - WebRtc_Word32 add_constant, - WebRtc_Word16 right_shifts, - int vector_length); +void WebRtcSpl_ReverseOrderMultArrayElements(int16_t* out_vector, + const int16_t* in_vector, + const int16_t* window, + size_t vector_length, + int16_t right_shifts); +void WebRtcSpl_ElementwiseVectorMult(int16_t* out_vector, + const int16_t* in_vector, + const int16_t* window, + size_t vector_length, + int16_t right_shifts); +void WebRtcSpl_AddVectorsAndShift(int16_t* out_vector, + const int16_t* in_vector1, + const int16_t* in_vector2, + size_t vector_length, + int16_t right_shifts); +void WebRtcSpl_AddAffineVectorToVector(int16_t* out_vector, + int16_t* in_vector, + int16_t gain, + int32_t add_constant, + int16_t right_shifts, + size_t vector_length); +void WebRtcSpl_AffineTransformVector(int16_t* out_vector, + int16_t* in_vector, + int16_t gain, + int32_t add_constant, + int16_t right_shifts, + size_t vector_length); // End: iLBC specific functions. -// Signal processing operations. Descriptions at bottom of this file. -int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* vector, - int vector_length, int order, - WebRtc_Word32* result_vector, - int* scale); -WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr, - WebRtc_Word16* lpc_coef, - WebRtc_Word16* refl_coef, - WebRtc_Word16 order); -void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef, +// Signal processing operations. + +// A 32-bit fix-point implementation of auto-correlation computation +// +// Input: +// - in_vector : Vector to calculate autocorrelation upon +// - in_vector_length : Length (in samples) of |vector| +// - order : The order up to which the autocorrelation should be +// calculated +// +// Output: +// - result : auto-correlation values (values should be seen +// relative to each other since the absolute values +// might have been down shifted to avoid overflow) +// +// - scale : The number of left shifts required to obtain the +// auto-correlation in Q0 +// +// Return value : Number of samples in |result|, i.e. (order+1) +size_t WebRtcSpl_AutoCorrelation(const int16_t* in_vector, + size_t in_vector_length, + size_t order, + int32_t* result, + int* scale); + +// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that +// does NOT use the 64 bit class +// +// Input: +// - auto_corr : Vector with autocorrelation values of length >= |order|+1 +// - order : The LPC filter order (support up to order 20) +// +// Output: +// - lpc_coef : lpc_coef[0..order] LPC coefficients in Q12 +// - refl_coef : refl_coef[0...order-1]| Reflection coefficients in Q15 +// +// Return value : 1 for stable 0 for unstable +int16_t WebRtcSpl_LevinsonDurbin(const int32_t* auto_corr, + int16_t* lpc_coef, + int16_t* refl_coef, + size_t order); + +// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|. +// This version is a 16 bit operation. +// +// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a +// "slightly unstable" filter (i.e., a pole just outside the unit circle) in +// "rare" cases even if the reflection coefficients are stable. +// +// Input: +// - refl_coef : Reflection coefficients in Q15 that should be converted +// to LPC coefficients +// - use_order : Number of coefficients in |refl_coef| +// +// Output: +// - lpc_coef : LPC coefficients in Q12 +void WebRtcSpl_ReflCoefToLpc(const int16_t* refl_coef, int use_order, - WebRtc_Word16* lpc_coef); -void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef, + int16_t* lpc_coef); + +// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|. +// This version is a 16 bit operation. +// The conversion is implemented by the step-down algorithm. +// +// Input: +// - lpc_coef : LPC coefficients in Q12, that should be converted to +// reflection coefficients +// - use_order : Number of coefficients in |lpc_coef| +// +// Output: +// - refl_coef : Reflection coefficients in Q15. +void WebRtcSpl_LpcToReflCoef(int16_t* lpc_coef, int use_order, - WebRtc_Word16* refl_coef); -void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr, + int16_t* refl_coef); + +// Calculates reflection coefficients (16 bit) from auto-correlation values +// +// Input: +// - auto_corr : Auto-correlation values +// - use_order : Number of coefficients wanted be calculated +// +// Output: +// - refl_coef : Reflection coefficients in Q15. +void WebRtcSpl_AutoCorrToReflCoef(const int32_t* auto_corr, int use_order, - WebRtc_Word16* refl_coef); -void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_corr, - WebRtc_Word16* vector1, - WebRtc_Word16* vector2, - WebRtc_Word16 dim_vector, - WebRtc_Word16 dim_cross_corr, - WebRtc_Word16 right_shifts, - WebRtc_Word16 step_vector2); -void WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size); -void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector, - int vector_length, - WebRtc_Word16* out_vector); + int16_t* refl_coef); + +// The functions (with related pointer) calculate the cross-correlation between +// two sequences |seq1| and |seq2|. +// |seq1| is fixed and |seq2| slides as the pointer is increased with the +// amount |step_seq2|. Note the arguments should obey the relationship: +// |dim_seq| - 1 + |step_seq2| * (|dim_cross_correlation| - 1) < +// buffer size of |seq2| +// +// Input: +// - seq1 : First sequence (fixed throughout the correlation) +// - seq2 : Second sequence (slides |step_vector2| for each +// new correlation) +// - dim_seq : Number of samples to use in the cross-correlation +// - dim_cross_correlation : Number of cross-correlations to calculate (the +// start position for |vector2| is updated for each +// new one) +// - right_shifts : Number of right bit shifts to use. This will +// become the output Q-domain. +// - step_seq2 : How many (positive or negative) steps the +// |vector2| pointer should be updated for each new +// cross-correlation value. +// +// Output: +// - cross_correlation : The cross-correlation in Q(-right_shifts) +typedef void (*CrossCorrelation)(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2); +extern CrossCorrelation WebRtcSpl_CrossCorrelation; +void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +void WebRtcSpl_CrossCorrelationNeon(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2); +#endif +#if defined(MIPS32_LE) +void WebRtcSpl_CrossCorrelation_mips(int32_t* cross_correlation, + const int16_t* seq1, + const int16_t* seq2, + size_t dim_seq, + size_t dim_cross_correlation, + int right_shifts, + int step_seq2); +#endif + +// Creates (the first half of) a Hanning window. Size must be at least 1 and +// at most 512. +// +// Input: +// - size : Length of the requested Hanning window (1 to 512) +// +// Output: +// - window : Hanning vector in Q14. +void WebRtcSpl_GetHanningWindow(int16_t* window, size_t size); + +// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector +// |in_vector|. Input and output values are in Q15. +// +// Inputs: +// - in_vector : Values to calculate sqrt(1 - x^2) of +// - vector_length : Length of vector |in_vector| +// +// Output: +// - out_vector : Output values in Q15 +void WebRtcSpl_SqrtOfOneMinusXSquared(int16_t* in_vector, + size_t vector_length, + int16_t* out_vector); // End: Signal processing operations. -// Randomization functions. Implementations collected in randomization_functions.c and -// descriptions at bottom of this file. -WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32* seed); -WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, - WebRtc_Word16 vector_length, - WebRtc_UWord32* seed); +// Randomization functions. Implementations collected in +// randomization_functions.c and descriptions at bottom of this file. +int16_t WebRtcSpl_RandU(uint32_t* seed); +int16_t WebRtcSpl_RandN(uint32_t* seed); +int16_t WebRtcSpl_RandUArray(int16_t* vector, + int16_t vector_length, + uint32_t* seed); // End: Randomization functions. // Math functions -WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value); -WebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value); +int32_t WebRtcSpl_Sqrt(int32_t value); +int32_t WebRtcSpl_SqrtFloor(int32_t value); // Divisions. Implementations collected in division_operations.c and // descriptions at bottom of this file. -WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den); -WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den); -WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den); -WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den); -WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, - WebRtc_Word16 den_low); +uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den); +int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den); +int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den); +int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den); +int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low); // End: Divisions. -WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, - int vector_length, - int* scale_factor); +int32_t WebRtcSpl_Energy(int16_t* vector, + size_t vector_length, + int* scale_factor); -WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16* vector1, - WebRtc_Word16* vector2, - int vector_length, - int scaling); +// Calculates the dot product between two (int16_t) vectors. +// +// Input: +// - vector1 : Vector 1 +// - vector2 : Vector 2 +// - vector_length : Number of samples used in the dot product +// - scaling : The number of right bit shifts to apply on each term +// during calculation to avoid overflow, i.e., the +// output will be in Q(-|scaling|) +// +// Return value : The dot product in Q(-scaling) +int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1, + const int16_t* vector2, + size_t length, + int scaling); // Filter operations. -int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length, - G_CONST WebRtc_Word16* in_vector, int in_vector_length, - WebRtc_Word16* filter_state, int filter_state_length, - WebRtc_Word16* filter_state_low, - int filter_state_low_length, WebRtc_Word16* out_vector, - WebRtc_Word16* out_vector_low, int out_vector_low_length); +size_t WebRtcSpl_FilterAR(const int16_t* ar_coef, + size_t ar_coef_length, + const int16_t* in_vector, + size_t in_vector_length, + int16_t* filter_state, + size_t filter_state_length, + int16_t* filter_state_low, + size_t filter_state_low_length, + int16_t* out_vector, + int16_t* out_vector_low, + size_t out_vector_low_length); + +// WebRtcSpl_FilterMAFastQ12(...) +// +// Performs a MA filtering on a vector in Q12 +// +// Input: +// - in_vector : Input samples (state in positions +// in_vector[-order] .. in_vector[-1]) +// - ma_coef : Filter coefficients (in Q12) +// - ma_coef_length : Number of B coefficients (order+1) +// - vector_length : Number of samples to be filtered +// +// Output: +// - out_vector : Filtered samples +// +void WebRtcSpl_FilterMAFastQ12(const int16_t* in_vector, + int16_t* out_vector, + const int16_t* ma_coef, + size_t ma_coef_length, + size_t vector_length); + +// Performs a AR filtering on a vector in Q12 +// Input: +// - data_in : Input samples +// - data_out : State information in positions +// data_out[-order] .. data_out[-1] +// - coefficients : Filter coefficients (in Q12) +// - coefficients_length: Number of coefficients (order+1) +// - data_length : Number of samples to be filtered +// Output: +// - data_out : Filtered samples +void WebRtcSpl_FilterARFastQ12(const int16_t* data_in, + int16_t* data_out, + const int16_t* __restrict coefficients, + size_t coefficients_length, + size_t data_length); + +// The functions (with related pointer) perform a MA down sampling filter +// on a vector. +// Input: +// - data_in : Input samples (state in positions +// data_in[-order] .. data_in[-1]) +// - data_in_length : Number of samples in |data_in| to be filtered. +// This must be at least +// |delay| + |factor|*(|out_vector_length|-1) + 1) +// - data_out_length : Number of down sampled samples desired +// - coefficients : Filter coefficients (in Q12) +// - coefficients_length: Number of coefficients (order+1) +// - factor : Decimation factor +// - delay : Delay of filter (compensated for in out_vector) +// Output: +// - data_out : Filtered samples +// Return value : 0 if OK, -1 if |in_vector| is too short +typedef int (*DownsampleFast)(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay); +extern DownsampleFast WebRtcSpl_DownsampleFast; +int WebRtcSpl_DownsampleFastC(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay); +#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +int WebRtcSpl_DownsampleFastNeon(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay); +#endif +#if defined(MIPS32_LE) +int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in, + size_t data_in_length, + int16_t* data_out, + size_t data_out_length, + const int16_t* __restrict coefficients, + size_t coefficients_length, + int factor, + size_t delay); +#endif -void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16* ma_coef, - WebRtc_Word16 ma_coef_length, - WebRtc_Word16 vector_length); -void WebRtcSpl_FilterARFastQ12(WebRtc_Word16* in_vector, - WebRtc_Word16* out_vector, - WebRtc_Word16* ar_coef, - WebRtc_Word16 ar_coef_length, - WebRtc_Word16 vector_length); -int WebRtcSpl_DownsampleFast(WebRtc_Word16* in_vector, - WebRtc_Word16 in_vector_length, - WebRtc_Word16* out_vector, - WebRtc_Word16 out_vector_length, - WebRtc_Word16* ma_coef, - WebRtc_Word16 ma_coef_length, - WebRtc_Word16 factor, - WebRtc_Word16 delay); // End: Filter operations. // FFT operations -int WebRtcSpl_ComplexFFT(WebRtc_Word16 vector[], int stages, int mode); -int WebRtcSpl_ComplexIFFT(WebRtc_Word16 vector[], int stages, int mode); -void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 vector[], int stages); + +int WebRtcSpl_ComplexFFT(int16_t vector[], int stages, int mode); +int WebRtcSpl_ComplexIFFT(int16_t vector[], int stages, int mode); + +// Treat a 16-bit complex data buffer |complex_data| as an array of 32-bit +// values, and swap elements whose indexes are bit-reverses of each other. +// +// Input: +// - complex_data : Complex data buffer containing 2^|stages| real +// elements interleaved with 2^|stages| imaginary +// elements: [Re Im Re Im Re Im....] +// - stages : Number of FFT stages. Must be at least 3 and at most +// 10, since the table WebRtcSpl_kSinTable1024[] is 1024 +// elements long. +// +// Output: +// - complex_data : The complex data buffer. + +void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages); + // End: FFT operations /************************************************************ @@ -434,59 +762,55 @@ void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 vector[], int stages); ******************************************************************/ // state structure for 22 -> 16 resampler -typedef struct -{ - WebRtc_Word32 S_22_44[8]; - WebRtc_Word32 S_44_32[8]; - WebRtc_Word32 S_32_16[8]; +typedef struct { + int32_t S_22_44[8]; + int32_t S_44_32[8]; + int32_t S_32_16[8]; } WebRtcSpl_State22khzTo16khz; -void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, - WebRtc_Word16* out, +void WebRtcSpl_Resample22khzTo16khz(const int16_t* in, + int16_t* out, WebRtcSpl_State22khzTo16khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state); // state structure for 16 -> 22 resampler -typedef struct -{ - WebRtc_Word32 S_16_32[8]; - WebRtc_Word32 S_32_22[8]; +typedef struct { + int32_t S_16_32[8]; + int32_t S_32_22[8]; } WebRtcSpl_State16khzTo22khz; -void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, - WebRtc_Word16* out, +void WebRtcSpl_Resample16khzTo22khz(const int16_t* in, + int16_t* out, WebRtcSpl_State16khzTo22khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state); // state structure for 22 -> 8 resampler -typedef struct -{ - WebRtc_Word32 S_22_22[16]; - WebRtc_Word32 S_22_16[8]; - WebRtc_Word32 S_16_8[8]; +typedef struct { + int32_t S_22_22[16]; + int32_t S_22_16[8]; + int32_t S_16_8[8]; } WebRtcSpl_State22khzTo8khz; -void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample22khzTo8khz(const int16_t* in, int16_t* out, WebRtcSpl_State22khzTo8khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state); // state structure for 8 -> 22 resampler -typedef struct -{ - WebRtc_Word32 S_8_16[8]; - WebRtc_Word32 S_16_11[8]; - WebRtc_Word32 S_11_22[8]; +typedef struct { + int32_t S_8_16[8]; + int32_t S_16_11[8]; + int32_t S_11_22[8]; } WebRtcSpl_State8khzTo22khz; -void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample8khzTo22khz(const int16_t* in, int16_t* out, WebRtcSpl_State8khzTo22khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state); @@ -501,14 +825,11 @@ void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state); * ******************************************************************/ -void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); +void WebRtcSpl_Resample48khzTo32khz(const int32_t* In, int32_t* Out, size_t K); -void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); +void WebRtcSpl_Resample32khzTo24khz(const int32_t* In, int32_t* Out, size_t K); -void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, - const WebRtc_Word32 K); +void WebRtcSpl_Resample44khzTo32khz(const int32_t* In, int32_t* Out, size_t K); /******************************************************************* * resample_48khz.c @@ -521,57 +842,53 @@ void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, * ******************************************************************/ -typedef struct -{ - WebRtc_Word32 S_48_48[16]; - WebRtc_Word32 S_48_32[8]; - WebRtc_Word32 S_32_16[8]; +typedef struct { + int32_t S_48_48[16]; + int32_t S_48_32[8]; + int32_t S_32_16[8]; } WebRtcSpl_State48khzTo16khz; -void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample48khzTo16khz(const int16_t* in, int16_t* out, WebRtcSpl_State48khzTo16khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state); -typedef struct -{ - WebRtc_Word32 S_16_32[8]; - WebRtc_Word32 S_32_24[8]; - WebRtc_Word32 S_24_48[8]; +typedef struct { + int32_t S_16_32[8]; + int32_t S_32_24[8]; + int32_t S_24_48[8]; } WebRtcSpl_State16khzTo48khz; -void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample16khzTo48khz(const int16_t* in, int16_t* out, WebRtcSpl_State16khzTo48khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state); -typedef struct -{ - WebRtc_Word32 S_48_24[8]; - WebRtc_Word32 S_24_24[16]; - WebRtc_Word32 S_24_16[8]; - WebRtc_Word32 S_16_8[8]; +typedef struct { + int32_t S_48_24[8]; + int32_t S_24_24[16]; + int32_t S_24_16[8]; + int32_t S_16_8[8]; } WebRtcSpl_State48khzTo8khz; -void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample48khzTo8khz(const int16_t* in, int16_t* out, WebRtcSpl_State48khzTo8khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state); -typedef struct -{ - WebRtc_Word32 S_8_16[8]; - WebRtc_Word32 S_16_12[8]; - WebRtc_Word32 S_12_24[8]; - WebRtc_Word32 S_24_48[8]; +typedef struct { + int32_t S_8_16[8]; + int32_t S_16_12[8]; + int32_t S_12_24[8]; + int32_t S_24_48[8]; } WebRtcSpl_State8khzTo48khz; -void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, +void WebRtcSpl_Resample8khzTo48khz(const int16_t* in, int16_t* out, WebRtcSpl_State8khzTo48khz* state, - WebRtc_Word32* tmpmem); + int32_t* tmpmem); void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state); @@ -582,30 +899,32 @@ void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state); * ******************************************************************/ -void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState); +void WebRtcSpl_DownsampleBy2(const int16_t* in, size_t len, + int16_t* out, int32_t* filtState); -void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out, - WebRtc_Word32* filtState); +void WebRtcSpl_UpsampleBy2(const int16_t* in, size_t len, + int16_t* out, int32_t* filtState); /************************************************************ * END OF RESAMPLING FUNCTIONS ************************************************************/ -void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, - WebRtc_Word16* low_band, - WebRtc_Word16* high_band, - WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2); -void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, - const WebRtc_Word16* high_band, - WebRtc_Word16* out_data, - WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2); +void WebRtcSpl_AnalysisQMF(const int16_t* in_data, + size_t in_data_length, + int16_t* low_band, + int16_t* high_band, + int32_t* filter_state1, + int32_t* filter_state2); +void WebRtcSpl_SynthesisQMF(const int16_t* low_band, + const int16_t* high_band, + size_t band_length, + int16_t* out_data, + int32_t* filter_state1, + int32_t* filter_state2); #ifdef __cplusplus } -#endif // __cplusplus -#endif // WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ +#endif // __cplusplus +#endif // WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ // // WebRtcSpl_AddSatW16(...) @@ -689,7 +1008,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // Returns the # of bits required to scale the samples specified in the // |in_vector| parameter so that, if the squares of the samples are added the // # of times specified by the |times| parameter, the 32-bit addition will not -// overflow (result in WebRtc_Word32). +// overflow (result in int32_t). // // Input: // - in_vector : Input vector to check scaling on @@ -703,11 +1022,11 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_MemSetW16(...) // -// Sets all the values in the WebRtc_Word16 vector |vector| of length +// Sets all the values in the int16_t vector |vector| of length // |vector_length| to the specified value |set_value| // // Input: -// - vector : Pointer to the WebRtc_Word16 vector +// - vector : Pointer to the int16_t vector // - set_value : Value specified // - vector_length : Length of vector // @@ -715,11 +1034,11 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_MemSetW32(...) // -// Sets all the values in the WebRtc_Word32 vector |vector| of length +// Sets all the values in the int32_t vector |vector| of length // |vector_length| to the specified value |set_value| // // Input: -// - vector : Pointer to the WebRtc_Word16 vector +// - vector : Pointer to the int16_t vector // - set_value : Value specified // - vector_length : Length of vector // @@ -727,20 +1046,20 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_MemCpyReversedOrder(...) // -// Copies all the values from the source WebRtc_Word16 vector |in_vector| to a -// destination WebRtc_Word16 vector |out_vector|. It is done in reversed order, +// Copies all the values from the source int16_t vector |in_vector| to a +// destination int16_t vector |out_vector|. It is done in reversed order, // meaning that the first sample of |in_vector| is copied to the last sample of // the |out_vector|. The procedure continues until the last sample of // |in_vector| has been copied to the first sample of |out_vector|. This // creates a reversed vector. Used in e.g. prediction in iLBC. // // Input: -// - in_vector : Pointer to the first sample in a WebRtc_Word16 vector +// - in_vector : Pointer to the first sample in a int16_t vector // of length |length| // - vector_length : Number of elements to copy // // Output: -// - out_vector : Pointer to the last sample in a WebRtc_Word16 vector +// - out_vector : Pointer to the last sample in a int16_t vector // of length |length| // @@ -759,8 +1078,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // Output: // - out_vector : Vector with the requested samples // -// Return value : Number of copied samples in |out_vector| -// // // WebRtcSpl_ZerosArrayW16(...) @@ -775,108 +1092,13 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // Output: // - vector : Vector containing all zeros // -// Return value : Number of samples in vector -// - -// -// WebRtcSpl_OnesArrayW16(...) -// WebRtcSpl_OnesArrayW32(...) -// -// Inserts the value "one" in all positions of a w16 and a w32 vector -// respectively. -// -// Input: -// - vector_length : Number of samples in vector -// -// Output: -// - vector : Vector containing all ones -// -// Return value : Number of samples in vector -// - -// -// WebRtcSpl_MinValueW16(...) -// WebRtcSpl_MinValueW32(...) -// -// Returns the minimum value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Minimum sample value in vector -// - -// -// WebRtcSpl_MaxValueW16(...) -// WebRtcSpl_MaxValueW32(...) -// -// Returns the maximum value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Maximum sample value in vector -// - -// -// WebRtcSpl_MaxAbsValueW16(...) -// WebRtcSpl_MaxAbsValueW32(...) -// -// Returns the largest absolute value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Maximum absolute value in vector -// - -// -// WebRtcSpl_MaxAbsIndexW16(...) -// -// Returns the vector index to the largest absolute value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to maximum absolute value in vector -// - -// -// WebRtcSpl_MinIndexW16(...) -// WebRtcSpl_MinIndexW32(...) -// -// Returns the vector index to the minimum sample value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to minimum sample value in vector -// - -// -// WebRtcSpl_MaxIndexW16(...) -// WebRtcSpl_MaxIndexW32(...) -// -// Returns the vector index to the maximum sample value of a vector -// -// Input: -// - vector : Input vector -// - vector_length : Number of samples in vector -// -// Return value : Index to maximum sample value in vector -// // // WebRtcSpl_VectorBitShiftW16(...) // WebRtcSpl_VectorBitShiftW32(...) // // Bit shifts all the values in a vector up or downwards. Different calls for -// WebRtc_Word16 and WebRtc_Word32 vectors respectively. +// int16_t and int32_t vectors respectively. // // Input: // - vector_length : Length of vector @@ -892,8 +1114,9 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_VectorBitShiftW32ToW16(...) // -// Bit shifts all the values in a WebRtc_Word32 vector up or downwards and -// stores the result as a WebRtc_Word16 vector +// Bit shifts all the values in a int32_t vector up or downwards and +// stores the result as an int16_t vector. The function will saturate the +// signal if needed, before storing in the output vector. // // Input: // - vector_length : Length of vector @@ -958,30 +1181,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // - out_vector : Output vector // -// -// WebRtcSpl_ScaleAndAddVectorsWithRound(...) -// -// Performs the vector operation: -// -// out_vector[k] = ((scale1*in_vector1[k]) + (scale2*in_vector2[k]) -// + round_value) >> right_shifts -// -// where: -// -// round_value = (1<>1 -// -// Input: -// - in_vector1 : Input vector 1 -// - scale1 : Gain to be used for vector 1 -// - in_vector2 : Input vector 2 -// - scale2 : Gain to be used for vector 2 -// - right_shifts : Number of right bit shifts to be applied -// - vector_length : Number of elements in the input vectors -// -// Output: -// - out_vector : Output vector -// - // // WebRtcSpl_ReverseOrderMultArrayElements(...) // @@ -1071,147 +1270,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // - out_vector : Vector with the output // -// -// WebRtcSpl_AutoCorrelation(...) -// -// A 32-bit fix-point implementation of auto-correlation computation -// -// Input: -// - vector : Vector to calculate autocorrelation upon -// - vector_length : Length (in samples) of |vector| -// - order : The order up to which the autocorrelation should be -// calculated -// -// Output: -// - result_vector : auto-correlation values (values should be seen -// relative to each other since the absolute values -// might have been down shifted to avoid overflow) -// -// - scale : The number of left shifts required to obtain the -// auto-correlation in Q0 -// -// Return value : Number of samples in |result_vector|, i.e., (order+1) -// - -// -// WebRtcSpl_LevinsonDurbin(...) -// -// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that -// does NOT use the 64 bit class -// -// Input: -// - auto_corr : Vector with autocorrelation values of length >= -// |use_order|+1 -// - use_order : The LPC filter order (support up to order 20) -// -// Output: -// - lpc_coef : lpc_coef[0..use_order] LPC coefficients in Q12 -// - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in -// Q15 -// -// Return value : 1 for stable 0 for unstable -// - -// -// WebRtcSpl_ReflCoefToLpc(...) -// -// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|. -// This version is a 16 bit operation. -// -// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a -// "slightly unstable" filter (i.e., a pole just outside the unit circle) in -// "rare" cases even if the reflection coefficients are stable. -// -// Input: -// - refl_coef : Reflection coefficients in Q15 that should be converted -// to LPC coefficients -// - use_order : Number of coefficients in |refl_coef| -// -// Output: -// - lpc_coef : LPC coefficients in Q12 -// - -// -// WebRtcSpl_LpcToReflCoef(...) -// -// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|. -// This version is a 16 bit operation. -// The conversion is implemented by the step-down algorithm. -// -// Input: -// - lpc_coef : LPC coefficients in Q12, that should be converted to -// reflection coefficients -// - use_order : Number of coefficients in |lpc_coef| -// -// Output: -// - refl_coef : Reflection coefficients in Q15. -// - -// -// WebRtcSpl_AutoCorrToReflCoef(...) -// -// Calculates reflection coefficients (16 bit) from auto-correlation values -// -// Input: -// - auto_corr : Auto-correlation values -// - use_order : Number of coefficients wanted be calculated -// -// Output: -// - refl_coef : Reflection coefficients in Q15. -// - -// -// WebRtcSpl_CrossCorrelation(...) -// -// Calculates the cross-correlation between two sequences |vector1| and -// |vector2|. |vector1| is fixed and |vector2| slides as the pointer is -// increased with the amount |step_vector2| -// -// Input: -// - vector1 : First sequence (fixed throughout the correlation) -// - vector2 : Second sequence (slides |step_vector2| for each -// new correlation) -// - dim_vector : Number of samples to use in the cross-correlation -// - dim_cross_corr : Number of cross-correlations to calculate (the -// start position for |vector2| is updated for each -// new one) -// - right_shifts : Number of right bit shifts to use. This will -// become the output Q-domain. -// - step_vector2 : How many (positive or negative) steps the -// |vector2| pointer should be updated for each new -// cross-correlation value. -// -// Output: -// - cross_corr : The cross-correlation in Q(-right_shifts) -// - -// -// WebRtcSpl_GetHanningWindow(...) -// -// Creates (the first half of) a Hanning window. Size must be at least 1 and -// at most 512. -// -// Input: -// - size : Length of the requested Hanning window (1 to 512) -// -// Output: -// - window : Hanning vector in Q14. -// - -// -// WebRtcSpl_SqrtOfOneMinusXSquared(...) -// -// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector -// |in_vector|. Input and output values are in Q15. -// -// Inputs: -// - in_vector : Values to calculate sqrt(1 - x^2) of -// - vector_length : Length of vector |in_vector| -// -// Output: -// - out_vector : Output values in Q15 -// - // // WebRtcSpl_IncreaseSeed(...) // @@ -1229,7 +1287,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_RandU(...) // -// Produces a uniformly distributed value in the WebRtc_Word16 range +// Produces a uniformly distributed value in the int16_t range // // Input: // - seed : Seed for random calculation @@ -1244,7 +1302,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_RandN(...) // -// Produces a normal distributed value in the WebRtc_Word16 range +// Produces a normal distributed value in the int16_t range // // Input: // - seed : Seed for random calculation @@ -1258,7 +1316,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_RandUArray(...) // -// Produces a uniformly distributed vector with elements in the WebRtc_Word16 +// Produces a uniformly distributed vector with elements in the int16_t // range // // Input: @@ -1314,53 +1372,53 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_DivU32U16(...) // -// Divides a WebRtc_UWord32 |num| by a WebRtc_UWord16 |den|. +// Divides a uint32_t |num| by a uint16_t |den|. // -// If |den|==0, (WebRtc_UWord32)0xFFFFFFFF is returned. +// If |den|==0, (uint32_t)0xFFFFFFFF is returned. // // Input: // - num : Numerator // - den : Denominator // -// Return value : Result of the division (as a WebRtc_UWord32), i.e., the +// Return value : Result of the division (as a uint32_t), i.e., the // integer part of num/den. // // // WebRtcSpl_DivW32W16(...) // -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|. +// Divides a int32_t |num| by a int16_t |den|. // -// If |den|==0, (WebRtc_Word32)0x7FFFFFFF is returned. +// If |den|==0, (int32_t)0x7FFFFFFF is returned. // // Input: // - num : Numerator // - den : Denominator // -// Return value : Result of the division (as a WebRtc_Word32), i.e., the +// Return value : Result of the division (as a int32_t), i.e., the // integer part of num/den. // // // WebRtcSpl_DivW32W16ResW16(...) // -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the +// Divides a int32_t |num| by a int16_t |den|, assuming that the // result is less than 32768, otherwise an unpredictable result will occur. // -// If |den|==0, (WebRtc_Word16)0x7FFF is returned. +// If |den|==0, (int16_t)0x7FFF is returned. // // Input: // - num : Numerator // - den : Denominator // -// Return value : Result of the division (as a WebRtc_Word16), i.e., the +// Return value : Result of the division (as a int16_t), i.e., the // integer part of num/den. // // // WebRtcSpl_DivResultInQ31(...) // -// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the +// Divides a int32_t |num| by a int16_t |den|, assuming that the // absolute value of the denominator is larger than the numerator, otherwise // an unpredictable result will occur. // @@ -1374,7 +1432,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // WebRtcSpl_DivW32HiLow(...) // -// Divides a WebRtc_Word32 |num| by a denominator in hi, low format. The +// Divides a int32_t |num| by a denominator in hi, low format. The // absolute value of the denominator has to be larger (or equal to) the // numerator. // @@ -1431,78 +1489,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // Return value : Number of samples in the |out_vector|. // -// -// WebRtcSpl_FilterMAFastQ12(...) -// -// Performs a MA filtering on a vector in Q12 -// -// Input: -// - in_vector : Input samples (state in positions -// in_vector[-order] .. in_vector[-1]) -// - ma_coef : Filter coefficients (in Q12) -// - ma_coef_length : Number of B coefficients (order+1) -// - vector_length : Number of samples to be filtered -// -// Output: -// - out_vector : Filtered samples -// - -// -// WebRtcSpl_FilterARFastQ12(...) -// -// Performs a AR filtering on a vector in Q12 -// -// Input: -// - in_vector : Input samples -// - out_vector : State information in positions -// out_vector[-order] .. out_vector[-1] -// - ar_coef : Filter coefficients (in Q12) -// - ar_coef_length : Number of B coefficients (order+1) -// - vector_length : Number of samples to be filtered -// -// Output: -// - out_vector : Filtered samples -// - -// -// WebRtcSpl_DownsampleFast(...) -// -// Performs a MA down sampling filter on a vector -// -// Input: -// - in_vector : Input samples (state in positions -// in_vector[-order] .. in_vector[-1]) -// - in_vector_length : Number of samples in |in_vector| to be filtered. -// This must be at least -// |delay| + |factor|*(|out_vector_length|-1) + 1) -// - out_vector_length : Number of down sampled samples desired -// - ma_coef : Filter coefficients (in Q12) -// - ma_coef_length : Number of B coefficients (order+1) -// - factor : Decimation factor -// - delay : Delay of filter (compensated for in out_vector) -// -// Output: -// - out_vector : Filtered samples -// -// Return value : 0 if OK, -1 if |in_vector| is too short -// - -// -// WebRtcSpl_DotProductWithScale(...) -// -// Calculates the dot product between two (WebRtc_Word16) vectors -// -// Input: -// - vector1 : Vector 1 -// - vector2 : Vector 2 -// - vector_length : Number of samples used in the dot product -// - scaling : The number of right bit shifts to apply on each term -// during calculation to avoid overflow, i.e., the -// output will be in Q(-|scaling|) -// -// Return value : The dot product in Q(-scaling) -// - // // WebRtcSpl_ComplexIFFT(...) // @@ -1594,31 +1580,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // which returns a scale value of -1, indicating error. // -// -// WebRtcSpl_ComplexBitReverse(...) -// -// Complex Bit Reverse -// -// This function bit-reverses the position of elements in the complex input -// vector into the output vector. -// -// If you bit-reverse a linear-order array, you obtain a bit-reversed order -// array. If you bit-reverse a bit-reversed order array, you obtain a -// linear-order array. -// -// Input: -// - vector : In pointer to complex vector containing 2^|stages| real -// elements interleaved with 2^|stages| imaginary elements. -// [ReImReImReIm....] -// - stages : Number of FFT stages. Must be at least 3 and at most 10, -// since the table WebRtcSpl_kSinTable1024[] is 1024 -// elements long. -// -// Output: -// - vector : Out pointer to complex vector in bit-reversed order. -// The input vector is over written. -// - // // WebRtcSpl_AnalysisQMF(...) // @@ -1659,10 +1620,10 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // - out_data : Super-wideband speech signal, 0-16 kHz // -// WebRtc_Word16 WebRtcSpl_SatW32ToW16(...) +// int16_t WebRtcSpl_SatW32ToW16(...) // // This function saturates a 32-bit word into a 16-bit word. -// +// // Input: // - value32 : The value of a 32-bit word. // @@ -1674,7 +1635,7 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // This function multiply a 16-bit word by a 16-bit word, and accumulate this // value to a 32-bit integer. -// +// // Input: // - a : The value of the first 16-bit word. // - b : The value of the second 16-bit word. @@ -1682,15 +1643,3 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, // // Return Value: The value of a * b + c. // - -// WebRtc_Word16 WebRtcSpl_get_version(...) -// -// This function gives the version string of the Signal Processing Library. -// -// Input: -// - length_in_bytes : The size of Allocated space (in Bytes) where -// the version number is written to (in string format). -// -// Output: -// - version : Pointer to a buffer where the version number is written to. -// diff --git a/webrtc/common_audio/signal_processing/include/spl_inl.h b/webrtc/common_audio/signal_processing/include/spl_inl.h new file mode 100644 index 0000000..d3cc6de --- /dev/null +++ b/webrtc/common_audio/signal_processing/include/spl_inl.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +// This header file includes the inline functions in +// the fix point signal processing library. + +#ifndef WEBRTC_SPL_SPL_INL_H_ +#define WEBRTC_SPL_SPL_INL_H_ + +#ifdef WEBRTC_ARCH_ARM_V7 +#include "webrtc/common_audio/signal_processing/include/spl_inl_armv7.h" +#else + +#if defined(MIPS32_LE) +#include "webrtc/common_audio/signal_processing/include/spl_inl_mips.h" +#endif + +#if !defined(MIPS_DSP_R1_LE) +static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { + int16_t out16 = (int16_t) value32; + + if (value32 > 32767) + out16 = 32767; + else if (value32 < -32768) + out16 = -32768; + + return out16; +} + +static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_sum; + + // Perform long addition + l_sum = l_var1 + l_var2; + + if (l_var1 < 0) { // Check for underflow. + if ((l_var2 < 0) && (l_sum >= 0)) { + l_sum = (int32_t)0x80000000; + } + } else { // Check for overflow. + if ((l_var2 > 0) && (l_sum < 0)) { + l_sum = (int32_t)0x7FFFFFFF; + } + } + + return l_sum; +} + +static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_diff; + + // Perform subtraction. + l_diff = l_var1 - l_var2; + + if (l_var1 < 0) { // Check for underflow. + if ((l_var2 > 0) && (l_diff > 0)) { + l_diff = (int32_t)0x80000000; + } + } else { // Check for overflow. + if ((l_var2 < 0) && (l_diff < 0)) { + l_diff = (int32_t)0x7FFFFFFF; + } + } + + return l_diff; +} + +static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { + return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b); +} + +static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { + return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2); +} +#endif // #if !defined(MIPS_DSP_R1_LE) + +#if !defined(MIPS32_LE) +static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { + int16_t bits; + + if (0xFFFF0000 & n) { + bits = 16; + } else { + bits = 0; + } + if (0x0000FF00 & (n >> bits)) bits += 8; + if (0x000000F0 & (n >> bits)) bits += 4; + if (0x0000000C & (n >> bits)) bits += 2; + if (0x00000002 & (n >> bits)) bits += 1; + if (0x00000001 & (n >> bits)) bits += 1; + + return bits; +} + +static __inline int16_t WebRtcSpl_NormW32(int32_t a) { + int16_t zeros; + + if (a == 0) { + return 0; + } + else if (a < 0) { + a = ~a; + } + + if (!(0xFFFF8000 & a)) { + zeros = 16; + } else { + zeros = 0; + } + if (!(0xFF800000 & (a << zeros))) zeros += 8; + if (!(0xF8000000 & (a << zeros))) zeros += 4; + if (!(0xE0000000 & (a << zeros))) zeros += 2; + if (!(0xC0000000 & (a << zeros))) zeros += 1; + + return zeros; +} + +static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { + int16_t zeros; + + if (a == 0) return 0; + + if (!(0xFFFF0000 & a)) { + zeros = 16; + } else { + zeros = 0; + } + if (!(0xFF000000 & (a << zeros))) zeros += 8; + if (!(0xF0000000 & (a << zeros))) zeros += 4; + if (!(0xC0000000 & (a << zeros))) zeros += 2; + if (!(0x80000000 & (a << zeros))) zeros += 1; + + return zeros; +} + +static __inline int16_t WebRtcSpl_NormW16(int16_t a) { + int16_t zeros; + + if (a == 0) { + return 0; + } + else if (a < 0) { + a = ~a; + } + + if (!(0xFF80 & a)) { + zeros = 8; + } else { + zeros = 0; + } + if (!(0xF800 & (a << zeros))) zeros += 4; + if (!(0xE000 & (a << zeros))) zeros += 2; + if (!(0xC000 & (a << zeros))) zeros += 1; + + return zeros; +} + +static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { + return (a * b + c); +} +#endif // #if !defined(MIPS32_LE) + +#endif // WEBRTC_ARCH_ARM_V7 + +#endif // WEBRTC_SPL_SPL_INL_H_ diff --git a/webrtc/common_audio/signal_processing/include/spl_inl_armv7.h b/webrtc/common_audio/signal_processing/include/spl_inl_armv7.h new file mode 100644 index 0000000..2718801 --- /dev/null +++ b/webrtc/common_audio/signal_processing/include/spl_inl_armv7.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* This header file includes the inline functions for ARM processors in + * the fix point signal processing library. + */ + +#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_ +#define WEBRTC_SPL_SPL_INL_ARMV7_H_ + +/* TODO(kma): Replace some assembly code with GCC intrinsics + * (e.g. __builtin_clz). + */ + +/* This function produces result that is not bit exact with that by the generic + * C version in some cases, although the former is at least as accurate as the + * later. + */ +static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) { + int32_t tmp = 0; + __asm __volatile ("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); + return tmp; +} + +static __inline int32_t WEBRTC_SPL_MUL_16_16(int16_t a, int16_t b) { + int32_t tmp = 0; + __asm __volatile ("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); + return tmp; +} + +// TODO(kma): add unit test. +static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { + int32_t tmp = 0; + __asm __volatile ("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c)); + return tmp; +} + +static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { + int32_t s_sum = 0; + + __asm __volatile ("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); + + return (int16_t) s_sum; +} + +static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_sum = 0; + + __asm __volatile ("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); + + return l_sum; +} + +static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_sub = 0; + + __asm __volatile ("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); + + return l_sub; +} + +static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { + int32_t s_sub = 0; + + __asm __volatile ("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); + + return (int16_t)s_sub; +} + +static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { + int32_t tmp = 0; + + __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(n)); + + return (int16_t)(32 - tmp); +} + +static __inline int16_t WebRtcSpl_NormW32(int32_t a) { + int32_t tmp = 0; + + if (a == 0) { + return 0; + } + else if (a < 0) { + a ^= 0xFFFFFFFF; + } + + __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a)); + + return (int16_t)(tmp - 1); +} + +static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { + int tmp = 0; + + if (a == 0) return 0; + + __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a)); + + return (int16_t)tmp; +} + +static __inline int16_t WebRtcSpl_NormW16(int16_t a) { + int32_t tmp = 0; + int32_t a_32 = a; + + if (a_32 == 0) { + return 0; + } + else if (a_32 < 0) { + a_32 ^= 0xFFFFFFFF; + } + + __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a_32)); + + return (int16_t)(tmp - 17); +} + +// TODO(kma): add unit test. +static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { + int32_t out = 0; + + __asm __volatile ("ssat %0, #16, %1" : "=r"(out) : "r"(value32)); + + return (int16_t)out; +} + +#endif // WEBRTC_SPL_SPL_INL_ARMV7_H_ diff --git a/webrtc/common_audio/signal_processing/include/spl_inl_mips.h b/webrtc/common_audio/signal_processing/include/spl_inl_mips.h new file mode 100644 index 0000000..cd04bdd --- /dev/null +++ b/webrtc/common_audio/signal_processing/include/spl_inl_mips.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +// This header file includes the inline functions in +// the fix point signal processing library. + +#ifndef WEBRTC_SPL_SPL_INL_MIPS_H_ +#define WEBRTC_SPL_SPL_INL_MIPS_H_ + +static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a, + int32_t b) { + int32_t value32 = 0; + int32_t a1 = 0, b1 = 0; + + __asm __volatile( +#if defined(MIPS32_R2_LE) + "seh %[a1], %[a] \n\t" + "seh %[b1], %[b] \n\t" +#else + "sll %[a1], %[a], 16 \n\t" + "sll %[b1], %[b], 16 \n\t" + "sra %[a1], %[a1], 16 \n\t" + "sra %[b1], %[b1], 16 \n\t" +#endif + "mul %[value32], %[a1], %[b1] \n\t" + : [value32] "=r" (value32), [a1] "=&r" (a1), [b1] "=&r" (b1) + : [a] "r" (a), [b] "r" (b) + : "hi", "lo" + ); + return value32; +} + +static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, + int32_t b) { + int32_t value32 = 0, b1 = 0, b2 = 0; + int32_t a1 = 0; + + __asm __volatile( +#if defined(MIPS32_R2_LE) + "seh %[a1], %[a] \n\t" +#else + "sll %[a1], %[a], 16 \n\t" + "sra %[a1], %[a1], 16 \n\t" +#endif + "andi %[b2], %[b], 0xFFFF \n\t" + "sra %[b1], %[b], 16 \n\t" + "sra %[b2], %[b2], 1 \n\t" + "mul %[value32], %[a1], %[b1] \n\t" + "mul %[b2], %[a1], %[b2] \n\t" + "addiu %[b2], %[b2], 0x4000 \n\t" + "sra %[b2], %[b2], 15 \n\t" + "addu %[value32], %[value32], %[b2] \n\t" + : [value32] "=&r" (value32), [b1] "=&r" (b1), [b2] "=&r" (b2), + [a1] "=&r" (a1) + : [a] "r" (a), [b] "r" (b) + : "hi", "lo" + ); + return value32; +} + +#if defined(MIPS_DSP_R1_LE) +static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { + __asm __volatile( + "shll_s.w %[value32], %[value32], 16 \n\t" + "sra %[value32], %[value32], 16 \n\t" + : [value32] "+r" (value32) + : + ); + int16_t out16 = (int16_t)value32; + return out16; +} + +static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { + int32_t value32 = 0; + + __asm __volatile( + "addq_s.ph %[value32], %[a], %[b] \n\t" + : [value32] "=r" (value32) + : [a] "r" (a), [b] "r" (b) + ); + return (int16_t)value32; +} + +static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_sum; + + __asm __volatile( + "addq_s.w %[l_sum], %[l_var1], %[l_var2] \n\t" + : [l_sum] "=r" (l_sum) + : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2) + ); + + return l_sum; +} + +static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { + int32_t value32; + + __asm __volatile( + "subq_s.ph %[value32], %[var1], %[var2] \n\t" + : [value32] "=r" (value32) + : [var1] "r" (var1), [var2] "r" (var2) + ); + + return (int16_t)value32; +} + +static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { + int32_t l_diff; + + __asm __volatile( + "subq_s.w %[l_diff], %[l_var1], %[l_var2] \n\t" + : [l_diff] "=r" (l_diff) + : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2) + ); + + return l_diff; +} +#endif + +static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { + int bits = 0; + int i32 = 32; + + __asm __volatile( + "clz %[bits], %[n] \n\t" + "subu %[bits], %[i32], %[bits] \n\t" + : [bits] "=&r" (bits) + : [n] "r" (n), [i32] "r" (i32) + ); + + return (int16_t)bits; +} + +static __inline int16_t WebRtcSpl_NormW32(int32_t a) { + int zeros = 0; + + __asm __volatile( + ".set push \n\t" + ".set noreorder \n\t" + "bnez %[a], 1f \n\t" + " sra %[zeros], %[a], 31 \n\t" + "b 2f \n\t" + " move %[zeros], $zero \n\t" + "1: \n\t" + "xor %[zeros], %[a], %[zeros] \n\t" + "clz %[zeros], %[zeros] \n\t" + "addiu %[zeros], %[zeros], -1 \n\t" + "2: \n\t" + ".set pop \n\t" + : [zeros]"=&r"(zeros) + : [a] "r" (a) + ); + + return (int16_t)zeros; +} + +static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { + int zeros = 0; + + __asm __volatile( + "clz %[zeros], %[a] \n\t" + : [zeros] "=r" (zeros) + : [a] "r" (a) + ); + + return (int16_t)(zeros & 0x1f); +} + +static __inline int16_t WebRtcSpl_NormW16(int16_t a) { + int zeros = 0; + int a0 = a << 16; + + __asm __volatile( + ".set push \n\t" + ".set noreorder \n\t" + "bnez %[a0], 1f \n\t" + " sra %[zeros], %[a0], 31 \n\t" + "b 2f \n\t" + " move %[zeros], $zero \n\t" + "1: \n\t" + "xor %[zeros], %[a0], %[zeros] \n\t" + "clz %[zeros], %[zeros] \n\t" + "addiu %[zeros], %[zeros], -1 \n\t" + "2: \n\t" + ".set pop \n\t" + : [zeros]"=&r"(zeros) + : [a0] "r" (a0) + ); + + return (int16_t)zeros; +} + +static __inline int32_t WebRtc_MulAccumW16(int16_t a, + int16_t b, + int32_t c) { + int32_t res = 0, c1 = 0; + __asm __volatile( +#if defined(MIPS32_R2_LE) + "seh %[a], %[a] \n\t" + "seh %[b], %[b] \n\t" +#else + "sll %[a], %[a], 16 \n\t" + "sll %[b], %[b], 16 \n\t" + "sra %[a], %[a], 16 \n\t" + "sra %[b], %[b], 16 \n\t" +#endif + "mul %[res], %[a], %[b] \n\t" + "addu %[c1], %[c], %[res] \n\t" + : [c1] "=r" (c1), [res] "=&r" (res) + : [a] "r" (a), [b] "r" (b), [c] "r" (c) + : "hi", "lo" + ); + return (c1); +} + +#endif // WEBRTC_SPL_SPL_INL_MIPS_H_ diff --git a/webrtc/common_audio/signal_processing/levinson_durbin.c b/webrtc/common_audio/signal_processing/levinson_durbin.c new file mode 100644 index 0000000..d46e551 --- /dev/null +++ b/webrtc/common_audio/signal_processing/levinson_durbin.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_LevinsonDurbin(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +#define SPL_LEVINSON_MAXORDER 20 + +int16_t WebRtcSpl_LevinsonDurbin(const int32_t* R, int16_t* A, int16_t* K, + size_t order) +{ + size_t i, j; + // Auto-correlation coefficients in high precision + int16_t R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1]; + // LPC coefficients in high precision + int16_t A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1]; + // LPC coefficients for next iteration + int16_t A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1]; + // Reflection coefficient in high precision + int16_t K_hi, K_low; + // Prediction gain Alpha in high precision and with scale factor + int16_t Alpha_hi, Alpha_low, Alpha_exp; + int16_t tmp_hi, tmp_low; + int32_t temp1W32, temp2W32, temp3W32; + int16_t norm; + + // Normalize the autocorrelation R[0]...R[order+1] + + norm = WebRtcSpl_NormW32(R[0]); + + for (i = 0; i <= order; ++i) + { + temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm); + // Put R in hi and low format + R_hi[i] = (int16_t)(temp1W32 >> 16); + R_low[i] = (int16_t)((temp1W32 - ((int32_t)R_hi[i] << 16)) >> 1); + } + + // K = A[1] = -R[1] / R[0] + + temp2W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[1],16) + + WEBRTC_SPL_LSHIFT_W32((int32_t)R_low[1],1); // R[1] in Q31 + temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1] + temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31 + // Put back the sign on R[1] + if (temp2W32 > 0) + { + temp1W32 = -temp1W32; + } + + // Put K in hi and low format + K_hi = (int16_t)(temp1W32 >> 16); + K_low = (int16_t)((temp1W32 - ((int32_t)K_hi << 16)) >> 1); + + // Store first reflection coefficient + K[0] = K_hi; + + temp1W32 >>= 4; // A[1] in Q27. + + // Put A[1] in hi and low format + A_hi[1] = (int16_t)(temp1W32 >> 16); + A_low[1] = (int16_t)((temp1W32 - ((int32_t)A_hi[1] << 16)) >> 1); + + // Alpha = R[0] * (1-K^2) + + temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) << 1; // = k^2 in Q31 + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 + temp1W32 = (int32_t)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31 + + // Store temp1W32 = 1 - K[0]*K[0] on hi and low format + tmp_hi = (int16_t)(temp1W32 >> 16); + tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1); + + // Calculate Alpha in Q31 + temp1W32 = (R_hi[0] * tmp_hi + (R_hi[0] * tmp_low >> 15) + + (R_low[0] * tmp_hi >> 15)) << 1; + + // Normalize Alpha and put it in hi and low format + + Alpha_exp = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); + Alpha_hi = (int16_t)(temp1W32 >> 16); + Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1); + + // Perform the iterative calculations in the Levinson-Durbin algorithm + + for (i = 2; i <= order; i++) + { + /* ---- + temp1W32 = R[i] + > R[j]*A[i-j] + / + ---- + j=1..i-1 + */ + + temp1W32 = 0; + + for (j = 1; j < i; j++) + { + // temp1W32 is in Q31 + temp1W32 += (R_hi[j] * A_hi[i - j] << 1) + + (((R_hi[j] * A_low[i - j] >> 15) + + (R_low[j] * A_hi[i - j] >> 15)) << 1); + } + + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4); + temp1W32 += (WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((int32_t)R_low[i], 1)); + + // K = -temp1W32 / Alpha + temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32) + temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha + + // Put the sign of temp1W32 back again + if (temp1W32 > 0) + { + temp3W32 = -temp3W32; + } + + // Use the Alpha shifts from earlier to de-normalize + norm = WebRtcSpl_NormW32(temp3W32); + if ((Alpha_exp <= norm) || (temp3W32 == 0)) + { + temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp); + } else + { + if (temp3W32 > 0) + { + temp3W32 = (int32_t)0x7fffffffL; + } else + { + temp3W32 = (int32_t)0x80000000L; + } + } + + // Put K on hi and low format + K_hi = (int16_t)(temp3W32 >> 16); + K_low = (int16_t)((temp3W32 - ((int32_t)K_hi << 16)) >> 1); + + // Store Reflection coefficient in Q15 + K[i - 1] = K_hi; + + // Test for unstable filter. + // If unstable return 0 and let the user decide what to do in that case + + if ((int32_t)WEBRTC_SPL_ABS_W16(K_hi) > (int32_t)32750) + { + return 0; // Unstable filter + } + + /* + Compute updated LPC coefficient: Anew[i] + Anew[j]= A[j] + K*A[i-j] for j=1..i-1 + Anew[i]= K + */ + + for (j = 1; j < i; j++) + { + // temp1W32 = A[j] in Q27 + temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[j],16) + + WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[j],1); + + // temp1W32 += K*A[i-j] in Q27 + temp1W32 += (K_hi * A_hi[i - j] + (K_hi * A_low[i - j] >> 15) + + (K_low * A_hi[i - j] >> 15)) << 1; + + // Put Anew in hi and low format + A_upd_hi[j] = (int16_t)(temp1W32 >> 16); + A_upd_low[j] = (int16_t)( + (temp1W32 - ((int32_t)A_upd_hi[j] << 16)) >> 1); + } + + // temp3W32 = K in Q27 (Convert from Q31 to Q27) + temp3W32 >>= 4; + + // Store Anew in hi and low format + A_upd_hi[i] = (int16_t)(temp3W32 >> 16); + A_upd_low[i] = (int16_t)( + (temp3W32 - ((int32_t)A_upd_hi[i] << 16)) >> 1); + + // Alpha = Alpha * (1-K^2) + + temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) << 1; // K*K in Q31 + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 + temp1W32 = (int32_t)0x7fffffffL - temp1W32; // 1 - K*K in Q31 + + // Convert 1- K^2 in hi and low format + tmp_hi = (int16_t)(temp1W32 >> 16); + tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1); + + // Calculate Alpha = Alpha * (1-K^2) in Q31 + temp1W32 = (Alpha_hi * tmp_hi + (Alpha_hi * tmp_low >> 15) + + (Alpha_low * tmp_hi >> 15)) << 1; + + // Normalize Alpha and store it on hi and low format + + norm = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); + + Alpha_hi = (int16_t)(temp1W32 >> 16); + Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1); + + // Update the total normalization of Alpha + Alpha_exp = Alpha_exp + norm; + + // Update A[] + + for (j = 1; j <= i; j++) + { + A_hi[j] = A_upd_hi[j]; + A_low[j] = A_upd_low[j]; + } + } + + /* + Set A[0] to 1.0 and store the A[i] i=1...order in Q12 + (Convert from Q27 and use rounding) + */ + + A[0] = 4096; + + for (i = 1; i <= order; i++) + { + // temp1W32 in Q27 + temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[i], 1); + // Round and store upper word + A[i] = (int16_t)(((temp1W32 << 1) + 32768) >> 16); + } + return 1; // Stable filters +} diff --git a/src/common_audio/signal_processing_library/main/source/lpc_to_refl_coef.c b/webrtc/common_audio/signal_processing/lpc_to_refl_coef.c similarity index 56% rename from src/common_audio/signal_processing_library/main/source/lpc_to_refl_coef.c rename to webrtc/common_audio/signal_processing/lpc_to_refl_coef.c index 2cb83c2..edcebd4 100644 --- a/src/common_audio/signal_processing_library/main/source/lpc_to_refl_coef.c +++ b/webrtc/common_audio/signal_processing/lpc_to_refl_coef.c @@ -15,43 +15,42 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" #define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50 -void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16) +void WebRtcSpl_LpcToReflCoef(int16_t* a16, int use_order, int16_t* k16) { int m, k; - WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER]; - WebRtc_Word32 tmp_inv_denom32; - WebRtc_Word16 tmp_inv_denom16; + int32_t tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER]; + int32_t tmp_inv_denom32; + int16_t tmp_inv_denom16; - k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15 + k16[use_order - 1] = a16[use_order] << 3; // Q12<<3 => Q15 for (m = use_order - 1; m > 0; m--) { // (1 - k^2) in Q30 - tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); + tmp_inv_denom32 = 1073741823 - k16[m] * k16[m]; // (1 - k^2) in Q15 - tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15); + tmp_inv_denom16 = (int16_t)(tmp_inv_denom32 >> 15); for (k = 1; k <= m; k++) { // tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]); // [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28 - tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) - - WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1); + tmp32[k] = (a16[k] << 16) - (k16[m] * a16[m - k + 1] << 1); tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13 } for (k = 1; k < m; k++) { - a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12 + a16[k] = (int16_t)(tmp32[k] >> 1); // Q13>>1 => Q12 } tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191); - k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15 + k16[m - 1] = (int16_t)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15 } return; } diff --git a/webrtc/common_audio/signal_processing/min_max_operations.c b/webrtc/common_audio/signal_processing/min_max_operations.c new file mode 100644 index 0000000..4a962f8 --- /dev/null +++ b/webrtc/common_audio/signal_processing/min_max_operations.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the implementation of functions + * WebRtcSpl_MaxAbsValueW16C() + * WebRtcSpl_MaxAbsValueW32C() + * WebRtcSpl_MaxValueW16C() + * WebRtcSpl_MaxValueW32C() + * WebRtcSpl_MinValueW16C() + * WebRtcSpl_MinValueW32C() + * WebRtcSpl_MaxAbsIndexW16() + * WebRtcSpl_MaxIndexW16() + * WebRtcSpl_MaxIndexW32() + * WebRtcSpl_MinIndexW16() + * WebRtcSpl_MinIndexW32() + * + */ + +#include +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// TODO(bjorn/kma): Consolidate function pairs (e.g. combine +// WebRtcSpl_MaxAbsValueW16C and WebRtcSpl_MaxAbsIndexW16 into a single one.) +// TODO(kma): Move the next six functions into min_max_operations_c.c. + +// Maximum absolute value of word16 vector. C version for generic platforms. +int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length) { + size_t i = 0; + int absolute = 0, maximum = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + absolute = abs((int)vector[i]); + + if (absolute > maximum) { + maximum = absolute; + } + } + + // Guard the case for abs(-32768). + if (maximum > WEBRTC_SPL_WORD16_MAX) { + maximum = WEBRTC_SPL_WORD16_MAX; + } + + return (int16_t)maximum; +} + +// Maximum absolute value of word32 vector. C version for generic platforms. +int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length) { + // Use uint32_t for the local variables, to accommodate the return value + // of abs(0x80000000), which is 0x80000000. + + uint32_t absolute = 0, maximum = 0; + size_t i = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + absolute = abs((int)vector[i]); + if (absolute > maximum) { + maximum = absolute; + } + } + + maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX); + + return (int32_t)maximum; +} + +// Maximum value of word16 vector. C version for generic platforms. +int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length) { + int16_t maximum = WEBRTC_SPL_WORD16_MIN; + size_t i = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] > maximum) + maximum = vector[i]; + } + return maximum; +} + +// Maximum value of word32 vector. C version for generic platforms. +int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length) { + int32_t maximum = WEBRTC_SPL_WORD32_MIN; + size_t i = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] > maximum) + maximum = vector[i]; + } + return maximum; +} + +// Minimum value of word16 vector. C version for generic platforms. +int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length) { + int16_t minimum = WEBRTC_SPL_WORD16_MAX; + size_t i = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] < minimum) + minimum = vector[i]; + } + return minimum; +} + +// Minimum value of word32 vector. C version for generic platforms. +int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length) { + int32_t minimum = WEBRTC_SPL_WORD32_MAX; + size_t i = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] < minimum) + minimum = vector[i]; + } + return minimum; +} + +// Index of maximum absolute value in a word16 vector. +size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length) { + // Use type int for local variables, to accomodate the value of abs(-32768). + + size_t i = 0, index = 0; + int absolute = 0, maximum = 0; + + assert(length > 0); + + for (i = 0; i < length; i++) { + absolute = abs((int)vector[i]); + + if (absolute > maximum) { + maximum = absolute; + index = i; + } + } + + return index; +} + +// Index of maximum value in a word16 vector. +size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length) { + size_t i = 0, index = 0; + int16_t maximum = WEBRTC_SPL_WORD16_MIN; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] > maximum) { + maximum = vector[i]; + index = i; + } + } + + return index; +} + +// Index of maximum value in a word32 vector. +size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length) { + size_t i = 0, index = 0; + int32_t maximum = WEBRTC_SPL_WORD32_MIN; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] > maximum) { + maximum = vector[i]; + index = i; + } + } + + return index; +} + +// Index of minimum value in a word16 vector. +size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length) { + size_t i = 0, index = 0; + int16_t minimum = WEBRTC_SPL_WORD16_MAX; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] < minimum) { + minimum = vector[i]; + index = i; + } + } + + return index; +} + +// Index of minimum value in a word32 vector. +size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length) { + size_t i = 0, index = 0; + int32_t minimum = WEBRTC_SPL_WORD32_MAX; + + assert(length > 0); + + for (i = 0; i < length; i++) { + if (vector[i] < minimum) { + minimum = vector[i]; + index = i; + } + } + + return index; +} diff --git a/webrtc/common_audio/signal_processing/min_max_operations_mips.c b/webrtc/common_audio/signal_processing/min_max_operations_mips.c new file mode 100644 index 0000000..28de45b --- /dev/null +++ b/webrtc/common_audio/signal_processing/min_max_operations_mips.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the implementation of function + * WebRtcSpl_MaxAbsValueW16() + * + * The description header can be found in signal_processing_library.h. + * + */ + +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// Maximum absolute value of word16 vector. +int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, size_t length) { + int32_t totMax = 0; + int32_t tmp32_0, tmp32_1, tmp32_2, tmp32_3; + size_t i, loop_size; + + assert(length > 0); + +#if defined(MIPS_DSP_R1) + const int32_t* tmpvec32 = (int32_t*)vector; + loop_size = length >> 4; + + for (i = 0; i < loop_size; i++) { + __asm__ volatile ( + "lw %[tmp32_0], 0(%[tmpvec32]) \n\t" + "lw %[tmp32_1], 4(%[tmpvec32]) \n\t" + "lw %[tmp32_2], 8(%[tmpvec32]) \n\t" + "lw %[tmp32_3], 12(%[tmpvec32]) \n\t" + + "absq_s.ph %[tmp32_0], %[tmp32_0] \n\t" + "absq_s.ph %[tmp32_1], %[tmp32_1] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_0] \n\t" + "pick.ph %[totMax], %[tmp32_0], %[totMax] \n\t" + + "lw %[tmp32_0], 16(%[tmpvec32]) \n\t" + "absq_s.ph %[tmp32_2], %[tmp32_2] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_1] \n\t" + "pick.ph %[totMax], %[tmp32_1], %[totMax] \n\t" + + "lw %[tmp32_1], 20(%[tmpvec32]) \n\t" + "absq_s.ph %[tmp32_3], %[tmp32_3] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_2] \n\t" + "pick.ph %[totMax], %[tmp32_2], %[totMax] \n\t" + + "lw %[tmp32_2], 24(%[tmpvec32]) \n\t" + "cmp.lt.ph %[totMax], %[tmp32_3] \n\t" + "pick.ph %[totMax], %[tmp32_3], %[totMax] \n\t" + + "lw %[tmp32_3], 28(%[tmpvec32]) \n\t" + "absq_s.ph %[tmp32_0], %[tmp32_0] \n\t" + "absq_s.ph %[tmp32_1], %[tmp32_1] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_0] \n\t" + "pick.ph %[totMax], %[tmp32_0], %[totMax] \n\t" + + "absq_s.ph %[tmp32_2], %[tmp32_2] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_1] \n\t" + "pick.ph %[totMax], %[tmp32_1], %[totMax] \n\t" + "absq_s.ph %[tmp32_3], %[tmp32_3] \n\t" + "cmp.lt.ph %[totMax], %[tmp32_2] \n\t" + "pick.ph %[totMax], %[tmp32_2], %[totMax] \n\t" + + "cmp.lt.ph %[totMax], %[tmp32_3] \n\t" + "pick.ph %[totMax], %[tmp32_3], %[totMax] \n\t" + + "addiu %[tmpvec32], %[tmpvec32], 32 \n\t" + : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1), + [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3), + [totMax] "+r" (totMax), [tmpvec32] "+r" (tmpvec32) + : + : "memory" + ); + } + __asm__ volatile ( + "rotr %[tmp32_0], %[totMax], 16 \n\t" + "cmp.lt.ph %[totMax], %[tmp32_0] \n\t" + "pick.ph %[totMax], %[tmp32_0], %[totMax] \n\t" + "packrl.ph %[totMax], $0, %[totMax] \n\t" + : [tmp32_0] "=&r" (tmp32_0), [totMax] "+r" (totMax) + : + ); + loop_size = length & 0xf; + for (i = 0; i < loop_size; i++) { + __asm__ volatile ( + "lh %[tmp32_0], 0(%[tmpvec32]) \n\t" + "addiu %[tmpvec32], %[tmpvec32], 2 \n\t" + "absq_s.w %[tmp32_0], %[tmp32_0] \n\t" + "slt %[tmp32_1], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[tmp32_1] \n\t" + : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1), + [tmpvec32] "+r" (tmpvec32), [totMax] "+r" (totMax) + : + : "memory" + ); + } +#else // #if defined(MIPS_DSP_R1) + int32_t v16MaxMax = WEBRTC_SPL_WORD16_MAX; + int32_t r, r1, r2, r3; + const int16_t* tmpvector = vector; + loop_size = length >> 4; + for (i = 0; i < loop_size; i++) { + __asm__ volatile ( + "lh %[tmp32_0], 0(%[tmpvector]) \n\t" + "lh %[tmp32_1], 2(%[tmpvector]) \n\t" + "lh %[tmp32_2], 4(%[tmpvector]) \n\t" + "lh %[tmp32_3], 6(%[tmpvector]) \n\t" + + "abs %[tmp32_0], %[tmp32_0] \n\t" + "abs %[tmp32_1], %[tmp32_1] \n\t" + "abs %[tmp32_2], %[tmp32_2] \n\t" + "abs %[tmp32_3], %[tmp32_3] \n\t" + + "slt %[r], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[r] \n\t" + "slt %[r1], %[totMax], %[tmp32_1] \n\t" + "movn %[totMax], %[tmp32_1], %[r1] \n\t" + "slt %[r2], %[totMax], %[tmp32_2] \n\t" + "movn %[totMax], %[tmp32_2], %[r2] \n\t" + "slt %[r3], %[totMax], %[tmp32_3] \n\t" + "movn %[totMax], %[tmp32_3], %[r3] \n\t" + + "lh %[tmp32_0], 8(%[tmpvector]) \n\t" + "lh %[tmp32_1], 10(%[tmpvector]) \n\t" + "lh %[tmp32_2], 12(%[tmpvector]) \n\t" + "lh %[tmp32_3], 14(%[tmpvector]) \n\t" + + "abs %[tmp32_0], %[tmp32_0] \n\t" + "abs %[tmp32_1], %[tmp32_1] \n\t" + "abs %[tmp32_2], %[tmp32_2] \n\t" + "abs %[tmp32_3], %[tmp32_3] \n\t" + + "slt %[r], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[r] \n\t" + "slt %[r1], %[totMax], %[tmp32_1] \n\t" + "movn %[totMax], %[tmp32_1], %[r1] \n\t" + "slt %[r2], %[totMax], %[tmp32_2] \n\t" + "movn %[totMax], %[tmp32_2], %[r2] \n\t" + "slt %[r3], %[totMax], %[tmp32_3] \n\t" + "movn %[totMax], %[tmp32_3], %[r3] \n\t" + + "lh %[tmp32_0], 16(%[tmpvector]) \n\t" + "lh %[tmp32_1], 18(%[tmpvector]) \n\t" + "lh %[tmp32_2], 20(%[tmpvector]) \n\t" + "lh %[tmp32_3], 22(%[tmpvector]) \n\t" + + "abs %[tmp32_0], %[tmp32_0] \n\t" + "abs %[tmp32_1], %[tmp32_1] \n\t" + "abs %[tmp32_2], %[tmp32_2] \n\t" + "abs %[tmp32_3], %[tmp32_3] \n\t" + + "slt %[r], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[r] \n\t" + "slt %[r1], %[totMax], %[tmp32_1] \n\t" + "movn %[totMax], %[tmp32_1], %[r1] \n\t" + "slt %[r2], %[totMax], %[tmp32_2] \n\t" + "movn %[totMax], %[tmp32_2], %[r2] \n\t" + "slt %[r3], %[totMax], %[tmp32_3] \n\t" + "movn %[totMax], %[tmp32_3], %[r3] \n\t" + + "lh %[tmp32_0], 24(%[tmpvector]) \n\t" + "lh %[tmp32_1], 26(%[tmpvector]) \n\t" + "lh %[tmp32_2], 28(%[tmpvector]) \n\t" + "lh %[tmp32_3], 30(%[tmpvector]) \n\t" + + "abs %[tmp32_0], %[tmp32_0] \n\t" + "abs %[tmp32_1], %[tmp32_1] \n\t" + "abs %[tmp32_2], %[tmp32_2] \n\t" + "abs %[tmp32_3], %[tmp32_3] \n\t" + + "slt %[r], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[r] \n\t" + "slt %[r1], %[totMax], %[tmp32_1] \n\t" + "movn %[totMax], %[tmp32_1], %[r1] \n\t" + "slt %[r2], %[totMax], %[tmp32_2] \n\t" + "movn %[totMax], %[tmp32_2], %[r2] \n\t" + "slt %[r3], %[totMax], %[tmp32_3] \n\t" + "movn %[totMax], %[tmp32_3], %[r3] \n\t" + + "addiu %[tmpvector], %[tmpvector], 32 \n\t" + : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1), + [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3), + [totMax] "+r" (totMax), [r] "=&r" (r), [tmpvector] "+r" (tmpvector), + [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3) + : + : "memory" + ); + } + loop_size = length & 0xf; + for (i = 0; i < loop_size; i++) { + __asm__ volatile ( + "lh %[tmp32_0], 0(%[tmpvector]) \n\t" + "addiu %[tmpvector], %[tmpvector], 2 \n\t" + "abs %[tmp32_0], %[tmp32_0] \n\t" + "slt %[tmp32_1], %[totMax], %[tmp32_0] \n\t" + "movn %[totMax], %[tmp32_0], %[tmp32_1] \n\t" + : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1), + [tmpvector] "+r" (tmpvector), [totMax] "+r" (totMax) + : + : "memory" + ); + } + + __asm__ volatile ( + "slt %[r], %[v16MaxMax], %[totMax] \n\t" + "movn %[totMax], %[v16MaxMax], %[r] \n\t" + : [totMax] "+r" (totMax), [r] "=&r" (r) + : [v16MaxMax] "r" (v16MaxMax) + ); +#endif // #if defined(MIPS_DSP_R1) + return (int16_t)totMax; +} + +#if defined(MIPS_DSP_R1_LE) +// Maximum absolute value of word32 vector. Version for MIPS platform. +int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, size_t length) { + // Use uint32_t for the local variables, to accommodate the return value + // of abs(0x80000000), which is 0x80000000. + + uint32_t absolute = 0, maximum = 0; + int tmp1 = 0, max_value = 0x7fffffff; + + assert(length > 0); + + __asm__ volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "1: \n\t" + "lw %[absolute], 0(%[vector]) \n\t" + "absq_s.w %[absolute], %[absolute] \n\t" + "addiu %[length], %[length], -1 \n\t" + "slt %[tmp1], %[maximum], %[absolute] \n\t" + "movn %[maximum], %[absolute], %[tmp1] \n\t" + "bgtz %[length], 1b \n\t" + " addiu %[vector], %[vector], 4 \n\t" + "slt %[tmp1], %[max_value], %[maximum] \n\t" + "movn %[maximum], %[max_value], %[tmp1] \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [absolute] "+r" (absolute) + : [vector] "r" (vector), [length] "r" (length), [max_value] "r" (max_value) + : "memory" + ); + + return (int32_t)maximum; +} +#endif // #if defined(MIPS_DSP_R1_LE) + +// Maximum value of word16 vector. Version for MIPS platform. +int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, size_t length) { + int16_t maximum = WEBRTC_SPL_WORD16_MIN; + int tmp1; + int16_t value; + + assert(length > 0); + + __asm__ volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "1: \n\t" + "lh %[value], 0(%[vector]) \n\t" + "addiu %[length], %[length], -1 \n\t" + "slt %[tmp1], %[maximum], %[value] \n\t" + "movn %[maximum], %[value], %[tmp1] \n\t" + "bgtz %[length], 1b \n\t" + " addiu %[vector], %[vector], 2 \n\t" + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value) + : [vector] "r" (vector), [length] "r" (length) + : "memory" + ); + + return maximum; +} + +// Maximum value of word32 vector. Version for MIPS platform. +int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, size_t length) { + int32_t maximum = WEBRTC_SPL_WORD32_MIN; + int tmp1, value; + + assert(length > 0); + + __asm__ volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "1: \n\t" + "lw %[value], 0(%[vector]) \n\t" + "addiu %[length], %[length], -1 \n\t" + "slt %[tmp1], %[maximum], %[value] \n\t" + "movn %[maximum], %[value], %[tmp1] \n\t" + "bgtz %[length], 1b \n\t" + " addiu %[vector], %[vector], 4 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value) + : [vector] "r" (vector), [length] "r" (length) + : "memory" + ); + + return maximum; +} + +// Minimum value of word16 vector. Version for MIPS platform. +int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, size_t length) { + int16_t minimum = WEBRTC_SPL_WORD16_MAX; + int tmp1; + int16_t value; + + assert(length > 0); + + __asm__ volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "1: \n\t" + "lh %[value], 0(%[vector]) \n\t" + "addiu %[length], %[length], -1 \n\t" + "slt %[tmp1], %[value], %[minimum] \n\t" + "movn %[minimum], %[value], %[tmp1] \n\t" + "bgtz %[length], 1b \n\t" + " addiu %[vector], %[vector], 2 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value) + : [vector] "r" (vector), [length] "r" (length) + : "memory" + ); + + return minimum; +} + +// Minimum value of word32 vector. Version for MIPS platform. +int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, size_t length) { + int32_t minimum = WEBRTC_SPL_WORD32_MAX; + int tmp1, value; + + assert(length > 0); + + __asm__ volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "1: \n\t" + "lw %[value], 0(%[vector]) \n\t" + "addiu %[length], %[length], -1 \n\t" + "slt %[tmp1], %[value], %[minimum] \n\t" + "movn %[minimum], %[value], %[tmp1] \n\t" + "bgtz %[length], 1b \n\t" + " addiu %[vector], %[vector], 4 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value) + : [vector] "r" (vector), [length] "r" (length) + : "memory" + ); + + return minimum; +} diff --git a/webrtc/common_audio/signal_processing/min_max_operations_neon.c b/webrtc/common_audio/signal_processing/min_max_operations_neon.c new file mode 100644 index 0000000..6fbbf94 --- /dev/null +++ b/webrtc/common_audio/signal_processing/min_max_operations_neon.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// Maximum absolute value of word16 vector. C version for generic platforms. +int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, size_t length) { + int absolute = 0, maximum = 0; + + assert(length > 0); + + const int16_t* p_start = vector; + size_t rest = length & 7; + const int16_t* p_end = vector + length - rest; + + int16x8_t v; + uint16x8_t max_qv; + max_qv = vdupq_n_u16(0); + + while (p_start < p_end) { + v = vld1q_s16(p_start); + // Note vabs doesn't change the value of -32768. + v = vabsq_s16(v); + // Use u16 so we don't lose the value -32768. + max_qv = vmaxq_u16(max_qv, vreinterpretq_u16_s16(v)); + p_start += 8; + } + +#ifdef WEBRTC_ARCH_ARM64 + maximum = (int)vmaxvq_u16(max_qv); +#else + uint16x4_t max_dv; + max_dv = vmax_u16(vget_low_u16(max_qv), vget_high_u16(max_qv)); + max_dv = vpmax_u16(max_dv, max_dv); + max_dv = vpmax_u16(max_dv, max_dv); + + maximum = (int)vget_lane_u16(max_dv, 0); +#endif + + p_end = vector + length; + while (p_start < p_end) { + absolute = abs((int)(*p_start)); + + if (absolute > maximum) { + maximum = absolute; + } + p_start++; + } + + // Guard the case for abs(-32768). + if (maximum > WEBRTC_SPL_WORD16_MAX) { + maximum = WEBRTC_SPL_WORD16_MAX; + } + + return (int16_t)maximum; +} + +// Maximum absolute value of word32 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int32_t WebRtcSpl_MaxAbsValueW32Neon(const int32_t* vector, size_t length) { + // Use uint32_t for the local variables, to accommodate the return value + // of abs(0x80000000), which is 0x80000000. + + uint32_t absolute = 0, maximum = 0; + size_t i = 0; + size_t residual = length & 0x7; + + assert(length > 0); + + const int32_t* p_start = vector; + uint32x4_t max32x4_0 = vdupq_n_u32(0); + uint32x4_t max32x4_1 = vdupq_n_u32(0); + + // First part, unroll the loop 8 times. + for (i = 0; i < length - residual; i += 8) { + int32x4_t in32x4_0 = vld1q_s32(p_start); + p_start += 4; + int32x4_t in32x4_1 = vld1q_s32(p_start); + p_start += 4; + in32x4_0 = vabsq_s32(in32x4_0); + in32x4_1 = vabsq_s32(in32x4_1); + // vabs doesn't change the value of 0x80000000. + // Use u32 so we don't lose the value 0x80000000. + max32x4_0 = vmaxq_u32(max32x4_0, vreinterpretq_u32_s32(in32x4_0)); + max32x4_1 = vmaxq_u32(max32x4_1, vreinterpretq_u32_s32(in32x4_1)); + } + + uint32x4_t max32x4 = vmaxq_u32(max32x4_0, max32x4_1); +#if defined(WEBRTC_ARCH_ARM64) + maximum = vmaxvq_u32(max32x4); +#else + uint32x2_t max32x2 = vmax_u32(vget_low_u32(max32x4), vget_high_u32(max32x4)); + max32x2 = vpmax_u32(max32x2, max32x2); + + maximum = vget_lane_u32(max32x2, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + absolute = abs((int)(*p_start)); + if (absolute > maximum) { + maximum = absolute; + } + p_start++; + } + + // Guard against the case for 0x80000000. + maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX); + + return (int32_t)maximum; +} + +// Maximum value of word16 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int16_t WebRtcSpl_MaxValueW16Neon(const int16_t* vector, size_t length) { + int16_t maximum = WEBRTC_SPL_WORD16_MIN; + size_t i = 0; + size_t residual = length & 0x7; + + assert(length > 0); + + const int16_t* p_start = vector; + int16x8_t max16x8 = vdupq_n_s16(WEBRTC_SPL_WORD16_MIN); + + // First part, unroll the loop 8 times. + for (i = 0; i < length - residual; i += 8) { + int16x8_t in16x8 = vld1q_s16(p_start); + max16x8 = vmaxq_s16(max16x8, in16x8); + p_start += 8; + } + +#if defined(WEBRTC_ARCH_ARM64) + maximum = vmaxvq_s16(max16x8); +#else + int16x4_t max16x4 = vmax_s16(vget_low_s16(max16x8), vget_high_s16(max16x8)); + max16x4 = vpmax_s16(max16x4, max16x4); + max16x4 = vpmax_s16(max16x4, max16x4); + + maximum = vget_lane_s16(max16x4, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + if (*p_start > maximum) + maximum = *p_start; + p_start++; + } + return maximum; +} + +// Maximum value of word32 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int32_t WebRtcSpl_MaxValueW32Neon(const int32_t* vector, size_t length) { + int32_t maximum = WEBRTC_SPL_WORD32_MIN; + size_t i = 0; + size_t residual = length & 0x7; + + assert(length > 0); + + const int32_t* p_start = vector; + int32x4_t max32x4_0 = vdupq_n_s32(WEBRTC_SPL_WORD32_MIN); + int32x4_t max32x4_1 = vdupq_n_s32(WEBRTC_SPL_WORD32_MIN); + + // First part, unroll the loop 8 times. + for (i = 0; i < length - residual; i += 8) { + int32x4_t in32x4_0 = vld1q_s32(p_start); + p_start += 4; + int32x4_t in32x4_1 = vld1q_s32(p_start); + p_start += 4; + max32x4_0 = vmaxq_s32(max32x4_0, in32x4_0); + max32x4_1 = vmaxq_s32(max32x4_1, in32x4_1); + } + + int32x4_t max32x4 = vmaxq_s32(max32x4_0, max32x4_1); +#if defined(WEBRTC_ARCH_ARM64) + maximum = vmaxvq_s32(max32x4); +#else + int32x2_t max32x2 = vmax_s32(vget_low_s32(max32x4), vget_high_s32(max32x4)); + max32x2 = vpmax_s32(max32x2, max32x2); + + maximum = vget_lane_s32(max32x2, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + if (*p_start > maximum) + maximum = *p_start; + p_start++; + } + return maximum; +} + +// Minimum value of word16 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, size_t length) { + int16_t minimum = WEBRTC_SPL_WORD16_MAX; + size_t i = 0; + size_t residual = length & 0x7; + + assert(length > 0); + + const int16_t* p_start = vector; + int16x8_t min16x8 = vdupq_n_s16(WEBRTC_SPL_WORD16_MAX); + + // First part, unroll the loop 8 times. + for (i = 0; i < length - residual; i += 8) { + int16x8_t in16x8 = vld1q_s16(p_start); + min16x8 = vminq_s16(min16x8, in16x8); + p_start += 8; + } + +#if defined(WEBRTC_ARCH_ARM64) + minimum = vminvq_s16(min16x8); +#else + int16x4_t min16x4 = vmin_s16(vget_low_s16(min16x8), vget_high_s16(min16x8)); + min16x4 = vpmin_s16(min16x4, min16x4); + min16x4 = vpmin_s16(min16x4, min16x4); + + minimum = vget_lane_s16(min16x4, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + if (*p_start < minimum) + minimum = *p_start; + p_start++; + } + return minimum; +} + +// Minimum value of word32 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int32_t WebRtcSpl_MinValueW32Neon(const int32_t* vector, size_t length) { + int32_t minimum = WEBRTC_SPL_WORD32_MAX; + size_t i = 0; + size_t residual = length & 0x7; + + assert(length > 0); + + const int32_t* p_start = vector; + int32x4_t min32x4_0 = vdupq_n_s32(WEBRTC_SPL_WORD32_MAX); + int32x4_t min32x4_1 = vdupq_n_s32(WEBRTC_SPL_WORD32_MAX); + + // First part, unroll the loop 8 times. + for (i = 0; i < length - residual; i += 8) { + int32x4_t in32x4_0 = vld1q_s32(p_start); + p_start += 4; + int32x4_t in32x4_1 = vld1q_s32(p_start); + p_start += 4; + min32x4_0 = vminq_s32(min32x4_0, in32x4_0); + min32x4_1 = vminq_s32(min32x4_1, in32x4_1); + } + + int32x4_t min32x4 = vminq_s32(min32x4_0, min32x4_1); +#if defined(WEBRTC_ARCH_ARM64) + minimum = vminvq_s32(min32x4); +#else + int32x2_t min32x2 = vmin_s32(vget_low_s32(min32x4), vget_high_s32(min32x4)); + min32x2 = vpmin_s32(min32x2, min32x2); + + minimum = vget_lane_s32(min32x2, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + if (*p_start < minimum) + minimum = *p_start; + p_start++; + } + return minimum; +} + diff --git a/src/common_audio/signal_processing_library/main/source/randn_table.c b/webrtc/common_audio/signal_processing/randomization_functions.c similarity index 84% rename from src/common_audio/signal_processing_library/main/source/randn_table.c rename to webrtc/common_audio/signal_processing/randomization_functions.c index 734fa79..73f2409 100644 --- a/src/common_audio/signal_processing_library/main/source/randn_table.c +++ b/webrtc/common_audio/signal_processing/randomization_functions.c @@ -10,14 +10,20 @@ /* - * Table with 512 samples from a normal distribution with mean 1 and std 1 - * The values are shifted up 13 steps (multiplied by 8192) + * This file contains implementations of the randomization functions + * WebRtcSpl_RandU() + * WebRtcSpl_RandN() + * WebRtcSpl_RandUArray() + * + * The description header can be found in signal_processing_library.h + * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -WebRtc_Word16 WebRtcSpl_kRandNTable[] = -{ +static const uint32_t kMaxSeedUsed = 0x80000000; + +static const int16_t kRandNTable[] = { 9178, -7260, 40, 10189, 4894, -3531, -13779, 14764, -4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817, -9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361, @@ -83,3 +89,27 @@ WebRtc_Word16 WebRtcSpl_kRandNTable[] = 2406, 7703, -951, 11196, -564, 3406, 2217, 4806, 2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492 }; + +static uint32_t IncreaseSeed(uint32_t* seed) { + seed[0] = (seed[0] * ((int32_t)69069) + 1) & (kMaxSeedUsed - 1); + return seed[0]; +} + +int16_t WebRtcSpl_RandU(uint32_t* seed) { + return (int16_t)(IncreaseSeed(seed) >> 16); +} + +int16_t WebRtcSpl_RandN(uint32_t* seed) { + return kRandNTable[IncreaseSeed(seed) >> 23]; +} + +// Creates an array of uniformly distributed variables. +int16_t WebRtcSpl_RandUArray(int16_t* vector, + int16_t vector_length, + uint32_t* seed) { + int i; + for (i = 0; i < vector_length; i++) { + vector[i] = WebRtcSpl_RandU(seed); + } + return vector_length; +} diff --git a/webrtc/common_audio/signal_processing/real_fft.c b/webrtc/common_audio/signal_processing/real_fft.c new file mode 100644 index 0000000..92daae4 --- /dev/null +++ b/webrtc/common_audio/signal_processing/real_fft.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/real_fft.h" + +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +struct RealFFT { + int order; +}; + +struct RealFFT* WebRtcSpl_CreateRealFFT(int order) { + struct RealFFT* self = NULL; + + if (order > kMaxFFTOrder || order < 0) { + return NULL; + } + + self = malloc(sizeof(struct RealFFT)); + if (self == NULL) { + return NULL; + } + self->order = order; + + return self; +} + +void WebRtcSpl_FreeRealFFT(struct RealFFT* self) { + if (self != NULL) { + free(self); + } +} + +// The C version FFT functions (i.e. WebRtcSpl_RealForwardFFT and +// WebRtcSpl_RealInverseFFT) are real-valued FFT wrappers for complex-valued +// FFT implementation in SPL. + +int WebRtcSpl_RealForwardFFT(struct RealFFT* self, + const int16_t* real_data_in, + int16_t* complex_data_out) { + int i = 0; + int j = 0; + int result = 0; + int n = 1 << self->order; + // The complex-value FFT implementation needs a buffer to hold 2^order + // 16-bit COMPLEX numbers, for both time and frequency data. + int16_t complex_buffer[2 << kMaxFFTOrder]; + + // Insert zeros to the imaginary parts for complex forward FFT input. + for (i = 0, j = 0; i < n; i += 1, j += 2) { + complex_buffer[j] = real_data_in[i]; + complex_buffer[j + 1] = 0; + }; + + WebRtcSpl_ComplexBitReverse(complex_buffer, self->order); + result = WebRtcSpl_ComplexFFT(complex_buffer, self->order, 1); + + // For real FFT output, use only the first N + 2 elements from + // complex forward FFT. + memcpy(complex_data_out, complex_buffer, sizeof(int16_t) * (n + 2)); + + return result; +} + +int WebRtcSpl_RealInverseFFT(struct RealFFT* self, + const int16_t* complex_data_in, + int16_t* real_data_out) { + int i = 0; + int j = 0; + int result = 0; + int n = 1 << self->order; + // Create the buffer specific to complex-valued FFT implementation. + int16_t complex_buffer[2 << kMaxFFTOrder]; + + // For n-point FFT, first copy the first n + 2 elements into complex + // FFT, then construct the remaining n - 2 elements by real FFT's + // conjugate-symmetric properties. + memcpy(complex_buffer, complex_data_in, sizeof(int16_t) * (n + 2)); + for (i = n + 2; i < 2 * n; i += 2) { + complex_buffer[i] = complex_data_in[2 * n - i]; + complex_buffer[i + 1] = -complex_data_in[2 * n - i + 1]; + } + + WebRtcSpl_ComplexBitReverse(complex_buffer, self->order); + result = WebRtcSpl_ComplexIFFT(complex_buffer, self->order, 1); + + // Strip out the imaginary parts of the complex inverse FFT output. + for (i = 0, j = 0; i < n; i += 1, j += 2) { + real_data_out[i] = complex_buffer[j]; + } + + return result; +} diff --git a/src/common_audio/signal_processing_library/main/source/refl_coef_to_lpc.c b/webrtc/common_audio/signal_processing/refl_coef_to_lpc.c similarity index 70% rename from src/common_audio/signal_processing_library/main/source/refl_coef_to_lpc.c rename to webrtc/common_audio/signal_processing/refl_coef_to_lpc.c index d07804d..06a29b6 100644 --- a/src/common_audio/signal_processing_library/main/source/refl_coef_to_lpc.c +++ b/webrtc/common_audio/signal_processing/refl_coef_to_lpc.c @@ -15,19 +15,19 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a) +void WebRtcSpl_ReflCoefToLpc(const int16_t *k, int use_order, int16_t *a) { - WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; - WebRtc_Word16 *aptr, *aptr2, *anyptr; - G_CONST WebRtc_Word16 *kptr; + int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; + int16_t *aptr, *aptr2, *anyptr; + const int16_t *kptr; int m, i; kptr = k; *a = 4096; // i.e., (Word16_MAX >> 3)+1. *any = *a; - a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3); + a[1] = *k >> 3; for (m = 1; m < use_order; m++) { @@ -38,11 +38,10 @@ void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Wor anyptr = any; anyptr++; - any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3); + any[m + 1] = *kptr >> 3; for (i = 0; i < m; i++) { - *anyptr = (*aptr) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15); + *anyptr = *aptr + (int16_t)((*aptr2 * *kptr) >> 15); anyptr++; aptr++; aptr2--; diff --git a/src/common_audio/signal_processing_library/main/source/resample.c b/webrtc/common_audio/signal_processing/resample.c similarity index 78% rename from src/common_audio/signal_processing_library/main/source/resample.c rename to webrtc/common_audio/signal_processing/resample.c index 19d1778..45fe52a 100644 --- a/src/common_audio/signal_processing_library/main/source/resample.c +++ b/webrtc/common_audio/signal_processing/resample.c @@ -15,18 +15,18 @@ * */ -#include "signal_processing_library.h" -#include "resample_by_2_internal.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h" // Declaration of internally used functions -static void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, WebRtc_Word16 *Out, - const WebRtc_Word32 K); +static void WebRtcSpl_32khzTo22khzIntToShort(const int32_t *In, int16_t *Out, + int32_t K); -void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K); +void WebRtcSpl_32khzTo22khzIntToInt(const int32_t *In, int32_t *Out, + int32_t K); // interpolation coefficients -static const WebRtc_Word16 kCoefficients32To22[5][9] = { +static const int16_t kCoefficients32To22[5][9] = { {127, -712, 2359, -6333, 23456, 16775, -3695, 945, -154}, {-39, 230, -830, 2785, 32366, -2324, 760, -218, 38}, {117, -663, 2222, -6133, 26634, 13070, -3174, 831, -137}, @@ -42,8 +42,8 @@ static const WebRtc_Word16 kCoefficients32To22[5][9] = { #define SUB_BLOCKS_22_16 5 // 22 -> 16 resampler -void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State22khzTo16khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample22khzTo16khz(const int16_t* in, int16_t* out, + WebRtcSpl_State22khzTo16khz* state, int32_t* tmpmem) { int k; @@ -51,14 +51,14 @@ void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, for (k = 0; k < SUB_BLOCKS_22_16; k++) { ///// 22 --> 44 ///// - // WebRtc_Word16 in[220/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[440/SUB_BLOCKS_22_16] + // int16_t in[220/SUB_BLOCKS_22_16] + // int32_t out[440/SUB_BLOCKS_22_16] ///// WebRtcSpl_UpBy2ShortToInt(in, 220 / SUB_BLOCKS_22_16, tmpmem + 16, state->S_22_44); ///// 44 --> 32 ///// - // WebRtc_Word32 in[440/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[320/SUB_BLOCKS_22_16] + // int32_t in[440/SUB_BLOCKS_22_16] + // int32_t out[320/SUB_BLOCKS_22_16] ///// // copy state to and from input array tmpmem[8] = state->S_44_32[0]; @@ -81,8 +81,8 @@ void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 40 / SUB_BLOCKS_22_16); ///// 32 --> 16 ///// - // WebRtc_Word32 in[320/SUB_BLOCKS_22_16] - // WebRtc_Word32 out[160/SUB_BLOCKS_22_16] + // int32_t in[320/SUB_BLOCKS_22_16] + // int32_t out[160/SUB_BLOCKS_22_16] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16); @@ -112,8 +112,8 @@ void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state) #define SUB_BLOCKS_16_22 4 // 16 -> 22 resampler -void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State16khzTo22khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample16khzTo22khz(const int16_t* in, int16_t* out, + WebRtcSpl_State16khzTo22khz* state, int32_t* tmpmem) { int k; @@ -121,14 +121,14 @@ void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, for (k = 0; k < SUB_BLOCKS_16_22; k++) { ///// 16 --> 32 ///// - // WebRtc_Word16 in[160/SUB_BLOCKS_16_22] - // WebRtc_Word32 out[320/SUB_BLOCKS_16_22] + // int16_t in[160/SUB_BLOCKS_16_22] + // int32_t out[320/SUB_BLOCKS_16_22] ///// WebRtcSpl_UpBy2ShortToInt(in, 160 / SUB_BLOCKS_16_22, tmpmem + 8, state->S_16_32); ///// 32 --> 22 ///// - // WebRtc_Word32 in[320/SUB_BLOCKS_16_22] - // WebRtc_Word32 out[220/SUB_BLOCKS_16_22] + // int32_t in[320/SUB_BLOCKS_16_22] + // int32_t out[220/SUB_BLOCKS_16_22] ///// // copy state to and from input array tmpmem[0] = state->S_32_22[0]; @@ -175,8 +175,8 @@ void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state) #define SUB_BLOCKS_22_8 2 // 22 -> 8 resampler -void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State22khzTo8khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample22khzTo8khz(const int16_t* in, int16_t* out, + WebRtcSpl_State22khzTo8khz* state, int32_t* tmpmem) { int k; @@ -184,14 +184,14 @@ void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, for (k = 0; k < SUB_BLOCKS_22_8; k++) { ///// 22 --> 22 lowpass ///// - // WebRtc_Word16 in[220/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[220/SUB_BLOCKS_22_8] + // int16_t in[220/SUB_BLOCKS_22_8] + // int32_t out[220/SUB_BLOCKS_22_8] ///// WebRtcSpl_LPBy2ShortToInt(in, 220 / SUB_BLOCKS_22_8, tmpmem + 16, state->S_22_22); ///// 22 --> 16 ///// - // WebRtc_Word32 in[220/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[160/SUB_BLOCKS_22_8] + // int32_t in[220/SUB_BLOCKS_22_8] + // int32_t out[160/SUB_BLOCKS_22_8] ///// // copy state to and from input array tmpmem[8] = state->S_22_16[0]; @@ -214,8 +214,8 @@ void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 20 / SUB_BLOCKS_22_8); ///// 16 --> 8 ///// - // WebRtc_Word32 in[160/SUB_BLOCKS_22_8] - // WebRtc_Word32 out[80/SUB_BLOCKS_22_8] + // int32_t in[160/SUB_BLOCKS_22_8] + // int32_t out[80/SUB_BLOCKS_22_8] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8); @@ -246,8 +246,8 @@ void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state) #define SUB_BLOCKS_8_22 2 // 8 -> 22 resampler -void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo22khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample8khzTo22khz(const int16_t* in, int16_t* out, + WebRtcSpl_State8khzTo22khz* state, int32_t* tmpmem) { int k; @@ -255,14 +255,14 @@ void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, for (k = 0; k < SUB_BLOCKS_8_22; k++) { ///// 8 --> 16 ///// - // WebRtc_Word16 in[80/SUB_BLOCKS_8_22] - // WebRtc_Word32 out[160/SUB_BLOCKS_8_22] + // int16_t in[80/SUB_BLOCKS_8_22] + // int32_t out[160/SUB_BLOCKS_8_22] ///// WebRtcSpl_UpBy2ShortToInt(in, 80 / SUB_BLOCKS_8_22, tmpmem + 18, state->S_8_16); ///// 16 --> 11 ///// - // WebRtc_Word32 in[160/SUB_BLOCKS_8_22] - // WebRtc_Word32 out[110/SUB_BLOCKS_8_22] + // int32_t in[160/SUB_BLOCKS_8_22] + // int32_t out[110/SUB_BLOCKS_8_22] ///// // copy state to and from input array tmpmem[10] = state->S_16_11[0]; @@ -285,8 +285,8 @@ void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, WebRtcSpl_32khzTo22khzIntToInt(tmpmem + 10, tmpmem, 10 / SUB_BLOCKS_8_22); ///// 11 --> 22 ///// - // WebRtc_Word32 in[110/SUB_BLOCKS_8_22] - // WebRtc_Word16 out[220/SUB_BLOCKS_8_22] + // int32_t in[110/SUB_BLOCKS_8_22] + // int16_t out[220/SUB_BLOCKS_8_22] ///// WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22); @@ -309,13 +309,13 @@ void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state) } // compute two inner-products and store them to output array -static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Word32* in2, - const WebRtc_Word16* coef_ptr, WebRtc_Word32* out1, - WebRtc_Word32* out2) +static void WebRtcSpl_DotProdIntToInt(const int32_t* in1, const int32_t* in2, + const int16_t* coef_ptr, int32_t* out1, + int32_t* out2) { - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; + int32_t tmp1 = 16384; + int32_t tmp2 = 16384; + int16_t coef; coef = coef_ptr[0]; tmp1 += coef * in1[0]; @@ -355,13 +355,13 @@ static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Wor } // compute two inner-products and store them to output array -static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_Word32* in2, - const WebRtc_Word16* coef_ptr, WebRtc_Word16* out1, - WebRtc_Word16* out2) +static void WebRtcSpl_DotProdIntToShort(const int32_t* in1, const int32_t* in2, + const int16_t* coef_ptr, int16_t* out1, + int16_t* out2) { - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; + int32_t tmp1 = 16384; + int32_t tmp2 = 16384; + int16_t coef; coef = coef_ptr[0]; tmp1 += coef * in1[0]; @@ -401,39 +401,39 @@ static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_W // scale down, round and saturate tmp1 >>= 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) + if (tmp1 > (int32_t)0x00007FFF) tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) + if (tmp1 < (int32_t)0xFFFF8000) tmp1 = 0xFFFF8000; tmp2 >>= 15; - if (tmp2 > (WebRtc_Word32)0x00007FFF) + if (tmp2 > (int32_t)0x00007FFF) tmp2 = 0x00007FFF; - if (tmp2 < (WebRtc_Word32)0xFFFF8000) + if (tmp2 < (int32_t)0xFFFF8000) tmp2 = 0xFFFF8000; - *out1 = (WebRtc_Word16)tmp1; - *out2 = (WebRtc_Word16)tmp2; + *out1 = (int16_t)tmp1; + *out2 = (int16_t)tmp2; } // Resampling ratio: 11/16 -// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 11 * K +// input: int32_t (normalized, not saturated) :: size 16 * K +// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 11 * K // K: Number of blocks -void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In, - WebRtc_Word32* Out, - const WebRtc_Word32 K) +void WebRtcSpl_32khzTo22khzIntToInt(const int32_t* In, + int32_t* Out, + int32_t K) { ///////////////////////////////////////////////////////////// // Filter operation: // // Perform resampling (16 input samples -> 11 output samples); // process in sub blocks of size 16 samples. - WebRtc_Word32 m; + int32_t m; for (m = 0; m < K; m++) { // first output sample - Out[0] = ((WebRtc_Word32)In[3] << 15) + (1 << 14); + Out[0] = ((int32_t)In[3] << 15) + (1 << 14); // sum and accumulate filter coefficients and input samples WebRtcSpl_DotProdIntToInt(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); @@ -457,31 +457,31 @@ void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In, } // Resampling ratio: 11/16 -// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K -// output: WebRtc_Word16 (saturated) :: size 11 * K +// input: int32_t (normalized, not saturated) :: size 16 * K +// output: int16_t (saturated) :: size 11 * K // K: Number of blocks -void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, - WebRtc_Word16 *Out, - const WebRtc_Word32 K) +void WebRtcSpl_32khzTo22khzIntToShort(const int32_t *In, + int16_t *Out, + int32_t K) { ///////////////////////////////////////////////////////////// // Filter operation: // // Perform resampling (16 input samples -> 11 output samples); // process in sub blocks of size 16 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; + int32_t tmp; + int32_t m; for (m = 0; m < K; m++) { // first output sample tmp = In[3]; - if (tmp > (WebRtc_Word32)0x00007FFF) + if (tmp > (int32_t)0x00007FFF) tmp = 0x00007FFF; - if (tmp < (WebRtc_Word32)0xFFFF8000) + if (tmp < (int32_t)0xFFFF8000) tmp = 0xFFFF8000; - Out[0] = (WebRtc_Word16)tmp; + Out[0] = (int16_t)tmp; // sum and accumulate filter coefficients and input samples WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); diff --git a/src/common_audio/signal_processing_library/main/source/resample_48khz.c b/webrtc/common_audio/signal_processing/resample_48khz.c similarity index 55% rename from src/common_audio/signal_processing_library/main/source/resample_48khz.c rename to webrtc/common_audio/signal_processing/resample_48khz.c index 31cbe6b..2220cc3 100644 --- a/src/common_audio/signal_processing_library/main/source/resample_48khz.c +++ b/webrtc/common_audio/signal_processing/resample_48khz.c @@ -16,35 +16,35 @@ */ #include -#include "signal_processing_library.h" -#include "resample_by_2_internal.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h" //////////////////////////// ///// 48 kHz -> 16 kHz ///// //////////////////////////// // 48 -> 16 resampler -void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample48khzTo16khz(const int16_t* in, int16_t* out, + WebRtcSpl_State48khzTo16khz* state, int32_t* tmpmem) { ///// 48 --> 48(LP) ///// - // WebRtc_Word16 in[480] - // WebRtc_Word32 out[480] + // int16_t in[480] + // int32_t out[480] ///// WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48); ///// 48 --> 32 ///// - // WebRtc_Word32 in[480] - // WebRtc_Word32 out[320] + // int32_t in[480] + // int32_t out[320] ///// // copy state to and from input array - memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32)); + memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(int32_t)); + memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(int32_t)); WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160); ///// 32 --> 16 ///// - // WebRtc_Word32 in[320] - // WebRtc_Word16 out[160] + // int32_t in[320] + // int16_t out[160] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16); } @@ -52,9 +52,9 @@ void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, // initialize state of 48 -> 16 resampler void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state) { - memset(state->S_48_48, 0, 16 * sizeof(WebRtc_Word32)); - memset(state->S_48_32, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_32_16, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_48_48, 0, 16 * sizeof(int32_t)); + memset(state->S_48_32, 0, 8 * sizeof(int32_t)); + memset(state->S_32_16, 0, 8 * sizeof(int32_t)); } //////////////////////////// @@ -62,27 +62,27 @@ void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state) //////////////////////////// // 16 -> 48 resampler -void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State16khzTo48khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample16khzTo48khz(const int16_t* in, int16_t* out, + WebRtcSpl_State16khzTo48khz* state, int32_t* tmpmem) { ///// 16 --> 32 ///// - // WebRtc_Word16 in[160] - // WebRtc_Word32 out[320] + // int16_t in[160] + // int32_t out[320] ///// WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32); ///// 32 --> 24 ///// - // WebRtc_Word32 in[320] - // WebRtc_Word32 out[240] + // int32_t in[320] + // int32_t out[240] // copy state to and from input array ///// - memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(WebRtc_Word32)); + memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(int32_t)); + memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(int32_t)); WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80); ///// 24 --> 48 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word16 out[480] + // int32_t in[240] + // int16_t out[480] ///// WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); } @@ -90,9 +90,9 @@ void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, // initialize state of 16 -> 48 resampler void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state) { - memset(state->S_16_32, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_32_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_16_32, 0, 8 * sizeof(int32_t)); + memset(state->S_32_24, 0, 8 * sizeof(int32_t)); + memset(state->S_24_48, 0, 8 * sizeof(int32_t)); } //////////////////////////// @@ -100,33 +100,33 @@ void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state) //////////////////////////// // 48 -> 8 resampler -void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample48khzTo8khz(const int16_t* in, int16_t* out, + WebRtcSpl_State48khzTo8khz* state, int32_t* tmpmem) { ///// 48 --> 24 ///// - // WebRtc_Word16 in[480] - // WebRtc_Word32 out[240] + // int16_t in[480] + // int32_t out[240] ///// WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24); ///// 24 --> 24(LP) ///// - // WebRtc_Word32 in[240] - // WebRtc_Word32 out[240] + // int32_t in[240] + // int32_t out[240] ///// WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24); ///// 24 --> 16 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word32 out[160] + // int32_t in[240] + // int32_t out[160] ///// // copy state to and from input array - memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32)); + memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(int32_t)); + memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(int32_t)); WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80); ///// 16 --> 8 ///// - // WebRtc_Word32 in[160] - // WebRtc_Word16 out[80] + // int32_t in[160] + // int16_t out[80] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8); } @@ -134,10 +134,10 @@ void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, // initialize state of 48 -> 8 resampler void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state) { - memset(state->S_48_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_24, 0, 16 * sizeof(WebRtc_Word32)); - memset(state->S_24_16, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_16_8, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_48_24, 0, 8 * sizeof(int32_t)); + memset(state->S_24_24, 0, 16 * sizeof(int32_t)); + memset(state->S_24_16, 0, 8 * sizeof(int32_t)); + memset(state->S_16_8, 0, 8 * sizeof(int32_t)); } //////////////////////////// @@ -145,33 +145,33 @@ void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state) //////////////////////////// // 8 -> 48 resampler -void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, - WebRtcSpl_State8khzTo48khz* state, WebRtc_Word32* tmpmem) +void WebRtcSpl_Resample8khzTo48khz(const int16_t* in, int16_t* out, + WebRtcSpl_State8khzTo48khz* state, int32_t* tmpmem) { ///// 8 --> 16 ///// - // WebRtc_Word16 in[80] - // WebRtc_Word32 out[160] + // int16_t in[80] + // int32_t out[160] ///// WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16); ///// 16 --> 12 ///// - // WebRtc_Word32 in[160] - // WebRtc_Word32 out[120] + // int32_t in[160] + // int32_t out[120] ///// // copy state to and from input array - memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(WebRtc_Word32)); - memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(WebRtc_Word32)); + memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(int32_t)); + memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(int32_t)); WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40); ///// 12 --> 24 ///// - // WebRtc_Word32 in[120] - // WebRtc_Word16 out[240] + // int32_t in[120] + // int16_t out[240] ///// WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24); ///// 24 --> 48 ///// - // WebRtc_Word32 in[240] - // WebRtc_Word16 out[480] + // int32_t in[240] + // int16_t out[480] ///// WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); } @@ -179,8 +179,8 @@ void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, // initialize state of 8 -> 48 resampler void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state) { - memset(state->S_8_16, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_16_12, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_12_24, 0, 8 * sizeof(WebRtc_Word32)); - memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_8_16, 0, 8 * sizeof(int32_t)); + memset(state->S_16_12, 0, 8 * sizeof(int32_t)); + memset(state->S_12_24, 0, 8 * sizeof(int32_t)); + memset(state->S_24_48, 0, 8 * sizeof(int32_t)); } diff --git a/src/common_audio/signal_processing_library/main/source/resample_by_2.c b/webrtc/common_audio/signal_processing/resample_by_2.c similarity index 60% rename from src/common_audio/signal_processing_library/main/source/resample_by_2.c rename to webrtc/common_audio/signal_processing/resample_by_2.c index e239db7..dcba82e 100644 --- a/src/common_audio/signal_processing_library/main/source/resample_by_2.c +++ b/webrtc/common_audio/signal_processing/resample_by_2.c @@ -15,24 +15,24 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -#ifdef WEBRTC_ARCH_ARM_V7A +#ifdef WEBRTC_ARCH_ARM_V7 // allpass filter coefficients. -static const WebRtc_UWord32 kResampleAllpass1[3] = {3284, 24441, 49528 << 15}; -static const WebRtc_UWord32 kResampleAllpass2[3] = +static const uint32_t kResampleAllpass1[3] = {3284, 24441, 49528 << 15}; +static const uint32_t kResampleAllpass2[3] = {12199, 37471 << 15, 60255 << 15}; // Multiply two 32-bit values and accumulate to another input value. // Return: state + ((diff * tbl_value) >> 16) -static __inline WebRtc_Word32 MUL_ACCUM_1(WebRtc_Word32 tbl_value, - WebRtc_Word32 diff, - WebRtc_Word32 state) { - WebRtc_Word32 result; - __asm__("smlawb %r0, %r1, %r2, %r3": "=r"(result): "r"(diff), - "r"(tbl_value), "r"(state)); +static __inline int32_t MUL_ACCUM_1(int32_t tbl_value, + int32_t diff, + int32_t state) { + int32_t result; + __asm __volatile ("smlawb %0, %1, %2, %3": "=r"(result): "r"(diff), + "r"(tbl_value), "r"(state)); return result; } @@ -43,46 +43,47 @@ static __inline WebRtc_Word32 MUL_ACCUM_1(WebRtc_Word32 tbl_value, // instruction (in MUL_ACCUM_1) due to input value range, we can still use // smmla to save some cycles. -static __inline WebRtc_Word32 MUL_ACCUM_2(WebRtc_Word32 tbl_value, - WebRtc_Word32 diff, - WebRtc_Word32 state) { - WebRtc_Word32 result; - __asm__("smmla %r0, %r1, %r2, %r3": "=r"(result): "r"(diff << 1), - "r"(tbl_value), "r"(state)); +static __inline int32_t MUL_ACCUM_2(int32_t tbl_value, + int32_t diff, + int32_t state) { + int32_t result; + __asm __volatile ("smmla %0, %1, %2, %3": "=r"(result): "r"(diff << 1), + "r"(tbl_value), "r"(state)); return result; } #else // allpass filter coefficients. -static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528}; -static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255}; +static const uint16_t kResampleAllpass1[3] = {3284, 24441, 49528}; +static const uint16_t kResampleAllpass2[3] = {12199, 37471, 60255}; // Multiply a 32-bit value with a 16-bit value and accumulate to another input: #define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) #define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) -#endif // WEBRTC_ARCH_ARM_V7A +#endif // WEBRTC_ARCH_ARM_V7 // decimator -void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState) { - WebRtc_Word32 tmp1, tmp2, diff, in32, out32; - WebRtc_Word16 i; +#if !defined(MIPS32_LE) +void WebRtcSpl_DownsampleBy2(const int16_t* in, size_t len, + int16_t* out, int32_t* filtState) { + int32_t tmp1, tmp2, diff, in32, out32; + size_t i; - register WebRtc_Word32 state0 = filtState[0]; - register WebRtc_Word32 state1 = filtState[1]; - register WebRtc_Word32 state2 = filtState[2]; - register WebRtc_Word32 state3 = filtState[3]; - register WebRtc_Word32 state4 = filtState[4]; - register WebRtc_Word32 state5 = filtState[5]; - register WebRtc_Word32 state6 = filtState[6]; - register WebRtc_Word32 state7 = filtState[7]; + register int32_t state0 = filtState[0]; + register int32_t state1 = filtState[1]; + register int32_t state2 = filtState[2]; + register int32_t state3 = filtState[3]; + register int32_t state4 = filtState[4]; + register int32_t state5 = filtState[5]; + register int32_t state6 = filtState[6]; + register int32_t state7 = filtState[7]; for (i = (len >> 1); i > 0; i--) { // lower allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; + in32 = (int32_t)(*in++) << 10; diff = in32 - state1; tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); state0 = in32; @@ -94,7 +95,7 @@ void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, state2 = tmp2; // upper allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; + in32 = (int32_t)(*in++) << 10; diff = in32 - state5; tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); state4 = in32; @@ -121,25 +122,26 @@ void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, filtState[6] = state6; filtState[7] = state7; } +#endif // #if defined(MIPS32_LE) -void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, - WebRtc_Word16* out, WebRtc_Word32* filtState) { - WebRtc_Word32 tmp1, tmp2, diff, in32, out32; - WebRtc_Word16 i; +void WebRtcSpl_UpsampleBy2(const int16_t* in, size_t len, + int16_t* out, int32_t* filtState) { + int32_t tmp1, tmp2, diff, in32, out32; + size_t i; - register WebRtc_Word32 state0 = filtState[0]; - register WebRtc_Word32 state1 = filtState[1]; - register WebRtc_Word32 state2 = filtState[2]; - register WebRtc_Word32 state3 = filtState[3]; - register WebRtc_Word32 state4 = filtState[4]; - register WebRtc_Word32 state5 = filtState[5]; - register WebRtc_Word32 state6 = filtState[6]; - register WebRtc_Word32 state7 = filtState[7]; + register int32_t state0 = filtState[0]; + register int32_t state1 = filtState[1]; + register int32_t state2 = filtState[2]; + register int32_t state3 = filtState[3]; + register int32_t state4 = filtState[4]; + register int32_t state5 = filtState[5]; + register int32_t state6 = filtState[6]; + register int32_t state7 = filtState[7]; for (i = len; i > 0; i--) { // lower allpass filter - in32 = (WebRtc_Word32)(*in++) << 10; + in32 = (int32_t)(*in++) << 10; diff = in32 - state1; tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state0); state0 = in32; diff --git a/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.c b/webrtc/common_audio/signal_processing/resample_by_2_internal.c similarity index 83% rename from src/common_audio/signal_processing_library/main/source/resample_by_2_internal.c rename to webrtc/common_audio/signal_processing/resample_by_2_internal.c index cbd2395..085069c 100644 --- a/src/common_audio/signal_processing_library/main/source/resample_by_2_internal.c +++ b/webrtc/common_audio/signal_processing/resample_by_2_internal.c @@ -14,25 +14,25 @@ * */ -#include "resample_by_2_internal.h" +#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h" // allpass filter coefficients. -static const WebRtc_Word16 kResampleAllpass[2][3] = { +static const int16_t kResampleAllpass[2][3] = { {821, 6110, 12382}, {3050, 9368, 15063} }; // // decimator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN! -// output: WebRtc_Word16 (saturated) (of length len/2) +// input: int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTEN! +// output: int16_t (saturated) (of length len/2) // state: filter state array; length = 8 -void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state) +void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out, + int32_t *state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; len >>= 1; @@ -102,39 +102,39 @@ void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Wo // divide by two, add both allpass outputs and round tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15; tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15; - if (tmp0 > (WebRtc_Word32)0x00007FFF) + if (tmp0 > (int32_t)0x00007FFF) tmp0 = 0x00007FFF; - if (tmp0 < (WebRtc_Word32)0xFFFF8000) + if (tmp0 < (int32_t)0xFFFF8000) tmp0 = 0xFFFF8000; - out[i] = (WebRtc_Word16)tmp0; - if (tmp1 > (WebRtc_Word32)0x00007FFF) + out[i] = (int16_t)tmp0; + if (tmp1 > (int32_t)0x00007FFF) tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) + if (tmp1 < (int32_t)0xFFFF8000) tmp1 = 0xFFFF8000; - out[i + 1] = (WebRtc_Word16)tmp1; + out[i + 1] = (int16_t)tmp1; } } // // decimator -// input: WebRtc_Word16 -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2) +// input: int16_t +// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len/2) // state: filter state array; length = 8 -void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, - WebRtc_Word32 len, - WebRtc_Word32 *out, - WebRtc_Word32 *state) +void WebRtcSpl_DownBy2ShortToInt(const int16_t *in, + int32_t len, + int32_t *out, + int32_t *state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; len >>= 1; // lower allpass filter (operates on even input samples) for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); diff = tmp0 - state[1]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -164,7 +164,7 @@ void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, // upper allpass filter (operates on odd input samples) for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); diff = tmp0 - state[5]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -194,19 +194,19 @@ void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, // // interpolator -// input: WebRtc_Word16 -// output: WebRtc_Word32 (normalized, not saturated) (of length len*2) +// input: int16_t +// output: int32_t (normalized, not saturated) (of length len*2) // state: filter state array; length = 8 -void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state) +void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, int32_t *out, + int32_t *state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; // upper allpass filter (generates odd output samples) for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i] << 15) + (1 << 14); diff = tmp0 - state[5]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -236,7 +236,7 @@ void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRt // lower allpass filter (generates even output samples) for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i] << 15) + (1 << 14); diff = tmp0 - state[1]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -264,14 +264,14 @@ void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRt // // interpolator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2) +// input: int32_t (shifted 15 positions to the left, + offset 16384) +// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len*2) // state: filter state array; length = 8 -void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, - WebRtc_Word32 *state) +void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out, + int32_t *state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; // upper allpass filter (generates odd output samples) for (i = 0; i < len; i++) @@ -334,14 +334,14 @@ void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_ // // interpolator -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word16 (saturated) (of length len*2) +// input: int32_t (shifted 15 positions to the left, + offset 16384) +// output: int16_t (saturated) (of length len*2) // state: filter state array; length = 8 -void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, - WebRtc_Word32 *state) +void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, int16_t *out, + int32_t *state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; // upper allpass filter (generates odd output samples) for (i = 0; i < len; i++) @@ -369,11 +369,11 @@ void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRt // scale down, saturate and store tmp1 = state[7] >> 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) + if (tmp1 > (int32_t)0x00007FFF) tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) + if (tmp1 < (int32_t)0xFFFF8000) tmp1 = 0xFFFF8000; - out[i << 1] = (WebRtc_Word16)tmp1; + out[i << 1] = (int16_t)tmp1; } out++; @@ -404,23 +404,23 @@ void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRt // scale down, saturate and store tmp1 = state[3] >> 15; - if (tmp1 > (WebRtc_Word32)0x00007FFF) + if (tmp1 > (int32_t)0x00007FFF) tmp1 = 0x00007FFF; - if (tmp1 < (WebRtc_Word32)0xFFFF8000) + if (tmp1 < (int32_t)0xFFFF8000) tmp1 = 0xFFFF8000; - out[i << 1] = (WebRtc_Word16)tmp1; + out[i << 1] = (int16_t)tmp1; } } // lowpass filter -// input: WebRtc_Word16 -// output: WebRtc_Word32 (normalized, not saturated) +// input: int16_t +// output: int32_t (normalized, not saturated) // state: filter state array; length = 8 -void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state) +void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, int32_t* out, + int32_t* state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; len >>= 1; @@ -452,14 +452,14 @@ void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRt // scale down, round and store out[i << 1] = state[3] >> 1; - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); } in--; // upper allpass filter: even input -> even output samples for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); diff = tmp0 - state[5]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -490,7 +490,7 @@ void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRt // lower allpass filter: even input -> odd output samples for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); diff = tmp0 - state[9]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -519,7 +519,7 @@ void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRt in++; for (i = 0; i < len; i++) { - tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); diff = tmp0 - state[13]; // scale down and round diff = (diff + (1 << 13)) >> 14; @@ -546,14 +546,14 @@ void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRt } // lowpass filter -// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) -// output: WebRtc_Word32 (normalized, not saturated) +// input: int32_t (shifted 15 positions to the left, + offset 16384) +// output: int32_t (normalized, not saturated) // state: filter state array; length = 8 -void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, - WebRtc_Word32* state) +void WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out, + int32_t* state) { - WebRtc_Word32 tmp0, tmp1, diff; - WebRtc_Word32 i; + int32_t tmp0, tmp1, diff; + int32_t i; len >>= 1; diff --git a/webrtc/common_audio/signal_processing/resample_by_2_internal.h b/webrtc/common_audio/signal_processing/resample_by_2_internal.h new file mode 100644 index 0000000..5c9533e --- /dev/null +++ b/webrtc/common_audio/signal_processing/resample_by_2_internal.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file contains some internal resampling functions. + * + */ + +#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ +#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ + +#include "webrtc/typedefs.h" + +/******************************************************************* + * resample_by_2_fast.c + * Functions for internal use in the other resample functions + ******************************************************************/ +void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out, + int32_t *state); + +void WebRtcSpl_DownBy2ShortToInt(const int16_t *in, int32_t len, + int32_t *out, int32_t *state); + +void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, + int32_t *out, int32_t *state); + +void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out, + int32_t *state); + +void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, + int16_t *out, int32_t *state); + +void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, + int32_t* out, int32_t* state); + +void WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out, + int32_t* state); + +#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ diff --git a/webrtc/common_audio/signal_processing/resample_by_2_mips.c b/webrtc/common_audio/signal_processing/resample_by_2_mips.c new file mode 100644 index 0000000..ec5fc8b --- /dev/null +++ b/webrtc/common_audio/signal_processing/resample_by_2_mips.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the resampling by two functions. + * The description header can be found in signal_processing_library.h + * + */ + +#if defined(MIPS32_LE) + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// allpass filter coefficients. +static const uint16_t kResampleAllpass1[3] = {3284, 24441, 49528}; +static const uint16_t kResampleAllpass2[3] = {12199, 37471, 60255}; + +// Multiply a 32-bit value with a 16-bit value and accumulate to another input: +#define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) +#define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c) + +// decimator +void WebRtcSpl_DownsampleBy2(const int16_t* in, + size_t len, + int16_t* out, + int32_t* filtState) { + int32_t out32; + size_t i, len1; + + register int32_t state0 = filtState[0]; + register int32_t state1 = filtState[1]; + register int32_t state2 = filtState[2]; + register int32_t state3 = filtState[3]; + register int32_t state4 = filtState[4]; + register int32_t state5 = filtState[5]; + register int32_t state6 = filtState[6]; + register int32_t state7 = filtState[7]; + +#if defined(MIPS_DSP_R2_LE) + int32_t k1Res0, k1Res1, k1Res2, k2Res0, k2Res1, k2Res2; + + k1Res0= 3284; + k1Res1= 24441; + k1Res2= 49528; + k2Res0= 12199; + k2Res1= 37471; + k2Res2= 60255; + len1 = (len >> 1); + + const int32_t* inw = (int32_t*)in; + int32_t tmp11, tmp12, tmp21, tmp22; + int32_t in322, in321; + int32_t diff1, diff2; + for (i = len1; i > 0; i--) { + __asm__ volatile ( + "lh %[in321], 0(%[inw]) \n\t" + "lh %[in322], 2(%[inw]) \n\t" + + "sll %[in321], %[in321], 10 \n\t" + "sll %[in322], %[in322], 10 \n\t" + + "addiu %[inw], %[inw], 4 \n\t" + + "subu %[diff1], %[in321], %[state1] \n\t" + "subu %[diff2], %[in322], %[state5] \n\t" + + : [in322] "=&r" (in322), [in321] "=&r" (in321), + [diff1] "=&r" (diff1), [diff2] "=r" (diff2), [inw] "+r" (inw) + : [state1] "r" (state1), [state5] "r" (state5) + : "memory" + ); + + __asm__ volatile ( + "mult $ac0, %[diff1], %[k2Res0] \n\t" + "mult $ac1, %[diff2], %[k1Res0] \n\t" + + "extr.w %[tmp11], $ac0, 16 \n\t" + "extr.w %[tmp12], $ac1, 16 \n\t" + + "addu %[tmp11], %[state0], %[tmp11] \n\t" + "addu %[tmp12], %[state4], %[tmp12] \n\t" + + "addiu %[state0], %[in321], 0 \n\t" + "addiu %[state4], %[in322], 0 \n\t" + + "subu %[diff1], %[tmp11], %[state2] \n\t" + "subu %[diff2], %[tmp12], %[state6] \n\t" + + "mult $ac0, %[diff1], %[k2Res1] \n\t" + "mult $ac1, %[diff2], %[k1Res1] \n\t" + + "extr.w %[tmp21], $ac0, 16 \n\t" + "extr.w %[tmp22], $ac1, 16 \n\t" + + "addu %[tmp21], %[state1], %[tmp21] \n\t" + "addu %[tmp22], %[state5], %[tmp22] \n\t" + + "addiu %[state1], %[tmp11], 0 \n\t" + "addiu %[state5], %[tmp12], 0 \n\t" + : [tmp22] "=r" (tmp22), [tmp21] "=&r" (tmp21), + [tmp11] "=&r" (tmp11), [state0] "+r" (state0), + [state1] "+r" (state1), + [state2] "+r" (state2), + [state4] "+r" (state4), [tmp12] "=&r" (tmp12), + [state6] "+r" (state6), [state5] "+r" (state5) + : [k1Res1] "r" (k1Res1), [k2Res1] "r" (k2Res1), [k2Res0] "r" (k2Res0), + [diff2] "r" (diff2), [diff1] "r" (diff1), [in322] "r" (in322), + [in321] "r" (in321), [k1Res0] "r" (k1Res0) + : "hi", "lo", "$ac1hi", "$ac1lo" + ); + + // upper allpass filter + __asm__ volatile ( + "subu %[diff1], %[tmp21], %[state3] \n\t" + "subu %[diff2], %[tmp22], %[state7] \n\t" + + "mult $ac0, %[diff1], %[k2Res2] \n\t" + "mult $ac1, %[diff2], %[k1Res2] \n\t" + "extr.w %[state3], $ac0, 16 \n\t" + "extr.w %[state7], $ac1, 16 \n\t" + "addu %[state3], %[state2], %[state3] \n\t" + "addu %[state7], %[state6], %[state7] \n\t" + + "addiu %[state2], %[tmp21], 0 \n\t" + "addiu %[state6], %[tmp22], 0 \n\t" + + // add two allpass outputs, divide by two and round + "addu %[out32], %[state3], %[state7] \n\t" + "addiu %[out32], %[out32], 1024 \n\t" + "sra %[out32], %[out32], 11 \n\t" + : [state3] "+r" (state3), [state6] "+r" (state6), + [state2] "+r" (state2), [diff2] "=&r" (diff2), + [out32] "=r" (out32), [diff1] "=&r" (diff1), [state7] "+r" (state7) + : [tmp22] "r" (tmp22), [tmp21] "r" (tmp21), + [k1Res2] "r" (k1Res2), [k2Res2] "r" (k2Res2) + : "hi", "lo", "$ac1hi", "$ac1lo" + ); + + // limit amplitude to prevent wrap-around, and write to output array + *out++ = WebRtcSpl_SatW32ToW16(out32); + } +#else // #if defined(MIPS_DSP_R2_LE) + int32_t tmp1, tmp2, diff; + int32_t in32; + len1 = (len >> 1)/4; + for (i = len1; i > 0; i--) { + // lower allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state1; + tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); + state0 = in32; + diff = tmp1 - state2; + tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1); + state1 = tmp1; + diff = tmp2 - state3; + state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2); + state2 = tmp2; + + // upper allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state5; + tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); + state4 = in32; + diff = tmp1 - state6; + tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5); + state5 = tmp1; + diff = tmp2 - state7; + state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6); + state6 = tmp2; + + // add two allpass outputs, divide by two and round + out32 = (state3 + state7 + 1024) >> 11; + + // limit amplitude to prevent wrap-around, and write to output array + *out++ = WebRtcSpl_SatW32ToW16(out32); + // lower allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state1; + tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); + state0 = in32; + diff = tmp1 - state2; + tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1); + state1 = tmp1; + diff = tmp2 - state3; + state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2); + state2 = tmp2; + + // upper allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state5; + tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); + state4 = in32; + diff = tmp1 - state6; + tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5); + state5 = tmp1; + diff = tmp2 - state7; + state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6); + state6 = tmp2; + + // add two allpass outputs, divide by two and round + out32 = (state3 + state7 + 1024) >> 11; + + // limit amplitude to prevent wrap-around, and write to output array + *out++ = WebRtcSpl_SatW32ToW16(out32); + // lower allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state1; + tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); + state0 = in32; + diff = tmp1 - state2; + tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1); + state1 = tmp1; + diff = tmp2 - state3; + state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2); + state2 = tmp2; + + // upper allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state5; + tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); + state4 = in32; + diff = tmp1 - state6; + tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5); + state5 = tmp1; + diff = tmp2 - state7; + state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6); + state6 = tmp2; + + // add two allpass outputs, divide by two and round + out32 = (state3 + state7 + 1024) >> 11; + + // limit amplitude to prevent wrap-around, and write to output array + *out++ = WebRtcSpl_SatW32ToW16(out32); + // lower allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state1; + tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0); + state0 = in32; + diff = tmp1 - state2; + tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1); + state1 = tmp1; + diff = tmp2 - state3; + state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2); + state2 = tmp2; + + // upper allpass filter + in32 = (int32_t)(*in++) << 10; + diff = in32 - state5; + tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4); + state4 = in32; + diff = tmp1 - state6; + tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5); + state5 = tmp1; + diff = tmp2 - state7; + state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6); + state6 = tmp2; + + // add two allpass outputs, divide by two and round + out32 = (state3 + state7 + 1024) >> 11; + + // limit amplitude to prevent wrap-around, and write to output array + *out++ = WebRtcSpl_SatW32ToW16(out32); + } +#endif // #if defined(MIPS_DSP_R2_LE) + __asm__ volatile ( + "sw %[state0], 0(%[filtState]) \n\t" + "sw %[state1], 4(%[filtState]) \n\t" + "sw %[state2], 8(%[filtState]) \n\t" + "sw %[state3], 12(%[filtState]) \n\t" + "sw %[state4], 16(%[filtState]) \n\t" + "sw %[state5], 20(%[filtState]) \n\t" + "sw %[state6], 24(%[filtState]) \n\t" + "sw %[state7], 28(%[filtState]) \n\t" + : + : [state0] "r" (state0), [state1] "r" (state1), [state2] "r" (state2), + [state3] "r" (state3), [state4] "r" (state4), [state5] "r" (state5), + [state6] "r" (state6), [state7] "r" (state7), [filtState] "r" (filtState) + : "memory" + ); +} + +#endif // #if defined(MIPS32_LE) diff --git a/src/common_audio/signal_processing_library/main/source/resample_fractional.c b/webrtc/common_audio/signal_processing/resample_fractional.c similarity index 80% rename from src/common_audio/signal_processing_library/main/source/resample_fractional.c rename to webrtc/common_audio/signal_processing/resample_fractional.c index 51003d4..6409fba 100644 --- a/src/common_audio/signal_processing_library/main/source/resample_fractional.c +++ b/webrtc/common_audio/signal_processing/resample_fractional.c @@ -15,21 +15,21 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" // interpolation coefficients -static const WebRtc_Word16 kCoefficients48To32[2][8] = { +static const int16_t kCoefficients48To32[2][8] = { {778, -2050, 1087, 23285, 12903, -3783, 441, 222}, {222, 441, -3783, 12903, 23285, 1087, -2050, 778} }; -static const WebRtc_Word16 kCoefficients32To24[3][8] = { +static const int16_t kCoefficients32To24[3][8] = { {767, -2362, 2434, 24406, 10620, -3838, 721, 90}, {386, -381, -2646, 19062, 19062, -2646, -381, 386}, {90, 721, -3838, 10620, 24406, 2434, -2362, 767} }; -static const WebRtc_Word16 kCoefficients44To32[4][9] = { +static const int16_t kCoefficients44To32[4][9] = { {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138}, {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91}, {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53}, @@ -37,20 +37,19 @@ static const WebRtc_Word16 kCoefficients44To32[4][9] = { }; // Resampling ratio: 2/3 -// input: WebRtc_Word32 (normalized, not saturated) :: size 3 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K +// input: int32_t (normalized, not saturated) :: size 3 * K +// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 2 * K // K: number of blocks -void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) +void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K) { ///////////////////////////////////////////////////////////// // Filter operation: // // Perform resampling (3 input samples -> 2 output samples); // process in sub blocks of size 3 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; + int32_t tmp; + size_t m; for (m = 0; m < K; m++) { @@ -83,20 +82,19 @@ void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, } // Resampling ratio: 3/4 -// input: WebRtc_Word32 (normalized, not saturated) :: size 4 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K +// input: int32_t (normalized, not saturated) :: size 4 * K +// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K // K: number of blocks -void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) +void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K) { ///////////////////////////////////////////////////////////// // Filter operation: // // Perform resampling (4 input samples -> 3 output samples); // process in sub blocks of size 4 samples. - WebRtc_Word32 m; - WebRtc_Word32 tmp; + size_t m; + int32_t tmp; for (m = 0; m < K; m++) { @@ -146,13 +144,13 @@ void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, // // compute two inner-products and store them to output array -static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2, - const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1, - WebRtc_Word32 *out2) +static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2, + const int16_t *coef_ptr, int32_t *out1, + int32_t *out2) { - WebRtc_Word32 tmp1 = 16384; - WebRtc_Word32 tmp2 = 16384; - WebRtc_Word16 coef; + int32_t tmp1 = 16384; + int32_t tmp2 = 16384; + int16_t coef; coef = coef_ptr[0]; tmp1 += coef * in1[0]; @@ -192,27 +190,26 @@ static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Wo } // Resampling ratio: 8/11 -// input: WebRtc_Word32 (normalized, not saturated) :: size 11 * K -// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 8 * K +// input: int32_t (normalized, not saturated) :: size 11 * K +// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 8 * K // K: number of blocks -void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, - const WebRtc_Word32 K) +void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K) { ///////////////////////////////////////////////////////////// // Filter operation: // // Perform resampling (11 input samples -> 8 output samples); // process in sub blocks of size 11 samples. - WebRtc_Word32 tmp; - WebRtc_Word32 m; + int32_t tmp; + size_t m; for (m = 0; m < K; m++) { tmp = 1 << 14; // first output sample - Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp; + Out[0] = ((int32_t)In[3] << 15) + tmp; // sum and accumulate filter coefficients and input samples tmp += kCoefficients44To32[3][0] * In[5]; diff --git a/webrtc/common_audio/signal_processing/spl_init.c b/webrtc/common_audio/signal_processing/spl_init.c new file mode 100644 index 0000000..73c2039 --- /dev/null +++ b/webrtc/common_audio/signal_processing/spl_init.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* The global function contained in this file initializes SPL function + * pointers, currently only for ARM platforms. + * + * Some code came from common/rtcd.c in the WebM project. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h" + +/* Declare function pointers. */ +MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16; +MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32; +MaxValueW16 WebRtcSpl_MaxValueW16; +MaxValueW32 WebRtcSpl_MaxValueW32; +MinValueW16 WebRtcSpl_MinValueW16; +MinValueW32 WebRtcSpl_MinValueW32; +CrossCorrelation WebRtcSpl_CrossCorrelation; +DownsampleFast WebRtcSpl_DownsampleFast; +ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound; + +#if (defined(WEBRTC_DETECT_NEON) || !defined(WEBRTC_HAS_NEON)) && \ + !defined(MIPS32_LE) +/* Initialize function pointers to the generic C version. */ +static void InitPointersToC() { + WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C; + WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C; + WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C; + WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C; + WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C; + WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C; + WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC; + WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC; + WebRtcSpl_ScaleAndAddVectorsWithRound = + WebRtcSpl_ScaleAndAddVectorsWithRoundC; +} +#endif + +#if defined(WEBRTC_DETECT_NEON) || defined(WEBRTC_HAS_NEON) +/* Initialize function pointers to the Neon version. */ +static void InitPointersToNeon() { + WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon; + WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon; + WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon; + WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon; + WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon; + WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon; + WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon; + WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon; + WebRtcSpl_ScaleAndAddVectorsWithRound = + WebRtcSpl_ScaleAndAddVectorsWithRoundC; +} +#endif + +#if defined(MIPS32_LE) +/* Initialize function pointers to the MIPS version. */ +static void InitPointersToMIPS() { + WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips; + WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips; + WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips; + WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips; + WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips; + WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips; + WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips; +#if defined(MIPS_DSP_R1_LE) + WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips; + WebRtcSpl_ScaleAndAddVectorsWithRound = + WebRtcSpl_ScaleAndAddVectorsWithRound_mips; +#else + WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C; + WebRtcSpl_ScaleAndAddVectorsWithRound = + WebRtcSpl_ScaleAndAddVectorsWithRoundC; +#endif +} +#endif + +static void InitFunctionPointers(void) { +#if defined(WEBRTC_DETECT_NEON) + if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { + InitPointersToNeon(); + } else { + InitPointersToC(); + } +#elif defined(WEBRTC_HAS_NEON) + InitPointersToNeon(); +#elif defined(MIPS32_LE) + InitPointersToMIPS(); +#else + InitPointersToC(); +#endif /* WEBRTC_DETECT_NEON */ +} + +#if defined(WEBRTC_POSIX) +#include + +static void once(void (*func)(void)) { + static pthread_once_t lock = PTHREAD_ONCE_INIT; + pthread_once(&lock, func); +} + +#elif defined(_WIN32) +#include + +static void once(void (*func)(void)) { + /* Didn't use InitializeCriticalSection() since there's no race-free context + * in which to execute it. + * + * TODO(kma): Change to different implementation (e.g. + * InterlockedCompareExchangePointer) to avoid issues similar to + * http://code.google.com/p/webm/issues/detail?id=467. + */ + static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0}; + static int done = 0; + + EnterCriticalSection(&lock); + if (!done) { + func(); + done = 1; + } + LeaveCriticalSection(&lock); +} + +/* There's no fallback version as an #else block here to ensure thread safety. + * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build + * system should pick it up. + */ +#endif /* WEBRTC_POSIX */ + +void WebRtcSpl_Init() { + once(InitFunctionPointers); +} diff --git a/src/common_audio/signal_processing_library/main/source/spl_sqrt.c b/webrtc/common_audio/signal_processing/spl_sqrt.c similarity index 56% rename from src/common_audio/signal_processing_library/main/source/spl_sqrt.c rename to webrtc/common_audio/signal_processing/spl_sqrt.c index cfe2cd3..24db4f8 100644 --- a/src/common_audio/signal_processing_library/main/source/spl_sqrt.c +++ b/webrtc/common_audio/signal_processing/spl_sqrt.c @@ -15,15 +15,17 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in); +#include -WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in) +int32_t WebRtcSpl_SqrtLocal(int32_t in); + +int32_t WebRtcSpl_SqrtLocal(int32_t in) { - WebRtc_Word16 x_half, t16; - WebRtc_Word32 A, B, x2; + int16_t x_half, t16; + int32_t A, B, x2; /* The following block performs: y=in/2 @@ -33,42 +35,40 @@ WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in) + 0.875*((x_half)^5) */ - B = in; + B = in / 2; - B = WEBRTC_SPL_RSHIFT_W32(B, 1); // B = in/2 - B = B - ((WebRtc_Word32)0x40000000); // B = in/2 - 1/2 - x_half = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(B, 16);// x_half = x/2 = (in-1)/2 - B = B + ((WebRtc_Word32)0x40000000); // B = 1 + x/2 - B = B + ((WebRtc_Word32)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31) + B = B - ((int32_t)0x40000000); // B = in/2 - 1/2 + x_half = (int16_t)(B >> 16); // x_half = x/2 = (in-1)/2 + B = B + ((int32_t)0x40000000); // B = 1 + x/2 + B = B + ((int32_t)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31) - x2 = ((WebRtc_Word32)x_half) * ((WebRtc_Word32)x_half) * 2; // A = (x/2)^2 + x2 = ((int32_t)x_half) * ((int32_t)x_half) * 2; // A = (x/2)^2 A = -x2; // A = -(x/2)^2 B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2 - A = WEBRTC_SPL_RSHIFT_W32(A, 16); + A >>= 16; A = A * A * 2; // A = (x/2)^4 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A + t16 = (int16_t)(A >> 16); + B += -20480 * t16 * 2; // B = B - 0.625*A // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); - B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A + A = x_half * t16 * 2; // A = (x/2)^5 + t16 = (int16_t)(A >> 16); + B += 28672 * t16 * 2; // B = B + 0.875*A // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5 - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(x2, 16); - A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3 + t16 = (int16_t)(x2 >> 16); + A = x_half * t16 * 2; // A = x/2^3 B = B + (A >> 1); // B = B + 0.5*A // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5 - B = B + ((WebRtc_Word32)32768); // Round off bit + B = B + ((int32_t)32768); // Round off bit return B; } -WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value) +int32_t WebRtcSpl_Sqrt(int32_t value) { /* Algorithm: @@ -132,53 +132,53 @@ WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value) */ - WebRtc_Word16 x_norm, nshift, t16, sh; - WebRtc_Word32 A; + int16_t x_norm, nshift, t16, sh; + int32_t A; - WebRtc_Word16 k_sqrt_2 = 23170; // 1/sqrt2 (==5a82) + int16_t k_sqrt_2 = 23170; // 1/sqrt2 (==5a82) A = value; if (A == 0) - return (WebRtc_Word32)0; // sqrt(0) = 0 + return (int32_t)0; // sqrt(0) = 0 sh = WebRtcSpl_NormW32(A); // # shifts to normalize A A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A if (A < (WEBRTC_SPL_WORD32_MAX - 32767)) { - A = A + ((WebRtc_Word32)32768); // Round off bit + A = A + ((int32_t)32768); // Round off bit } else { A = WEBRTC_SPL_WORD32_MAX; } - x_norm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // x_norm = AH + x_norm = (int16_t)(A >> 16); // x_norm = AH - nshift = WEBRTC_SPL_RSHIFT_W16(sh, 1); // nshift = sh>>1 - nshift = -nshift; // Negate the power for later de-normalization + nshift = (sh / 2); + assert(nshift >= 0); - A = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x_norm, 16); + A = (int32_t)WEBRTC_SPL_LSHIFT_W32((int32_t)x_norm, 16); A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16) A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A) - if ((-2 * nshift) == sh) - { // Even shift value case + if (2 * nshift == sh) { + // Even shift value case - t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // t16 = AH + t16 = (int16_t)(A >> 16); // t16 = AH - A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16 - A = A + ((WebRtc_Word32)32768); // Round off - A = A & ((WebRtc_Word32)0x7fff0000); // Round off + A = k_sqrt_2 * t16 * 2; // A = 1/sqrt(2)*t16 + A = A + ((int32_t)32768); // Round off + A = A & ((int32_t)0x7fff0000); // Round off - A = WEBRTC_SPL_RSHIFT_W32(A, 15); // A = A>>16 + A >>= 15; // A = A>>16 } else { - A = WEBRTC_SPL_RSHIFT_W32(A, 16); // A = A>>16 + A >>= 16; // A = A>>16 } - A = A & ((WebRtc_Word32)0x0000ffff); - A = (WebRtc_Word32)WEBRTC_SPL_SHIFT_W32(A, nshift); // De-normalize the result + A = A & ((int32_t)0x0000ffff); + A >>= nshift; // De-normalize the result. return A; } diff --git a/webrtc/common_audio/signal_processing/spl_sqrt_floor.c b/webrtc/common_audio/signal_processing/spl_sqrt_floor.c new file mode 100644 index 0000000..370307a --- /dev/null +++ b/webrtc/common_audio/signal_processing/spl_sqrt_floor.c @@ -0,0 +1,77 @@ +/* + * Written by Wilco Dijkstra, 1996. The following email exchange establishes the + * license. + * + * From: Wilco Dijkstra + * Date: Fri, Jun 24, 2011 at 3:20 AM + * Subject: Re: sqrt routine + * To: Kevin Ma + * Hi Kevin, + * Thanks for asking. Those routines are public domain (originally posted to + * comp.sys.arm a long time ago), so you can use them freely for any purpose. + * Cheers, + * Wilco + * + * ----- Original Message ----- + * From: "Kevin Ma" + * To: + * Sent: Thursday, June 23, 2011 11:44 PM + * Subject: Fwd: sqrt routine + * Hi Wilco, + * I saw your sqrt routine from several web sites, including + * http://www.finesse.demon.co.uk/steven/sqrt.html. + * Just wonder if there's any copyright information with your Successive + * approximation routines, or if I can freely use it for any purpose. + * Thanks. + * Kevin + */ + +// Minor modifications in code style for WebRTC, 2012. + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +/* + * Algorithm: + * Successive approximation of the equation (root + delta) ^ 2 = N + * until delta < 1. If delta < 1 we have the integer part of SQRT (N). + * Use delta = 2^i for i = 15 .. 0. + * + * Output precision is 16 bits. Note for large input values (close to + * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word) + * contains the MSB information (a non-sign value). Do with caution + * if you need to cast the output to int16_t type. + * + * If the input value is negative, it returns 0. + */ + +#define WEBRTC_SPL_SQRT_ITER(N) \ + try1 = root + (1 << (N)); \ + if (value >= try1 << (N)) \ + { \ + value -= try1 << (N); \ + root |= 2 << (N); \ + } + +int32_t WebRtcSpl_SqrtFloor(int32_t value) +{ + int32_t root = 0, try1; + + WEBRTC_SPL_SQRT_ITER (15); + WEBRTC_SPL_SQRT_ITER (14); + WEBRTC_SPL_SQRT_ITER (13); + WEBRTC_SPL_SQRT_ITER (12); + WEBRTC_SPL_SQRT_ITER (11); + WEBRTC_SPL_SQRT_ITER (10); + WEBRTC_SPL_SQRT_ITER ( 9); + WEBRTC_SPL_SQRT_ITER ( 8); + WEBRTC_SPL_SQRT_ITER ( 7); + WEBRTC_SPL_SQRT_ITER ( 6); + WEBRTC_SPL_SQRT_ITER ( 5); + WEBRTC_SPL_SQRT_ITER ( 4); + WEBRTC_SPL_SQRT_ITER ( 3); + WEBRTC_SPL_SQRT_ITER ( 2); + WEBRTC_SPL_SQRT_ITER ( 1); + WEBRTC_SPL_SQRT_ITER ( 0); + + return root >> 1; +} diff --git a/webrtc/common_audio/signal_processing/spl_sqrt_floor_arm.S b/webrtc/common_audio/signal_processing/spl_sqrt_floor_arm.S new file mode 100644 index 0000000..f44ddd4 --- /dev/null +++ b/webrtc/common_audio/signal_processing/spl_sqrt_floor_arm.S @@ -0,0 +1,110 @@ +@ +@ Written by Wilco Dijkstra, 1996. The following email exchange establishes the +@ license. +@ +@ From: Wilco Dijkstra +@ Date: Fri, Jun 24, 2011 at 3:20 AM +@ Subject: Re: sqrt routine +@ To: Kevin Ma +@ Hi Kevin, +@ Thanks for asking. Those routines are public domain (originally posted to +@ comp.sys.arm a long time ago), so you can use them freely for any purpose. +@ Cheers, +@ Wilco +@ +@ ----- Original Message ----- +@ From: "Kevin Ma" +@ To: +@ Sent: Thursday, June 23, 2011 11:44 PM +@ Subject: Fwd: sqrt routine +@ Hi Wilco, +@ I saw your sqrt routine from several web sites, including +@ http://www.finesse.demon.co.uk/steven/sqrt.html. +@ Just wonder if there's any copyright information with your Successive +@ approximation routines, or if I can freely use it for any purpose. +@ Thanks. +@ Kevin + +@ Minor modifications in code style for WebRTC, 2012. +@ Output is bit-exact with the reference C code in spl_sqrt_floor.c. + +@ Input : r0 32 bit unsigned integer +@ Output: r0 = INT (SQRT (r0)), precision is 16 bits +@ Registers touched: r1, r2 + +#include "webrtc/system_wrappers/interface/asm_defines.h" + +GLOBAL_FUNCTION WebRtcSpl_SqrtFloor +.align 2 +DEFINE_FUNCTION WebRtcSpl_SqrtFloor + mov r1, #3 << 30 + mov r2, #1 << 30 + + @ unroll for i = 0 .. 15 + + cmp r0, r2, ror #2 * 0 + subhs r0, r0, r2, ror #2 * 0 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 1 + subhs r0, r0, r2, ror #2 * 1 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 2 + subhs r0, r0, r2, ror #2 * 2 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 3 + subhs r0, r0, r2, ror #2 * 3 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 4 + subhs r0, r0, r2, ror #2 * 4 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 5 + subhs r0, r0, r2, ror #2 * 5 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 6 + subhs r0, r0, r2, ror #2 * 6 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 7 + subhs r0, r0, r2, ror #2 * 7 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 8 + subhs r0, r0, r2, ror #2 * 8 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 9 + subhs r0, r0, r2, ror #2 * 9 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 10 + subhs r0, r0, r2, ror #2 * 10 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 11 + subhs r0, r0, r2, ror #2 * 11 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 12 + subhs r0, r0, r2, ror #2 * 12 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 13 + subhs r0, r0, r2, ror #2 * 13 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 14 + subhs r0, r0, r2, ror #2 * 14 + adc r2, r1, r2, lsl #1 + + cmp r0, r2, ror #2 * 15 + subhs r0, r0, r2, ror #2 * 15 + adc r2, r1, r2, lsl #1 + + bic r0, r2, #3 << 30 @ for rounding add: cmp r0, r2 adc r2, #1 + bx lr diff --git a/webrtc/common_audio/signal_processing/spl_sqrt_floor_mips.c b/webrtc/common_audio/signal_processing/spl_sqrt_floor_mips.c new file mode 100644 index 0000000..8716459 --- /dev/null +++ b/webrtc/common_audio/signal_processing/spl_sqrt_floor_mips.c @@ -0,0 +1,207 @@ +/* + * Written by Wilco Dijkstra, 1996. The following email exchange establishes the + * license. + * + * From: Wilco Dijkstra + * Date: Fri, Jun 24, 2011 at 3:20 AM + * Subject: Re: sqrt routine + * To: Kevin Ma + * Hi Kevin, + * Thanks for asking. Those routines are public domain (originally posted to + * comp.sys.arm a long time ago), so you can use them freely for any purpose. + * Cheers, + * Wilco + * + * ----- Original Message ----- + * From: "Kevin Ma" + * To: + * Sent: Thursday, June 23, 2011 11:44 PM + * Subject: Fwd: sqrt routine + * Hi Wilco, + * I saw your sqrt routine from several web sites, including + * http://www.finesse.demon.co.uk/steven/sqrt.html. + * Just wonder if there's any copyright information with your Successive + * approximation routines, or if I can freely use it for any purpose. + * Thanks. + * Kevin + */ + +// Minor modifications in code style for WebRTC, 2012. +// Code optimizations for MIPS, 2013. + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +/* + * Algorithm: + * Successive approximation of the equation (root + delta) ^ 2 = N + * until delta < 1. If delta < 1 we have the integer part of SQRT (N). + * Use delta = 2^i for i = 15 .. 0. + * + * Output precision is 16 bits. Note for large input values (close to + * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word) + * contains the MSB information (a non-sign value). Do with caution + * if you need to cast the output to int16_t type. + * + * If the input value is negative, it returns 0. + */ + + +int32_t WebRtcSpl_SqrtFloor(int32_t value) +{ + int32_t root = 0, tmp1, tmp2, tmp3, tmp4; + + __asm __volatile( + ".set push \n\t" + ".set noreorder \n\t" + + "lui %[tmp1], 0x4000 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "sub %[tmp3], %[value], %[tmp1] \n\t" + "lui %[tmp1], 0x1 \n\t" + "or %[tmp4], %[root], %[tmp1] \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x4000 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 14 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x8000 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x2000 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 13 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x4000 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x1000 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 12 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x2000 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x800 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 11 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x1000 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x400 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 10 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x800 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x200 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 9 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x400 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x100 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 8 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x200 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x80 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 7 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x100 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x40 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 6 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x80 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x20 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 5 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x40 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x10 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 4 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x20 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x8 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 3 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x10 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x4 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 2 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x8 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x2 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "sll %[tmp1], 1 \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "subu %[tmp3], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x4 \n\t" + "movz %[value], %[tmp3], %[tmp2] \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + "addiu %[tmp1], $0, 0x1 \n\t" + "addu %[tmp1], %[tmp1], %[root] \n\t" + "slt %[tmp2], %[value], %[tmp1] \n\t" + "ori %[tmp4], %[root], 0x2 \n\t" + "movz %[root], %[tmp4], %[tmp2] \n\t" + + ".set pop \n\t" + + : [root] "+r" (root), [value] "+r" (value), + [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), + [tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4) + : + ); + + return root >> 1; +} + diff --git a/src/common_audio/signal_processing_library/main/source/splitting_filter.c b/webrtc/common_audio/signal_processing/splitting_filter.c similarity index 60% rename from src/common_audio/signal_processing_library/main/source/splitting_filter.c rename to webrtc/common_audio/signal_processing/splitting_filter.c index f1acf67..36fcf35 100644 --- a/src/common_audio/signal_processing_library/main/source/splitting_filter.c +++ b/webrtc/common_audio/signal_processing/splitting_filter.c @@ -13,17 +13,19 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -// Number of samples in a low/high-band frame. +#include + +// Maximum number of samples in a low/high-band frame. enum { - kBandFrameLength = 160 + kMaxBandFrameLength = 320 // 10 ms at 64 kHz. }; // QMF filter coefficients in Q16. -static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; -static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; +static const uint16_t WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; +static const uint16_t WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; /////////////////////////////////////////////////////////////////////////////////////////////// // WebRtcSpl_AllPassQMF(...) @@ -43,9 +45,9 @@ static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010} // |data_length| // -void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length, - WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients, - WebRtc_Word32* filter_state) +void WebRtcSpl_AllPassQMF(int32_t* in_data, size_t data_length, + int32_t* out_data, const uint16_t* filter_coefficients, + int32_t* filter_state) { // The procedure is to filter the input with three first order all pass filters // (cascade operations). @@ -63,8 +65,8 @@ void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_lengt // filter operation takes the |in_data| (which is the output from the previous cascade // filter) and store the output in |out_data|. // Note that the input vector values are changed during the process. - WebRtc_Word16 k; - WebRtc_Word32 diff; + size_t k; + int32_t diff; // First all-pass cascade; filter from in_data to out_data. // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at @@ -72,14 +74,16 @@ void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_lengt // First loop, use the states stored in memory. // "diff" should be safe from wrap around since max values are 2^25 - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1]) + // diff = (x[0] - y_1[-1]) + diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]); // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1]) out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]); // For the remaining loops, use previous values. for (k = 1; k < data_length; k++) { - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1]) + // diff = (x[n] - y_1[n-1]) + diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1]) out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]); } @@ -89,12 +93,14 @@ void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_lengt filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time // Second all-pass cascade; filter from out_data to in_data. - diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1]) + // diff = (y_1[0] - y_2[-1]) + diff = WebRtcSpl_SubSatW32(out_data[0], filter_state[3]); // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]); for (k = 1; k < data_length; k++) { - diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1]) + // diff = (y_1[n] - y_2[n-1]) + diff = WebRtcSpl_SubSatW32(out_data[k], in_data[k - 1]); // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]); } @@ -103,12 +109,14 @@ void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_lengt filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time // Third all-pass cascade; filter from in_data to out_data. - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1]) + // diff = (y_2[0] - y[-1]) + diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[5]); // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1]) out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]); for (k = 1; k < data_length; k++) { - diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1]) + // diff = (y_2[n] - y[n-1]) + diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]); } @@ -116,82 +124,84 @@ void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_lengt filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time } -void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band, - WebRtc_Word16* high_band, WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2) +void WebRtcSpl_AnalysisQMF(const int16_t* in_data, size_t in_data_length, + int16_t* low_band, int16_t* high_band, + int32_t* filter_state1, int32_t* filter_state2) { - WebRtc_Word16 i; - WebRtc_Word16 k; - WebRtc_Word32 tmp; - WebRtc_Word32 half_in1[kBandFrameLength]; - WebRtc_Word32 half_in2[kBandFrameLength]; - WebRtc_Word32 filter1[kBandFrameLength]; - WebRtc_Word32 filter2[kBandFrameLength]; + size_t i; + int16_t k; + int32_t tmp; + int32_t half_in1[kMaxBandFrameLength]; + int32_t half_in2[kMaxBandFrameLength]; + int32_t filter1[kMaxBandFrameLength]; + int32_t filter2[kMaxBandFrameLength]; + const size_t band_length = in_data_length / 2; + assert(in_data_length % 2 == 0); + assert(band_length <= kMaxBandFrameLength); // Split even and odd samples. Also shift them to Q10. - for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2) + for (i = 0, k = 0; i < band_length; i++, k += 2) { - half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10); - half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10); + half_in2[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k], 10); + half_in1[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k + 1], 10); } // All pass filter even and odd samples, independently. - WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1, - filter_state1); - WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2, - filter_state2); + WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, + WebRtcSpl_kAllPassFilter1, filter_state1); + WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, + WebRtcSpl_kAllPassFilter2, filter_state2); // Take the sum and difference of filtered version of odd and even // branches to get upper & lower band. - for (i = 0; i < kBandFrameLength; i++) + for (i = 0; i < band_length; i++) { - tmp = filter1[i] + filter2[i] + 1024; - tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); + tmp = (filter1[i] + filter2[i] + 1024) >> 11; low_band[i] = WebRtcSpl_SatW32ToW16(tmp); - tmp = filter1[i] - filter2[i] + 1024; - tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); + tmp = (filter1[i] - filter2[i] + 1024) >> 11; high_band[i] = WebRtcSpl_SatW32ToW16(tmp); } } -void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band, - WebRtc_Word16* out_data, WebRtc_Word32* filter_state1, - WebRtc_Word32* filter_state2) +void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band, + size_t band_length, int16_t* out_data, + int32_t* filter_state1, int32_t* filter_state2) { - WebRtc_Word32 tmp; - WebRtc_Word32 half_in1[kBandFrameLength]; - WebRtc_Word32 half_in2[kBandFrameLength]; - WebRtc_Word32 filter1[kBandFrameLength]; - WebRtc_Word32 filter2[kBandFrameLength]; - WebRtc_Word16 i; - WebRtc_Word16 k; + int32_t tmp; + int32_t half_in1[kMaxBandFrameLength]; + int32_t half_in2[kMaxBandFrameLength]; + int32_t filter1[kMaxBandFrameLength]; + int32_t filter2[kMaxBandFrameLength]; + size_t i; + int16_t k; + assert(band_length <= kMaxBandFrameLength); // Obtain the sum and difference channels out of upper and lower-band channels. // Also shift to Q10 domain. - for (i = 0; i < kBandFrameLength; i++) + for (i = 0; i < band_length; i++) { - tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i]; + tmp = (int32_t)low_band[i] + (int32_t)high_band[i]; half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); - tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i]; + tmp = (int32_t)low_band[i] - (int32_t)high_band[i]; half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); } // all-pass filter the sum and difference channels - WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2, - filter_state1); - WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1, - filter_state2); + WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, + WebRtcSpl_kAllPassFilter2, filter_state1); + WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, + WebRtcSpl_kAllPassFilter1, filter_state2); // The filtered signals are even and odd samples of the output. Combine // them. The signals are Q10 should shift them back to Q0 and take care of // saturation. - for (i = 0, k = 0; i < kBandFrameLength; i++) + for (i = 0, k = 0; i < band_length; i++) { - tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10); + tmp = (filter2[i] + 512) >> 10; out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); - tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10); + tmp = (filter1[i] + 512) >> 10; out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); } diff --git a/src/common_audio/signal_processing_library/main/source/sqrt_of_one_minus_x_squared.c b/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c similarity index 70% rename from src/common_audio/signal_processing_library/main/source/sqrt_of_one_minus_x_squared.c rename to webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c index 9fb2c73..ff78b52 100644 --- a/src/common_audio/signal_processing_library/main/source/sqrt_of_one_minus_x_squared.c +++ b/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c @@ -15,21 +15,21 @@ * */ -#include "signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16 *xQ15, int vector_length, - WebRtc_Word16 *yQ15) +void WebRtcSpl_SqrtOfOneMinusXSquared(int16_t *xQ15, size_t vector_length, + int16_t *yQ15) { - WebRtc_Word32 sq; - int m; - WebRtc_Word16 tmp; + int32_t sq; + size_t m; + int16_t tmp; for (m = 0; m < vector_length; m++) { tmp = xQ15[m]; - sq = WEBRTC_SPL_MUL_16_16(tmp, tmp); // x^2 in Q30 + sq = tmp * tmp; // x^2 in Q30 sq = 1073741823 - sq; // 1-x^2, where 1 ~= 0.99999999906 is 1073741823 in Q30 sq = WebRtcSpl_Sqrt(sq); // sqrt(1-x^2) in Q15 - yQ15[m] = (WebRtc_Word16)sq; + yQ15[m] = (int16_t)sq; } } diff --git a/webrtc/common_audio/signal_processing/vector_scaling_operations.c b/webrtc/common_audio/signal_processing/vector_scaling_operations.c new file mode 100644 index 0000000..fdefd06 --- /dev/null +++ b/webrtc/common_audio/signal_processing/vector_scaling_operations.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the functions + * WebRtcSpl_VectorBitShiftW16() + * WebRtcSpl_VectorBitShiftW32() + * WebRtcSpl_VectorBitShiftW32ToW16() + * WebRtcSpl_ScaleVector() + * WebRtcSpl_ScaleVectorWithSat() + * WebRtcSpl_ScaleAndAddVectors() + * WebRtcSpl_ScaleAndAddVectorsWithRoundC() + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +void WebRtcSpl_VectorBitShiftW16(int16_t *res, size_t length, + const int16_t *in, int16_t right_shifts) +{ + size_t i; + + if (right_shifts > 0) + { + for (i = length; i > 0; i--) + { + (*res++) = ((*in++) >> right_shifts); + } + } else + { + for (i = length; i > 0; i--) + { + (*res++) = ((*in++) << (-right_shifts)); + } + } +} + +void WebRtcSpl_VectorBitShiftW32(int32_t *out_vector, + size_t vector_length, + const int32_t *in_vector, + int16_t right_shifts) +{ + size_t i; + + if (right_shifts > 0) + { + for (i = vector_length; i > 0; i--) + { + (*out_vector++) = ((*in_vector++) >> right_shifts); + } + } else + { + for (i = vector_length; i > 0; i--) + { + (*out_vector++) = ((*in_vector++) << (-right_shifts)); + } + } +} + +void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out, size_t length, + const int32_t* in, int right_shifts) { + size_t i; + int32_t tmp_w32; + + if (right_shifts >= 0) { + for (i = length; i > 0; i--) { + tmp_w32 = (*in++) >> right_shifts; + (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32); + } + } else { + int left_shifts = -right_shifts; + for (i = length; i > 0; i--) { + tmp_w32 = (*in++) << left_shifts; + (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32); + } + } +} + +void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector, + int16_t gain, size_t in_vector_length, + int16_t right_shifts) +{ + // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts + size_t i; + const int16_t *inptr; + int16_t *outptr; + + inptr = in_vector; + outptr = out_vector; + + for (i = 0; i < in_vector_length; i++) + { + *outptr++ = (int16_t)((*inptr++ * gain) >> right_shifts); + } +} + +void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector, + int16_t gain, size_t in_vector_length, + int16_t right_shifts) +{ + // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts + size_t i; + const int16_t *inptr; + int16_t *outptr; + + inptr = in_vector; + outptr = out_vector; + + for (i = 0; i < in_vector_length; i++) { + *outptr++ = WebRtcSpl_SatW32ToW16((*inptr++ * gain) >> right_shifts); + } +} + +void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1, + const int16_t *in2, int16_t gain2, int shift2, + int16_t *out, size_t vector_length) +{ + // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2 + size_t i; + const int16_t *in1ptr; + const int16_t *in2ptr; + int16_t *outptr; + + in1ptr = in1; + in2ptr = in2; + outptr = out; + + for (i = 0; i < vector_length; i++) + { + *outptr++ = (int16_t)((gain1 * *in1ptr++) >> shift1) + + (int16_t)((gain2 * *in2ptr++) >> shift2); + } +} + +// C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms. +int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1, + int16_t in_vector1_scale, + const int16_t* in_vector2, + int16_t in_vector2_scale, + int right_shifts, + int16_t* out_vector, + size_t length) { + size_t i = 0; + int round_value = (1 << right_shifts) >> 1; + + if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL || + length == 0 || right_shifts < 0) { + return -1; + } + + for (i = 0; i < length; i++) { + out_vector[i] = (int16_t)(( + in_vector1[i] * in_vector1_scale + in_vector2[i] * in_vector2_scale + + round_value) >> right_shifts); + } + + return 0; +} diff --git a/webrtc/common_audio/signal_processing/vector_scaling_operations_mips.c b/webrtc/common_audio/signal_processing/vector_scaling_operations_mips.c new file mode 100644 index 0000000..dd73eea --- /dev/null +++ b/webrtc/common_audio/signal_processing/vector_scaling_operations_mips.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the functions + * WebRtcSpl_ScaleAndAddVectorsWithRound_mips() + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +int WebRtcSpl_ScaleAndAddVectorsWithRound_mips(const int16_t* in_vector1, + int16_t in_vector1_scale, + const int16_t* in_vector2, + int16_t in_vector2_scale, + int right_shifts, + int16_t* out_vector, + size_t length) { + int16_t r0 = 0, r1 = 0; + int16_t *in1 = (int16_t*)in_vector1; + int16_t *in2 = (int16_t*)in_vector2; + int16_t *out = out_vector; + size_t i = 0; + int value32 = 0; + + if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL || + length == 0 || right_shifts < 0) { + return -1; + } + for (i = 0; i < length; i++) { + __asm __volatile ( + "lh %[r0], 0(%[in1]) \n\t" + "lh %[r1], 0(%[in2]) \n\t" + "mult %[r0], %[in_vector1_scale] \n\t" + "madd %[r1], %[in_vector2_scale] \n\t" + "extrv_r.w %[value32], $ac0, %[right_shifts] \n\t" + "addiu %[in1], %[in1], 2 \n\t" + "addiu %[in2], %[in2], 2 \n\t" + "sh %[value32], 0(%[out]) \n\t" + "addiu %[out], %[out], 2 \n\t" + : [value32] "=&r" (value32), [out] "+r" (out), [in1] "+r" (in1), + [in2] "+r" (in2), [r0] "=&r" (r0), [r1] "=&r" (r1) + : [in_vector1_scale] "r" (in_vector1_scale), + [in_vector2_scale] "r" (in_vector2_scale), + [right_shifts] "r" (right_shifts) + : "hi", "lo", "memory" + ); + } + return 0; +} diff --git a/webrtc/common_audio/vad/include/vad.h b/webrtc/common_audio/vad/include/vad.h new file mode 100644 index 0000000..087970f --- /dev/null +++ b/webrtc/common_audio/vad/include/vad.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_ +#define WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_ + +#include "webrtc/base/checks.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/common_audio/vad/include/webrtc_vad.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +class Vad { + public: + enum Aggressiveness { + kVadNormal = 0, + kVadLowBitrate = 1, + kVadAggressive = 2, + kVadVeryAggressive = 3 + }; + + enum Activity { kPassive = 0, kActive = 1, kError = -1 }; + + virtual ~Vad() = default; + + // Calculates a VAD decision for the given audio frame. Valid sample rates + // are 8000, 16000, and 32000 Hz; the number of samples must be such that the + // frame is 10, 20, or 30 ms long. + virtual Activity VoiceActivity(const int16_t* audio, + size_t num_samples, + int sample_rate_hz) = 0; + + // Resets VAD state. + virtual void Reset() = 0; +}; + +// Returns a Vad instance that's implemented on top of WebRtcVad. +rtc::scoped_ptr CreateVad(Vad::Aggressiveness aggressiveness); + +} // namespace webrtc + +#endif // WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_ diff --git a/webrtc/common_audio/vad/include/webrtc_vad.h b/webrtc/common_audio/vad/include/webrtc_vad.h new file mode 100644 index 0000000..91308ee --- /dev/null +++ b/webrtc/common_audio/vad/include/webrtc_vad.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the VAD API calls. Specific function calls are given below. + */ + +#ifndef WEBRTC_COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT +#define WEBRTC_COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ + +#include + +#include "webrtc/typedefs.h" + +typedef struct WebRtcVadInst VadInst; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates an instance to the VAD structure. +VadInst* WebRtcVad_Create(); + +// Frees the dynamic memory of a specified VAD instance. +// +// - handle [i] : Pointer to VAD instance that should be freed. +void WebRtcVad_Free(VadInst* handle); + +// Initializes a VAD instance. +// +// - handle [i/o] : Instance that should be initialized. +// +// returns : 0 - (OK), +// -1 - (NULL pointer or Default mode could not be set). +int WebRtcVad_Init(VadInst* handle); + +// Sets the VAD operating mode. A more aggressive (higher mode) VAD is more +// restrictive in reporting speech. Put in other words the probability of being +// speech when the VAD returns 1 is increased with increasing mode. As a +// consequence also the missed detection rate goes up. +// +// - handle [i/o] : VAD instance. +// - mode [i] : Aggressiveness mode (0, 1, 2, or 3). +// +// returns : 0 - (OK), +// -1 - (NULL pointer, mode could not be set or the VAD instance +// has not been initialized). +int WebRtcVad_set_mode(VadInst* handle, int mode); + +// Calculates a VAD decision for the |audio_frame|. For valid sampling rates +// frame lengths, see the description of WebRtcVad_ValidRatesAndFrameLengths(). +// +// - handle [i/o] : VAD Instance. Needs to be initialized by +// WebRtcVad_Init() before call. +// - fs [i] : Sampling frequency (Hz): 8000, 16000, or 32000 +// - audio_frame [i] : Audio frame buffer. +// - frame_length [i] : Length of audio frame buffer in number of samples. +// +// returns : 1 - (Active Voice), +// 0 - (Non-active Voice), +// -1 - (Error) +int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame, + size_t frame_length); + +// Checks for valid combinations of |rate| and |frame_length|. We support 10, +// 20 and 30 ms frames and the rates 8000, 16000 and 32000 Hz. +// +// - rate [i] : Sampling frequency (Hz). +// - frame_length [i] : Speech frame buffer length in number of samples. +// +// returns : 0 - (valid combination), -1 - (invalid combination) +int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT diff --git a/webrtc/common_audio/vad/vad.cc b/webrtc/common_audio/vad/vad.cc new file mode 100644 index 0000000..95a162f --- /dev/null +++ b/webrtc/common_audio/vad/vad.cc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/include/vad.h" + +#include "webrtc/base/checks.h" + +namespace webrtc { + +namespace { + +class VadImpl final : public Vad { + public: + explicit VadImpl(Aggressiveness aggressiveness) + : handle_(nullptr), aggressiveness_(aggressiveness) { + Reset(); + } + + ~VadImpl() override { WebRtcVad_Free(handle_); } + + Activity VoiceActivity(const int16_t* audio, + size_t num_samples, + int sample_rate_hz) override { + int ret = WebRtcVad_Process(handle_, sample_rate_hz, audio, num_samples); + switch (ret) { + case 0: + return kPassive; + case 1: + return kActive; + default: + RTC_DCHECK(false) << "WebRtcVad_Process returned an error."; + return kError; + } + } + + void Reset() override { + if (handle_) + WebRtcVad_Free(handle_); + handle_ = WebRtcVad_Create(); + RTC_CHECK(handle_); + RTC_CHECK_EQ(WebRtcVad_Init(handle_), 0); + RTC_CHECK_EQ(WebRtcVad_set_mode(handle_, aggressiveness_), 0); + } + + private: + VadInst* handle_; + Aggressiveness aggressiveness_; +}; + +} // namespace + +rtc::scoped_ptr CreateVad(Vad::Aggressiveness aggressiveness) { + return rtc::scoped_ptr(new VadImpl(aggressiveness)); +} + +} // namespace webrtc diff --git a/webrtc/common_audio/vad/vad_core.c b/webrtc/common_audio/vad/vad_core.c new file mode 100644 index 0000000..51797ee --- /dev/null +++ b/webrtc/common_audio/vad/vad_core.c @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/vad_core.h" + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/vad/vad_filterbank.h" +#include "webrtc/common_audio/vad/vad_gmm.h" +#include "webrtc/common_audio/vad/vad_sp.h" +#include "webrtc/typedefs.h" + +// Spectrum Weighting +static const int16_t kSpectrumWeight[kNumChannels] = { 6, 8, 10, 12, 14, 16 }; +static const int16_t kNoiseUpdateConst = 655; // Q15 +static const int16_t kSpeechUpdateConst = 6554; // Q15 +static const int16_t kBackEta = 154; // Q8 +// Minimum difference between the two models, Q5 +static const int16_t kMinimumDifference[kNumChannels] = { + 544, 544, 576, 576, 576, 576 }; +// Upper limit of mean value for speech model, Q7 +static const int16_t kMaximumSpeech[kNumChannels] = { + 11392, 11392, 11520, 11520, 11520, 11520 }; +// Minimum value for mean value +static const int16_t kMinimumMean[kNumGaussians] = { 640, 768 }; +// Upper limit of mean value for noise model, Q7 +static const int16_t kMaximumNoise[kNumChannels] = { + 9216, 9088, 8960, 8832, 8704, 8576 }; +// Start values for the Gaussian models, Q7 +// Weights for the two Gaussians for the six channels (noise) +static const int16_t kNoiseDataWeights[kTableSize] = { + 34, 62, 72, 66, 53, 25, 94, 66, 56, 62, 75, 103 }; +// Weights for the two Gaussians for the six channels (speech) +static const int16_t kSpeechDataWeights[kTableSize] = { + 48, 82, 45, 87, 50, 47, 80, 46, 83, 41, 78, 81 }; +// Means for the two Gaussians for the six channels (noise) +static const int16_t kNoiseDataMeans[kTableSize] = { + 6738, 4892, 7065, 6715, 6771, 3369, 7646, 3863, 7820, 7266, 5020, 4362 }; +// Means for the two Gaussians for the six channels (speech) +static const int16_t kSpeechDataMeans[kTableSize] = { + 8306, 10085, 10078, 11823, 11843, 6309, 9473, 9571, 10879, 7581, 8180, 7483 +}; +// Stds for the two Gaussians for the six channels (noise) +static const int16_t kNoiseDataStds[kTableSize] = { + 378, 1064, 493, 582, 688, 593, 474, 697, 475, 688, 421, 455 }; +// Stds for the two Gaussians for the six channels (speech) +static const int16_t kSpeechDataStds[kTableSize] = { + 555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540, 1079, 850 }; + +// Constants used in GmmProbability(). +// +// Maximum number of counted speech (VAD = 1) frames in a row. +static const int16_t kMaxSpeechFrames = 6; +// Minimum standard deviation for both speech and noise. +static const int16_t kMinStd = 384; + +// Constants in WebRtcVad_InitCore(). +// Default aggressiveness mode. +static const short kDefaultMode = 0; +static const int kInitCheck = 42; + +// Constants used in WebRtcVad_set_mode_core(). +// +// Thresholds for different frame lengths (10 ms, 20 ms and 30 ms). +// +// Mode 0, Quality. +static const int16_t kOverHangMax1Q[3] = { 8, 4, 3 }; +static const int16_t kOverHangMax2Q[3] = { 14, 7, 5 }; +static const int16_t kLocalThresholdQ[3] = { 24, 21, 24 }; +static const int16_t kGlobalThresholdQ[3] = { 57, 48, 57 }; +// Mode 1, Low bitrate. +static const int16_t kOverHangMax1LBR[3] = { 8, 4, 3 }; +static const int16_t kOverHangMax2LBR[3] = { 14, 7, 5 }; +static const int16_t kLocalThresholdLBR[3] = { 37, 32, 37 }; +static const int16_t kGlobalThresholdLBR[3] = { 100, 80, 100 }; +// Mode 2, Aggressive. +static const int16_t kOverHangMax1AGG[3] = { 6, 3, 2 }; +static const int16_t kOverHangMax2AGG[3] = { 9, 5, 3 }; +static const int16_t kLocalThresholdAGG[3] = { 82, 78, 82 }; +static const int16_t kGlobalThresholdAGG[3] = { 285, 260, 285 }; +// Mode 3, Very aggressive. +static const int16_t kOverHangMax1VAG[3] = { 6, 3, 2 }; +static const int16_t kOverHangMax2VAG[3] = { 9, 5, 3 }; +static const int16_t kLocalThresholdVAG[3] = { 94, 94, 94 }; +static const int16_t kGlobalThresholdVAG[3] = { 1100, 1050, 1100 }; + +// Calculates the weighted average w.r.t. number of Gaussians. The |data| are +// updated with an |offset| before averaging. +// +// - data [i/o] : Data to average. +// - offset [i] : An offset added to |data|. +// - weights [i] : Weights used for averaging. +// +// returns : The weighted average. +static int32_t WeightedAverage(int16_t* data, int16_t offset, + const int16_t* weights) { + int k; + int32_t weighted_average = 0; + + for (k = 0; k < kNumGaussians; k++) { + data[k * kNumChannels] += offset; + weighted_average += data[k * kNumChannels] * weights[k * kNumChannels]; + } + return weighted_average; +} + +// Calculates the probabilities for both speech and background noise using +// Gaussian Mixture Models (GMM). A hypothesis-test is performed to decide which +// type of signal is most probable. +// +// - self [i/o] : Pointer to VAD instance +// - features [i] : Feature vector of length |kNumChannels| +// = log10(energy in frequency band) +// - total_power [i] : Total power in audio frame. +// - frame_length [i] : Number of input samples +// +// - returns : the VAD decision (0 - noise, 1 - speech). +static int16_t GmmProbability(VadInstT* self, int16_t* features, + int16_t total_power, size_t frame_length) { + int channel, k; + int16_t feature_minimum; + int16_t h0, h1; + int16_t log_likelihood_ratio; + int16_t vadflag = 0; + int16_t shifts_h0, shifts_h1; + int16_t tmp_s16, tmp1_s16, tmp2_s16; + int16_t diff; + int gaussian; + int16_t nmk, nmk2, nmk3, smk, smk2, nsk, ssk; + int16_t delt, ndelt; + int16_t maxspe, maxmu; + int16_t deltaN[kTableSize], deltaS[kTableSize]; + int16_t ngprvec[kTableSize] = { 0 }; // Conditional probability = 0. + int16_t sgprvec[kTableSize] = { 0 }; // Conditional probability = 0. + int32_t h0_test, h1_test; + int32_t tmp1_s32, tmp2_s32; + int32_t sum_log_likelihood_ratios = 0; + int32_t noise_global_mean, speech_global_mean; + int32_t noise_probability[kNumGaussians], speech_probability[kNumGaussians]; + int16_t overhead1, overhead2, individualTest, totalTest; + + // Set various thresholds based on frame lengths (80, 160 or 240 samples). + if (frame_length == 80) { + overhead1 = self->over_hang_max_1[0]; + overhead2 = self->over_hang_max_2[0]; + individualTest = self->individual[0]; + totalTest = self->total[0]; + } else if (frame_length == 160) { + overhead1 = self->over_hang_max_1[1]; + overhead2 = self->over_hang_max_2[1]; + individualTest = self->individual[1]; + totalTest = self->total[1]; + } else { + overhead1 = self->over_hang_max_1[2]; + overhead2 = self->over_hang_max_2[2]; + individualTest = self->individual[2]; + totalTest = self->total[2]; + } + + if (total_power > kMinEnergy) { + // The signal power of current frame is large enough for processing. The + // processing consists of two parts: + // 1) Calculating the likelihood of speech and thereby a VAD decision. + // 2) Updating the underlying model, w.r.t., the decision made. + + // The detection scheme is an LRT with hypothesis + // H0: Noise + // H1: Speech + // + // We combine a global LRT with local tests, for each frequency sub-band, + // here defined as |channel|. + for (channel = 0; channel < kNumChannels; channel++) { + // For each channel we model the probability with a GMM consisting of + // |kNumGaussians|, with different means and standard deviations depending + // on H0 or H1. + h0_test = 0; + h1_test = 0; + for (k = 0; k < kNumGaussians; k++) { + gaussian = channel + k * kNumChannels; + // Probability under H0, that is, probability of frame being noise. + // Value given in Q27 = Q7 * Q20. + tmp1_s32 = WebRtcVad_GaussianProbability(features[channel], + self->noise_means[gaussian], + self->noise_stds[gaussian], + &deltaN[gaussian]); + noise_probability[k] = kNoiseDataWeights[gaussian] * tmp1_s32; + h0_test += noise_probability[k]; // Q27 + + // Probability under H1, that is, probability of frame being speech. + // Value given in Q27 = Q7 * Q20. + tmp1_s32 = WebRtcVad_GaussianProbability(features[channel], + self->speech_means[gaussian], + self->speech_stds[gaussian], + &deltaS[gaussian]); + speech_probability[k] = kSpeechDataWeights[gaussian] * tmp1_s32; + h1_test += speech_probability[k]; // Q27 + } + + // Calculate the log likelihood ratio: log2(Pr{X|H1} / Pr{X|H1}). + // Approximation: + // log2(Pr{X|H1} / Pr{X|H1}) = log2(Pr{X|H1}*2^Q) - log2(Pr{X|H1}*2^Q) + // = log2(h1_test) - log2(h0_test) + // = log2(2^(31-shifts_h1)*(1+b1)) + // - log2(2^(31-shifts_h0)*(1+b0)) + // = shifts_h0 - shifts_h1 + // + log2(1+b1) - log2(1+b0) + // ~= shifts_h0 - shifts_h1 + // + // Note that b0 and b1 are values less than 1, hence, 0 <= log2(1+b0) < 1. + // Further, b0 and b1 are independent and on the average the two terms + // cancel. + shifts_h0 = WebRtcSpl_NormW32(h0_test); + shifts_h1 = WebRtcSpl_NormW32(h1_test); + if (h0_test == 0) { + shifts_h0 = 31; + } + if (h1_test == 0) { + shifts_h1 = 31; + } + log_likelihood_ratio = shifts_h0 - shifts_h1; + + // Update |sum_log_likelihood_ratios| with spectrum weighting. This is + // used for the global VAD decision. + sum_log_likelihood_ratios += + (int32_t) (log_likelihood_ratio * kSpectrumWeight[channel]); + + // Local VAD decision. + if ((log_likelihood_ratio << 2) > individualTest) { + vadflag = 1; + } + + // TODO(bjornv): The conditional probabilities below are applied on the + // hard coded number of Gaussians set to two. Find a way to generalize. + // Calculate local noise probabilities used later when updating the GMM. + h0 = (int16_t) (h0_test >> 12); // Q15 + if (h0 > 0) { + // High probability of noise. Assign conditional probabilities for each + // Gaussian in the GMM. + tmp1_s32 = (noise_probability[0] & 0xFFFFF000) << 2; // Q29 + ngprvec[channel] = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, h0); // Q14 + ngprvec[channel + kNumChannels] = 16384 - ngprvec[channel]; + } else { + // Low noise probability. Assign conditional probability 1 to the first + // Gaussian and 0 to the rest (which is already set at initialization). + ngprvec[channel] = 16384; + } + + // Calculate local speech probabilities used later when updating the GMM. + h1 = (int16_t) (h1_test >> 12); // Q15 + if (h1 > 0) { + // High probability of speech. Assign conditional probabilities for each + // Gaussian in the GMM. Otherwise use the initialized values, i.e., 0. + tmp1_s32 = (speech_probability[0] & 0xFFFFF000) << 2; // Q29 + sgprvec[channel] = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, h1); // Q14 + sgprvec[channel + kNumChannels] = 16384 - sgprvec[channel]; + } + } + + // Make a global VAD decision. + vadflag |= (sum_log_likelihood_ratios >= totalTest); + + // Update the model parameters. + maxspe = 12800; + for (channel = 0; channel < kNumChannels; channel++) { + + // Get minimum value in past which is used for long term correction in Q4. + feature_minimum = WebRtcVad_FindMinimum(self, features[channel], channel); + + // Compute the "global" mean, that is the sum of the two means weighted. + noise_global_mean = WeightedAverage(&self->noise_means[channel], 0, + &kNoiseDataWeights[channel]); + tmp1_s16 = (int16_t) (noise_global_mean >> 6); // Q8 + + for (k = 0; k < kNumGaussians; k++) { + gaussian = channel + k * kNumChannels; + + nmk = self->noise_means[gaussian]; + smk = self->speech_means[gaussian]; + nsk = self->noise_stds[gaussian]; + ssk = self->speech_stds[gaussian]; + + // Update noise mean vector if the frame consists of noise only. + nmk2 = nmk; + if (!vadflag) { + // deltaN = (x-mu)/sigma^2 + // ngprvec[k] = |noise_probability[k]| / + // (|noise_probability[0]| + |noise_probability[1]|) + + // (Q14 * Q11 >> 11) = Q14. + delt = (int16_t)((ngprvec[gaussian] * deltaN[gaussian]) >> 11); + // Q7 + (Q14 * Q15 >> 22) = Q7. + nmk2 = nmk + (int16_t)((delt * kNoiseUpdateConst) >> 22); + } + + // Long term correction of the noise mean. + // Q8 - Q8 = Q8. + ndelt = (feature_minimum << 4) - tmp1_s16; + // Q7 + (Q8 * Q8) >> 9 = Q7. + nmk3 = nmk2 + (int16_t)((ndelt * kBackEta) >> 9); + + // Control that the noise mean does not drift to much. + tmp_s16 = (int16_t) ((k + 5) << 7); + if (nmk3 < tmp_s16) { + nmk3 = tmp_s16; + } + tmp_s16 = (int16_t) ((72 + k - channel) << 7); + if (nmk3 > tmp_s16) { + nmk3 = tmp_s16; + } + self->noise_means[gaussian] = nmk3; + + if (vadflag) { + // Update speech mean vector: + // |deltaS| = (x-mu)/sigma^2 + // sgprvec[k] = |speech_probability[k]| / + // (|speech_probability[0]| + |speech_probability[1]|) + + // (Q14 * Q11) >> 11 = Q14. + delt = (int16_t)((sgprvec[gaussian] * deltaS[gaussian]) >> 11); + // Q14 * Q15 >> 21 = Q8. + tmp_s16 = (int16_t)((delt * kSpeechUpdateConst) >> 21); + // Q7 + (Q8 >> 1) = Q7. With rounding. + smk2 = smk + ((tmp_s16 + 1) >> 1); + + // Control that the speech mean does not drift to much. + maxmu = maxspe + 640; + if (smk2 < kMinimumMean[k]) { + smk2 = kMinimumMean[k]; + } + if (smk2 > maxmu) { + smk2 = maxmu; + } + self->speech_means[gaussian] = smk2; // Q7. + + // (Q7 >> 3) = Q4. With rounding. + tmp_s16 = ((smk + 4) >> 3); + + tmp_s16 = features[channel] - tmp_s16; // Q4 + // (Q11 * Q4 >> 3) = Q12. + tmp1_s32 = (deltaS[gaussian] * tmp_s16) >> 3; + tmp2_s32 = tmp1_s32 - 4096; + tmp_s16 = sgprvec[gaussian] >> 2; + // (Q14 >> 2) * Q12 = Q24. + tmp1_s32 = tmp_s16 * tmp2_s32; + + tmp2_s32 = tmp1_s32 >> 4; // Q20 + + // 0.1 * Q20 / Q7 = Q13. + if (tmp2_s32 > 0) { + tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(tmp2_s32, ssk * 10); + } else { + tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(-tmp2_s32, ssk * 10); + tmp_s16 = -tmp_s16; + } + // Divide by 4 giving an update factor of 0.025 (= 0.1 / 4). + // Note that division by 4 equals shift by 2, hence, + // (Q13 >> 8) = (Q13 >> 6) / 4 = Q7. + tmp_s16 += 128; // Rounding. + ssk += (tmp_s16 >> 8); + if (ssk < kMinStd) { + ssk = kMinStd; + } + self->speech_stds[gaussian] = ssk; + } else { + // Update GMM variance vectors. + // deltaN * (features[channel] - nmk) - 1 + // Q4 - (Q7 >> 3) = Q4. + tmp_s16 = features[channel] - (nmk >> 3); + // (Q11 * Q4 >> 3) = Q12. + tmp1_s32 = (deltaN[gaussian] * tmp_s16) >> 3; + tmp1_s32 -= 4096; + + // (Q14 >> 2) * Q12 = Q24. + tmp_s16 = (ngprvec[gaussian] + 2) >> 2; + tmp2_s32 = tmp_s16 * tmp1_s32; + // Q20 * approx 0.001 (2^-10=0.0009766), hence, + // (Q24 >> 14) = (Q24 >> 4) / 2^10 = Q20. + tmp1_s32 = tmp2_s32 >> 14; + + // Q20 / Q7 = Q13. + if (tmp1_s32 > 0) { + tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, nsk); + } else { + tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(-tmp1_s32, nsk); + tmp_s16 = -tmp_s16; + } + tmp_s16 += 32; // Rounding + nsk += tmp_s16 >> 6; // Q13 >> 6 = Q7. + if (nsk < kMinStd) { + nsk = kMinStd; + } + self->noise_stds[gaussian] = nsk; + } + } + + // Separate models if they are too close. + // |noise_global_mean| in Q14 (= Q7 * Q7). + noise_global_mean = WeightedAverage(&self->noise_means[channel], 0, + &kNoiseDataWeights[channel]); + + // |speech_global_mean| in Q14 (= Q7 * Q7). + speech_global_mean = WeightedAverage(&self->speech_means[channel], 0, + &kSpeechDataWeights[channel]); + + // |diff| = "global" speech mean - "global" noise mean. + // (Q14 >> 9) - (Q14 >> 9) = Q5. + diff = (int16_t) (speech_global_mean >> 9) - + (int16_t) (noise_global_mean >> 9); + if (diff < kMinimumDifference[channel]) { + tmp_s16 = kMinimumDifference[channel] - diff; + + // |tmp1_s16| = ~0.8 * (kMinimumDifference - diff) in Q7. + // |tmp2_s16| = ~0.2 * (kMinimumDifference - diff) in Q7. + tmp1_s16 = (int16_t)((13 * tmp_s16) >> 2); + tmp2_s16 = (int16_t)((3 * tmp_s16) >> 2); + + // Move Gaussian means for speech model by |tmp1_s16| and update + // |speech_global_mean|. Note that |self->speech_means[channel]| is + // changed after the call. + speech_global_mean = WeightedAverage(&self->speech_means[channel], + tmp1_s16, + &kSpeechDataWeights[channel]); + + // Move Gaussian means for noise model by -|tmp2_s16| and update + // |noise_global_mean|. Note that |self->noise_means[channel]| is + // changed after the call. + noise_global_mean = WeightedAverage(&self->noise_means[channel], + -tmp2_s16, + &kNoiseDataWeights[channel]); + } + + // Control that the speech & noise means do not drift to much. + maxspe = kMaximumSpeech[channel]; + tmp2_s16 = (int16_t) (speech_global_mean >> 7); + if (tmp2_s16 > maxspe) { + // Upper limit of speech model. + tmp2_s16 -= maxspe; + + for (k = 0; k < kNumGaussians; k++) { + self->speech_means[channel + k * kNumChannels] -= tmp2_s16; + } + } + + tmp2_s16 = (int16_t) (noise_global_mean >> 7); + if (tmp2_s16 > kMaximumNoise[channel]) { + tmp2_s16 -= kMaximumNoise[channel]; + + for (k = 0; k < kNumGaussians; k++) { + self->noise_means[channel + k * kNumChannels] -= tmp2_s16; + } + } + } + self->frame_counter++; + } + + // Smooth with respect to transition hysteresis. + if (!vadflag) { + if (self->over_hang > 0) { + vadflag = 2 + self->over_hang; + self->over_hang--; + } + self->num_of_speech = 0; + } else { + self->num_of_speech++; + if (self->num_of_speech > kMaxSpeechFrames) { + self->num_of_speech = kMaxSpeechFrames; + self->over_hang = overhead2; + } else { + self->over_hang = overhead1; + } + } + return vadflag; +} + +// Initialize the VAD. Set aggressiveness mode to default value. +int WebRtcVad_InitCore(VadInstT* self) { + int i; + + if (self == NULL) { + return -1; + } + + // Initialization of general struct variables. + self->vad = 1; // Speech active (=1). + self->frame_counter = 0; + self->over_hang = 0; + self->num_of_speech = 0; + + // Initialization of downsampling filter state. + memset(self->downsampling_filter_states, 0, + sizeof(self->downsampling_filter_states)); + + // Initialization of 48 to 8 kHz downsampling. + WebRtcSpl_ResetResample48khzTo8khz(&self->state_48_to_8); + + // Read initial PDF parameters. + for (i = 0; i < kTableSize; i++) { + self->noise_means[i] = kNoiseDataMeans[i]; + self->speech_means[i] = kSpeechDataMeans[i]; + self->noise_stds[i] = kNoiseDataStds[i]; + self->speech_stds[i] = kSpeechDataStds[i]; + } + + // Initialize Index and Minimum value vectors. + for (i = 0; i < 16 * kNumChannels; i++) { + self->low_value_vector[i] = 10000; + self->index_vector[i] = 0; + } + + // Initialize splitting filter states. + memset(self->upper_state, 0, sizeof(self->upper_state)); + memset(self->lower_state, 0, sizeof(self->lower_state)); + + // Initialize high pass filter states. + memset(self->hp_filter_state, 0, sizeof(self->hp_filter_state)); + + // Initialize mean value memory, for WebRtcVad_FindMinimum(). + for (i = 0; i < kNumChannels; i++) { + self->mean_value[i] = 1600; + } + + // Set aggressiveness mode to default (=|kDefaultMode|). + if (WebRtcVad_set_mode_core(self, kDefaultMode) != 0) { + return -1; + } + + self->init_flag = kInitCheck; + + return 0; +} + +// Set aggressiveness mode +int WebRtcVad_set_mode_core(VadInstT* self, int mode) { + int return_value = 0; + + switch (mode) { + case 0: + // Quality mode. + memcpy(self->over_hang_max_1, kOverHangMax1Q, + sizeof(self->over_hang_max_1)); + memcpy(self->over_hang_max_2, kOverHangMax2Q, + sizeof(self->over_hang_max_2)); + memcpy(self->individual, kLocalThresholdQ, + sizeof(self->individual)); + memcpy(self->total, kGlobalThresholdQ, + sizeof(self->total)); + break; + case 1: + // Low bitrate mode. + memcpy(self->over_hang_max_1, kOverHangMax1LBR, + sizeof(self->over_hang_max_1)); + memcpy(self->over_hang_max_2, kOverHangMax2LBR, + sizeof(self->over_hang_max_2)); + memcpy(self->individual, kLocalThresholdLBR, + sizeof(self->individual)); + memcpy(self->total, kGlobalThresholdLBR, + sizeof(self->total)); + break; + case 2: + // Aggressive mode. + memcpy(self->over_hang_max_1, kOverHangMax1AGG, + sizeof(self->over_hang_max_1)); + memcpy(self->over_hang_max_2, kOverHangMax2AGG, + sizeof(self->over_hang_max_2)); + memcpy(self->individual, kLocalThresholdAGG, + sizeof(self->individual)); + memcpy(self->total, kGlobalThresholdAGG, + sizeof(self->total)); + break; + case 3: + // Very aggressive mode. + memcpy(self->over_hang_max_1, kOverHangMax1VAG, + sizeof(self->over_hang_max_1)); + memcpy(self->over_hang_max_2, kOverHangMax2VAG, + sizeof(self->over_hang_max_2)); + memcpy(self->individual, kLocalThresholdVAG, + sizeof(self->individual)); + memcpy(self->total, kGlobalThresholdVAG, + sizeof(self->total)); + break; + default: + return_value = -1; + break; + } + + return return_value; +} + +// Calculate VAD decision by first extracting feature values and then calculate +// probability for both speech and background noise. + +int WebRtcVad_CalcVad48khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length) { + int vad; + size_t i; + int16_t speech_nb[240]; // 30 ms in 8 kHz. + // |tmp_mem| is a temporary memory used by resample function, length is + // frame length in 10 ms (480 samples) + 256 extra. + int32_t tmp_mem[480 + 256] = { 0 }; + const size_t kFrameLen10ms48khz = 480; + const size_t kFrameLen10ms8khz = 80; + size_t num_10ms_frames = frame_length / kFrameLen10ms48khz; + + for (i = 0; i < num_10ms_frames; i++) { + WebRtcSpl_Resample48khzTo8khz(speech_frame, + &speech_nb[i * kFrameLen10ms8khz], + &inst->state_48_to_8, + tmp_mem); + } + + // Do VAD on an 8 kHz signal + vad = WebRtcVad_CalcVad8khz(inst, speech_nb, frame_length / 6); + + return vad; +} + +int WebRtcVad_CalcVad32khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length) +{ + size_t len; + int vad; + int16_t speechWB[480]; // Downsampled speech frame: 960 samples (30ms in SWB) + int16_t speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) + + + // Downsample signal 32->16->8 before doing VAD + WebRtcVad_Downsampling(speech_frame, speechWB, &(inst->downsampling_filter_states[2]), + frame_length); + len = frame_length / 2; + + WebRtcVad_Downsampling(speechWB, speechNB, inst->downsampling_filter_states, len); + len /= 2; + + // Do VAD on an 8 kHz signal + vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); + + return vad; +} + +int WebRtcVad_CalcVad16khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length) +{ + size_t len; + int vad; + int16_t speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) + + // Wideband: Downsample signal before doing VAD + WebRtcVad_Downsampling(speech_frame, speechNB, inst->downsampling_filter_states, + frame_length); + + len = frame_length / 2; + vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); + + return vad; +} + +int WebRtcVad_CalcVad8khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length) +{ + int16_t feature_vector[kNumChannels], total_power; + + // Get power in the bands + total_power = WebRtcVad_CalculateFeatures(inst, speech_frame, frame_length, + feature_vector); + + // Make a VAD + inst->vad = GmmProbability(inst, feature_vector, total_power, frame_length); + + return inst->vad; +} diff --git a/webrtc/common_audio/vad/vad_core.h b/webrtc/common_audio/vad/vad_core.h new file mode 100644 index 0000000..b38c515 --- /dev/null +++ b/webrtc/common_audio/vad/vad_core.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the descriptions of the core VAD calls. + */ + +#ifndef WEBRTC_COMMON_AUDIO_VAD_VAD_CORE_H_ +#define WEBRTC_COMMON_AUDIO_VAD_VAD_CORE_H_ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/typedefs.h" + +enum { kNumChannels = 6 }; // Number of frequency bands (named channels). +enum { kNumGaussians = 2 }; // Number of Gaussians per channel in the GMM. +enum { kTableSize = kNumChannels * kNumGaussians }; +enum { kMinEnergy = 10 }; // Minimum energy required to trigger audio signal. + +typedef struct VadInstT_ +{ + + int vad; + int32_t downsampling_filter_states[4]; + WebRtcSpl_State48khzTo8khz state_48_to_8; + int16_t noise_means[kTableSize]; + int16_t speech_means[kTableSize]; + int16_t noise_stds[kTableSize]; + int16_t speech_stds[kTableSize]; + // TODO(bjornv): Change to |frame_count|. + int32_t frame_counter; + int16_t over_hang; // Over Hang + int16_t num_of_speech; + // TODO(bjornv): Change to |age_vector|. + int16_t index_vector[16 * kNumChannels]; + int16_t low_value_vector[16 * kNumChannels]; + // TODO(bjornv): Change to |median|. + int16_t mean_value[kNumChannels]; + int16_t upper_state[5]; + int16_t lower_state[5]; + int16_t hp_filter_state[4]; + int16_t over_hang_max_1[3]; + int16_t over_hang_max_2[3]; + int16_t individual[3]; + int16_t total[3]; + + int init_flag; + +} VadInstT; + +// Initializes the core VAD component. The default aggressiveness mode is +// controlled by |kDefaultMode| in vad_core.c. +// +// - self [i/o] : Instance that should be initialized +// +// returns : 0 (OK), -1 (NULL pointer in or if the default mode can't be +// set) +int WebRtcVad_InitCore(VadInstT* self); + +/**************************************************************************** + * WebRtcVad_set_mode_core(...) + * + * This function changes the VAD settings + * + * Input: + * - inst : VAD instance + * - mode : Aggressiveness degree + * 0 (High quality) - 3 (Highly aggressive) + * + * Output: + * - inst : Changed instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcVad_set_mode_core(VadInstT* self, int mode); + +/**************************************************************************** + * WebRtcVad_CalcVad48khz(...) + * WebRtcVad_CalcVad32khz(...) + * WebRtcVad_CalcVad16khz(...) + * WebRtcVad_CalcVad8khz(...) + * + * Calculate probability for active speech and make VAD decision. + * + * Input: + * - inst : Instance that should be initialized + * - speech_frame : Input speech frame + * - frame_length : Number of input samples + * + * Output: + * - inst : Updated filter states etc. + * + * Return value : VAD decision + * 0 - No active speech + * 1-6 - Active speech + */ +int WebRtcVad_CalcVad48khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length); +int WebRtcVad_CalcVad32khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length); +int WebRtcVad_CalcVad16khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length); +int WebRtcVad_CalcVad8khz(VadInstT* inst, const int16_t* speech_frame, + size_t frame_length); + +#endif // WEBRTC_COMMON_AUDIO_VAD_VAD_CORE_H_ diff --git a/src/common_audio/vad/main/source/vad_defines.h b/webrtc/common_audio/vad/vad_defines.h similarity index 100% rename from src/common_audio/vad/main/source/vad_defines.h rename to webrtc/common_audio/vad/vad_defines.h diff --git a/webrtc/common_audio/vad/vad_filterbank.c b/webrtc/common_audio/vad/vad_filterbank.c new file mode 100644 index 0000000..8b9df93 --- /dev/null +++ b/webrtc/common_audio/vad/vad_filterbank.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/vad_filterbank.h" + +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/typedefs.h" + +// Constants used in LogOfEnergy(). +static const int16_t kLogConst = 24660; // 160*log10(2) in Q9. +static const int16_t kLogEnergyIntPart = 14336; // 14 in Q10 + +// Coefficients used by HighPassFilter, Q14. +static const int16_t kHpZeroCoefs[3] = { 6631, -13262, 6631 }; +static const int16_t kHpPoleCoefs[3] = { 16384, -7756, 5620 }; + +// Allpass filter coefficients, upper and lower, in Q15. +// Upper: 0.64, Lower: 0.17 +static const int16_t kAllPassCoefsQ15[2] = { 20972, 5571 }; + +// Adjustment for division with two in SplitFilter. +static const int16_t kOffsetVector[6] = { 368, 368, 272, 176, 176, 176 }; + +// High pass filtering, with a cut-off frequency at 80 Hz, if the |data_in| is +// sampled at 500 Hz. +// +// - data_in [i] : Input audio data sampled at 500 Hz. +// - data_length [i] : Length of input and output data. +// - filter_state [i/o] : State of the filter. +// - data_out [o] : Output audio data in the frequency interval +// 80 - 250 Hz. +static void HighPassFilter(const int16_t* data_in, size_t data_length, + int16_t* filter_state, int16_t* data_out) { + size_t i; + const int16_t* in_ptr = data_in; + int16_t* out_ptr = data_out; + int32_t tmp32 = 0; + + + // The sum of the absolute values of the impulse response: + // The zero/pole-filter has a max amplification of a single sample of: 1.4546 + // Impulse response: 0.4047 -0.6179 -0.0266 0.1993 0.1035 -0.0194 + // The all-zero section has a max amplification of a single sample of: 1.6189 + // Impulse response: 0.4047 -0.8094 0.4047 0 0 0 + // The all-pole section has a max amplification of a single sample of: 1.9931 + // Impulse response: 1.0000 0.4734 -0.1189 -0.2187 -0.0627 0.04532 + + for (i = 0; i < data_length; i++) { + // All-zero section (filter coefficients in Q14). + tmp32 = kHpZeroCoefs[0] * *in_ptr; + tmp32 += kHpZeroCoefs[1] * filter_state[0]; + tmp32 += kHpZeroCoefs[2] * filter_state[1]; + filter_state[1] = filter_state[0]; + filter_state[0] = *in_ptr++; + + // All-pole section (filter coefficients in Q14). + tmp32 -= kHpPoleCoefs[1] * filter_state[2]; + tmp32 -= kHpPoleCoefs[2] * filter_state[3]; + filter_state[3] = filter_state[2]; + filter_state[2] = (int16_t) (tmp32 >> 14); + *out_ptr++ = filter_state[2]; + } +} + +// All pass filtering of |data_in|, used before splitting the signal into two +// frequency bands (low pass vs high pass). +// Note that |data_in| and |data_out| can NOT correspond to the same address. +// +// - data_in [i] : Input audio signal given in Q0. +// - data_length [i] : Length of input and output data. +// - filter_coefficient [i] : Given in Q15. +// - filter_state [i/o] : State of the filter given in Q(-1). +// - data_out [o] : Output audio signal given in Q(-1). +static void AllPassFilter(const int16_t* data_in, size_t data_length, + int16_t filter_coefficient, int16_t* filter_state, + int16_t* data_out) { + // The filter can only cause overflow (in the w16 output variable) + // if more than 4 consecutive input numbers are of maximum value and + // has the the same sign as the impulse responses first taps. + // First 6 taps of the impulse response: + // 0.6399 0.5905 -0.3779 0.2418 -0.1547 0.0990 + + size_t i; + int16_t tmp16 = 0; + int32_t tmp32 = 0; + int32_t state32 = ((int32_t) (*filter_state) << 16); // Q15 + + for (i = 0; i < data_length; i++) { + tmp32 = state32 + filter_coefficient * *data_in; + tmp16 = (int16_t) (tmp32 >> 16); // Q(-1) + *data_out++ = tmp16; + state32 = (*data_in << 14) - filter_coefficient * tmp16; // Q14 + state32 <<= 1; // Q15. + data_in += 2; + } + + *filter_state = (int16_t) (state32 >> 16); // Q(-1) +} + +// Splits |data_in| into |hp_data_out| and |lp_data_out| corresponding to +// an upper (high pass) part and a lower (low pass) part respectively. +// +// - data_in [i] : Input audio data to be split into two frequency bands. +// - data_length [i] : Length of |data_in|. +// - upper_state [i/o] : State of the upper filter, given in Q(-1). +// - lower_state [i/o] : State of the lower filter, given in Q(-1). +// - hp_data_out [o] : Output audio data of the upper half of the spectrum. +// The length is |data_length| / 2. +// - lp_data_out [o] : Output audio data of the lower half of the spectrum. +// The length is |data_length| / 2. +static void SplitFilter(const int16_t* data_in, size_t data_length, + int16_t* upper_state, int16_t* lower_state, + int16_t* hp_data_out, int16_t* lp_data_out) { + size_t i; + size_t half_length = data_length >> 1; // Downsampling by 2. + int16_t tmp_out; + + // All-pass filtering upper branch. + AllPassFilter(&data_in[0], half_length, kAllPassCoefsQ15[0], upper_state, + hp_data_out); + + // All-pass filtering lower branch. + AllPassFilter(&data_in[1], half_length, kAllPassCoefsQ15[1], lower_state, + lp_data_out); + + // Make LP and HP signals. + for (i = 0; i < half_length; i++) { + tmp_out = *hp_data_out; + *hp_data_out++ -= *lp_data_out; + *lp_data_out++ += tmp_out; + } +} + +// Calculates the energy of |data_in| in dB, and also updates an overall +// |total_energy| if necessary. +// +// - data_in [i] : Input audio data for energy calculation. +// - data_length [i] : Length of input data. +// - offset [i] : Offset value added to |log_energy|. +// - total_energy [i/o] : An external energy updated with the energy of +// |data_in|. +// NOTE: |total_energy| is only updated if +// |total_energy| <= |kMinEnergy|. +// - log_energy [o] : 10 * log10("energy of |data_in|") given in Q4. +static void LogOfEnergy(const int16_t* data_in, size_t data_length, + int16_t offset, int16_t* total_energy, + int16_t* log_energy) { + // |tot_rshifts| accumulates the number of right shifts performed on |energy|. + int tot_rshifts = 0; + // The |energy| will be normalized to 15 bits. We use unsigned integer because + // we eventually will mask out the fractional part. + uint32_t energy = 0; + + assert(data_in != NULL); + assert(data_length > 0); + + energy = (uint32_t) WebRtcSpl_Energy((int16_t*) data_in, data_length, + &tot_rshifts); + + if (energy != 0) { + // By construction, normalizing to 15 bits is equivalent with 17 leading + // zeros of an unsigned 32 bit value. + int normalizing_rshifts = 17 - WebRtcSpl_NormU32(energy); + // In a 15 bit representation the leading bit is 2^14. log2(2^14) in Q10 is + // (14 << 10), which is what we initialize |log2_energy| with. For a more + // detailed derivations, see below. + int16_t log2_energy = kLogEnergyIntPart; + + tot_rshifts += normalizing_rshifts; + // Normalize |energy| to 15 bits. + // |tot_rshifts| is now the total number of right shifts performed on + // |energy| after normalization. This means that |energy| is in + // Q(-tot_rshifts). + if (normalizing_rshifts < 0) { + energy <<= -normalizing_rshifts; + } else { + energy >>= normalizing_rshifts; + } + + // Calculate the energy of |data_in| in dB, in Q4. + // + // 10 * log10("true energy") in Q4 = 2^4 * 10 * log10("true energy") = + // 160 * log10(|energy| * 2^|tot_rshifts|) = + // 160 * log10(2) * log2(|energy| * 2^|tot_rshifts|) = + // 160 * log10(2) * (log2(|energy|) + log2(2^|tot_rshifts|)) = + // (160 * log10(2)) * (log2(|energy|) + |tot_rshifts|) = + // |kLogConst| * (|log2_energy| + |tot_rshifts|) + // + // We know by construction that |energy| is normalized to 15 bits. Hence, + // |energy| = 2^14 + frac_Q15, where frac_Q15 is a fractional part in Q15. + // Further, we'd like |log2_energy| in Q10 + // log2(|energy|) in Q10 = 2^10 * log2(2^14 + frac_Q15) = + // 2^10 * log2(2^14 * (1 + frac_Q15 * 2^-14)) = + // 2^10 * (14 + log2(1 + frac_Q15 * 2^-14)) ~= + // (14 << 10) + 2^10 * (frac_Q15 * 2^-14) = + // (14 << 10) + (frac_Q15 * 2^-4) = (14 << 10) + (frac_Q15 >> 4) + // + // Note that frac_Q15 = (|energy| & 0x00003FFF) + + // Calculate and add the fractional part to |log2_energy|. + log2_energy += (int16_t) ((energy & 0x00003FFF) >> 4); + + // |kLogConst| is in Q9, |log2_energy| in Q10 and |tot_rshifts| in Q0. + // Note that we in our derivation above have accounted for an output in Q4. + *log_energy = (int16_t)(((kLogConst * log2_energy) >> 19) + + ((tot_rshifts * kLogConst) >> 9)); + + if (*log_energy < 0) { + *log_energy = 0; + } + } else { + *log_energy = offset; + return; + } + + *log_energy += offset; + + // Update the approximate |total_energy| with the energy of |data_in|, if + // |total_energy| has not exceeded |kMinEnergy|. |total_energy| is used as an + // energy indicator in WebRtcVad_GmmProbability() in vad_core.c. + if (*total_energy <= kMinEnergy) { + if (tot_rshifts >= 0) { + // We know by construction that the |energy| > |kMinEnergy| in Q0, so add + // an arbitrary value such that |total_energy| exceeds |kMinEnergy|. + *total_energy += kMinEnergy + 1; + } else { + // By construction |energy| is represented by 15 bits, hence any number of + // right shifted |energy| will fit in an int16_t. In addition, adding the + // value to |total_energy| is wrap around safe as long as + // |kMinEnergy| < 8192. + *total_energy += (int16_t) (energy >> -tot_rshifts); // Q0. + } + } +} + +int16_t WebRtcVad_CalculateFeatures(VadInstT* self, const int16_t* data_in, + size_t data_length, int16_t* features) { + int16_t total_energy = 0; + // We expect |data_length| to be 80, 160 or 240 samples, which corresponds to + // 10, 20 or 30 ms in 8 kHz. Therefore, the intermediate downsampled data will + // have at most 120 samples after the first split and at most 60 samples after + // the second split. + int16_t hp_120[120], lp_120[120]; + int16_t hp_60[60], lp_60[60]; + const size_t half_data_length = data_length >> 1; + size_t length = half_data_length; // |data_length| / 2, corresponds to + // bandwidth = 2000 Hz after downsampling. + + // Initialize variables for the first SplitFilter(). + int frequency_band = 0; + const int16_t* in_ptr = data_in; // [0 - 4000] Hz. + int16_t* hp_out_ptr = hp_120; // [2000 - 4000] Hz. + int16_t* lp_out_ptr = lp_120; // [0 - 2000] Hz. + + assert(data_length <= 240); + assert(4 < kNumChannels - 1); // Checking maximum |frequency_band|. + + // Split at 2000 Hz and downsample. + SplitFilter(in_ptr, data_length, &self->upper_state[frequency_band], + &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr); + + // For the upper band (2000 Hz - 4000 Hz) split at 3000 Hz and downsample. + frequency_band = 1; + in_ptr = hp_120; // [2000 - 4000] Hz. + hp_out_ptr = hp_60; // [3000 - 4000] Hz. + lp_out_ptr = lp_60; // [2000 - 3000] Hz. + SplitFilter(in_ptr, length, &self->upper_state[frequency_band], + &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr); + + // Energy in 3000 Hz - 4000 Hz. + length >>= 1; // |data_length| / 4 <=> bandwidth = 1000 Hz. + + LogOfEnergy(hp_60, length, kOffsetVector[5], &total_energy, &features[5]); + + // Energy in 2000 Hz - 3000 Hz. + LogOfEnergy(lp_60, length, kOffsetVector[4], &total_energy, &features[4]); + + // For the lower band (0 Hz - 2000 Hz) split at 1000 Hz and downsample. + frequency_band = 2; + in_ptr = lp_120; // [0 - 2000] Hz. + hp_out_ptr = hp_60; // [1000 - 2000] Hz. + lp_out_ptr = lp_60; // [0 - 1000] Hz. + length = half_data_length; // |data_length| / 2 <=> bandwidth = 2000 Hz. + SplitFilter(in_ptr, length, &self->upper_state[frequency_band], + &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr); + + // Energy in 1000 Hz - 2000 Hz. + length >>= 1; // |data_length| / 4 <=> bandwidth = 1000 Hz. + LogOfEnergy(hp_60, length, kOffsetVector[3], &total_energy, &features[3]); + + // For the lower band (0 Hz - 1000 Hz) split at 500 Hz and downsample. + frequency_band = 3; + in_ptr = lp_60; // [0 - 1000] Hz. + hp_out_ptr = hp_120; // [500 - 1000] Hz. + lp_out_ptr = lp_120; // [0 - 500] Hz. + SplitFilter(in_ptr, length, &self->upper_state[frequency_band], + &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr); + + // Energy in 500 Hz - 1000 Hz. + length >>= 1; // |data_length| / 8 <=> bandwidth = 500 Hz. + LogOfEnergy(hp_120, length, kOffsetVector[2], &total_energy, &features[2]); + + // For the lower band (0 Hz - 500 Hz) split at 250 Hz and downsample. + frequency_band = 4; + in_ptr = lp_120; // [0 - 500] Hz. + hp_out_ptr = hp_60; // [250 - 500] Hz. + lp_out_ptr = lp_60; // [0 - 250] Hz. + SplitFilter(in_ptr, length, &self->upper_state[frequency_band], + &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr); + + // Energy in 250 Hz - 500 Hz. + length >>= 1; // |data_length| / 16 <=> bandwidth = 250 Hz. + LogOfEnergy(hp_60, length, kOffsetVector[1], &total_energy, &features[1]); + + // Remove 0 Hz - 80 Hz, by high pass filtering the lower band. + HighPassFilter(lp_60, length, self->hp_filter_state, hp_120); + + // Energy in 80 Hz - 250 Hz. + LogOfEnergy(hp_120, length, kOffsetVector[0], &total_energy, &features[0]); + + return total_energy; +} diff --git a/webrtc/common_audio/vad/vad_filterbank.h b/webrtc/common_audio/vad/vad_filterbank.h new file mode 100644 index 0000000..42bf3fc --- /dev/null +++ b/webrtc/common_audio/vad/vad_filterbank.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file includes feature calculating functionality used in vad_core.c. + */ + +#ifndef WEBRTC_COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ +#define WEBRTC_COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ + +#include "webrtc/common_audio/vad/vad_core.h" +#include "webrtc/typedefs.h" + +// Takes |data_length| samples of |data_in| and calculates the logarithm of the +// energy of each of the |kNumChannels| = 6 frequency bands used by the VAD: +// 80 Hz - 250 Hz +// 250 Hz - 500 Hz +// 500 Hz - 1000 Hz +// 1000 Hz - 2000 Hz +// 2000 Hz - 3000 Hz +// 3000 Hz - 4000 Hz +// +// The values are given in Q4 and written to |features|. Further, an approximate +// overall energy is returned. The return value is used in +// WebRtcVad_GmmProbability() as a signal indicator, hence it is arbitrary above +// the threshold |kMinEnergy|. +// +// - self [i/o] : State information of the VAD. +// - data_in [i] : Input audio data, for feature extraction. +// - data_length [i] : Audio data size, in number of samples. +// - features [o] : 10 * log10(energy in each frequency band), Q4. +// - returns : Total energy of the signal (NOTE! This value is not +// exact. It is only used in a comparison.) +int16_t WebRtcVad_CalculateFeatures(VadInstT* self, const int16_t* data_in, + size_t data_length, int16_t* features); + +#endif // WEBRTC_COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ diff --git a/webrtc/common_audio/vad/vad_gmm.c b/webrtc/common_audio/vad/vad_gmm.c new file mode 100644 index 0000000..4a01440 --- /dev/null +++ b/webrtc/common_audio/vad/vad_gmm.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/vad_gmm.h" + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/typedefs.h" + +static const int32_t kCompVar = 22005; +static const int16_t kLog2Exp = 5909; // log2(exp(1)) in Q12. + +// For a normal distribution, the probability of |input| is calculated and +// returned (in Q20). The formula for normal distributed probability is +// +// 1 / s * exp(-(x - m)^2 / (2 * s^2)) +// +// where the parameters are given in the following Q domains: +// m = |mean| (Q7) +// s = |std| (Q7) +// x = |input| (Q4) +// in addition to the probability we output |delta| (in Q11) used when updating +// the noise/speech model. +int32_t WebRtcVad_GaussianProbability(int16_t input, + int16_t mean, + int16_t std, + int16_t* delta) { + int16_t tmp16, inv_std, inv_std2, exp_value = 0; + int32_t tmp32; + + // Calculate |inv_std| = 1 / s, in Q10. + // 131072 = 1 in Q17, and (|std| >> 1) is for rounding instead of truncation. + // Q-domain: Q17 / Q7 = Q10. + tmp32 = (int32_t) 131072 + (int32_t) (std >> 1); + inv_std = (int16_t) WebRtcSpl_DivW32W16(tmp32, std); + + // Calculate |inv_std2| = 1 / s^2, in Q14. + tmp16 = (inv_std >> 2); // Q10 -> Q8. + // Q-domain: (Q8 * Q8) >> 2 = Q14. + inv_std2 = (int16_t)((tmp16 * tmp16) >> 2); + // TODO(bjornv): Investigate if changing to + // inv_std2 = (int16_t)((inv_std * inv_std) >> 6); + // gives better accuracy. + + tmp16 = (input << 3); // Q4 -> Q7 + tmp16 = tmp16 - mean; // Q7 - Q7 = Q7 + + // To be used later, when updating noise/speech model. + // |delta| = (x - m) / s^2, in Q11. + // Q-domain: (Q14 * Q7) >> 10 = Q11. + *delta = (int16_t)((inv_std2 * tmp16) >> 10); + + // Calculate the exponent |tmp32| = (x - m)^2 / (2 * s^2), in Q10. Replacing + // division by two with one shift. + // Q-domain: (Q11 * Q7) >> 8 = Q10. + tmp32 = (*delta * tmp16) >> 9; + + // If the exponent is small enough to give a non-zero probability we calculate + // |exp_value| ~= exp(-(x - m)^2 / (2 * s^2)) + // ~= exp2(-log2(exp(1)) * |tmp32|). + if (tmp32 < kCompVar) { + // Calculate |tmp16| = log2(exp(1)) * |tmp32|, in Q10. + // Q-domain: (Q12 * Q10) >> 12 = Q10. + tmp16 = (int16_t)((kLog2Exp * tmp32) >> 12); + tmp16 = -tmp16; + exp_value = (0x0400 | (tmp16 & 0x03FF)); + tmp16 ^= 0xFFFF; + tmp16 >>= 10; + tmp16 += 1; + // Get |exp_value| = exp(-|tmp32|) in Q10. + exp_value >>= tmp16; + } + + // Calculate and return (1 / s) * exp(-(x - m)^2 / (2 * s^2)), in Q20. + // Q-domain: Q10 * Q10 = Q20. + return inv_std * exp_value; +} diff --git a/webrtc/common_audio/vad/vad_gmm.h b/webrtc/common_audio/vad/vad_gmm.h new file mode 100644 index 0000000..992a156 --- /dev/null +++ b/webrtc/common_audio/vad/vad_gmm.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Gaussian probability calculations internally used in vad_core.c. + +#ifndef WEBRTC_COMMON_AUDIO_VAD_VAD_GMM_H_ +#define WEBRTC_COMMON_AUDIO_VAD_VAD_GMM_H_ + +#include "webrtc/typedefs.h" + +// Calculates the probability for |input|, given that |input| comes from a +// normal distribution with mean and standard deviation (|mean|, |std|). +// +// Inputs: +// - input : input sample in Q4. +// - mean : mean input in the statistical model, Q7. +// - std : standard deviation, Q7. +// +// Output: +// +// - delta : input used when updating the model, Q11. +// |delta| = (|input| - |mean|) / |std|^2. +// +// Return: +// (probability for |input|) = +// 1 / |std| * exp(-(|input| - |mean|)^2 / (2 * |std|^2)); +int32_t WebRtcVad_GaussianProbability(int16_t input, + int16_t mean, + int16_t std, + int16_t* delta); + +#endif // WEBRTC_COMMON_AUDIO_VAD_VAD_GMM_H_ diff --git a/webrtc/common_audio/vad/vad_sp.c b/webrtc/common_audio/vad/vad_sp.c new file mode 100644 index 0000000..a54be17 --- /dev/null +++ b/webrtc/common_audio/vad/vad_sp.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/vad_sp.h" + +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/vad/vad_core.h" +#include "webrtc/typedefs.h" + +// Allpass filter coefficients, upper and lower, in Q13. +// Upper: 0.64, Lower: 0.17. +static const int16_t kAllPassCoefsQ13[2] = { 5243, 1392 }; // Q13. +static const int16_t kSmoothingDown = 6553; // 0.2 in Q15. +static const int16_t kSmoothingUp = 32439; // 0.99 in Q15. + +// TODO(bjornv): Move this function to vad_filterbank.c. +// Downsampling filter based on splitting filter and allpass functions. +void WebRtcVad_Downsampling(const int16_t* signal_in, + int16_t* signal_out, + int32_t* filter_state, + size_t in_length) { + int16_t tmp16_1 = 0, tmp16_2 = 0; + int32_t tmp32_1 = filter_state[0]; + int32_t tmp32_2 = filter_state[1]; + size_t n = 0; + // Downsampling by 2 gives half length. + size_t half_length = (in_length >> 1); + + // Filter coefficients in Q13, filter state in Q0. + for (n = 0; n < half_length; n++) { + // All-pass filtering upper branch. + tmp16_1 = (int16_t) ((tmp32_1 >> 1) + + ((kAllPassCoefsQ13[0] * *signal_in) >> 14)); + *signal_out = tmp16_1; + tmp32_1 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[0] * tmp16_1) >> 12); + + // All-pass filtering lower branch. + tmp16_2 = (int16_t) ((tmp32_2 >> 1) + + ((kAllPassCoefsQ13[1] * *signal_in) >> 14)); + *signal_out++ += tmp16_2; + tmp32_2 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[1] * tmp16_2) >> 12); + } + // Store the filter states. + filter_state[0] = tmp32_1; + filter_state[1] = tmp32_2; +} + +// Inserts |feature_value| into |low_value_vector|, if it is one of the 16 +// smallest values the last 100 frames. Then calculates and returns the median +// of the five smallest values. +int16_t WebRtcVad_FindMinimum(VadInstT* self, + int16_t feature_value, + int channel) { + int i = 0, j = 0; + int position = -1; + // Offset to beginning of the 16 minimum values in memory. + const int offset = (channel << 4); + int16_t current_median = 1600; + int16_t alpha = 0; + int32_t tmp32 = 0; + // Pointer to memory for the 16 minimum values and the age of each value of + // the |channel|. + int16_t* age = &self->index_vector[offset]; + int16_t* smallest_values = &self->low_value_vector[offset]; + + assert(channel < kNumChannels); + + // Each value in |smallest_values| is getting 1 loop older. Update |age|, and + // remove old values. + for (i = 0; i < 16; i++) { + if (age[i] != 100) { + age[i]++; + } else { + // Too old value. Remove from memory and shift larger values downwards. + for (j = i; j < 16; j++) { + smallest_values[j] = smallest_values[j + 1]; + age[j] = age[j + 1]; + } + age[15] = 101; + smallest_values[15] = 10000; + } + } + + // Check if |feature_value| is smaller than any of the values in + // |smallest_values|. If so, find the |position| where to insert the new value + // (|feature_value|). + if (feature_value < smallest_values[7]) { + if (feature_value < smallest_values[3]) { + if (feature_value < smallest_values[1]) { + if (feature_value < smallest_values[0]) { + position = 0; + } else { + position = 1; + } + } else if (feature_value < smallest_values[2]) { + position = 2; + } else { + position = 3; + } + } else if (feature_value < smallest_values[5]) { + if (feature_value < smallest_values[4]) { + position = 4; + } else { + position = 5; + } + } else if (feature_value < smallest_values[6]) { + position = 6; + } else { + position = 7; + } + } else if (feature_value < smallest_values[15]) { + if (feature_value < smallest_values[11]) { + if (feature_value < smallest_values[9]) { + if (feature_value < smallest_values[8]) { + position = 8; + } else { + position = 9; + } + } else if (feature_value < smallest_values[10]) { + position = 10; + } else { + position = 11; + } + } else if (feature_value < smallest_values[13]) { + if (feature_value < smallest_values[12]) { + position = 12; + } else { + position = 13; + } + } else if (feature_value < smallest_values[14]) { + position = 14; + } else { + position = 15; + } + } + + // If we have detected a new small value, insert it at the correct position + // and shift larger values up. + if (position > -1) { + for (i = 15; i > position; i--) { + smallest_values[i] = smallest_values[i - 1]; + age[i] = age[i - 1]; + } + smallest_values[position] = feature_value; + age[position] = 1; + } + + // Get |current_median|. + if (self->frame_counter > 2) { + current_median = smallest_values[2]; + } else if (self->frame_counter > 0) { + current_median = smallest_values[0]; + } + + // Smooth the median value. + if (self->frame_counter > 0) { + if (current_median < self->mean_value[channel]) { + alpha = kSmoothingDown; // 0.2 in Q15. + } else { + alpha = kSmoothingUp; // 0.99 in Q15. + } + } + tmp32 = (alpha + 1) * self->mean_value[channel]; + tmp32 += (WEBRTC_SPL_WORD16_MAX - alpha) * current_median; + tmp32 += 16384; + self->mean_value[channel] = (int16_t) (tmp32 >> 15); + + return self->mean_value[channel]; +} diff --git a/webrtc/common_audio/vad/vad_sp.h b/webrtc/common_audio/vad/vad_sp.h new file mode 100644 index 0000000..4d2b02a --- /dev/null +++ b/webrtc/common_audio/vad/vad_sp.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +// This file includes specific signal processing tools used in vad_core.c. + +#ifndef WEBRTC_COMMON_AUDIO_VAD_VAD_SP_H_ +#define WEBRTC_COMMON_AUDIO_VAD_VAD_SP_H_ + +#include "webrtc/common_audio/vad/vad_core.h" +#include "webrtc/typedefs.h" + +// Downsamples the signal by a factor 2, eg. 32->16 or 16->8. +// +// Inputs: +// - signal_in : Input signal. +// - in_length : Length of input signal in samples. +// +// Input & Output: +// - filter_state : Current filter states of the two all-pass filters. The +// |filter_state| is updated after all samples have been +// processed. +// +// Output: +// - signal_out : Downsampled signal (of length |in_length| / 2). +void WebRtcVad_Downsampling(const int16_t* signal_in, + int16_t* signal_out, + int32_t* filter_state, + size_t in_length); + +// Updates and returns the smoothed feature minimum. As minimum we use the +// median of the five smallest feature values in a 100 frames long window. +// As long as |handle->frame_counter| is zero, that is, we haven't received any +// "valid" data, FindMinimum() outputs the default value of 1600. +// +// Inputs: +// - feature_value : New feature value to update with. +// - channel : Channel number. +// +// Input & Output: +// - handle : State information of the VAD. +// +// Returns: +// : Smoothed minimum value for a moving window. +int16_t WebRtcVad_FindMinimum(VadInstT* handle, + int16_t feature_value, + int channel); + +#endif // WEBRTC_COMMON_AUDIO_VAD_VAD_SP_H_ diff --git a/webrtc/common_audio/vad/webrtc_vad.c b/webrtc/common_audio/vad/webrtc_vad.c new file mode 100644 index 0000000..80c8f3c --- /dev/null +++ b/webrtc/common_audio/vad/webrtc_vad.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/vad/include/webrtc_vad.h" + +#include +#include + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/vad/vad_core.h" +#include "webrtc/typedefs.h" + +static const int kInitCheck = 42; +static const int kValidRates[] = { 8000, 16000, 32000, 48000 }; +static const size_t kRatesSize = sizeof(kValidRates) / sizeof(*kValidRates); +static const int kMaxFrameLengthMs = 30; + +VadInst* WebRtcVad_Create() { + VadInstT* self = (VadInstT*)malloc(sizeof(VadInstT)); + + WebRtcSpl_Init(); + self->init_flag = 0; + + return (VadInst*)self; +} + +void WebRtcVad_Free(VadInst* handle) { + free(handle); +} + +// TODO(bjornv): Move WebRtcVad_InitCore() code here. +int WebRtcVad_Init(VadInst* handle) { + // Initialize the core VAD component. + return WebRtcVad_InitCore((VadInstT*) handle); +} + +// TODO(bjornv): Move WebRtcVad_set_mode_core() code here. +int WebRtcVad_set_mode(VadInst* handle, int mode) { + VadInstT* self = (VadInstT*) handle; + + if (handle == NULL) { + return -1; + } + if (self->init_flag != kInitCheck) { + return -1; + } + + return WebRtcVad_set_mode_core(self, mode); +} + +int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame, + size_t frame_length) { + int vad = -1; + VadInstT* self = (VadInstT*) handle; + + if (handle == NULL) { + return -1; + } + + if (self->init_flag != kInitCheck) { + return -1; + } + if (audio_frame == NULL) { + return -1; + } + if (WebRtcVad_ValidRateAndFrameLength(fs, frame_length) != 0) { + return -1; + } + + if (fs == 48000) { + vad = WebRtcVad_CalcVad48khz(self, audio_frame, frame_length); + } else if (fs == 32000) { + vad = WebRtcVad_CalcVad32khz(self, audio_frame, frame_length); + } else if (fs == 16000) { + vad = WebRtcVad_CalcVad16khz(self, audio_frame, frame_length); + } else if (fs == 8000) { + vad = WebRtcVad_CalcVad8khz(self, audio_frame, frame_length); + } + + if (vad > 0) { + vad = 1; + } + return vad; +} + +int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length) { + int return_value = -1; + size_t i; + int valid_length_ms; + size_t valid_length; + + // We only allow 10, 20 or 30 ms frames. Loop through valid frame rates and + // see if we have a matching pair. + for (i = 0; i < kRatesSize; i++) { + if (kValidRates[i] == rate) { + for (valid_length_ms = 10; valid_length_ms <= kMaxFrameLengthMs; + valid_length_ms += 10) { + valid_length = (size_t)(kValidRates[i] / 1000 * valid_length_ms); + if (frame_length == valid_length) { + return_value = 0; + break; + } + } + break; + } + } + + return return_value; +} diff --git a/webrtc/common_types.h b/webrtc/common_types.h new file mode 100644 index 0000000..c11c4d7 --- /dev/null +++ b/webrtc/common_types.h @@ -0,0 +1,903 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_COMMON_TYPES_H_ +#define WEBRTC_COMMON_TYPES_H_ + +#include +#include + +#include +#include + +#include "webrtc/typedefs.h" + +#if defined(_MSC_VER) +// Disable "new behavior: elements of array will be default initialized" +// warning. Affects OverUseDetectorOptions. +#pragma warning(disable:4351) +#endif + +#ifdef WEBRTC_EXPORT +#define WEBRTC_DLLEXPORT _declspec(dllexport) +#elif WEBRTC_DLL +#define WEBRTC_DLLEXPORT _declspec(dllimport) +#else +#define WEBRTC_DLLEXPORT +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define RTP_PAYLOAD_NAME_SIZE 32 + +#if defined(WEBRTC_WIN) || defined(WIN32) +// Compares two strings without regard to case. +#define STR_CASE_CMP(s1, s2) ::_stricmp(s1, s2) +// Compares characters of two strings without regard to case. +#define STR_NCASE_CMP(s1, s2, n) ::_strnicmp(s1, s2, n) +#else +#define STR_CASE_CMP(s1, s2) ::strcasecmp(s1, s2) +#define STR_NCASE_CMP(s1, s2, n) ::strncasecmp(s1, s2, n) +#endif + +namespace webrtc { + +class Config; + +class InStream +{ +public: + // Reads |length| bytes from file to |buf|. Returns the number of bytes read + // or -1 on error. + virtual int Read(void *buf, size_t len) = 0; + virtual int Rewind(); + virtual ~InStream() {} +protected: + InStream() {} +}; + +class OutStream +{ +public: + // Writes |length| bytes from |buf| to file. The actual writing may happen + // some time later. Call Flush() to force a write. + virtual bool Write(const void *buf, size_t len) = 0; + virtual int Rewind(); + virtual ~OutStream() {} +protected: + OutStream() {} +}; + +enum TraceModule +{ + kTraceUndefined = 0, + // not a module, triggered from the engine code + kTraceVoice = 0x0001, + // not a module, triggered from the engine code + kTraceVideo = 0x0002, + // not a module, triggered from the utility code + kTraceUtility = 0x0003, + kTraceRtpRtcp = 0x0004, + kTraceTransport = 0x0005, + kTraceSrtp = 0x0006, + kTraceAudioCoding = 0x0007, + kTraceAudioMixerServer = 0x0008, + kTraceAudioMixerClient = 0x0009, + kTraceFile = 0x000a, + kTraceAudioProcessing = 0x000b, + kTraceVideoCoding = 0x0010, + kTraceVideoMixer = 0x0011, + kTraceAudioDevice = 0x0012, + kTraceVideoRenderer = 0x0014, + kTraceVideoCapture = 0x0015, + kTraceRemoteBitrateEstimator = 0x0017, +}; + +enum TraceLevel +{ + kTraceNone = 0x0000, // no trace + kTraceStateInfo = 0x0001, + kTraceWarning = 0x0002, + kTraceError = 0x0004, + kTraceCritical = 0x0008, + kTraceApiCall = 0x0010, + kTraceDefault = 0x00ff, + + kTraceModuleCall = 0x0020, + kTraceMemory = 0x0100, // memory info + kTraceTimer = 0x0200, // timing info + kTraceStream = 0x0400, // "continuous" stream of data + + // used for debug purposes + kTraceDebug = 0x0800, // debug + kTraceInfo = 0x1000, // debug info + + // Non-verbose level used by LS_INFO of logging.h. Do not use directly. + kTraceTerseInfo = 0x2000, + + kTraceAll = 0xffff +}; + +// External Trace API +class TraceCallback { + public: + virtual void Print(TraceLevel level, const char* message, int length) = 0; + + protected: + virtual ~TraceCallback() {} + TraceCallback() {} +}; + +enum FileFormats +{ + kFileFormatWavFile = 1, + kFileFormatCompressedFile = 2, + kFileFormatPreencodedFile = 4, + kFileFormatPcm16kHzFile = 7, + kFileFormatPcm8kHzFile = 8, + kFileFormatPcm32kHzFile = 9 +}; + +enum ProcessingTypes +{ + kPlaybackPerChannel = 0, + kPlaybackAllChannelsMixed, + kRecordingPerChannel, + kRecordingAllChannelsMixed, + kRecordingPreprocessing +}; + +enum FrameType +{ + kFrameEmpty = 0, + kAudioFrameSpeech = 1, + kAudioFrameCN = 2, + kVideoFrameKey = 3, // independent frame + kVideoFrameDelta = 4, // depends on the previus frame +}; + +// Statistics for an RTCP channel +struct RtcpStatistics { + RtcpStatistics() + : fraction_lost(0), + cumulative_lost(0), + extended_max_sequence_number(0), + jitter(0) {} + + uint8_t fraction_lost; + uint32_t cumulative_lost; + uint32_t extended_max_sequence_number; + uint32_t jitter; +}; + +class RtcpStatisticsCallback { + public: + virtual ~RtcpStatisticsCallback() {} + + virtual void StatisticsUpdated(const RtcpStatistics& statistics, + uint32_t ssrc) = 0; + virtual void CNameChanged(const char* cname, uint32_t ssrc) = 0; +}; + +// Statistics for RTCP packet types. +struct RtcpPacketTypeCounter { + RtcpPacketTypeCounter() + : first_packet_time_ms(-1), + nack_packets(0), + fir_packets(0), + pli_packets(0), + nack_requests(0), + unique_nack_requests(0) {} + + void Add(const RtcpPacketTypeCounter& other) { + nack_packets += other.nack_packets; + fir_packets += other.fir_packets; + pli_packets += other.pli_packets; + nack_requests += other.nack_requests; + unique_nack_requests += other.unique_nack_requests; + if (other.first_packet_time_ms != -1 && + (other.first_packet_time_ms < first_packet_time_ms || + first_packet_time_ms == -1)) { + // Use oldest time. + first_packet_time_ms = other.first_packet_time_ms; + } + } + + int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const { + return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms); + } + + int UniqueNackRequestsInPercent() const { + if (nack_requests == 0) { + return 0; + } + return static_cast( + (unique_nack_requests * 100.0f / nack_requests) + 0.5f); + } + + int64_t first_packet_time_ms; // Time when first packet is sent/received. + uint32_t nack_packets; // Number of RTCP NACK packets. + uint32_t fir_packets; // Number of RTCP FIR packets. + uint32_t pli_packets; // Number of RTCP PLI packets. + uint32_t nack_requests; // Number of NACKed RTP packets. + uint32_t unique_nack_requests; // Number of unique NACKed RTP packets. +}; + +class RtcpPacketTypeCounterObserver { + public: + virtual ~RtcpPacketTypeCounterObserver() {} + virtual void RtcpPacketTypesCounterUpdated( + uint32_t ssrc, + const RtcpPacketTypeCounter& packet_counter) = 0; +}; + +// Rate statistics for a stream. +struct BitrateStatistics { + BitrateStatistics() : bitrate_bps(0), packet_rate(0), timestamp_ms(0) {} + + uint32_t bitrate_bps; // Bitrate in bits per second. + uint32_t packet_rate; // Packet rate in packets per second. + uint64_t timestamp_ms; // Ntp timestamp in ms at time of rate estimation. +}; + +// Callback, used to notify an observer whenever new rates have been estimated. +class BitrateStatisticsObserver { + public: + virtual ~BitrateStatisticsObserver() {} + + virtual void Notify(const BitrateStatistics& total_stats, + const BitrateStatistics& retransmit_stats, + uint32_t ssrc) = 0; +}; + +struct FrameCounts { + FrameCounts() : key_frames(0), delta_frames(0) {} + int key_frames; + int delta_frames; +}; + +// Callback, used to notify an observer whenever frame counts have been updated. +class FrameCountObserver { + public: + virtual ~FrameCountObserver() {} + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) = 0; +}; + +// Callback, used to notify an observer whenever the send-side delay is updated. +class SendSideDelayObserver { + public: + virtual ~SendSideDelayObserver() {} + virtual void SendSideDelayUpdated(int avg_delay_ms, + int max_delay_ms, + uint32_t ssrc) = 0; +}; + +// ================================================================== +// Voice specific types +// ================================================================== + +// Each codec supported can be described by this structure. +struct CodecInst { + int pltype; + char plname[RTP_PAYLOAD_NAME_SIZE]; + int plfreq; + int pacsize; + int channels; + int rate; // bits/sec unlike {start,min,max}Bitrate elsewhere in this file! + + bool operator==(const CodecInst& other) const { + return pltype == other.pltype && + (STR_CASE_CMP(plname, other.plname) == 0) && + plfreq == other.plfreq && + pacsize == other.pacsize && + channels == other.channels && + rate == other.rate; + } + + bool operator!=(const CodecInst& other) const { + return !(*this == other); + } +}; + +// RTP +enum {kRtpCsrcSize = 15}; // RFC 3550 page 13 + +enum RTPDirections +{ + kRtpIncoming = 0, + kRtpOutgoing +}; + +enum PayloadFrequencies +{ + kFreq8000Hz = 8000, + kFreq16000Hz = 16000, + kFreq32000Hz = 32000 +}; + +enum VadModes // degree of bandwidth reduction +{ + kVadConventional = 0, // lowest reduction + kVadAggressiveLow, + kVadAggressiveMid, + kVadAggressiveHigh // highest reduction +}; + +struct NetworkStatistics // NETEQ statistics +{ + // current jitter buffer size in ms + uint16_t currentBufferSize; + // preferred (optimal) buffer size in ms + uint16_t preferredBufferSize; + // adding extra delay due to "peaky jitter" + bool jitterPeaksFound; + // Loss rate (network + late); fraction between 0 and 1, scaled to Q14. + uint16_t currentPacketLossRate; + // Late loss rate; fraction between 0 and 1, scaled to Q14. + uint16_t currentDiscardRate; + // fraction (of original stream) of synthesized audio inserted through + // expansion (in Q14) + uint16_t currentExpandRate; + // fraction (of original stream) of synthesized speech inserted through + // expansion (in Q14) + uint16_t currentSpeechExpandRate; + // fraction of synthesized speech inserted through pre-emptive expansion + // (in Q14) + uint16_t currentPreemptiveRate; + // fraction of data removed through acceleration (in Q14) + uint16_t currentAccelerateRate; + // fraction of data coming from secondary decoding (in Q14) + uint16_t currentSecondaryDecodedRate; + // clock-drift in parts-per-million (negative or positive) + int32_t clockDriftPPM; + // average packet waiting time in the jitter buffer (ms) + int meanWaitingTimeMs; + // median packet waiting time in the jitter buffer (ms) + int medianWaitingTimeMs; + // min packet waiting time in the jitter buffer (ms) + int minWaitingTimeMs; + // max packet waiting time in the jitter buffer (ms) + int maxWaitingTimeMs; + // added samples in off mode due to packet loss + size_t addedSamples; +}; + +// Statistics for calls to AudioCodingModule::PlayoutData10Ms(). +struct AudioDecodingCallStats { + AudioDecodingCallStats() + : calls_to_silence_generator(0), + calls_to_neteq(0), + decoded_normal(0), + decoded_plc(0), + decoded_cng(0), + decoded_plc_cng(0) {} + + int calls_to_silence_generator; // Number of calls where silence generated, + // and NetEq was disengaged from decoding. + int calls_to_neteq; // Number of calls to NetEq. + int decoded_normal; // Number of calls where audio RTP packet decoded. + int decoded_plc; // Number of calls resulted in PLC. + int decoded_cng; // Number of calls where comfort noise generated due to DTX. + int decoded_plc_cng; // Number of calls resulted where PLC faded to CNG. +}; + +typedef struct +{ + int min; // minumum + int max; // maximum + int average; // average +} StatVal; + +typedef struct // All levels are reported in dBm0 +{ + StatVal speech_rx; // long-term speech levels on receiving side + StatVal speech_tx; // long-term speech levels on transmitting side + StatVal noise_rx; // long-term noise/silence levels on receiving side + StatVal noise_tx; // long-term noise/silence levels on transmitting side +} LevelStatistics; + +typedef struct // All levels are reported in dB +{ + StatVal erl; // Echo Return Loss + StatVal erle; // Echo Return Loss Enhancement + StatVal rerl; // RERL = ERL + ERLE + // Echo suppression inside EC at the point just before its NLP + StatVal a_nlp; +} EchoStatistics; + +enum NsModes // type of Noise Suppression +{ + kNsUnchanged = 0, // previously set mode + kNsDefault, // platform default + kNsConference, // conferencing default + kNsLowSuppression, // lowest suppression + kNsModerateSuppression, + kNsHighSuppression, + kNsVeryHighSuppression, // highest suppression +}; + +enum AgcModes // type of Automatic Gain Control +{ + kAgcUnchanged = 0, // previously set mode + kAgcDefault, // platform default + // adaptive mode for use when analog volume control exists (e.g. for + // PC softphone) + kAgcAdaptiveAnalog, + // scaling takes place in the digital domain (e.g. for conference servers + // and embedded devices) + kAgcAdaptiveDigital, + // can be used on embedded devices where the capture signal level + // is predictable + kAgcFixedDigital +}; + +// EC modes +enum EcModes // type of Echo Control +{ + kEcUnchanged = 0, // previously set mode + kEcDefault, // platform default + kEcConference, // conferencing default (aggressive AEC) + kEcAec, // Acoustic Echo Cancellation + kEcAecm, // AEC mobile +}; + +// AECM modes +enum AecmModes // mode of AECM +{ + kAecmQuietEarpieceOrHeadset = 0, + // Quiet earpiece or headset use + kAecmEarpiece, // most earpiece use + kAecmLoudEarpiece, // Loud earpiece or quiet speakerphone use + kAecmSpeakerphone, // most speakerphone use (default) + kAecmLoudSpeakerphone // Loud speakerphone +}; + +// AGC configuration +typedef struct +{ + unsigned short targetLeveldBOv; + unsigned short digitalCompressionGaindB; + bool limiterEnable; +} AgcConfig; // AGC configuration parameters + +enum StereoChannel +{ + kStereoLeft = 0, + kStereoRight, + kStereoBoth +}; + +// Audio device layers +enum AudioLayers +{ + kAudioPlatformDefault = 0, + kAudioWindowsWave = 1, + kAudioWindowsCore = 2, + kAudioLinuxAlsa = 3, + kAudioLinuxPulse = 4 +}; + +// TODO(henrika): to be removed. +enum NetEqModes // NetEQ playout configurations +{ + // Optimized trade-off between low delay and jitter robustness for two-way + // communication. + kNetEqDefault = 0, + // Improved jitter robustness at the cost of increased delay. Can be + // used in one-way communication. + kNetEqStreaming = 1, + // Optimzed for decodability of fax signals rather than for perceived audio + // quality. + kNetEqFax = 2, + // Minimal buffer management. Inserts zeros for lost packets and during + // buffer increases. + kNetEqOff = 3, +}; + +// TODO(henrika): to be removed. +enum OnHoldModes // On Hold direction +{ + kHoldSendAndPlay = 0, // Put both sending and playing in on-hold state. + kHoldSendOnly, // Put only sending in on-hold state. + kHoldPlayOnly // Put only playing in on-hold state. +}; + +// TODO(henrika): to be removed. +enum AmrMode +{ + kRfc3267BwEfficient = 0, + kRfc3267OctetAligned = 1, + kRfc3267FileStorage = 2, +}; + +// ================================================================== +// Video specific types +// ================================================================== + +// Raw video types +enum RawVideoType +{ + kVideoI420 = 0, + kVideoYV12 = 1, + kVideoYUY2 = 2, + kVideoUYVY = 3, + kVideoIYUV = 4, + kVideoARGB = 5, + kVideoRGB24 = 6, + kVideoRGB565 = 7, + kVideoARGB4444 = 8, + kVideoARGB1555 = 9, + kVideoMJPEG = 10, + kVideoNV12 = 11, + kVideoNV21 = 12, + kVideoBGRA = 13, + kVideoUnknown = 99 +}; + +// Video codec +enum { kConfigParameterSize = 128}; +enum { kPayloadNameSize = 32}; +enum { kMaxSimulcastStreams = 4}; +enum { kMaxTemporalStreams = 4}; + +enum VideoCodecComplexity +{ + kComplexityNormal = 0, + kComplexityHigh = 1, + kComplexityHigher = 2, + kComplexityMax = 3 +}; + +enum VideoCodecProfile +{ + kProfileBase = 0x00, + kProfileMain = 0x01 +}; + +enum VP8ResilienceMode { + kResilienceOff, // The stream produced by the encoder requires a + // recovery frame (typically a key frame) to be + // decodable after a packet loss. + kResilientStream, // A stream produced by the encoder is resilient to + // packet losses, but packets within a frame subsequent + // to a loss can't be decoded. + kResilientFrames // Same as kResilientStream but with added resilience + // within a frame. +}; + +// VP8 specific +struct VideoCodecVP8 { + bool pictureLossIndicationOn; + bool feedbackModeOn; + VideoCodecComplexity complexity; + VP8ResilienceMode resilience; + unsigned char numberOfTemporalLayers; + bool denoisingOn; + bool errorConcealmentOn; + bool automaticResizeOn; + bool frameDroppingOn; + int keyFrameInterval; + + bool operator==(const VideoCodecVP8& other) const { + return pictureLossIndicationOn == other.pictureLossIndicationOn && + feedbackModeOn == other.feedbackModeOn && + complexity == other.complexity && + resilience == other.resilience && + numberOfTemporalLayers == other.numberOfTemporalLayers && + denoisingOn == other.denoisingOn && + errorConcealmentOn == other.errorConcealmentOn && + automaticResizeOn == other.automaticResizeOn && + frameDroppingOn == other.frameDroppingOn && + keyFrameInterval == other.keyFrameInterval; + } + + bool operator!=(const VideoCodecVP8& other) const { + return !(*this == other); + } +}; + +// VP9 specific. +struct VideoCodecVP9 { + VideoCodecComplexity complexity; + int resilience; + unsigned char numberOfTemporalLayers; + bool denoisingOn; + bool frameDroppingOn; + int keyFrameInterval; + bool adaptiveQpMode; + bool automaticResizeOn; + unsigned char numberOfSpatialLayers; + bool flexibleMode; +}; + +// H264 specific. +struct VideoCodecH264 { + VideoCodecProfile profile; + bool frameDroppingOn; + int keyFrameInterval; + // These are NULL/0 if not externally negotiated. + const uint8_t* spsData; + size_t spsLen; + const uint8_t* ppsData; + size_t ppsLen; +}; + +// Video codec types +enum VideoCodecType { + kVideoCodecVP8, + kVideoCodecVP9, + kVideoCodecH264, + kVideoCodecI420, + kVideoCodecRED, + kVideoCodecULPFEC, + kVideoCodecGeneric, + kVideoCodecUnknown +}; + +union VideoCodecUnion { + VideoCodecVP8 VP8; + VideoCodecVP9 VP9; + VideoCodecH264 H264; +}; + + +// Simulcast is when the same stream is encoded multiple times with different +// settings such as resolution. +struct SimulcastStream { + unsigned short width; + unsigned short height; + unsigned char numberOfTemporalLayers; + unsigned int maxBitrate; // kilobits/sec. + unsigned int targetBitrate; // kilobits/sec. + unsigned int minBitrate; // kilobits/sec. + unsigned int qpMax; // minimum quality + + bool operator==(const SimulcastStream& other) const { + return width == other.width && + height == other.height && + numberOfTemporalLayers == other.numberOfTemporalLayers && + maxBitrate == other.maxBitrate && + targetBitrate == other.targetBitrate && + minBitrate == other.minBitrate && + qpMax == other.qpMax; + } + + bool operator!=(const SimulcastStream& other) const { + return !(*this == other); + } +}; + +enum VideoCodecMode { + kRealtimeVideo, + kScreensharing +}; + +// Common video codec properties +struct VideoCodec { + VideoCodecType codecType; + char plName[kPayloadNameSize]; + unsigned char plType; + + unsigned short width; + unsigned short height; + + unsigned int startBitrate; // kilobits/sec. + unsigned int maxBitrate; // kilobits/sec. + unsigned int minBitrate; // kilobits/sec. + unsigned int targetBitrate; // kilobits/sec. + + unsigned char maxFramerate; + + VideoCodecUnion codecSpecific; + + unsigned int qpMax; + unsigned char numberOfSimulcastStreams; + SimulcastStream simulcastStream[kMaxSimulcastStreams]; + + VideoCodecMode mode; + + // When using an external encoder/decoder this allows to pass + // extra options without requiring webrtc to be aware of them. + Config* extra_options; + + bool operator==(const VideoCodec& other) const { + bool ret = codecType == other.codecType && + (STR_CASE_CMP(plName, other.plName) == 0) && + plType == other.plType && + width == other.width && + height == other.height && + startBitrate == other.startBitrate && + maxBitrate == other.maxBitrate && + minBitrate == other.minBitrate && + targetBitrate == other.targetBitrate && + maxFramerate == other.maxFramerate && + qpMax == other.qpMax && + numberOfSimulcastStreams == other.numberOfSimulcastStreams && + mode == other.mode; + if (ret && codecType == kVideoCodecVP8) { + ret &= (codecSpecific.VP8 == other.codecSpecific.VP8); + } + + for (unsigned char i = 0; i < other.numberOfSimulcastStreams && ret; ++i) { + ret &= (simulcastStream[i] == other.simulcastStream[i]); + } + return ret; + } + + bool operator!=(const VideoCodec& other) const { + return !(*this == other); + } +}; + +// Bandwidth over-use detector options. These are used to drive +// experimentation with bandwidth estimation parameters. +// See modules/remote_bitrate_estimator/overuse_detector.h +struct OverUseDetectorOptions { + OverUseDetectorOptions() + : initial_slope(8.0/512.0), + initial_offset(0), + initial_e(), + initial_process_noise(), + initial_avg_noise(0.0), + initial_var_noise(50) { + initial_e[0][0] = 100; + initial_e[1][1] = 1e-1; + initial_e[0][1] = initial_e[1][0] = 0; + initial_process_noise[0] = 1e-13; + initial_process_noise[1] = 1e-2; + } + double initial_slope; + double initial_offset; + double initial_e[2][2]; + double initial_process_noise[2]; + double initial_avg_noise; + double initial_var_noise; +}; + +// This structure will have the information about when packet is actually +// received by socket. +struct PacketTime { + PacketTime() : timestamp(-1), not_before(-1) {} + PacketTime(int64_t timestamp, int64_t not_before) + : timestamp(timestamp), not_before(not_before) { + } + + int64_t timestamp; // Receive time after socket delivers the data. + int64_t not_before; // Earliest possible time the data could have arrived, + // indicating the potential error in the |timestamp| + // value,in case the system is busy. + // For example, the time of the last select() call. + // If unknown, this value will be set to zero. +}; + +struct RTPHeaderExtension { + RTPHeaderExtension(); + + bool hasTransmissionTimeOffset; + int32_t transmissionTimeOffset; + bool hasAbsoluteSendTime; + uint32_t absoluteSendTime; + bool hasTransportSequenceNumber; + uint16_t transportSequenceNumber; + + // Audio Level includes both level in dBov and voiced/unvoiced bit. See: + // https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/ + bool hasAudioLevel; + bool voiceActivity; + uint8_t audioLevel; + + // For Coordination of Video Orientation. See + // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ + // ts_126114v120700p.pdf + bool hasVideoRotation; + uint8_t videoRotation; +}; + +struct RTPHeader { + RTPHeader(); + + bool markerBit; + uint8_t payloadType; + uint16_t sequenceNumber; + uint32_t timestamp; + uint32_t ssrc; + uint8_t numCSRCs; + uint32_t arrOfCSRCs[kRtpCsrcSize]; + size_t paddingLength; + size_t headerLength; + int payload_type_frequency; + RTPHeaderExtension extension; +}; + +struct RtpPacketCounter { + RtpPacketCounter() + : header_bytes(0), + payload_bytes(0), + padding_bytes(0), + packets(0) {} + + void Add(const RtpPacketCounter& other) { + header_bytes += other.header_bytes; + payload_bytes += other.payload_bytes; + padding_bytes += other.padding_bytes; + packets += other.packets; + } + + void AddPacket(size_t packet_length, const RTPHeader& header) { + ++packets; + header_bytes += header.headerLength; + padding_bytes += header.paddingLength; + payload_bytes += + packet_length - (header.headerLength + header.paddingLength); + } + + size_t TotalBytes() const { + return header_bytes + payload_bytes + padding_bytes; + } + + size_t header_bytes; // Number of bytes used by RTP headers. + size_t payload_bytes; // Payload bytes, excluding RTP headers and padding. + size_t padding_bytes; // Number of padding bytes. + uint32_t packets; // Number of packets. +}; + +// Data usage statistics for a (rtp) stream. +struct StreamDataCounters { + StreamDataCounters(); + + void Add(const StreamDataCounters& other) { + transmitted.Add(other.transmitted); + retransmitted.Add(other.retransmitted); + fec.Add(other.fec); + if (other.first_packet_time_ms != -1 && + (other.first_packet_time_ms < first_packet_time_ms || + first_packet_time_ms == -1)) { + // Use oldest time. + first_packet_time_ms = other.first_packet_time_ms; + } + } + + int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const { + return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms); + } + + // Returns the number of bytes corresponding to the actual media payload (i.e. + // RTP headers, padding, retransmissions and fec packets are excluded). + // Note this function does not have meaning for an RTX stream. + size_t MediaPayloadBytes() const { + return transmitted.payload_bytes - retransmitted.payload_bytes - + fec.payload_bytes; + } + + int64_t first_packet_time_ms; // Time when first packet is sent/received. + RtpPacketCounter transmitted; // Number of transmitted packets/bytes. + RtpPacketCounter retransmitted; // Number of retransmitted packets/bytes. + RtpPacketCounter fec; // Number of redundancy packets/bytes. +}; + +// Callback, called whenever byte/packet counts have been updated. +class StreamDataCountersCallback { + public: + virtual ~StreamDataCountersCallback() {} + + virtual void DataCountersUpdated(const StreamDataCounters& counters, + uint32_t ssrc) = 0; +}; + +// RTCP mode to use. Compound mode is described by RFC 4585 and reduced-size +// RTCP mode is described by RFC 5506. +enum class RtcpMode { kOff, kCompound, kReducedSize }; + +} // namespace webrtc + +#endif // WEBRTC_COMMON_TYPES_H_ diff --git a/src/modules/Makefile.am b/webrtc/modules/Makefile.am similarity index 100% rename from src/modules/Makefile.am rename to webrtc/modules/Makefile.am diff --git a/src/modules/audio_processing/Makefile.am b/webrtc/modules/audio_processing/Makefile.am similarity index 100% rename from src/modules/audio_processing/Makefile.am rename to webrtc/modules/audio_processing/Makefile.am diff --git a/src/modules/audio_processing/OWNERS b/webrtc/modules/audio_processing/OWNERS similarity index 100% rename from src/modules/audio_processing/OWNERS rename to webrtc/modules/audio_processing/OWNERS diff --git a/src/modules/audio_processing/aec/Makefile.am b/webrtc/modules/audio_processing/aec/Makefile.am similarity index 100% rename from src/modules/audio_processing/aec/Makefile.am rename to webrtc/modules/audio_processing/aec/Makefile.am diff --git a/src/modules/audio_processing/aec/aec.gypi b/webrtc/modules/audio_processing/aec/aec.gypi similarity index 100% rename from src/modules/audio_processing/aec/aec.gypi rename to webrtc/modules/audio_processing/aec/aec.gypi diff --git a/src/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c similarity index 100% rename from src/modules/audio_processing/aec/aec_core.c rename to webrtc/modules/audio_processing/aec/aec_core.c diff --git a/src/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h similarity index 100% rename from src/modules/audio_processing/aec/aec_core.h rename to webrtc/modules/audio_processing/aec/aec_core.h diff --git a/src/modules/audio_processing/aec/aec_core_sse2.c b/webrtc/modules/audio_processing/aec/aec_core_sse2.c similarity index 100% rename from src/modules/audio_processing/aec/aec_core_sse2.c rename to webrtc/modules/audio_processing/aec/aec_core_sse2.c diff --git a/src/modules/audio_processing/aec/aec_rdft.c b/webrtc/modules/audio_processing/aec/aec_rdft.c similarity index 100% rename from src/modules/audio_processing/aec/aec_rdft.c rename to webrtc/modules/audio_processing/aec/aec_rdft.c diff --git a/src/modules/audio_processing/aec/aec_rdft.h b/webrtc/modules/audio_processing/aec/aec_rdft.h similarity index 100% rename from src/modules/audio_processing/aec/aec_rdft.h rename to webrtc/modules/audio_processing/aec/aec_rdft.h diff --git a/src/modules/audio_processing/aec/aec_rdft_sse2.c b/webrtc/modules/audio_processing/aec/aec_rdft_sse2.c similarity index 100% rename from src/modules/audio_processing/aec/aec_rdft_sse2.c rename to webrtc/modules/audio_processing/aec/aec_rdft_sse2.c diff --git a/src/modules/audio_processing/aec/echo_cancellation.c b/webrtc/modules/audio_processing/aec/echo_cancellation.c similarity index 100% rename from src/modules/audio_processing/aec/echo_cancellation.c rename to webrtc/modules/audio_processing/aec/echo_cancellation.c diff --git a/src/modules/audio_processing/aec/interface/echo_cancellation.h b/webrtc/modules/audio_processing/aec/interface/echo_cancellation.h similarity index 100% rename from src/modules/audio_processing/aec/interface/echo_cancellation.h rename to webrtc/modules/audio_processing/aec/interface/echo_cancellation.h diff --git a/src/modules/audio_processing/aec/resampler.c b/webrtc/modules/audio_processing/aec/resampler.c similarity index 100% rename from src/modules/audio_processing/aec/resampler.c rename to webrtc/modules/audio_processing/aec/resampler.c diff --git a/src/modules/audio_processing/aec/resampler.h b/webrtc/modules/audio_processing/aec/resampler.h similarity index 100% rename from src/modules/audio_processing/aec/resampler.h rename to webrtc/modules/audio_processing/aec/resampler.h diff --git a/src/modules/audio_processing/aecm/Makefile.am b/webrtc/modules/audio_processing/aecm/Makefile.am similarity index 100% rename from src/modules/audio_processing/aecm/Makefile.am rename to webrtc/modules/audio_processing/aecm/Makefile.am diff --git a/src/modules/audio_processing/aecm/aecm.gypi b/webrtc/modules/audio_processing/aecm/aecm.gypi similarity index 100% rename from src/modules/audio_processing/aecm/aecm.gypi rename to webrtc/modules/audio_processing/aecm/aecm.gypi diff --git a/src/modules/audio_processing/aecm/aecm_core.c b/webrtc/modules/audio_processing/aecm/aecm_core.c similarity index 100% rename from src/modules/audio_processing/aecm/aecm_core.c rename to webrtc/modules/audio_processing/aecm/aecm_core.c diff --git a/src/modules/audio_processing/aecm/aecm_core.h b/webrtc/modules/audio_processing/aecm/aecm_core.h similarity index 100% rename from src/modules/audio_processing/aecm/aecm_core.h rename to webrtc/modules/audio_processing/aecm/aecm_core.h diff --git a/src/modules/audio_processing/aecm/aecm_core_neon.c b/webrtc/modules/audio_processing/aecm/aecm_core_neon.c similarity index 100% rename from src/modules/audio_processing/aecm/aecm_core_neon.c rename to webrtc/modules/audio_processing/aecm/aecm_core_neon.c diff --git a/src/modules/audio_processing/aecm/echo_control_mobile.c b/webrtc/modules/audio_processing/aecm/echo_control_mobile.c similarity index 100% rename from src/modules/audio_processing/aecm/echo_control_mobile.c rename to webrtc/modules/audio_processing/aecm/echo_control_mobile.c diff --git a/src/modules/audio_processing/aecm/interface/echo_control_mobile.h b/webrtc/modules/audio_processing/aecm/interface/echo_control_mobile.h similarity index 100% rename from src/modules/audio_processing/aecm/interface/echo_control_mobile.h rename to webrtc/modules/audio_processing/aecm/interface/echo_control_mobile.h diff --git a/src/modules/audio_processing/agc/Makefile.am b/webrtc/modules/audio_processing/agc/Makefile.am similarity index 100% rename from src/modules/audio_processing/agc/Makefile.am rename to webrtc/modules/audio_processing/agc/Makefile.am diff --git a/src/modules/audio_processing/agc/agc.gypi b/webrtc/modules/audio_processing/agc/agc.gypi similarity index 100% rename from src/modules/audio_processing/agc/agc.gypi rename to webrtc/modules/audio_processing/agc/agc.gypi diff --git a/src/modules/audio_processing/agc/analog_agc.c b/webrtc/modules/audio_processing/agc/analog_agc.c similarity index 100% rename from src/modules/audio_processing/agc/analog_agc.c rename to webrtc/modules/audio_processing/agc/analog_agc.c diff --git a/src/modules/audio_processing/agc/analog_agc.h b/webrtc/modules/audio_processing/agc/analog_agc.h similarity index 100% rename from src/modules/audio_processing/agc/analog_agc.h rename to webrtc/modules/audio_processing/agc/analog_agc.h diff --git a/src/modules/audio_processing/agc/digital_agc.c b/webrtc/modules/audio_processing/agc/digital_agc.c similarity index 100% rename from src/modules/audio_processing/agc/digital_agc.c rename to webrtc/modules/audio_processing/agc/digital_agc.c diff --git a/src/modules/audio_processing/agc/digital_agc.h b/webrtc/modules/audio_processing/agc/digital_agc.h similarity index 100% rename from src/modules/audio_processing/agc/digital_agc.h rename to webrtc/modules/audio_processing/agc/digital_agc.h diff --git a/src/modules/audio_processing/agc/interface/gain_control.h b/webrtc/modules/audio_processing/agc/interface/gain_control.h similarity index 100% rename from src/modules/audio_processing/agc/interface/gain_control.h rename to webrtc/modules/audio_processing/agc/interface/gain_control.h diff --git a/src/modules/audio_processing/apm_tests.gypi b/webrtc/modules/audio_processing/apm_tests.gypi similarity index 100% rename from src/modules/audio_processing/apm_tests.gypi rename to webrtc/modules/audio_processing/apm_tests.gypi diff --git a/src/modules/audio_processing/audio_buffer.cc b/webrtc/modules/audio_processing/audio_buffer.cc similarity index 100% rename from src/modules/audio_processing/audio_buffer.cc rename to webrtc/modules/audio_processing/audio_buffer.cc diff --git a/src/modules/audio_processing/audio_buffer.h b/webrtc/modules/audio_processing/audio_buffer.h similarity index 100% rename from src/modules/audio_processing/audio_buffer.h rename to webrtc/modules/audio_processing/audio_buffer.h diff --git a/src/modules/audio_processing/audio_processing.gypi b/webrtc/modules/audio_processing/audio_processing.gypi similarity index 100% rename from src/modules/audio_processing/audio_processing.gypi rename to webrtc/modules/audio_processing/audio_processing.gypi diff --git a/src/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc similarity index 100% rename from src/modules/audio_processing/audio_processing_impl.cc rename to webrtc/modules/audio_processing/audio_processing_impl.cc diff --git a/src/modules/audio_processing/audio_processing_impl.h b/webrtc/modules/audio_processing/audio_processing_impl.h similarity index 100% rename from src/modules/audio_processing/audio_processing_impl.h rename to webrtc/modules/audio_processing/audio_processing_impl.h diff --git a/src/modules/audio_processing/debug.proto b/webrtc/modules/audio_processing/debug.proto similarity index 100% rename from src/modules/audio_processing/debug.proto rename to webrtc/modules/audio_processing/debug.proto diff --git a/src/modules/audio_processing/echo_cancellation_impl.cc b/webrtc/modules/audio_processing/echo_cancellation_impl.cc similarity index 100% rename from src/modules/audio_processing/echo_cancellation_impl.cc rename to webrtc/modules/audio_processing/echo_cancellation_impl.cc diff --git a/src/modules/audio_processing/echo_cancellation_impl.h b/webrtc/modules/audio_processing/echo_cancellation_impl.h similarity index 100% rename from src/modules/audio_processing/echo_cancellation_impl.h rename to webrtc/modules/audio_processing/echo_cancellation_impl.h diff --git a/src/modules/audio_processing/echo_control_mobile_impl.cc b/webrtc/modules/audio_processing/echo_control_mobile_impl.cc similarity index 100% rename from src/modules/audio_processing/echo_control_mobile_impl.cc rename to webrtc/modules/audio_processing/echo_control_mobile_impl.cc diff --git a/src/modules/audio_processing/echo_control_mobile_impl.h b/webrtc/modules/audio_processing/echo_control_mobile_impl.h similarity index 100% rename from src/modules/audio_processing/echo_control_mobile_impl.h rename to webrtc/modules/audio_processing/echo_control_mobile_impl.h diff --git a/src/modules/audio_processing/gain_control_impl.cc b/webrtc/modules/audio_processing/gain_control_impl.cc similarity index 100% rename from src/modules/audio_processing/gain_control_impl.cc rename to webrtc/modules/audio_processing/gain_control_impl.cc diff --git a/src/modules/audio_processing/gain_control_impl.h b/webrtc/modules/audio_processing/gain_control_impl.h similarity index 100% rename from src/modules/audio_processing/gain_control_impl.h rename to webrtc/modules/audio_processing/gain_control_impl.h diff --git a/src/modules/audio_processing/high_pass_filter_impl.cc b/webrtc/modules/audio_processing/high_pass_filter_impl.cc similarity index 100% rename from src/modules/audio_processing/high_pass_filter_impl.cc rename to webrtc/modules/audio_processing/high_pass_filter_impl.cc diff --git a/src/modules/audio_processing/high_pass_filter_impl.h b/webrtc/modules/audio_processing/high_pass_filter_impl.h similarity index 100% rename from src/modules/audio_processing/high_pass_filter_impl.h rename to webrtc/modules/audio_processing/high_pass_filter_impl.h diff --git a/src/modules/audio_processing/interface/audio_processing.h b/webrtc/modules/audio_processing/interface/audio_processing.h similarity index 100% rename from src/modules/audio_processing/interface/audio_processing.h rename to webrtc/modules/audio_processing/interface/audio_processing.h diff --git a/src/modules/audio_processing/level_estimator_impl.cc b/webrtc/modules/audio_processing/level_estimator_impl.cc similarity index 100% rename from src/modules/audio_processing/level_estimator_impl.cc rename to webrtc/modules/audio_processing/level_estimator_impl.cc diff --git a/src/modules/audio_processing/level_estimator_impl.h b/webrtc/modules/audio_processing/level_estimator_impl.h similarity index 100% rename from src/modules/audio_processing/level_estimator_impl.h rename to webrtc/modules/audio_processing/level_estimator_impl.h diff --git a/src/modules/audio_processing/noise_suppression_impl.cc b/webrtc/modules/audio_processing/noise_suppression_impl.cc similarity index 100% rename from src/modules/audio_processing/noise_suppression_impl.cc rename to webrtc/modules/audio_processing/noise_suppression_impl.cc diff --git a/src/modules/audio_processing/noise_suppression_impl.h b/webrtc/modules/audio_processing/noise_suppression_impl.h similarity index 100% rename from src/modules/audio_processing/noise_suppression_impl.h rename to webrtc/modules/audio_processing/noise_suppression_impl.h diff --git a/src/modules/audio_processing/ns/Makefile.am b/webrtc/modules/audio_processing/ns/Makefile.am similarity index 100% rename from src/modules/audio_processing/ns/Makefile.am rename to webrtc/modules/audio_processing/ns/Makefile.am diff --git a/src/modules/audio_processing/ns/defines.h b/webrtc/modules/audio_processing/ns/defines.h similarity index 100% rename from src/modules/audio_processing/ns/defines.h rename to webrtc/modules/audio_processing/ns/defines.h diff --git a/src/modules/audio_processing/ns/interface/noise_suppression.h b/webrtc/modules/audio_processing/ns/interface/noise_suppression.h similarity index 100% rename from src/modules/audio_processing/ns/interface/noise_suppression.h rename to webrtc/modules/audio_processing/ns/interface/noise_suppression.h diff --git a/src/modules/audio_processing/ns/interface/noise_suppression_x.h b/webrtc/modules/audio_processing/ns/interface/noise_suppression_x.h similarity index 100% rename from src/modules/audio_processing/ns/interface/noise_suppression_x.h rename to webrtc/modules/audio_processing/ns/interface/noise_suppression_x.h diff --git a/src/modules/audio_processing/ns/noise_suppression.c b/webrtc/modules/audio_processing/ns/noise_suppression.c similarity index 100% rename from src/modules/audio_processing/ns/noise_suppression.c rename to webrtc/modules/audio_processing/ns/noise_suppression.c diff --git a/src/modules/audio_processing/ns/noise_suppression_x.c b/webrtc/modules/audio_processing/ns/noise_suppression_x.c similarity index 100% rename from src/modules/audio_processing/ns/noise_suppression_x.c rename to webrtc/modules/audio_processing/ns/noise_suppression_x.c diff --git a/src/modules/audio_processing/ns/ns.gypi b/webrtc/modules/audio_processing/ns/ns.gypi similarity index 100% rename from src/modules/audio_processing/ns/ns.gypi rename to webrtc/modules/audio_processing/ns/ns.gypi diff --git a/src/modules/audio_processing/ns/ns_core.c b/webrtc/modules/audio_processing/ns/ns_core.c similarity index 100% rename from src/modules/audio_processing/ns/ns_core.c rename to webrtc/modules/audio_processing/ns/ns_core.c diff --git a/src/modules/audio_processing/ns/ns_core.h b/webrtc/modules/audio_processing/ns/ns_core.h similarity index 100% rename from src/modules/audio_processing/ns/ns_core.h rename to webrtc/modules/audio_processing/ns/ns_core.h diff --git a/src/modules/audio_processing/ns/nsx_core.c b/webrtc/modules/audio_processing/ns/nsx_core.c similarity index 100% rename from src/modules/audio_processing/ns/nsx_core.c rename to webrtc/modules/audio_processing/ns/nsx_core.c diff --git a/src/modules/audio_processing/ns/nsx_core.h b/webrtc/modules/audio_processing/ns/nsx_core.h similarity index 100% rename from src/modules/audio_processing/ns/nsx_core.h rename to webrtc/modules/audio_processing/ns/nsx_core.h diff --git a/src/modules/audio_processing/ns/nsx_core_neon.c b/webrtc/modules/audio_processing/ns/nsx_core_neon.c similarity index 100% rename from src/modules/audio_processing/ns/nsx_core_neon.c rename to webrtc/modules/audio_processing/ns/nsx_core_neon.c diff --git a/src/modules/audio_processing/ns/nsx_defines.h b/webrtc/modules/audio_processing/ns/nsx_defines.h similarity index 100% rename from src/modules/audio_processing/ns/nsx_defines.h rename to webrtc/modules/audio_processing/ns/nsx_defines.h diff --git a/src/modules/audio_processing/ns/windows_private.h b/webrtc/modules/audio_processing/ns/windows_private.h similarity index 100% rename from src/modules/audio_processing/ns/windows_private.h rename to webrtc/modules/audio_processing/ns/windows_private.h diff --git a/src/modules/audio_processing/processing_component.cc b/webrtc/modules/audio_processing/processing_component.cc similarity index 100% rename from src/modules/audio_processing/processing_component.cc rename to webrtc/modules/audio_processing/processing_component.cc diff --git a/src/modules/audio_processing/processing_component.h b/webrtc/modules/audio_processing/processing_component.h similarity index 100% rename from src/modules/audio_processing/processing_component.h rename to webrtc/modules/audio_processing/processing_component.h diff --git a/src/modules/audio_processing/splitting_filter.cc b/webrtc/modules/audio_processing/splitting_filter.cc similarity index 100% rename from src/modules/audio_processing/splitting_filter.cc rename to webrtc/modules/audio_processing/splitting_filter.cc diff --git a/src/modules/audio_processing/splitting_filter.h b/webrtc/modules/audio_processing/splitting_filter.h similarity index 100% rename from src/modules/audio_processing/splitting_filter.h rename to webrtc/modules/audio_processing/splitting_filter.h diff --git a/src/modules/audio_processing/test/android/apmtest/AndroidManifest.xml b/webrtc/modules/audio_processing/test/android/apmtest/AndroidManifest.xml similarity index 100% rename from src/modules/audio_processing/test/android/apmtest/AndroidManifest.xml rename to webrtc/modules/audio_processing/test/android/apmtest/AndroidManifest.xml diff --git a/src/modules/audio_processing/test/android/apmtest/default.properties b/webrtc/modules/audio_processing/test/android/apmtest/default.properties similarity index 100% rename from src/modules/audio_processing/test/android/apmtest/default.properties rename to webrtc/modules/audio_processing/test/android/apmtest/default.properties diff --git a/src/modules/audio_processing/test/android/apmtest/jni/Application.mk b/webrtc/modules/audio_processing/test/android/apmtest/jni/Application.mk similarity index 100% rename from src/modules/audio_processing/test/android/apmtest/jni/Application.mk rename to webrtc/modules/audio_processing/test/android/apmtest/jni/Application.mk diff --git a/src/modules/audio_processing/test/android/apmtest/jni/main.c b/webrtc/modules/audio_processing/test/android/apmtest/jni/main.c similarity index 100% rename from src/modules/audio_processing/test/android/apmtest/jni/main.c rename to webrtc/modules/audio_processing/test/android/apmtest/jni/main.c diff --git a/src/modules/audio_processing/test/android/apmtest/res/values/strings.xml b/webrtc/modules/audio_processing/test/android/apmtest/res/values/strings.xml similarity index 100% rename from src/modules/audio_processing/test/android/apmtest/res/values/strings.xml rename to webrtc/modules/audio_processing/test/android/apmtest/res/values/strings.xml diff --git a/src/modules/audio_processing/test/apmtest.m b/webrtc/modules/audio_processing/test/apmtest.m similarity index 100% rename from src/modules/audio_processing/test/apmtest.m rename to webrtc/modules/audio_processing/test/apmtest.m diff --git a/src/modules/audio_processing/test/process_test.cc b/webrtc/modules/audio_processing/test/process_test.cc similarity index 100% rename from src/modules/audio_processing/test/process_test.cc rename to webrtc/modules/audio_processing/test/process_test.cc diff --git a/src/modules/audio_processing/test/unit_test.cc b/webrtc/modules/audio_processing/test/unit_test.cc similarity index 100% rename from src/modules/audio_processing/test/unit_test.cc rename to webrtc/modules/audio_processing/test/unit_test.cc diff --git a/src/modules/audio_processing/test/unittest.proto b/webrtc/modules/audio_processing/test/unittest.proto similarity index 100% rename from src/modules/audio_processing/test/unittest.proto rename to webrtc/modules/audio_processing/test/unittest.proto diff --git a/src/modules/audio_processing/utility/Makefile.am b/webrtc/modules/audio_processing/utility/Makefile.am similarity index 100% rename from src/modules/audio_processing/utility/Makefile.am rename to webrtc/modules/audio_processing/utility/Makefile.am diff --git a/src/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c similarity index 100% rename from src/modules/audio_processing/utility/delay_estimator.c rename to webrtc/modules/audio_processing/utility/delay_estimator.c diff --git a/src/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h similarity index 100% rename from src/modules/audio_processing/utility/delay_estimator.h rename to webrtc/modules/audio_processing/utility/delay_estimator.h diff --git a/src/modules/audio_processing/utility/delay_estimator_float.c b/webrtc/modules/audio_processing/utility/delay_estimator_float.c similarity index 100% rename from src/modules/audio_processing/utility/delay_estimator_float.c rename to webrtc/modules/audio_processing/utility/delay_estimator_float.c diff --git a/src/modules/audio_processing/utility/delay_estimator_float.h b/webrtc/modules/audio_processing/utility/delay_estimator_float.h similarity index 100% rename from src/modules/audio_processing/utility/delay_estimator_float.h rename to webrtc/modules/audio_processing/utility/delay_estimator_float.h diff --git a/src/modules/audio_processing/utility/fft4g.c b/webrtc/modules/audio_processing/utility/fft4g.c similarity index 100% rename from src/modules/audio_processing/utility/fft4g.c rename to webrtc/modules/audio_processing/utility/fft4g.c diff --git a/src/modules/audio_processing/utility/fft4g.h b/webrtc/modules/audio_processing/utility/fft4g.h similarity index 100% rename from src/modules/audio_processing/utility/fft4g.h rename to webrtc/modules/audio_processing/utility/fft4g.h diff --git a/src/modules/audio_processing/utility/ring_buffer.c b/webrtc/modules/audio_processing/utility/ring_buffer.c similarity index 100% rename from src/modules/audio_processing/utility/ring_buffer.c rename to webrtc/modules/audio_processing/utility/ring_buffer.c diff --git a/src/modules/audio_processing/utility/ring_buffer.h b/webrtc/modules/audio_processing/utility/ring_buffer.h similarity index 100% rename from src/modules/audio_processing/utility/ring_buffer.h rename to webrtc/modules/audio_processing/utility/ring_buffer.h diff --git a/src/modules/audio_processing/utility/util.gypi b/webrtc/modules/audio_processing/utility/util.gypi similarity index 100% rename from src/modules/audio_processing/utility/util.gypi rename to webrtc/modules/audio_processing/utility/util.gypi diff --git a/src/modules/audio_processing/voice_detection_impl.cc b/webrtc/modules/audio_processing/voice_detection_impl.cc similarity index 100% rename from src/modules/audio_processing/voice_detection_impl.cc rename to webrtc/modules/audio_processing/voice_detection_impl.cc diff --git a/src/modules/audio_processing/voice_detection_impl.h b/webrtc/modules/audio_processing/voice_detection_impl.h similarity index 100% rename from src/modules/audio_processing/voice_detection_impl.h rename to webrtc/modules/audio_processing/voice_detection_impl.h diff --git a/src/modules/interface/module.h b/webrtc/modules/interface/module.h similarity index 100% rename from src/modules/interface/module.h rename to webrtc/modules/interface/module.h diff --git a/src/modules/interface/module_common_types.h b/webrtc/modules/interface/module_common_types.h similarity index 100% rename from src/modules/interface/module_common_types.h rename to webrtc/modules/interface/module_common_types.h diff --git a/src/system_wrappers/Makefile.am b/webrtc/system_wrappers/Makefile.am similarity index 100% rename from src/system_wrappers/Makefile.am rename to webrtc/system_wrappers/Makefile.am diff --git a/src/system_wrappers/interface/cpu_features_wrapper.h b/webrtc/system_wrappers/interface/cpu_features_wrapper.h similarity index 64% rename from src/system_wrappers/interface/cpu_features_wrapper.h rename to webrtc/system_wrappers/interface/cpu_features_wrapper.h index 5d8a828..5697c49 100644 --- a/src/system_wrappers/interface/cpu_features_wrapper.h +++ b/webrtc/system_wrappers/interface/cpu_features_wrapper.h @@ -15,20 +15,37 @@ extern "C" { #endif -// list of features. +#include "webrtc/typedefs.h" + +// List of features in x86. typedef enum { kSSE2, kSSE3 } CPUFeature; +// List of features in ARM. +enum { + kCPUFeatureARMv7 = (1 << 0), + kCPUFeatureVFPv3 = (1 << 1), + kCPUFeatureNEON = (1 << 2), + kCPUFeatureLDREXSTREX = (1 << 3) +}; + typedef int (*WebRtc_CPUInfo)(CPUFeature feature); -// returns true if the CPU supports the feature. + +// Returns true if the CPU supports the feature. extern WebRtc_CPUInfo WebRtc_GetCPUInfo; + // No CPU feature is available => straight C path. extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM; +// Return the features in an ARM device. +// It detects the features in the hardware platform, and returns supported +// values in the above enum definition as a bitmask. +extern uint64_t WebRtc_GetCPUFeaturesARM(void); + #if defined(__cplusplus) || defined(c_plusplus) -} // extern "C" +} // extern "C" #endif #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_ diff --git a/webrtc/system_wrappers/interface/critical_section_wrapper.h b/webrtc/system_wrappers/interface/critical_section_wrapper.h new file mode 100644 index 0000000..e93a249 --- /dev/null +++ b/webrtc/system_wrappers/interface/critical_section_wrapper.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ + +// If the critical section is heavily contended it may be beneficial to use +// read/write locks instead. + +#include "webrtc/base/thread_annotations.h" +#include "webrtc/common_types.h" + +namespace webrtc { +class LOCKABLE CriticalSectionWrapper { + public: + // Factory method, constructor disabled + static CriticalSectionWrapper* CreateCriticalSection(); + + virtual ~CriticalSectionWrapper() {} + + // Tries to grab lock, beginning of a critical section. Will wait for the + // lock to become available if the grab failed. + virtual void Enter() EXCLUSIVE_LOCK_FUNCTION() = 0; + + // Returns a grabbed lock, end of critical section. + virtual void Leave() UNLOCK_FUNCTION() = 0; +}; + +// RAII extension of the critical section. Prevents Enter/Leave mismatches and +// provides more compact critical section syntax. +class SCOPED_LOCKABLE CriticalSectionScoped { + public: + explicit CriticalSectionScoped(CriticalSectionWrapper* critsec) + EXCLUSIVE_LOCK_FUNCTION(critsec) + : ptr_crit_sec_(critsec) { + ptr_crit_sec_->Enter(); + } + + ~CriticalSectionScoped() UNLOCK_FUNCTION() { ptr_crit_sec_->Leave(); } + + private: + CriticalSectionWrapper* ptr_crit_sec_; +}; + +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ diff --git a/src/system_wrappers/source/cpu_features.cc b/webrtc/system_wrappers/source/cpu_features.cc similarity index 100% rename from src/system_wrappers/source/cpu_features.cc rename to webrtc/system_wrappers/source/cpu_features.cc diff --git a/src/system_wrappers/source/critical_section.cc b/webrtc/system_wrappers/source/critical_section.cc similarity index 100% rename from src/system_wrappers/source/critical_section.cc rename to webrtc/system_wrappers/source/critical_section.cc diff --git a/src/system_wrappers/source/critical_section_posix.cc b/webrtc/system_wrappers/source/critical_section_posix.cc similarity index 100% rename from src/system_wrappers/source/critical_section_posix.cc rename to webrtc/system_wrappers/source/critical_section_posix.cc diff --git a/src/system_wrappers/source/critical_section_posix.h b/webrtc/system_wrappers/source/critical_section_posix.h similarity index 100% rename from src/system_wrappers/source/critical_section_posix.h rename to webrtc/system_wrappers/source/critical_section_posix.h diff --git a/src/system_wrappers/source/critical_section_windows.cc b/webrtc/system_wrappers/source/critical_section_windows.cc similarity index 100% rename from src/system_wrappers/source/critical_section_windows.cc rename to webrtc/system_wrappers/source/critical_section_windows.cc diff --git a/src/system_wrappers/source/critical_section_windows.h b/webrtc/system_wrappers/source/critical_section_windows.h similarity index 100% rename from src/system_wrappers/source/critical_section_windows.h rename to webrtc/system_wrappers/source/critical_section_windows.h diff --git a/src/system_wrappers/source/system_wrappers.gyp b/webrtc/system_wrappers/source/system_wrappers.gyp similarity index 100% rename from src/system_wrappers/source/system_wrappers.gyp rename to webrtc/system_wrappers/source/system_wrappers.gyp diff --git a/webrtc/typedefs.h b/webrtc/typedefs.h new file mode 100644 index 0000000..d875490 --- /dev/null +++ b/webrtc/typedefs.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// This file contains platform-specific typedefs and defines. +// Much of it is derived from Chromium's build/build_config.h. + +#ifndef WEBRTC_TYPEDEFS_H_ +#define WEBRTC_TYPEDEFS_H_ + +// Processor architecture detection. For more info on what's defined, see: +// http://msdn.microsoft.com/en-us/library/b0084kay.aspx +// http://www.agner.org/optimize/calling_conventions.pdf +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define WEBRTC_ARCH_X86_FAMILY +#define WEBRTC_ARCH_X86_64 +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__aarch64__) +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(_M_IX86) || defined(__i386__) +#define WEBRTC_ARCH_X86_FAMILY +#define WEBRTC_ARCH_X86 +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__ARMEL__) +// TODO(ajm): We'd prefer to control platform defines here, but this is +// currently provided by the Android makefiles. Commented to avoid duplicate +// definition warnings. +//#define WEBRTC_ARCH_ARM +// TODO(ajm): Chromium uses the following two defines. Should we switch? +//#define WEBRTC_ARCH_ARM_FAMILY +//#define WEBRTC_ARCH_ARMEL +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__MIPSEL__) +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__pnacl__) +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#else +#error Please add support for your architecture in typedefs.h +#endif + +#if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN)) +#error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN +#endif + +// TODO(zhongwei.yao): WEBRTC_CPU_DETECTION is only used in one place; we should +// probably just remove it. +#if (defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__)) || \ + defined(WEBRTC_DETECT_NEON) +#define WEBRTC_CPU_DETECTION +#endif + +// TODO(pbos): Use webrtc/base/basictypes.h instead to include fixed-size ints. +#include + +// Annotate a function indicating the caller must examine the return value. +// Use like: +// int foo() WARN_UNUSED_RESULT; +// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and +// libjingle are merged. +#if !defined(WARN_UNUSED_RESULT) +#if defined(__GNUC__) +#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define WARN_UNUSED_RESULT +#endif +#endif // WARN_UNUSED_RESULT + +// Put after a variable that might not be used, to prevent compiler warnings: +// int result ATTRIBUTE_UNUSED = DoSomething(); +// assert(result == 17); +#ifndef ATTRIBUTE_UNUSED +#if defined(__GNUC__) || defined(__clang__) +#define ATTRIBUTE_UNUSED __attribute__((unused)) +#else +#define ATTRIBUTE_UNUSED +#endif +#endif + +// Macro to be used for switch-case fallthrough (required for enabling +// -Wimplicit-fallthrough warning on Clang). +#ifndef FALLTHROUGH +#if defined(__clang__) +#define FALLTHROUGH() [[clang::fallthrough]] +#else +#define FALLTHROUGH() do { } while (0) +#endif +#endif + +// Annotate a function that will not return control flow to the caller. +#if defined(_MSC_VER) +#define NO_RETURN __declspec(noreturn) +#elif defined(__GNUC__) +#define NO_RETURN __attribute__((noreturn)) +#else +#define NO_RETURN +#endif + +#endif // WEBRTC_TYPEDEFS_H_