-SUBDIRS = src
+SUBDIRS = webrtc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = webrtc-audio-processing.pc
# 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])
[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
+++ /dev/null
-SUBDIRS = signal_processing_library vad
+++ /dev/null
-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)
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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 <string.h>
-#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 <samples> 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;
-}
+++ /dev/null
-/*
- * 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
-};
+++ /dev/null
-/*
- * 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
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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];
- }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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 <arm_neon.h>
-
-#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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
-};
+++ /dev/null
-/*
- * 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,
-};
+++ /dev/null
-# 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:
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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 <string.h>
-#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;
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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 };
+++ /dev/null
-/*
- * 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 };
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- * 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 <gtest/gtest.h>
-
-class SplTest: public ::testing::Test
-{
-protected:
- SplTest();
- virtual void SetUp();
- virtual void TearDown();
-};
-
-#endif // WEBRTC_SPL_UNIT_TEST_H_
+++ /dev/null
-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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-# 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:
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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);
- }
- }
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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];
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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 <stdlib.h>
-#include <string.h>
-
-#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;
- }
-}
+++ /dev/null
-/*
- * 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 <cstring>
-#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();
-}
+++ /dev/null
-/*
- * 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 <gtest/gtest.h>
-
-class VadTest : public ::testing::Test {
- protected:
- VadTest();
- virtual void SetUp();
- virtual void TearDown();
-};
-
-#endif // WEBRTC_VAD_UNIT_TEST_H_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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 <stdint.h>
-#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 <stdint.h>
-
- 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_
--- /dev/null
+/*
+ * 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 <sstream>
+#include <string>
+
+#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<void>(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<void>(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<class t1, class t2>
+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<int, int>(
+ const int&, const int&, const char* names);
+extern template
+std::string* MakeCheckOpString<unsigned long, unsigned long>(
+ const unsigned long&, const unsigned long&, const char* names);
+extern template
+std::string* MakeCheckOpString<unsigned long, unsigned int>(
+ const unsigned long&, const unsigned int&, const char* names);
+extern template
+std::string* MakeCheckOpString<unsigned int, unsigned long>(
+ const unsigned int&, const unsigned long&, const char* names);
+extern template
+std::string* MakeCheckOpString<std::string, std::string>(
+ 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 <class t1, class t2> \
+ 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 <typename T>
+inline T CheckedDivExact(T a, T b) {
+ RTC_CHECK_EQ(a % b, static_cast<T>(0));
+ return a / b;
+}
+
+} // namespace rtc
+
+#endif // WEBRTC_BASE_CHECKS_H_
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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<T>):
+// {
+// scoped_ptr<Foo> foo(new Foo("wee"));
+// } // foo goes out of scope, releasing the pointer with it.
+//
+// {
+// scoped_ptr<Foo> 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<T[]>):
+// {
+// scoped_ptr<Foo[]> 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<Foo> arg) {
+// // Do something with arg
+// }
+// scoped_ptr<Foo> CreateFoo() {
+// // No need for calling Pass() because we are constructing a temporary
+// // for the return value.
+// return scoped_ptr<Foo>(new Foo("new"));
+// }
+// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
+// return arg.Pass();
+// }
+//
+// {
+// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay").
+// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
+// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
+// scoped_ptr<Foo> 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<Child> to initialize a scoped_ptr<Parent>:
+//
+// scoped_ptr<Foo> foo(new Foo());
+// scoped_ptr<FooParent> parent(foo.Pass());
+//
+// PassAs<>() should be used to upcast return value in return statement:
+//
+// scoped_ptr<Foo> CreateFoo() {
+// scoped_ptr<FooChild> result(new FooChild());
+// return result.PassAs<Foo>();
+// }
+//
+// Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for
+// scoped_ptr<T[]>. 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 <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <algorithm> // 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<T>.
+template <class T>
+struct DefaultDeleter {
+ DefaultDeleter() {}
+ template <typename U> DefaultDeleter(const DefaultDeleter<U>& 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<U*, T*> 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<U*, T*>::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 <class T>
+struct DefaultDeleter<T[]> {
+ 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 <typename U> void operator()(U* array) const;
+};
+
+template <class T, int n>
+struct DefaultDeleter<T[n]> {
+ // Never allow someone to declare something like scoped_ptr<int[10]>.
+ 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<int, rtc::FreeDeleter> foo_ptr(
+// static_cast<int*>(malloc(sizeof(int))));
+struct FreeDeleter {
+ inline void operator()(void* ptr) const {
+ free(ptr);
+ }
+};
+
+namespace internal {
+
+template <typename T>
+struct ShouldAbortOnSelfReset {
+ template <typename U>
+ static rtc::internal::NoType Test(const typename U::AllowSelfReset*);
+
+ template <typename U>
+ static rtc::internal::YesType Test(...);
+
+ static const bool value =
+ sizeof(Test<T>(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 T, class D>
+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 <typename U, typename V>
+ scoped_ptr_impl(scoped_ptr_impl<U, V>* 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 <typename U, typename V>
+ void TakeState(scoped_ptr_impl<U, V>* 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<D&>(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<D>::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<D&>(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<D&>(data_), static_cast<D&>(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 <typename U, typename V> 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<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T
+// object. Also like T*, scoped_ptr<T> 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<T>) == 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 T, class D = rtc::DefaultDeleter<T> >
+class scoped_ptr {
+
+ // TODO(ajm): If we ever import RefCountedBase, this check needs to be
+ // enabled.
+ //static_assert(rtc::internal::IsNotRefCounted<T>::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 <typename U, typename V>
+ scoped_ptr(scoped_ptr<U, V>&& other)
+ : impl_(&other.impl_) {
+ static_assert(!rtc::is_array<U>::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 <typename U, typename V>
+ scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) {
+ static_assert(!rtc::is_array<U>::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<scoped_ptr&&>(*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<element_type> 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<element_type, deleter_type>
+ 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 <typename U, typename V> friend class scoped_ptr;
+ rtc::internal::scoped_ptr_impl<element_type, deleter_type> 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 <class U> bool operator==(scoped_ptr<U> const& p2) const;
+ template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
+};
+
+template <class T, class D>
+class scoped_ptr<T[], D> {
+ 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<const T*>().
+ // However, because of the first bullet in this comment, users MUST
+ // NOT use implicit_cast<Base*>() 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<scoped_ptr&&>(*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<element_type> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ private:
+ typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type>
+ 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<element_type, deleter_type> 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 <typename U> 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 <typename U> 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 <class U> bool operator==(scoped_ptr<U> const& p2) const;
+ template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
+};
+
+template <class T, class D>
+void swap(rtc::scoped_ptr<T, D>& p1, rtc::scoped_ptr<T, D>& p2) {
+ p1.swap(p2);
+}
+
+} // namespace rtc
+
+template <class T, class D>
+bool operator==(T* p1, const rtc::scoped_ptr<T, D>& p2) {
+ return p1 == p2.get();
+}
+
+template <class T, class D>
+bool operator!=(T* p1, const rtc::scoped_ptr<T, D>& p2) {
+ return p1 != p2.get();
+}
+
+// A function to convert T* into scoped_ptr<T>
+// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+rtc::scoped_ptr<T> rtc_make_scoped_ptr(T* ptr) {
+ return rtc::scoped_ptr<T>(ptr);
+}
+
+#endif // #ifndef WEBRTC_BASE_SCOPED_PTR_H__
--- /dev/null
+/*
+ * 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 <stddef.h> // For size_t.
+
+namespace rtc {
+
+// Template definitions from tr1.
+
+template<class T, T v>
+struct integral_constant {
+ static const T value = v;
+ typedef T value_type;
+ typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <class T> struct is_pointer : false_type {};
+template <class T> struct is_pointer<T*> : true_type {};
+
+template <class T, class U> struct is_same : public false_type {};
+template <class T> struct is_same<T, T> : true_type {};
+
+template<class> struct is_array : public false_type {};
+template<class T, size_t n> struct is_array<T[n]> : public true_type {};
+template<class T> struct is_array<T[]> : public true_type {};
+
+template <class T> struct is_non_const_reference : false_type {};
+template <class T> struct is_non_const_reference<T&> : true_type {};
+template <class T> struct is_non_const_reference<const T&> : false_type {};
+
+template <class T> struct is_void : false_type {};
+template <> struct is_void<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 <typename To>
+ static YesType Test(To);
+
+ template <typename To>
+ static NoType Test(...);
+
+ template <typename From>
+ 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 <typename C>
+ static YesType Test(void(C::*)(void));
+
+ template <typename C>
+ 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 <typename From, typename To>
+struct is_convertible
+ : integral_constant<bool,
+ sizeof(internal::ConvertHelper::Test<To>(
+ internal::ConvertHelper::Create<From>())) ==
+ sizeof(internal::YesType)> {
+};
+
+template <typename T>
+struct is_class
+ : integral_constant<bool,
+ sizeof(internal::IsClassHelper::Test<T>(0)) ==
+ sizeof(internal::YesType)> {
+};
+
+} // namespace rtc
+
+#endif // WEBRTC_BASE_TEMPLATE_UTIL_H_
--- /dev/null
+# 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" ]
+ }
+}
--- /dev/null
+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
*
*/
-#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.
// 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++;
}
// 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++;
}
}
--- /dev/null
+/*
+ * 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 <assert.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+@
+@ 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
--- /dev/null
+/*
+ * 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"
+ );
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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 <string.h>
+#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 <samples> 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);
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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"
+ );
+}
--- /dev/null
+/*
+ * 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 <arm_neon.h>
+
+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++;
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 <arm_neon.h>
+
+// 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;
+}
*
*/
-#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;
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 <assert.h>
+
+#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);
+ }
+}
--- /dev/null
+@
+@ 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);
+@ }
+@}
--- /dev/null
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <assert.h>
+
+#include "webrtc/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"
+ );
+}
+
*
*/
-#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;
}
/*
- * 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,
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];
+ }
+
+}
*
*/
-#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--)
{
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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_
/*
- * 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
#define WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_
#include <string.h>
-#include "typedefs.h"
-
-#ifdef ARM_WINM
-#include <Armintr.h> // 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"
-
-// Get SPL Version
-WebRtc_Word16 WebRtcSpl_get_version(char* version,
- WebRtc_Word16 length_in_bytes);
-
-int WebRtcSpl_GetScalingSquare(WebRtc_Word16* in_vector,
- int in_vector_length,
- int times);
+#include "webrtc/common_audio/signal_processing/include/spl_inl.h"
+
+// 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();
+
+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_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);
+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);
+
+// 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);
-
-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);
+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
+
// 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
/************************************************************
******************************************************************/
// 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);
*
******************************************************************/
-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
*
******************************************************************/
-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);
*
******************************************************************/
-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(...)
// 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
//
// 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
//
//
// 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
//
//
// 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|
//
// Output:
// - out_vector : Vector with the requested samples
//
-// Return value : Number of copied samples in |out_vector|
-//
//
// WebRtcSpl_ZerosArrayW16(...)
// 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
//
// 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
//
//
-// 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<<right_shifts)>>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(...)
//
// Performs the vector operation:
//
//
-// 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(...)
//
// Increases the seed (and returns the new value)
//
// 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
//
// 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
//
// 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:
//
// 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.
//
//
// 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.
//
//
//
-// 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(...)
//
// Complex Inverse FFT
//
//
-// 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(...)
//
// Splits a 0-2*F Hz signal into two sub bands: 0-F Hz and F-2*F Hz. The
// - 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.
//
//
// 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.
//
// 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.
-//
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
+}
*
*/
-#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;
}
--- /dev/null
+/*
+ * 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 <assert.h>
+#include <stdlib.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <assert.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <arm_neon.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#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;
+}
+
/*
- * 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,
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;
+}
--- /dev/null
+/*
+ * 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 <stdlib.h>
+
+#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;
+}
*
*/
-#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++)
{
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--;
*
*/
-#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},
#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;
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];
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);
#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;
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];
#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;
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];
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);
#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;
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];
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);
}
// 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];
}
// 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];
// 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]);
}
// 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]);
*/
#include <string.h>
-#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);
}
// 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));
}
////////////////////////////
////////////////////////////
// 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);
}
// 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));
}
////////////////////////////
////////////////////////////
// 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);
}
// 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));
}
////////////////////////////
////////////////////////////
// 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);
}
// 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));
}
*
*/
-#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;
}
// 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;
-
- 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];
+#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 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;
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;
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;
*
*/
-#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;
// 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;
// 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;
//
// 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;
// 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;
//
// 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++)
//
// 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++)
// 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++;
// 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;
// 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;
// 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;
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;
}
// 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;
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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)
*
*/
-#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},
};
// 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++)
{
}
// 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++)
{
//
// 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];
}
// 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];
--- /dev/null
+/*
+ * 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 <pthread.h>
+
+static void once(void (*func)(void)) {
+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+#elif defined(_WIN32)
+#include <windows.h>
+
+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);
+}
*
*/
-#include "signal_processing_library.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
-WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in);
+#include <assert.h>
-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
+ 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:
*/
- 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;
}
--- /dev/null
+/*
+ * Written by Wilco Dijkstra, 1996. The following email exchange establishes the
+ * license.
+ *
+ * From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
+ * Date: Fri, Jun 24, 2011 at 3:20 AM
+ * Subject: Re: sqrt routine
+ * To: Kevin Ma <kma@google.com>
+ * 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" <kma@google.com>
+ * To: <Wilco.Dijkstra@ntlworld.com>
+ * 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;
+}
--- /dev/null
+@
+@ Written by Wilco Dijkstra, 1996. The following email exchange establishes the
+@ license.
+@
+@ From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
+@ Date: Fri, Jun 24, 2011 at 3:20 AM
+@ Subject: Re: sqrt routine
+@ To: Kevin Ma <kma@google.com>
+@ 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" <kma@google.com>
+@ To: <Wilco.Dijkstra@ntlworld.com>
+@ 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
--- /dev/null
+/*
+ * Written by Wilco Dijkstra, 1996. The following email exchange establishes the
+ * license.
+ *
+ * From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
+ * Date: Fri, Jun 24, 2011 at 3:20 AM
+ * Subject: Re: sqrt routine
+ * To: Kevin Ma <kma@google.com>
+ * 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" <kma@google.com>
+ * To: <Wilco.Dijkstra@ntlworld.com>
+ * 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;
+}
+
*
*/
-#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 <assert.h>
+
+// 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(...)
// |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).
// 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
// 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]);
}
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]);
}
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]);
}
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);
}
*
*/
-#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;
}
}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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<Vad> CreateVad(Vad::Aggressiveness aggressiveness);
+
+} // namespace webrtc
+
+#endif // WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
--- /dev/null
+/*
+ * 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 <stddef.h>
+
+#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
--- /dev/null
+/*
+ * 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<Vad> CreateVad(Vad::Aggressiveness aggressiveness) {
+ return rtc::scoped_ptr<Vad>(new VadImpl(aggressiveness));
+}
+
+} // namespace webrtc
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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 <assert.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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 <assert.h>
+
+#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];
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <stddef.h>
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+#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<int>(
+ (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_
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_
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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 <stdint.h>
+
+// 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_