Update common_audio
Corresponds to upstream commit 524e9b043e7e86fd72353b987c9d5f6a1ebf83e1 Update notes: * Moved src/ to webrtc/ to easily diff against the third_party/webrtc in the chromium tree * ARM/NEON/MIPS support is not yet hooked up * Tests have not been copied
This commit is contained in:
parent
9413986e79
commit
c4fb4e38de
@ -1,4 +1,4 @@
|
||||
SUBDIRS = src
|
||||
SUBDIRS = webrtc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = webrtc-audio-processing.pc
|
||||
|
28
configure.ac
28
configure.ac
@ -1,7 +1,7 @@
|
||||
# Revision changelog (version - date, svn rev. from upstream that was merged)
|
||||
# 0.1 - 21 Oct 2011, r789
|
||||
AC_INIT([webrtc-audio-processing], [0.1])
|
||||
AM_INIT_AUTOMAKE([dist-xz tar-ustar])
|
||||
AM_INIT_AUTOMAKE([dist-xz subdir-objects tar-ustar])
|
||||
|
||||
AC_SUBST(LIBWEBRTC_AUDIO_PROCESSING_VERSION_INFO, [0:0:0])
|
||||
|
||||
@ -24,26 +24,24 @@ AS_CASE(["x${with_ns_mode}"],
|
||||
[NS_FIXED=0])
|
||||
AM_CONDITIONAL(NS_FIXED, [test "x${NS_FIXED}" = "x1"])
|
||||
|
||||
COMMON_CFLAGS="-DNDEBUG -I\$(srcdir)/interface -I\$(srcdir)/main/interface -I\$(top_srcdir)/src -I\$(top_srcdir)/src/modules/interface"
|
||||
COMMON_CXXFLAGS="-DNDEBUG -I\$(srcdir)/interface -I\$(srcdir)/main/interface -I\$(top_srcdir)/src -I\$(top_srcdir)/src/modules/interface"
|
||||
COMMON_CFLAGS="-DNDEBUG -I\$(top_srcdir)"
|
||||
COMMON_CXXFLAGS="-std=c++11 -DNDEBUG -I\$(top_srcdir)"
|
||||
AC_SUBST([COMMON_CFLAGS])
|
||||
AC_SUBST([COMMON_CXXFLAGS])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
webrtc-audio-processing.pc
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/common_audio/Makefile
|
||||
src/common_audio/signal_processing_library/Makefile
|
||||
src/common_audio/vad/Makefile
|
||||
src/system_wrappers/Makefile
|
||||
src/modules/Makefile
|
||||
src/modules/audio_processing/Makefile
|
||||
src/modules/audio_processing/utility/Makefile
|
||||
src/modules/audio_processing/ns/Makefile
|
||||
src/modules/audio_processing/aec/Makefile
|
||||
src/modules/audio_processing/aecm/Makefile
|
||||
src/modules/audio_processing/agc/Makefile
|
||||
webrtc/Makefile
|
||||
webrtc/common_audio/Makefile
|
||||
webrtc/system_wrappers/Makefile
|
||||
webrtc/modules/Makefile
|
||||
webrtc/modules/audio_processing/Makefile
|
||||
webrtc/modules/audio_processing/utility/Makefile
|
||||
webrtc/modules/audio_processing/ns/Makefile
|
||||
webrtc/modules/audio_processing/aec/Makefile
|
||||
webrtc/modules/audio_processing/aecm/Makefile
|
||||
webrtc/modules/audio_processing/agc/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
@ -1 +0,0 @@
|
||||
SUBDIRS = signal_processing_library vad
|
@ -1,44 +0,0 @@
|
||||
noinst_LTLIBRARIES = libspl.la
|
||||
|
||||
libspl_la_SOURCES = main/interface/signal_processing_library.h \
|
||||
main/interface/spl_inl.h \
|
||||
main/source/auto_corr_to_refl_coef.c \
|
||||
main/source/auto_correlation.c \
|
||||
main/source/complex_fft.c \
|
||||
main/source/complex_ifft.c \
|
||||
main/source/complex_bit_reverse.c \
|
||||
main/source/copy_set_operations.c \
|
||||
main/source/cos_table.c \
|
||||
main/source/cross_correlation.c \
|
||||
main/source/division_operations.c \
|
||||
main/source/dot_product_with_scale.c \
|
||||
main/source/downsample_fast.c \
|
||||
main/source/energy.c \
|
||||
main/source/filter_ar.c \
|
||||
main/source/filter_ar_fast_q12.c \
|
||||
main/source/filter_ma_fast_q12.c \
|
||||
main/source/get_hanning_window.c \
|
||||
main/source/get_scaling_square.c \
|
||||
main/source/hanning_table.c \
|
||||
main/source/ilbc_specific_functions.c \
|
||||
main/source/levinson_durbin.c \
|
||||
main/source/lpc_to_refl_coef.c \
|
||||
main/source/min_max_operations.c \
|
||||
main/source/randn_table.c \
|
||||
main/source/randomization_functions.c \
|
||||
main/source/refl_coef_to_lpc.c \
|
||||
main/source/resample.c \
|
||||
main/source/resample_48khz.c \
|
||||
main/source/resample_by_2.c \
|
||||
main/source/resample_by_2_internal.c \
|
||||
main/source/resample_by_2_internal.h \
|
||||
main/source/resample_fractional.c \
|
||||
main/source/sin_table.c \
|
||||
main/source/sin_table_1024.c \
|
||||
main/source/spl_sqrt.c \
|
||||
main/source/spl_sqrt_floor.c \
|
||||
main/source/spl_version.c \
|
||||
main/source/splitting_filter.c \
|
||||
main/source/sqrt_of_one_minus_x_squared.c \
|
||||
main/source/vector_scaling_operations.c
|
||||
libspl_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS)
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
// This header file includes the inline functions in
|
||||
// the fix point signal processing library.
|
||||
|
||||
#ifndef WEBRTC_SPL_SPL_INL_H_
|
||||
#define WEBRTC_SPL_SPL_INL_H_
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
#include "spl_inl_armv7.h"
|
||||
#else
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) {
|
||||
WebRtc_Word16 out16 = (WebRtc_Word16) value32;
|
||||
|
||||
if (value32 > 32767)
|
||||
out16 = 32767;
|
||||
else if (value32 < -32768)
|
||||
out16 = -32768;
|
||||
|
||||
return out16;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,
|
||||
WebRtc_Word16 b) {
|
||||
return WebRtcSpl_SatW32ToW16((WebRtc_Word32) a + (WebRtc_Word32) b);
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1,
|
||||
WebRtc_Word32 l_var2) {
|
||||
WebRtc_Word32 l_sum;
|
||||
|
||||
// perform long addition
|
||||
l_sum = l_var1 + l_var2;
|
||||
|
||||
// check for under or overflow
|
||||
if (WEBRTC_SPL_IS_NEG(l_var1)) {
|
||||
if (WEBRTC_SPL_IS_NEG(l_var2) && !WEBRTC_SPL_IS_NEG(l_sum)) {
|
||||
l_sum = (WebRtc_Word32)0x80000000;
|
||||
}
|
||||
} else {
|
||||
if (!WEBRTC_SPL_IS_NEG(l_var2) && WEBRTC_SPL_IS_NEG(l_sum)) {
|
||||
l_sum = (WebRtc_Word32)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
return l_sum;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1,
|
||||
WebRtc_Word16 var2) {
|
||||
return WebRtcSpl_SatW32ToW16((WebRtc_Word32) var1 - (WebRtc_Word32) var2);
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1,
|
||||
WebRtc_Word32 l_var2) {
|
||||
WebRtc_Word32 l_diff;
|
||||
|
||||
// perform subtraction
|
||||
l_diff = l_var1 - l_var2;
|
||||
|
||||
// check for underflow
|
||||
if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0))
|
||||
l_diff = (WebRtc_Word32)0x80000000;
|
||||
// check for overflow
|
||||
if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0))
|
||||
l_diff = (WebRtc_Word32)0x7FFFFFFF;
|
||||
|
||||
return l_diff;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) {
|
||||
int bits;
|
||||
|
||||
if (0xFFFF0000 & n) {
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 0;
|
||||
}
|
||||
if (0x0000FF00 & (n >> bits)) bits += 8;
|
||||
if (0x000000F0 & (n >> bits)) bits += 4;
|
||||
if (0x0000000C & (n >> bits)) bits += 2;
|
||||
if (0x00000002 & (n >> bits)) bits += 1;
|
||||
if (0x00000001 & (n >> bits)) bits += 1;
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) {
|
||||
int zeros;
|
||||
|
||||
if (a <= 0) a ^= 0xFFFFFFFF;
|
||||
|
||||
if (!(0xFFFF8000 & a)) {
|
||||
zeros = 16;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xFF800000 & (a << zeros))) zeros += 8;
|
||||
if (!(0xF8000000 & (a << zeros))) zeros += 4;
|
||||
if (!(0xE0000000 & (a << zeros))) zeros += 2;
|
||||
if (!(0xC0000000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) {
|
||||
int zeros;
|
||||
|
||||
if (a == 0) return 0;
|
||||
|
||||
if (!(0xFFFF0000 & a)) {
|
||||
zeros = 16;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xFF000000 & (a << zeros))) zeros += 8;
|
||||
if (!(0xF0000000 & (a << zeros))) zeros += 4;
|
||||
if (!(0xC0000000 & (a << zeros))) zeros += 2;
|
||||
if (!(0x80000000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) {
|
||||
int zeros;
|
||||
|
||||
if (a <= 0) a ^= 0xFFFF;
|
||||
|
||||
if (!(0xFF80 & a)) {
|
||||
zeros = 8;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xF800 & (a << zeros))) zeros += 4;
|
||||
if (!(0xE000 & (a << zeros))) zeros += 2;
|
||||
if (!(0xC000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtc_MulAccumW16(int16_t a,
|
||||
int16_t b,
|
||||
int32_t c) {
|
||||
return (a * b + c);
|
||||
}
|
||||
|
||||
#endif // WEBRTC_ARCH_ARM_V7A
|
||||
|
||||
#endif // WEBRTC_SPL_SPL_INL_H_
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
// This header file includes the inline functions for ARM processors in
|
||||
// the fix point signal processing library.
|
||||
|
||||
#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_
|
||||
#define WEBRTC_SPL_SPL_INL_ARMV7_H_
|
||||
|
||||
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a,
|
||||
WebRtc_Word32 b) {
|
||||
WebRtc_Word32 tmp;
|
||||
__asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a,
|
||||
WebRtc_Word16 b,
|
||||
WebRtc_Word32 c) {
|
||||
WebRtc_Word32 tmp;
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a));
|
||||
__asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI(WebRtc_Word32 a,
|
||||
WebRtc_Word32 b) {
|
||||
WebRtc_Word32 tmp;
|
||||
__asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a,
|
||||
WebRtc_Word16 b) {
|
||||
WebRtc_Word32 tmp;
|
||||
__asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtc_MulAccumW16(int16_t a,
|
||||
int16_t b,
|
||||
int32_t c) {
|
||||
int32_t tmp = 0;
|
||||
__asm__("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,
|
||||
WebRtc_Word16 b) {
|
||||
WebRtc_Word32 s_sum;
|
||||
|
||||
__asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b));
|
||||
|
||||
return (WebRtc_Word16) s_sum;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1,
|
||||
WebRtc_Word32 l_var2) {
|
||||
WebRtc_Word32 l_sum;
|
||||
|
||||
__asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2));
|
||||
|
||||
return l_sum;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1,
|
||||
WebRtc_Word16 var2) {
|
||||
WebRtc_Word32 s_sub;
|
||||
|
||||
__asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2));
|
||||
|
||||
return (WebRtc_Word16)s_sub;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1,
|
||||
WebRtc_Word32 l_var2) {
|
||||
WebRtc_Word32 l_sub;
|
||||
|
||||
__asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2));
|
||||
|
||||
return l_sub;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) {
|
||||
WebRtc_Word32 tmp;
|
||||
|
||||
__asm__("clz %0, %1":"=r"(tmp):"r"(n));
|
||||
|
||||
return (WebRtc_Word16)(32 - tmp);
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormW32(WebRtc_Word32 a) {
|
||||
WebRtc_Word32 tmp;
|
||||
|
||||
if (a <= 0) a ^= 0xFFFFFFFF;
|
||||
|
||||
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
|
||||
|
||||
return tmp - 1;
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormU32(WebRtc_UWord32 a) {
|
||||
int tmp;
|
||||
|
||||
if (a == 0) return 0;
|
||||
|
||||
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline int WebRtcSpl_NormW16(WebRtc_Word16 a) {
|
||||
WebRtc_Word32 tmp;
|
||||
|
||||
if (a <= 0) a ^= 0xFFFFFFFF;
|
||||
|
||||
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
|
||||
|
||||
return tmp - 17;
|
||||
}
|
||||
|
||||
static __inline WebRtc_Word16 WebRtcSpl_SatW32ToW16(WebRtc_Word32 value32) {
|
||||
WebRtc_Word16 out16;
|
||||
|
||||
__asm__("ssat %r0, #16, %r1" : "=r"(out16) : "r"(value32));
|
||||
|
||||
return out16;
|
||||
}
|
||||
#endif // WEBRTC_SPL_SPL_INL_ARMV7_H_
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_AutoCorrelation().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,
|
||||
int in_vector_length,
|
||||
int order,
|
||||
WebRtc_Word32* result,
|
||||
int* scale)
|
||||
{
|
||||
WebRtc_Word32 sum;
|
||||
int i, j;
|
||||
WebRtc_Word16 smax; // Sample max
|
||||
G_CONST WebRtc_Word16* xptr1;
|
||||
G_CONST WebRtc_Word16* xptr2;
|
||||
WebRtc_Word32* resultptr;
|
||||
int scaling = 0;
|
||||
|
||||
#ifdef _ARM_OPT_
|
||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
||||
WebRtc_Word16 loops4;
|
||||
#endif
|
||||
|
||||
if (order < 0)
|
||||
order = in_vector_length;
|
||||
|
||||
// Find the max. sample
|
||||
smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
|
||||
|
||||
// In order to avoid overflow when computing the sum we should scale the samples so that
|
||||
// (in_vector_length * smax * smax) will not overflow.
|
||||
|
||||
if (smax == 0)
|
||||
{
|
||||
scaling = 0;
|
||||
} else
|
||||
{
|
||||
int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop
|
||||
int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax
|
||||
|
||||
if (t > nbits)
|
||||
{
|
||||
scaling = 0;
|
||||
} else
|
||||
{
|
||||
scaling = nbits - t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resultptr = result;
|
||||
|
||||
// Perform the actual correlation calculation
|
||||
for (i = 0; i < order + 1; i++)
|
||||
{
|
||||
int loops = (in_vector_length - i);
|
||||
sum = 0;
|
||||
xptr1 = in_vector;
|
||||
xptr2 = &in_vector[i];
|
||||
#ifndef _ARM_OPT_
|
||||
for (j = loops; j > 0; j--)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling);
|
||||
}
|
||||
#else
|
||||
loops4 = (loops >> 2) << 2;
|
||||
|
||||
if (scaling == 0)
|
||||
{
|
||||
for (j = 0; j < loops4; j = j + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
|
||||
for (j = loops4; j < loops; j++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < loops4; j = j + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
|
||||
for (j = loops4; j < loops; j++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
||||
xptr1++;
|
||||
xptr2++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
*resultptr++ = sum;
|
||||
}
|
||||
|
||||
*scale = scaling;
|
||||
|
||||
return order + 1;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_ComplexBitReverse().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages)
|
||||
{
|
||||
int mr, nn, n, l, m;
|
||||
WebRtc_Word16 tr, ti;
|
||||
|
||||
n = 1 << stages;
|
||||
|
||||
mr = 0;
|
||||
nn = n - 1;
|
||||
|
||||
// decimation in time - re-order data
|
||||
for (m = 1; m <= nn; ++m)
|
||||
{
|
||||
l = n;
|
||||
do
|
||||
{
|
||||
l >>= 1;
|
||||
} while (mr + l > nn);
|
||||
mr = (mr & (l - 1)) + l;
|
||||
|
||||
if (mr <= m)
|
||||
continue;
|
||||
|
||||
tr = frfi[2 * m];
|
||||
frfi[2 * m] = frfi[2 * mr];
|
||||
frfi[2 * mr] = tr;
|
||||
|
||||
ti = frfi[2 * m + 1];
|
||||
frfi[2 * m + 1] = frfi[2 * mr + 1];
|
||||
frfi[2 * mr + 1] = ti;
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_ComplexFFT().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define CFFTSFT 14
|
||||
#define CFFTRND 1
|
||||
#define CFFTRND2 16384
|
||||
|
||||
int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode)
|
||||
{
|
||||
int i, j, l, k, istep, n, m;
|
||||
WebRtc_Word16 wr, wi;
|
||||
WebRtc_Word32 tr32, ti32, qr32, qi32;
|
||||
|
||||
/* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = WebRtcSpl_kSinTable1024[j + 256];
|
||||
wi = -WebRtcSpl_kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
|
||||
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
|
||||
|
||||
qr32 = (WebRtc_Word32)frfi[2 * i];
|
||||
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = WebRtcSpl_kSinTable1024[j + 256];
|
||||
wi = -WebRtcSpl_kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
WebRtc_Word32 wri;
|
||||
WebRtc_Word32 frfi_r;
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) :
|
||||
"r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1]));
|
||||
__asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CFFTRND));
|
||||
__asm__("smladx %0, %1, %2, %3" : "=r"(ti32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CFFTRND));
|
||||
|
||||
#else
|
||||
tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND;
|
||||
|
||||
ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND;
|
||||
#endif
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT);
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT);
|
||||
|
||||
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT;
|
||||
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT;
|
||||
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_ComplexIFFT().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define CIFFTSFT 14
|
||||
#define CIFFTRND 1
|
||||
|
||||
int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode)
|
||||
{
|
||||
int i, j, l, k, istep, n, m, scale, shift;
|
||||
WebRtc_Word16 wr, wi;
|
||||
WebRtc_Word32 tr32, ti32, qr32, qi32;
|
||||
WebRtc_Word32 tmp32, round2;
|
||||
|
||||
/* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
scale = 0;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
while (l < n)
|
||||
{
|
||||
// variable scaling, depending upon data
|
||||
shift = 0;
|
||||
round2 = 8192;
|
||||
|
||||
tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
|
||||
if (tmp32 > 13573)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
if (tmp32 > 27146)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
|
||||
istep = l << 1;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = WebRtcSpl_kSinTable1024[j + 256];
|
||||
wi = WebRtcSpl_kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
|
||||
- WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);
|
||||
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(
|
||||
(WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
|
||||
+ WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);
|
||||
|
||||
qr32 = (WebRtc_Word32)frfi[2 * i];
|
||||
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = WebRtcSpl_kSinTable1024[j + 256];
|
||||
wi = WebRtcSpl_kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
WebRtc_Word32 wri;
|
||||
WebRtc_Word32 frfi_r;
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((WebRtc_Word32)wr), "r"((WebRtc_Word32)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7A
|
||||
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(frfi_r) :
|
||||
"r"((WebRtc_Word32)frfi[2*j]), "r"((WebRtc_Word32)frfi[2*j +1]));
|
||||
__asm__("smlsd %0, %1, %2, %3" : "=r"(tr32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CIFFTRND));
|
||||
__asm__("smladx %0, %1, %2, %3" : "=r"(ti32) :
|
||||
"r"(wri), "r"(frfi_r), "r"(CIFFTRND));
|
||||
#else
|
||||
|
||||
tr32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
|
||||
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CIFFTRND;
|
||||
|
||||
ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
|
||||
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND;
|
||||
#endif
|
||||
tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT);
|
||||
ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT);
|
||||
|
||||
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT;
|
||||
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT;
|
||||
|
||||
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),
|
||||
shift+CIFFTSFT);
|
||||
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 - ti32 + round2), shift + CIFFTSFT);
|
||||
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),
|
||||
shift + CIFFTSFT);
|
||||
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
|
||||
(qi32 + ti32 + round2), shift + CIFFTSFT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
return scale;
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the implementation of functions
|
||||
* WebRtcSpl_MemSetW16()
|
||||
* WebRtcSpl_MemSetW32()
|
||||
* WebRtcSpl_MemCpyReversedOrder()
|
||||
* WebRtcSpl_CopyFromEndW16()
|
||||
* WebRtcSpl_ZerosArrayW16()
|
||||
* WebRtcSpl_ZerosArrayW32()
|
||||
* WebRtcSpl_OnesArrayW16()
|
||||
* WebRtcSpl_OnesArrayW32()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the 360 degree cos table.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_kCosTable[] = {
|
||||
8192, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112,
|
||||
8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834,
|
||||
7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362,
|
||||
7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710,
|
||||
6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892,
|
||||
5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930,
|
||||
4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845,
|
||||
3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667,
|
||||
2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422,
|
||||
1281, 1140, 998, 856, 713, 571, 428, 285, 142,
|
||||
0, -142, -285, -428, -571, -713, -856, -998, -1140,
|
||||
-1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395,
|
||||
-2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591,
|
||||
-3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698,
|
||||
-4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690,
|
||||
-5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542,
|
||||
-6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233,
|
||||
-7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745,
|
||||
-7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067,
|
||||
-8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190,
|
||||
-8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112,
|
||||
-8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834,
|
||||
-7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362,
|
||||
-7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710,
|
||||
-6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892,
|
||||
-5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930,
|
||||
-4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845,
|
||||
-3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667,
|
||||
-2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422,
|
||||
-1281, -1140, -998, -856, -713, -571, -428, -285, -142,
|
||||
0, 142, 285, 428, 571, 713, 856, 998, 1140,
|
||||
1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395,
|
||||
2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591,
|
||||
3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698,
|
||||
4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690,
|
||||
5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542,
|
||||
6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233,
|
||||
7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745,
|
||||
7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067,
|
||||
8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190
|
||||
};
|
@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_CrossCorrelation().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1,
|
||||
WebRtc_Word16* seq2, WebRtc_Word16 dim_seq,
|
||||
WebRtc_Word16 dim_cross_correlation,
|
||||
WebRtc_Word16 right_shifts,
|
||||
WebRtc_Word16 step_seq2)
|
||||
{
|
||||
int i, j;
|
||||
WebRtc_Word16* seq1Ptr;
|
||||
WebRtc_Word16* seq2Ptr;
|
||||
WebRtc_Word32* CrossCorrPtr;
|
||||
|
||||
#ifdef _XSCALE_OPT_
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)")
|
||||
#endif
|
||||
|
||||
__int64 macc40;
|
||||
|
||||
int iseq1[250];
|
||||
int iseq2[250];
|
||||
int iseq3[250];
|
||||
int * iseq1Ptr;
|
||||
int * iseq2Ptr;
|
||||
int * iseq3Ptr;
|
||||
int len, i_len;
|
||||
|
||||
seq1Ptr = seq1;
|
||||
iseq1Ptr = iseq1;
|
||||
for(i = 0; i < ((dim_seq + 1) >> 1); i++)
|
||||
{
|
||||
*iseq1Ptr = (unsigned short)*seq1Ptr++;
|
||||
*iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16;
|
||||
|
||||
}
|
||||
|
||||
if(dim_seq%2)
|
||||
{
|
||||
*(iseq1Ptr-1) &= 0x0000ffff;
|
||||
}
|
||||
*iseq1Ptr = 0;
|
||||
iseq1Ptr++;
|
||||
*iseq1Ptr = 0;
|
||||
iseq1Ptr++;
|
||||
*iseq1Ptr = 0;
|
||||
|
||||
if(step_seq2 < 0)
|
||||
{
|
||||
seq2Ptr = seq2 - dim_cross_correlation + 1;
|
||||
CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
seq2Ptr = seq2;
|
||||
CrossCorrPtr = cross_correlation;
|
||||
}
|
||||
|
||||
len = dim_seq + dim_cross_correlation - 1;
|
||||
i_len = (len + 1) >> 1;
|
||||
iseq2Ptr = iseq2;
|
||||
|
||||
iseq3Ptr = iseq3;
|
||||
for(i = 0; i < i_len; i++)
|
||||
{
|
||||
*iseq2Ptr = (unsigned short)*seq2Ptr++;
|
||||
*iseq3Ptr = (unsigned short)*seq2Ptr;
|
||||
*iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16;
|
||||
*iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16;
|
||||
}
|
||||
|
||||
if(len % 2)
|
||||
{
|
||||
iseq2[i_len - 1] &= 0x0000ffff;
|
||||
iseq3[i_len - 1] = 0;
|
||||
}
|
||||
else
|
||||
iseq3[i_len - 1] &= 0x0000ffff;
|
||||
|
||||
iseq2[i_len] = 0;
|
||||
iseq3[i_len] = 0;
|
||||
iseq2[i_len + 1] = 0;
|
||||
iseq3[i_len + 1] = 0;
|
||||
iseq2[i_len + 2] = 0;
|
||||
iseq3[i_len + 2] = 0;
|
||||
|
||||
// Set pointer to start value
|
||||
iseq2Ptr = iseq2;
|
||||
iseq3Ptr = iseq3;
|
||||
|
||||
i_len = (dim_seq + 7) >> 3;
|
||||
for (i = 0; i < dim_cross_correlation; i++)
|
||||
{
|
||||
|
||||
iseq1Ptr = iseq1;
|
||||
|
||||
macc40 = 0;
|
||||
|
||||
_WriteCoProcessor(macc40, 0);
|
||||
|
||||
if((i & 1))
|
||||
{
|
||||
iseq3Ptr = iseq3 + (i >> 1);
|
||||
for (j = i_len; j > 0; j--)
|
||||
{
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iseq2Ptr = iseq2 + (i >> 1);
|
||||
for (j = i_len; j > 0; j--)
|
||||
{
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
macc40 = _ReadCoProcessor(0);
|
||||
*CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts);
|
||||
CrossCorrPtr += step_seq2;
|
||||
}
|
||||
#else // #ifdef _XSCALE_OPT_
|
||||
#ifdef _ARM_OPT_
|
||||
WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3;
|
||||
#endif
|
||||
|
||||
CrossCorrPtr = cross_correlation;
|
||||
|
||||
for (i = 0; i < dim_cross_correlation; i++)
|
||||
{
|
||||
// Set the pointer to the static vector, set the pointer to the sliding vector
|
||||
// and initialize cross_correlation
|
||||
seq1Ptr = seq1;
|
||||
seq2Ptr = seq2 + (step_seq2 * i);
|
||||
(*CrossCorrPtr) = 0;
|
||||
|
||||
#ifndef _ARM_OPT_
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: default implementation is used")
|
||||
#endif
|
||||
// Perform the cross correlation
|
||||
for (j = 0; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
||||
#endif
|
||||
if (right_shifts == 0)
|
||||
{
|
||||
// Perform the optimized cross correlation
|
||||
for (j = 0; j < dim_seq8; j = j + 8)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
|
||||
for (j = dim_seq8; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
}
|
||||
else // right_shifts != 0
|
||||
|
||||
{
|
||||
// Perform the optimized cross correlation
|
||||
for (j = 0; j < dim_seq8; j = j + 8)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
|
||||
for (j = dim_seq8; j < dim_seq; j++)
|
||||
{
|
||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
||||
right_shifts);
|
||||
seq1Ptr++;
|
||||
seq2Ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CrossCorrPtr++;
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the divisions
|
||||
* WebRtcSpl_DivU32U16()
|
||||
* WebRtcSpl_DivW32W16()
|
||||
* WebRtcSpl_DivW32W16ResW16()
|
||||
* WebRtcSpl_DivResultInQ31()
|
||||
* WebRtcSpl_DivW32HiLow()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_UWord32)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_UWord32)0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_Word32)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_Word32)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (WebRtc_Word16)(num / den);
|
||||
} else
|
||||
{
|
||||
return (WebRtc_Word16)0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)
|
||||
{
|
||||
WebRtc_Word32 L_num = num;
|
||||
WebRtc_Word32 L_den = den;
|
||||
WebRtc_Word32 div = 0;
|
||||
int k = 31;
|
||||
int change_sign = 0;
|
||||
|
||||
if (num == 0)
|
||||
return 0;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_num = -num;
|
||||
}
|
||||
if (den < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_den = -den;
|
||||
}
|
||||
while (k--)
|
||||
{
|
||||
div <<= 1;
|
||||
L_num <<= 1;
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num -= L_den;
|
||||
div++;
|
||||
}
|
||||
}
|
||||
if (change_sign == 1)
|
||||
{
|
||||
div = -div;
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,
|
||||
WebRtc_Word16 den_low)
|
||||
{
|
||||
WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;
|
||||
WebRtc_Word32 tmpW32;
|
||||
|
||||
approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);
|
||||
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
|
||||
|
||||
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
|
||||
tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
|
||||
+ ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
|
||||
// tmpW32 = den * approx
|
||||
|
||||
tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
|
||||
|
||||
// Store tmpW32 in hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// tmpW32 = 1/den in Q29
|
||||
tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
|
||||
>> 15)) << 1);
|
||||
|
||||
// 1/den in hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// Store num in hi and low format
|
||||
num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);
|
||||
num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);
|
||||
|
||||
// num * (1/den) by 32 bit multiplication (result in Q28)
|
||||
|
||||
tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
|
||||
>> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
|
||||
|
||||
// Put result in Q31 (convert from Q28)
|
||||
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
|
||||
|
||||
return tmpW32;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_DotProductWithScale().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2,
|
||||
int length, int scaling)
|
||||
{
|
||||
WebRtc_Word32 sum;
|
||||
int i;
|
||||
#ifdef _ARM_OPT_
|
||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
||||
WebRtc_Word16 len4 = (length >> 2) << 2;
|
||||
#endif
|
||||
|
||||
sum = 0;
|
||||
|
||||
#ifndef _ARM_OPT_
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling);
|
||||
}
|
||||
#else
|
||||
if (scaling == 0)
|
||||
{
|
||||
for (i = 0; i < len4; i = i + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
||||
vector1++;
|
||||
vector2++;
|
||||
}
|
||||
|
||||
for (i = len4; i < length; i++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
||||
vector1++;
|
||||
vector2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < len4; i = i + 4)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
||||
vector1++;
|
||||
vector2++;
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
||||
vector1++;
|
||||
vector2++;
|
||||
}
|
||||
|
||||
for (i = len4; i < length; i++)
|
||||
{
|
||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
||||
vector1++;
|
||||
vector2++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return sum;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_DownsampleFast().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length,
|
||||
WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length,
|
||||
WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor,
|
||||
WebRtc_Word16 delay)
|
||||
{
|
||||
WebRtc_Word32 o;
|
||||
int i, j;
|
||||
|
||||
WebRtc_Word16 *downsampled_ptr = out_ptr;
|
||||
WebRtc_Word16 *b_ptr;
|
||||
WebRtc_Word16 *x_ptr;
|
||||
WebRtc_Word16 endpos = delay
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1;
|
||||
|
||||
if (in_length < endpos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = delay; i < endpos; i += factor)
|
||||
{
|
||||
b_ptr = &B[0];
|
||||
x_ptr = &in_ptr[i];
|
||||
|
||||
o = (WebRtc_Word32)2048; // Round val
|
||||
|
||||
for (j = 0; j < B_length; j++)
|
||||
{
|
||||
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
|
||||
}
|
||||
|
||||
o = WEBRTC_SPL_RSHIFT_W32(o, 12);
|
||||
|
||||
// If output is higher than 32768, saturate it. Same with negative side
|
||||
|
||||
*downsampled_ptr++ = WebRtcSpl_SatW32ToW16(o);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_FilterAR().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a,
|
||||
int a_length,
|
||||
G_CONST WebRtc_Word16* x,
|
||||
int x_length,
|
||||
WebRtc_Word16* state,
|
||||
int state_length,
|
||||
WebRtc_Word16* state_low,
|
||||
int state_low_length,
|
||||
WebRtc_Word16* filtered,
|
||||
WebRtc_Word16* filtered_low,
|
||||
int filtered_low_length)
|
||||
{
|
||||
WebRtc_Word32 o;
|
||||
WebRtc_Word32 oLOW;
|
||||
int i, j, stop;
|
||||
G_CONST WebRtc_Word16* x_ptr = &x[0];
|
||||
WebRtc_Word16* filteredFINAL_ptr = filtered;
|
||||
WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low;
|
||||
|
||||
for (i = 0; i < x_length; i++)
|
||||
{
|
||||
// Calculate filtered[i] and filtered_low[i]
|
||||
G_CONST WebRtc_Word16* a_ptr = &a[1];
|
||||
WebRtc_Word16* filtered_ptr = &filtered[i - 1];
|
||||
WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1];
|
||||
WebRtc_Word16* state_ptr = &state[state_length - 1];
|
||||
WebRtc_Word16* state_low_ptr = &state_low[state_length - 1];
|
||||
|
||||
o = (WebRtc_Word32)(*x_ptr++) << 12;
|
||||
oLOW = (WebRtc_Word32)0;
|
||||
|
||||
stop = (i < a_length) ? i + 1 : a_length;
|
||||
for (j = 1; j < stop; j++)
|
||||
{
|
||||
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
|
||||
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
|
||||
}
|
||||
for (j = i + 1; j < a_length; j++)
|
||||
{
|
||||
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--);
|
||||
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--);
|
||||
}
|
||||
|
||||
o += (oLOW >> 12);
|
||||
*filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
|
||||
*filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++)
|
||||
<< 12));
|
||||
}
|
||||
|
||||
// Save the filter state
|
||||
if (x_length >= state_length)
|
||||
{
|
||||
WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state);
|
||||
WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low);
|
||||
} else
|
||||
{
|
||||
for (i = 0; i < state_length - x_length; i++)
|
||||
{
|
||||
state[i] = state[i + x_length];
|
||||
state_low[i] = state_low[i + x_length];
|
||||
}
|
||||
for (i = 0; i < x_length; i++)
|
||||
{
|
||||
state[state_length - x_length + i] = filtered[i];
|
||||
state[state_length - x_length + i] = filtered_low[i];
|
||||
}
|
||||
}
|
||||
|
||||
return x_length;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_FilterARFastQ12().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A,
|
||||
WebRtc_Word16 A_length, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 o;
|
||||
int i, j;
|
||||
|
||||
WebRtc_Word16 *x_ptr = &in[0];
|
||||
WebRtc_Word16 *filtered_ptr = &out[0];
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
// Calculate filtered[i]
|
||||
G_CONST WebRtc_Word16 *a_ptr = &A[0];
|
||||
WebRtc_Word16 *state_ptr = &out[i - 1];
|
||||
|
||||
o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++);
|
||||
|
||||
for (j = 1; j < A_length; j++)
|
||||
{
|
||||
o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--);
|
||||
}
|
||||
|
||||
// Saturate the output
|
||||
o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);
|
||||
|
||||
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_GetHanningWindow().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size)
|
||||
{
|
||||
int jj;
|
||||
WebRtc_Word16 *vptr1;
|
||||
|
||||
WebRtc_Word32 index;
|
||||
WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000);
|
||||
|
||||
factor = WebRtcSpl_DivW32W16(factor, size);
|
||||
if (size < 513)
|
||||
index = (WebRtc_Word32)-0x200000;
|
||||
else
|
||||
index = (WebRtc_Word32)-0x100000;
|
||||
vptr1 = v;
|
||||
|
||||
for (jj = 0; jj < size; jj++)
|
||||
{
|
||||
index += factor;
|
||||
(*vptr1++) = WebRtcSpl_kHanningTable[index >> 22];
|
||||
}
|
||||
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the iLBC specific functions
|
||||
* WebRtcSpl_ScaleAndAddVectorsWithRound()
|
||||
* WebRtcSpl_ReverseOrderMultArrayElements()
|
||||
* WebRtcSpl_ElementwiseVectorMult()
|
||||
* WebRtcSpl_AddVectorsAndShift()
|
||||
* WebRtcSpl_AddAffineVectorToVector()
|
||||
* WebRtcSpl_AffineTransformVector()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1,
|
||||
WebRtc_Word16 *vector2, WebRtc_Word16 scale2,
|
||||
WebRtc_Word16 right_shifts, WebRtc_Word16 *out,
|
||||
WebRtc_Word16 vector_length)
|
||||
{
|
||||
int i;
|
||||
WebRtc_Word16 roundVal;
|
||||
roundVal = 1 << right_shifts;
|
||||
roundVal = roundVal >> 1;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1)
|
||||
+ WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,
|
||||
G_CONST WebRtc_Word16 *win,
|
||||
WebRtc_Word16 vector_length,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
WebRtc_Word16 *outptr = out;
|
||||
G_CONST WebRtc_Word16 *inptr = in;
|
||||
G_CONST WebRtc_Word16 *winptr = win;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,
|
||||
*winptr--, right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,
|
||||
G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
WebRtc_Word16 *outptr = out;
|
||||
G_CONST WebRtc_Word16 *inptr = in;
|
||||
G_CONST WebRtc_Word16 *winptr = win;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,
|
||||
*winptr++, right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1,
|
||||
G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
WebRtc_Word16 *outptr = out;
|
||||
G_CONST WebRtc_Word16 *in1ptr = in1;
|
||||
G_CONST WebRtc_Word16 *in2ptr = in2;
|
||||
for (i = vector_length; i > 0; i--)
|
||||
{
|
||||
(*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
|
||||
WebRtc_Word16 gain, WebRtc_Word32 add_constant,
|
||||
WebRtc_Word16 right_shifts, int vector_length)
|
||||
{
|
||||
WebRtc_Word16 *inPtr;
|
||||
WebRtc_Word16 *outPtr;
|
||||
int i;
|
||||
|
||||
inPtr = in;
|
||||
outPtr = out;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
(*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
|
||||
+ (WebRtc_Word32)add_constant) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
|
||||
WebRtc_Word16 gain, WebRtc_Word32 add_constant,
|
||||
WebRtc_Word16 right_shifts, int vector_length)
|
||||
{
|
||||
WebRtc_Word16 *inPtr;
|
||||
WebRtc_Word16 *outPtr;
|
||||
int i;
|
||||
|
||||
inPtr = in;
|
||||
outPtr = out;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
(*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
|
||||
+ (WebRtc_Word32)add_constant) >> right_shifts);
|
||||
}
|
||||
}
|
@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_LevinsonDurbin().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define SPL_LEVINSON_MAXORDER 20
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32 *R, WebRtc_Word16 *A, WebRtc_Word16 *K,
|
||||
WebRtc_Word16 order)
|
||||
{
|
||||
WebRtc_Word16 i, j;
|
||||
// Auto-correlation coefficients in high precision
|
||||
WebRtc_Word16 R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// LPC coefficients in high precision
|
||||
WebRtc_Word16 A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// LPC coefficients for next iteration
|
||||
WebRtc_Word16 A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// Reflection coefficient in high precision
|
||||
WebRtc_Word16 K_hi, K_low;
|
||||
// Prediction gain Alpha in high precision and with scale factor
|
||||
WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp;
|
||||
WebRtc_Word16 tmp_hi, tmp_low;
|
||||
WebRtc_Word32 temp1W32, temp2W32, temp3W32;
|
||||
WebRtc_Word16 norm;
|
||||
|
||||
// Normalize the autocorrelation R[0]...R[order+1]
|
||||
|
||||
norm = WebRtcSpl_NormW32(R[0]);
|
||||
|
||||
for (i = order; i >= 0; i--)
|
||||
{
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
|
||||
// Put R in hi and low format
|
||||
R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1);
|
||||
}
|
||||
|
||||
// K = A[1] = -R[1] / R[0]
|
||||
|
||||
temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31
|
||||
temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1]
|
||||
temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31
|
||||
// Put back the sign on R[1]
|
||||
if (temp2W32 > 0)
|
||||
{
|
||||
temp1W32 = -temp1W32;
|
||||
}
|
||||
|
||||
// Put K in hi and low format
|
||||
K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
|
||||
|
||||
// Store first reflection coefficient
|
||||
K[0] = K_hi;
|
||||
|
||||
temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27
|
||||
|
||||
// Put A[1] in hi and low format
|
||||
A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1);
|
||||
|
||||
// Alpha = R[0] * (1-K^2)
|
||||
|
||||
temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi))
|
||||
<< 1); // temp1W32 = k^2 in Q31
|
||||
|
||||
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
|
||||
temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31
|
||||
|
||||
// Store temp1W32 = 1 - K[0]*K[0] on hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// Calculate Alpha in Q31
|
||||
temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi)
|
||||
+ (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15)
|
||||
+ (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1);
|
||||
|
||||
// Normalize Alpha and put it in hi and low format
|
||||
|
||||
Alpha_exp = WebRtcSpl_NormW32(temp1W32);
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
|
||||
Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
|
||||
|
||||
// Perform the iterative calculations in the Levinson-Durbin algorithm
|
||||
|
||||
for (i = 2; i <= order; i++)
|
||||
{
|
||||
/* ----
|
||||
temp1W32 = R[i] + > R[j]*A[i-j]
|
||||
/
|
||||
----
|
||||
j=1..i-1
|
||||
*/
|
||||
|
||||
temp1W32 = 0;
|
||||
|
||||
for (j = 1; j < i; j++)
|
||||
{
|
||||
// temp1W32 is in Q31
|
||||
temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1)
|
||||
+ (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15)
|
||||
+ (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1));
|
||||
}
|
||||
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);
|
||||
temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1));
|
||||
|
||||
// K = -temp1W32 / Alpha
|
||||
temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32)
|
||||
temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha
|
||||
|
||||
// Put the sign of temp1W32 back again
|
||||
if (temp1W32 > 0)
|
||||
{
|
||||
temp3W32 = -temp3W32;
|
||||
}
|
||||
|
||||
// Use the Alpha shifts from earlier to de-normalize
|
||||
norm = WebRtcSpl_NormW32(temp3W32);
|
||||
if ((Alpha_exp <= norm) || (temp3W32 == 0))
|
||||
{
|
||||
temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp);
|
||||
} else
|
||||
{
|
||||
if (temp3W32 > 0)
|
||||
{
|
||||
temp3W32 = (WebRtc_Word32)0x7fffffffL;
|
||||
} else
|
||||
{
|
||||
temp3W32 = (WebRtc_Word32)0x80000000L;
|
||||
}
|
||||
}
|
||||
|
||||
// Put K on hi and low format
|
||||
K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
|
||||
K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
|
||||
|
||||
// Store Reflection coefficient in Q15
|
||||
K[i - 1] = K_hi;
|
||||
|
||||
// Test for unstable filter.
|
||||
// If unstable return 0 and let the user decide what to do in that case
|
||||
|
||||
if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750)
|
||||
{
|
||||
return 0; // Unstable filter
|
||||
}
|
||||
|
||||
/*
|
||||
Compute updated LPC coefficient: Anew[i]
|
||||
Anew[j]= A[j] + K*A[i-j] for j=1..i-1
|
||||
Anew[i]= K
|
||||
*/
|
||||
|
||||
for (j = 1; j < i; j++)
|
||||
{
|
||||
// temp1W32 = A[j] in Q27
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1);
|
||||
|
||||
// temp1W32 += K*A[i-j] in Q27
|
||||
temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j])
|
||||
+ (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15)
|
||||
+ (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1);
|
||||
|
||||
// Put Anew in hi and low format
|
||||
A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1);
|
||||
}
|
||||
|
||||
// temp3W32 = K in Q27 (Convert from Q31 to Q27)
|
||||
temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4);
|
||||
|
||||
// Store Anew in hi and low format
|
||||
A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
|
||||
A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1);
|
||||
|
||||
// Alpha = Alpha * (1-K^2)
|
||||
|
||||
temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14)
|
||||
+ WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31
|
||||
|
||||
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
|
||||
temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K in Q31
|
||||
|
||||
// Convert 1- K^2 in hi and low format
|
||||
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
|
||||
|
||||
// Calculate Alpha = Alpha * (1-K^2) in Q31
|
||||
temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi)
|
||||
+ (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15)
|
||||
+ (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1);
|
||||
|
||||
// Normalize Alpha and store it on hi and low format
|
||||
|
||||
norm = WebRtcSpl_NormW32(temp1W32);
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
|
||||
|
||||
Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
|
||||
Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
|
||||
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
|
||||
|
||||
// Update the total normalization of Alpha
|
||||
Alpha_exp = Alpha_exp + norm;
|
||||
|
||||
// Update A[]
|
||||
|
||||
for (j = 1; j <= i; j++)
|
||||
{
|
||||
A_hi[j] = A_upd_hi[j];
|
||||
A_low[j] = A_upd_low[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set A[0] to 1.0 and store the A[i] i=1...order in Q12
|
||||
(Convert from Q27 and use rounding)
|
||||
*/
|
||||
|
||||
A[0] = 4096;
|
||||
|
||||
for (i = 1; i <= order; i++)
|
||||
{
|
||||
// temp1W32 in Q27
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1);
|
||||
// Round and store upper word
|
||||
A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16);
|
||||
}
|
||||
return 1; // Stable filters
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the implementation of functions
|
||||
* WebRtcSpl_MaxAbsValueW16()
|
||||
* WebRtcSpl_MaxAbsIndexW16()
|
||||
* WebRtcSpl_MaxAbsValueW32()
|
||||
* WebRtcSpl_MaxValueW16()
|
||||
* WebRtcSpl_MaxIndexW16()
|
||||
* WebRtcSpl_MaxValueW32()
|
||||
* WebRtcSpl_MaxIndexW32()
|
||||
* WebRtcSpl_MinValueW16()
|
||||
* WebRtcSpl_MinIndexW16()
|
||||
* WebRtcSpl_MinValueW32()
|
||||
* WebRtcSpl_MinIndexW32()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#if !(defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON))
|
||||
|
||||
// Maximum absolute value of word16 vector.
|
||||
WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(const WebRtc_Word16 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 tempMax = 0;
|
||||
WebRtc_Word32 absVal;
|
||||
WebRtc_Word16 totMax;
|
||||
int i;
|
||||
G_CONST WebRtc_Word16 *tmpvector = vector;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
|
||||
if (absVal > tempMax)
|
||||
{
|
||||
tempMax = absVal;
|
||||
}
|
||||
tmpvector++;
|
||||
}
|
||||
totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX);
|
||||
return totMax;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Index of maximum absolute value in a word16 vector.
|
||||
WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 tempMax;
|
||||
WebRtc_Word16 absTemp;
|
||||
WebRtc_Word16 tempMaxIndex = 0;
|
||||
WebRtc_Word16 i = 0;
|
||||
G_CONST WebRtc_Word16 *tmpvector = vector;
|
||||
|
||||
tempMax = WEBRTC_SPL_ABS_W16(*tmpvector);
|
||||
tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
absTemp = WEBRTC_SPL_ABS_W16(*tmpvector);
|
||||
tmpvector++;
|
||||
if (absTemp > tempMax)
|
||||
{
|
||||
tempMax = absTemp;
|
||||
tempMaxIndex = i;
|
||||
}
|
||||
}
|
||||
return tempMaxIndex;
|
||||
}
|
||||
|
||||
// Maximum absolute value of word32 vector.
|
||||
WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_UWord32 tempMax = 0;
|
||||
WebRtc_UWord32 absVal;
|
||||
WebRtc_Word32 retval;
|
||||
int i;
|
||||
G_CONST WebRtc_Word32 *tmpvector = vector;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
|
||||
if (absVal > tempMax)
|
||||
{
|
||||
tempMax = absVal;
|
||||
}
|
||||
tmpvector++;
|
||||
}
|
||||
retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX));
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Maximum value of word16 vector.
|
||||
#ifndef XSCALE_OPT
|
||||
WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 tempMax;
|
||||
WebRtc_Word16 i;
|
||||
G_CONST WebRtc_Word16 *tmpvector = vector;
|
||||
|
||||
tempMax = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ > tempMax)
|
||||
tempMax = vector[i];
|
||||
}
|
||||
return tempMax;
|
||||
}
|
||||
#else
|
||||
#pragma message(">> WebRtcSpl_MaxValueW16 is excluded from this build")
|
||||
#endif
|
||||
|
||||
// Index of maximum value in a word16 vector.
|
||||
WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 tempMax;
|
||||
WebRtc_Word16 tempMaxIndex = 0;
|
||||
WebRtc_Word16 i = 0;
|
||||
G_CONST WebRtc_Word16 *tmpvector = vector;
|
||||
|
||||
tempMax = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ > tempMax)
|
||||
{
|
||||
tempMax = vector[i];
|
||||
tempMaxIndex = i;
|
||||
}
|
||||
}
|
||||
return tempMaxIndex;
|
||||
}
|
||||
|
||||
// Maximum value of word32 vector.
|
||||
#ifndef XSCALE_OPT
|
||||
WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 tempMax;
|
||||
WebRtc_Word16 i;
|
||||
G_CONST WebRtc_Word32 *tmpvector = vector;
|
||||
|
||||
tempMax = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ > tempMax)
|
||||
tempMax = vector[i];
|
||||
}
|
||||
return tempMax;
|
||||
}
|
||||
#else
|
||||
#pragma message(">> WebRtcSpl_MaxValueW32 is excluded from this build")
|
||||
#endif
|
||||
|
||||
// Index of maximum value in a word32 vector.
|
||||
WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 tempMax;
|
||||
WebRtc_Word16 tempMaxIndex = 0;
|
||||
WebRtc_Word16 i = 0;
|
||||
G_CONST WebRtc_Word32 *tmpvector = vector;
|
||||
|
||||
tempMax = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ > tempMax)
|
||||
{
|
||||
tempMax = vector[i];
|
||||
tempMaxIndex = i;
|
||||
}
|
||||
}
|
||||
return tempMaxIndex;
|
||||
}
|
||||
|
||||
// Minimum value of word16 vector.
|
||||
WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 tempMin;
|
||||
WebRtc_Word16 i;
|
||||
G_CONST WebRtc_Word16 *tmpvector = vector;
|
||||
|
||||
// Find the minimum value
|
||||
tempMin = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ < tempMin)
|
||||
tempMin = (vector[i]);
|
||||
}
|
||||
return tempMin;
|
||||
}
|
||||
|
||||
// Index of minimum value in a word16 vector.
|
||||
#ifndef XSCALE_OPT
|
||||
WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word16 tempMin;
|
||||
WebRtc_Word16 tempMinIndex = 0;
|
||||
WebRtc_Word16 i = 0;
|
||||
G_CONST WebRtc_Word16* tmpvector = vector;
|
||||
|
||||
// Find index of smallest value
|
||||
tempMin = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ < tempMin)
|
||||
{
|
||||
tempMin = vector[i];
|
||||
tempMinIndex = i;
|
||||
}
|
||||
}
|
||||
return tempMinIndex;
|
||||
}
|
||||
#else
|
||||
#pragma message(">> WebRtcSpl_MinIndexW16 is excluded from this build")
|
||||
#endif
|
||||
|
||||
// Minimum value of word32 vector.
|
||||
WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 tempMin;
|
||||
WebRtc_Word16 i;
|
||||
G_CONST WebRtc_Word32 *tmpvector = vector;
|
||||
|
||||
// Find the minimum value
|
||||
tempMin = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ < tempMin)
|
||||
tempMin = (vector[i]);
|
||||
}
|
||||
return tempMin;
|
||||
}
|
||||
|
||||
// Index of minimum value in a word32 vector.
|
||||
#ifndef XSCALE_OPT
|
||||
WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
|
||||
{
|
||||
WebRtc_Word32 tempMin;
|
||||
WebRtc_Word16 tempMinIndex = 0;
|
||||
WebRtc_Word16 i = 0;
|
||||
G_CONST WebRtc_Word32 *tmpvector = vector;
|
||||
|
||||
// Find index of smallest value
|
||||
tempMin = *tmpvector++;
|
||||
for (i = 1; i < length; i++)
|
||||
{
|
||||
if (*tmpvector++ < tempMin)
|
||||
{
|
||||
tempMin = vector[i];
|
||||
tempMinIndex = i;
|
||||
}
|
||||
}
|
||||
return tempMinIndex;
|
||||
}
|
||||
#else
|
||||
#pragma message(">> WebRtcSpl_MinIndexW32 is excluded from this build")
|
||||
#endif
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#if (defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM_NEON))
|
||||
|
||||
#include <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
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the randomization functions
|
||||
* WebRtcSpl_IncreaseSeed()
|
||||
* WebRtcSpl_RandU()
|
||||
* WebRtcSpl_RandN()
|
||||
* WebRtcSpl_RandUArray()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed)
|
||||
{
|
||||
seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1);
|
||||
return seed[0];
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32 *seed)
|
||||
{
|
||||
return (WebRtc_Word16)(WebRtcSpl_IncreaseSeed(seed) >> 16);
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32 *seed)
|
||||
{
|
||||
return WebRtcSpl_kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23];
|
||||
}
|
||||
|
||||
// Creates an array of uniformly distributed variables
|
||||
WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector,
|
||||
WebRtc_Word16 vector_length,
|
||||
WebRtc_UWord32* seed)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
vector[i] = WebRtcSpl_RandU(seed);
|
||||
}
|
||||
return vector_length;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file contains some internal resampling functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_
|
||||
#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
/*******************************************************************
|
||||
* resample_by_2_fast.c
|
||||
* Functions for internal use in the other resample functions
|
||||
******************************************************************/
|
||||
void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
|
||||
WebRtc_Word32 *state);
|
||||
|
||||
void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len,
|
||||
WebRtc_Word32 *out, WebRtc_Word32 *state);
|
||||
|
||||
void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len,
|
||||
WebRtc_Word32 *out, WebRtc_Word32 *state);
|
||||
|
||||
void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
|
||||
WebRtc_Word32 *state);
|
||||
|
||||
void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len,
|
||||
WebRtc_Word16 *out, WebRtc_Word32 *state);
|
||||
|
||||
void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len,
|
||||
WebRtc_Word32* out, WebRtc_Word32* state);
|
||||
|
||||
void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,
|
||||
WebRtc_Word32* state);
|
||||
|
||||
#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the 360 degree sine table.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_kSinTable[] = {
|
||||
0, 142, 285, 428, 571, 713, 856, 998, 1140,
|
||||
1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395,
|
||||
2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591,
|
||||
3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698,
|
||||
4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690,
|
||||
5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542,
|
||||
6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233,
|
||||
7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745,
|
||||
7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067,
|
||||
8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190,
|
||||
8191, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112,
|
||||
8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834,
|
||||
7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362,
|
||||
7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710,
|
||||
6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892,
|
||||
5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930,
|
||||
4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845,
|
||||
3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667,
|
||||
2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422,
|
||||
1281, 1140, 998, 856, 713, 571, 428, 285, 142,
|
||||
0, -142, -285, -428, -571, -713, -856, -998, -1140,
|
||||
-1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395,
|
||||
-2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591,
|
||||
-3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698,
|
||||
-4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690,
|
||||
-5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542,
|
||||
-6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233,
|
||||
-7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745,
|
||||
-7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067,
|
||||
-8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190,
|
||||
-8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112,
|
||||
-8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834,
|
||||
-7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362,
|
||||
-7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710,
|
||||
-6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892,
|
||||
-5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930,
|
||||
-4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845,
|
||||
-3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667,
|
||||
-2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422,
|
||||
-1281, -1140, -998, -856, -713, -571, -428, -285, -142
|
||||
};
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the 1024 point sine table.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_kSinTable1024[] =
|
||||
{
|
||||
0, 201, 402, 603, 804, 1005, 1206, 1406,
|
||||
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
|
||||
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
|
||||
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
|
||||
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
|
||||
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
|
||||
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
|
||||
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
|
||||
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
|
||||
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
|
||||
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
|
||||
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
|
||||
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
|
||||
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
|
||||
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
|
||||
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
|
||||
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
|
||||
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
|
||||
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
|
||||
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
|
||||
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
|
||||
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
|
||||
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
|
||||
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
|
||||
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
|
||||
30851, 30918, 30984, 31049,
|
||||
31113, 31175, 31236, 31297,
|
||||
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
|
||||
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
|
||||
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
|
||||
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
|
||||
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
|
||||
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
|
||||
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
|
||||
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
|
||||
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
|
||||
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
|
||||
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
|
||||
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
|
||||
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
|
||||
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
|
||||
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
|
||||
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
|
||||
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
|
||||
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
|
||||
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
|
||||
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
|
||||
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
|
||||
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
|
||||
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
|
||||
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
|
||||
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
|
||||
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
|
||||
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
|
||||
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
|
||||
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
|
||||
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
|
||||
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
|
||||
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
|
||||
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
|
||||
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
|
||||
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
|
||||
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
|
||||
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
|
||||
1607, 1406, 1206, 1005, 804, 603, 402, 201,
|
||||
0, -201, -402, -603, -804, -1005, -1206, -1406,
|
||||
-1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
|
||||
-3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
|
||||
-4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
|
||||
-6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
|
||||
-7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
|
||||
-9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
|
||||
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
|
||||
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
|
||||
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
|
||||
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
|
||||
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
|
||||
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
|
||||
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
|
||||
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
|
||||
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
|
||||
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
|
||||
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
|
||||
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
|
||||
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
|
||||
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
|
||||
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
|
||||
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
|
||||
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
|
||||
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
|
||||
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
|
||||
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
|
||||
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
|
||||
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
|
||||
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
|
||||
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
|
||||
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
|
||||
-32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,
|
||||
-32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,
|
||||
-32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
|
||||
-32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,
|
||||
-32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,
|
||||
-31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,
|
||||
-31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,
|
||||
-30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,
|
||||
-30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,
|
||||
-29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,
|
||||
-28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,
|
||||
-28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
|
||||
-27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,
|
||||
-26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,
|
||||
-25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,
|
||||
-24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,
|
||||
-23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,
|
||||
-22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,
|
||||
-20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,
|
||||
-19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,
|
||||
-18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
|
||||
-16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,
|
||||
-15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,
|
||||
-14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,
|
||||
-12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,
|
||||
-11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703,
|
||||
-9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156,
|
||||
-7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589,
|
||||
-6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006,
|
||||
-4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
|
||||
-3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808,
|
||||
-1607, -1406, -1206, -1005, -804, -603, -402, -201,
|
||||
};
|
@ -1,73 +0,0 @@
|
||||
# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'spl',
|
||||
'type': '<(library)',
|
||||
'include_dirs': [
|
||||
'../interface',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../interface',
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'../interface/signal_processing_library.h',
|
||||
'../interface/spl_inl.h',
|
||||
'auto_corr_to_refl_coef.c',
|
||||
'auto_correlation.c',
|
||||
'complex_fft.c',
|
||||
'complex_ifft.c',
|
||||
'complex_bit_reverse.c',
|
||||
'copy_set_operations.c',
|
||||
'cos_table.c',
|
||||
'cross_correlation.c',
|
||||
'division_operations.c',
|
||||
'dot_product_with_scale.c',
|
||||
'downsample_fast.c',
|
||||
'energy.c',
|
||||
'filter_ar.c',
|
||||
'filter_ar_fast_q12.c',
|
||||
'filter_ma_fast_q12.c',
|
||||
'get_hanning_window.c',
|
||||
'get_scaling_square.c',
|
||||
'hanning_table.c',
|
||||
'ilbc_specific_functions.c',
|
||||
'levinson_durbin.c',
|
||||
'lpc_to_refl_coef.c',
|
||||
'min_max_operations.c',
|
||||
'randn_table.c',
|
||||
'randomization_functions.c',
|
||||
'refl_coef_to_lpc.c',
|
||||
'resample.c',
|
||||
'resample_48khz.c',
|
||||
'resample_by_2.c',
|
||||
'resample_by_2_internal.c',
|
||||
'resample_by_2_internal.h',
|
||||
'resample_fractional.c',
|
||||
'sin_table.c',
|
||||
'sin_table_1024.c',
|
||||
'spl_sqrt.c',
|
||||
'spl_sqrt_floor.c',
|
||||
'spl_version.c',
|
||||
'splitting_filter.c',
|
||||
'sqrt_of_one_minus_x_squared.c',
|
||||
'vector_scaling_operations.c',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:2
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=2 shiftwidth=2:
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_SqrtFloor().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
#define WEBRTC_SPL_SQRT_ITER(N) \
|
||||
try1 = root + (1 << (N)); \
|
||||
if (value >= try1 << (N)) \
|
||||
{ \
|
||||
value -= try1 << (N); \
|
||||
root |= 2 << (N); \
|
||||
}
|
||||
|
||||
// (out) Square root of input parameter
|
||||
WebRtc_Word32 WebRtcSpl_SqrtFloor(WebRtc_Word32 value)
|
||||
{
|
||||
// new routine for performance, 4 cycles/bit in ARM
|
||||
// output precision is 16 bits
|
||||
|
||||
WebRtc_Word32 root = 0, try1;
|
||||
|
||||
WEBRTC_SPL_SQRT_ITER (15);
|
||||
WEBRTC_SPL_SQRT_ITER (14);
|
||||
WEBRTC_SPL_SQRT_ITER (13);
|
||||
WEBRTC_SPL_SQRT_ITER (12);
|
||||
WEBRTC_SPL_SQRT_ITER (11);
|
||||
WEBRTC_SPL_SQRT_ITER (10);
|
||||
WEBRTC_SPL_SQRT_ITER ( 9);
|
||||
WEBRTC_SPL_SQRT_ITER ( 8);
|
||||
WEBRTC_SPL_SQRT_ITER ( 7);
|
||||
WEBRTC_SPL_SQRT_ITER ( 6);
|
||||
WEBRTC_SPL_SQRT_ITER ( 5);
|
||||
WEBRTC_SPL_SQRT_ITER ( 4);
|
||||
WEBRTC_SPL_SQRT_ITER ( 3);
|
||||
WEBRTC_SPL_SQRT_ITER ( 2);
|
||||
WEBRTC_SPL_SQRT_ITER ( 1);
|
||||
WEBRTC_SPL_SQRT_ITER ( 0);
|
||||
|
||||
return root >> 1;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_get_version().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the functions
|
||||
* WebRtcSpl_VectorBitShiftW16()
|
||||
* WebRtcSpl_VectorBitShiftW32()
|
||||
* WebRtcSpl_VectorBitShiftW32ToW16()
|
||||
* WebRtcSpl_ScaleVector()
|
||||
* WebRtcSpl_ScaleVectorWithSat()
|
||||
* WebRtcSpl_ScaleAndAddVectors()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16 *res,
|
||||
WebRtc_Word16 length,
|
||||
G_CONST WebRtc_Word16 *in,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (right_shifts > 0)
|
||||
{
|
||||
for (i = length; i > 0; i--)
|
||||
{
|
||||
(*res++) = ((*in++) >> right_shifts);
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (i = length; i > 0; i--)
|
||||
{
|
||||
(*res++) = ((*in++) << (-right_shifts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32 *out_vector,
|
||||
WebRtc_Word16 vector_length,
|
||||
G_CONST WebRtc_Word32 *in_vector,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (right_shifts > 0)
|
||||
{
|
||||
for (i = vector_length; i > 0; i--)
|
||||
{
|
||||
(*out_vector++) = ((*in_vector++) >> right_shifts);
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (i = vector_length; i > 0; i--)
|
||||
{
|
||||
(*out_vector++) = ((*in_vector++) << (-right_shifts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16 *res,
|
||||
WebRtc_Word16 length,
|
||||
G_CONST WebRtc_Word32 *in,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (right_shifts >= 0)
|
||||
{
|
||||
for (i = length; i > 0; i--)
|
||||
{
|
||||
(*res++) = (WebRtc_Word16)((*in++) >> right_shifts);
|
||||
}
|
||||
} else
|
||||
{
|
||||
WebRtc_Word16 left_shifts = -right_shifts;
|
||||
for (i = length; i > 0; i--)
|
||||
{
|
||||
(*res++) = (WebRtc_Word16)((*in++) << left_shifts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector,
|
||||
WebRtc_Word16 gain, WebRtc_Word16 in_vector_length,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
// Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
|
||||
int i;
|
||||
G_CONST WebRtc_Word16 *inptr;
|
||||
WebRtc_Word16 *outptr;
|
||||
|
||||
inptr = in_vector;
|
||||
outptr = out_vector;
|
||||
|
||||
for (i = 0; i < in_vector_length; i++)
|
||||
{
|
||||
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector,
|
||||
WebRtc_Word16 gain, WebRtc_Word16 in_vector_length,
|
||||
WebRtc_Word16 right_shifts)
|
||||
{
|
||||
// Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
|
||||
int i;
|
||||
WebRtc_Word32 tmpW32;
|
||||
G_CONST WebRtc_Word16 *inptr;
|
||||
WebRtc_Word16 *outptr;
|
||||
|
||||
inptr = in_vector;
|
||||
outptr = out_vector;
|
||||
|
||||
for (i = 0; i < in_vector_length; i++)
|
||||
{
|
||||
tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
|
||||
(*outptr++) = WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16 *in1, WebRtc_Word16 gain1, int shift1,
|
||||
G_CONST WebRtc_Word16 *in2, WebRtc_Word16 gain2, int shift2,
|
||||
WebRtc_Word16 *out, int vector_length)
|
||||
{
|
||||
// Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2
|
||||
int i;
|
||||
G_CONST WebRtc_Word16 *in1ptr;
|
||||
G_CONST WebRtc_Word16 *in2ptr;
|
||||
WebRtc_Word16 *outptr;
|
||||
|
||||
in1ptr = in1;
|
||||
in2ptr = in2;
|
||||
outptr = out;
|
||||
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1)
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2);
|
||||
}
|
||||
}
|
@ -1,704 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the Q14 radix-8 tables used in ARM9e optimizations.
|
||||
*
|
||||
*/
|
||||
|
||||
extern const int s_Q14S_8;
|
||||
const int s_Q14S_8 = 1024;
|
||||
extern const unsigned short t_Q14S_8[2032];
|
||||
const unsigned short t_Q14S_8[2032] = {
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
|
||||
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
|
||||
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
|
||||
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
|
||||
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
|
||||
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
|
||||
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,
|
||||
0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,
|
||||
0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,
|
||||
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
|
||||
0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,
|
||||
0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,
|
||||
0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,
|
||||
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
|
||||
0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,
|
||||
0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,
|
||||
0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,
|
||||
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
|
||||
0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,
|
||||
0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,
|
||||
0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,
|
||||
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
|
||||
0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,
|
||||
0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,
|
||||
0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,
|
||||
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
|
||||
0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,
|
||||
0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,
|
||||
0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,
|
||||
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
|
||||
0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,
|
||||
0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,
|
||||
0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,
|
||||
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
|
||||
0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,
|
||||
0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,
|
||||
0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b ,
|
||||
0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 ,
|
||||
0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e ,
|
||||
0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,
|
||||
0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 ,
|
||||
0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 ,
|
||||
0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 ,
|
||||
0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,
|
||||
0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 ,
|
||||
0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 ,
|
||||
0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 ,
|
||||
0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,
|
||||
0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 ,
|
||||
0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c ,
|
||||
0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 ,
|
||||
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
|
||||
0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e ,
|
||||
0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 ,
|
||||
0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 ,
|
||||
0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,
|
||||
0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 ,
|
||||
0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a ,
|
||||
0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 ,
|
||||
0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,
|
||||
0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef ,
|
||||
0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 ,
|
||||
0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 ,
|
||||
0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,
|
||||
0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 ,
|
||||
0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b ,
|
||||
0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 ,
|
||||
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
|
||||
0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd ,
|
||||
0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 ,
|
||||
0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 ,
|
||||
0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,
|
||||
0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d ,
|
||||
0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f ,
|
||||
0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b ,
|
||||
0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,
|
||||
0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 ,
|
||||
0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb ,
|
||||
0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff ,
|
||||
0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,
|
||||
0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 ,
|
||||
0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 ,
|
||||
0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 ,
|
||||
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
|
||||
0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 ,
|
||||
0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf ,
|
||||
0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 ,
|
||||
0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,
|
||||
0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d ,
|
||||
0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 ,
|
||||
0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 ,
|
||||
0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,
|
||||
0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b ,
|
||||
0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 ,
|
||||
0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 ,
|
||||
0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,
|
||||
0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 ,
|
||||
0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 ,
|
||||
0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 ,
|
||||
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
|
||||
0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f ,
|
||||
0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce ,
|
||||
0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe ,
|
||||
0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,
|
||||
0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 ,
|
||||
0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d ,
|
||||
0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a ,
|
||||
0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,
|
||||
0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 ,
|
||||
0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef ,
|
||||
0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 ,
|
||||
0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,
|
||||
0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 ,
|
||||
0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 ,
|
||||
0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca ,
|
||||
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
|
||||
0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b ,
|
||||
0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 ,
|
||||
0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e ,
|
||||
0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,
|
||||
0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 ,
|
||||
0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e ,
|
||||
0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 ,
|
||||
0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,
|
||||
0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 ,
|
||||
0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f ,
|
||||
0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf ,
|
||||
0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,
|
||||
0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d ,
|
||||
0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed ,
|
||||
0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 ,
|
||||
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
|
||||
0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 ,
|
||||
0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a ,
|
||||
0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 ,
|
||||
0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,
|
||||
0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 ,
|
||||
0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 ,
|
||||
0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f ,
|
||||
0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,
|
||||
0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b ,
|
||||
0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df ,
|
||||
0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 ,
|
||||
0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,
|
||||
0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 ,
|
||||
0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c ,
|
||||
0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 ,
|
||||
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
|
||||
0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 ,
|
||||
0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 ,
|
||||
0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 ,
|
||||
0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,
|
||||
0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d ,
|
||||
0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a ,
|
||||
0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b ,
|
||||
0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,
|
||||
0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d ,
|
||||
0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e ,
|
||||
0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 ,
|
||||
0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,
|
||||
0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 ,
|
||||
0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c ,
|
||||
0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b ,
|
||||
0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 ,
|
||||
0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 ,
|
||||
0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 ,
|
||||
0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 ,
|
||||
0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e ,
|
||||
0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa ,
|
||||
0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 ,
|
||||
0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 ,
|
||||
0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b ,
|
||||
0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 ,
|
||||
0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c ,
|
||||
0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 ,
|
||||
0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca ,
|
||||
0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee ,
|
||||
0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 ,
|
||||
0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 ,
|
||||
0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 ,
|
||||
0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 ,
|
||||
0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 ,
|
||||
0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab ,
|
||||
0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 ,
|
||||
0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db ,
|
||||
0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef ,
|
||||
0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 ,
|
||||
0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 ,
|
||||
0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 ,
|
||||
0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b ,
|
||||
0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 ,
|
||||
0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a ,
|
||||
0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d ,
|
||||
0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d ,
|
||||
0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b ,
|
||||
0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 ,
|
||||
0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c ,
|
||||
0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 ,
|
||||
0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 ,
|
||||
0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe ,
|
||||
0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 ,
|
||||
0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce ,
|
||||
0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 ,
|
||||
0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f ,
|
||||
0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a ,
|
||||
0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 ,
|
||||
0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 ,
|
||||
0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 ,
|
||||
0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf ,
|
||||
0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 ,
|
||||
0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 ,
|
||||
0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 ,
|
||||
0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 ,
|
||||
0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 ,
|
||||
0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 ,
|
||||
0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 ,
|
||||
0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e ,
|
||||
0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 ,
|
||||
0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 ,
|
||||
0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b ,
|
||||
0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 ,
|
||||
0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 ,
|
||||
0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd ,
|
||||
0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 ,
|
||||
0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 ,
|
||||
0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 ,
|
||||
0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa ,
|
||||
0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d ,
|
||||
0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda ,
|
||||
0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 ,
|
||||
0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 ,
|
||||
0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 ,
|
||||
0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b ,
|
||||
0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf ,
|
||||
0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc ,
|
||||
0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 ,
|
||||
0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 ,
|
||||
0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 ,
|
||||
0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd ,
|
||||
0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 ,
|
||||
0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d ,
|
||||
0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 ,
|
||||
0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 ,
|
||||
0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 ,
|
||||
0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb ,
|
||||
0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec ,
|
||||
0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 ,
|
||||
0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff ,
|
||||
0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 ,
|
||||
0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb ,
|
||||
0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 ,
|
||||
0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 ,
|
||||
0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc ,
|
||||
0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 ,
|
||||
0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 ,
|
||||
0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b ,
|
||||
0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 ,
|
||||
0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f ,
|
||||
0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 ,
|
||||
0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d ,
|
||||
0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c ,
|
||||
0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 ,
|
||||
0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 ,
|
||||
0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 ,
|
||||
0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 ,
|
||||
0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 ,
|
||||
0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 ,
|
||||
0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd ,
|
||||
0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 ,
|
||||
0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 ,
|
||||
0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab ,
|
||||
0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 ,
|
||||
0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 ,
|
||||
0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b ,
|
||||
0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 ,
|
||||
0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 ,
|
||||
0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e ,
|
||||
0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 ,
|
||||
0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 ,
|
||||
0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 ,
|
||||
0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff ,
|
||||
0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 ,
|
||||
0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 ,
|
||||
0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef ,
|
||||
0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 ,
|
||||
0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 ,
|
||||
0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 ,
|
||||
0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 ,
|
||||
0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 ,
|
||||
0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a ,
|
||||
0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 ,
|
||||
0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 ,
|
||||
0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 ,
|
||||
0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb ,
|
||||
0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a ,
|
||||
0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 ,
|
||||
0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c ,
|
||||
0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 ,
|
||||
0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 ,
|
||||
0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e ,
|
||||
0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 ,
|
||||
0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e ,
|
||||
0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 ,
|
||||
0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 ,
|
||||
0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 ,
|
||||
0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c ,
|
||||
0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 ,
|
||||
0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 ,
|
||||
0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c ,
|
||||
0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d ,
|
||||
0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b ,
|
||||
0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 ,
|
||||
0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 ,
|
||||
0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 ,
|
||||
0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee ,
|
||||
0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 ,
|
||||
0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 ,
|
||||
0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 ,
|
||||
0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 ,
|
||||
0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 ,
|
||||
0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b ,
|
||||
0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 ,
|
||||
0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf ,
|
||||
0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 ,
|
||||
0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e ,
|
||||
0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 ,
|
||||
0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 ,
|
||||
0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e ,
|
||||
0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 ,
|
||||
0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 ,
|
||||
0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 ,
|
||||
0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b ,
|
||||
0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e ,
|
||||
0xbf38,0x00c9 ,0xbf9c,0x0065 };
|
||||
|
||||
|
||||
extern const int s_Q14R_8;
|
||||
const int s_Q14R_8 = 1024;
|
||||
extern const unsigned short t_Q14R_8[2032];
|
||||
const unsigned short t_Q14R_8[2032] = {
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
|
||||
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
|
||||
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
|
||||
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
|
||||
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
|
||||
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
|
||||
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,
|
||||
0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,
|
||||
0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,
|
||||
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
|
||||
0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,
|
||||
0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,
|
||||
0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,
|
||||
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
|
||||
0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,
|
||||
0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,
|
||||
0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,
|
||||
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
|
||||
0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,
|
||||
0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,
|
||||
0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,
|
||||
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
|
||||
0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,
|
||||
0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,
|
||||
0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,
|
||||
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
|
||||
0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,
|
||||
0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,
|
||||
0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,
|
||||
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
|
||||
0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,
|
||||
0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,
|
||||
0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,
|
||||
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
|
||||
0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,
|
||||
0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,
|
||||
0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,
|
||||
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
|
||||
0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b ,
|
||||
0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 ,
|
||||
0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e ,
|
||||
0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,
|
||||
0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 ,
|
||||
0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 ,
|
||||
0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 ,
|
||||
0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,
|
||||
0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 ,
|
||||
0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 ,
|
||||
0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 ,
|
||||
0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,
|
||||
0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 ,
|
||||
0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c ,
|
||||
0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 ,
|
||||
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
|
||||
0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e ,
|
||||
0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 ,
|
||||
0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 ,
|
||||
0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,
|
||||
0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 ,
|
||||
0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a ,
|
||||
0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 ,
|
||||
0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,
|
||||
0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef ,
|
||||
0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 ,
|
||||
0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 ,
|
||||
0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,
|
||||
0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 ,
|
||||
0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b ,
|
||||
0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 ,
|
||||
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
|
||||
0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd ,
|
||||
0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 ,
|
||||
0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 ,
|
||||
0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,
|
||||
0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d ,
|
||||
0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f ,
|
||||
0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b ,
|
||||
0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,
|
||||
0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 ,
|
||||
0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb ,
|
||||
0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff ,
|
||||
0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,
|
||||
0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 ,
|
||||
0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 ,
|
||||
0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 ,
|
||||
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
|
||||
0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 ,
|
||||
0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf ,
|
||||
0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 ,
|
||||
0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,
|
||||
0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d ,
|
||||
0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 ,
|
||||
0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 ,
|
||||
0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,
|
||||
0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b ,
|
||||
0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 ,
|
||||
0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 ,
|
||||
0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,
|
||||
0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 ,
|
||||
0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 ,
|
||||
0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 ,
|
||||
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
|
||||
0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f ,
|
||||
0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce ,
|
||||
0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe ,
|
||||
0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,
|
||||
0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 ,
|
||||
0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d ,
|
||||
0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a ,
|
||||
0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,
|
||||
0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 ,
|
||||
0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef ,
|
||||
0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 ,
|
||||
0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,
|
||||
0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 ,
|
||||
0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 ,
|
||||
0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca ,
|
||||
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
|
||||
0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b ,
|
||||
0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 ,
|
||||
0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e ,
|
||||
0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,
|
||||
0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 ,
|
||||
0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e ,
|
||||
0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 ,
|
||||
0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,
|
||||
0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 ,
|
||||
0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f ,
|
||||
0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf ,
|
||||
0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,
|
||||
0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d ,
|
||||
0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed ,
|
||||
0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 ,
|
||||
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
|
||||
0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 ,
|
||||
0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a ,
|
||||
0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 ,
|
||||
0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,
|
||||
0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 ,
|
||||
0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 ,
|
||||
0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f ,
|
||||
0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,
|
||||
0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b ,
|
||||
0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df ,
|
||||
0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 ,
|
||||
0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,
|
||||
0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 ,
|
||||
0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c ,
|
||||
0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 ,
|
||||
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
|
||||
0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 ,
|
||||
0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 ,
|
||||
0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 ,
|
||||
0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,
|
||||
0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d ,
|
||||
0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a ,
|
||||
0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b ,
|
||||
0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,
|
||||
0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d ,
|
||||
0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e ,
|
||||
0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 ,
|
||||
0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,
|
||||
0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 ,
|
||||
0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c ,
|
||||
0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b ,
|
||||
0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 ,
|
||||
0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 ,
|
||||
0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 ,
|
||||
0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 ,
|
||||
0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e ,
|
||||
0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa ,
|
||||
0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 ,
|
||||
0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 ,
|
||||
0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b ,
|
||||
0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 ,
|
||||
0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c ,
|
||||
0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 ,
|
||||
0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca ,
|
||||
0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee ,
|
||||
0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 ,
|
||||
0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 ,
|
||||
0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 ,
|
||||
0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 ,
|
||||
0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 ,
|
||||
0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab ,
|
||||
0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 ,
|
||||
0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db ,
|
||||
0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef ,
|
||||
0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 ,
|
||||
0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 ,
|
||||
0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 ,
|
||||
0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b ,
|
||||
0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 ,
|
||||
0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a ,
|
||||
0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d ,
|
||||
0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d ,
|
||||
0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b ,
|
||||
0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 ,
|
||||
0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c ,
|
||||
0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 ,
|
||||
0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 ,
|
||||
0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe ,
|
||||
0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 ,
|
||||
0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce ,
|
||||
0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 ,
|
||||
0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f ,
|
||||
0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a ,
|
||||
0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 ,
|
||||
0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 ,
|
||||
0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 ,
|
||||
0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf ,
|
||||
0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 ,
|
||||
0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 ,
|
||||
0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 ,
|
||||
0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 ,
|
||||
0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 ,
|
||||
0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 ,
|
||||
0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 ,
|
||||
0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e ,
|
||||
0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 ,
|
||||
0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 ,
|
||||
0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b ,
|
||||
0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 ,
|
||||
0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 ,
|
||||
0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd ,
|
||||
0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 ,
|
||||
0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 ,
|
||||
0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 ,
|
||||
0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa ,
|
||||
0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d ,
|
||||
0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda ,
|
||||
0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 ,
|
||||
0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 ,
|
||||
0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 ,
|
||||
0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b ,
|
||||
0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf ,
|
||||
0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc ,
|
||||
0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 ,
|
||||
0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 ,
|
||||
0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 ,
|
||||
0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd ,
|
||||
0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 ,
|
||||
0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d ,
|
||||
0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 ,
|
||||
0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 ,
|
||||
0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 ,
|
||||
0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb ,
|
||||
0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec ,
|
||||
0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 ,
|
||||
0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff ,
|
||||
0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 ,
|
||||
0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb ,
|
||||
0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 ,
|
||||
0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 ,
|
||||
0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc ,
|
||||
0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 ,
|
||||
0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 ,
|
||||
0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b ,
|
||||
0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 ,
|
||||
0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f ,
|
||||
0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 ,
|
||||
0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d ,
|
||||
0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c ,
|
||||
0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 ,
|
||||
0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 ,
|
||||
0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 ,
|
||||
0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 ,
|
||||
0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 ,
|
||||
0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 ,
|
||||
0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd ,
|
||||
0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 ,
|
||||
0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 ,
|
||||
0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab ,
|
||||
0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 ,
|
||||
0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 ,
|
||||
0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b ,
|
||||
0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 ,
|
||||
0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 ,
|
||||
0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e ,
|
||||
0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 ,
|
||||
0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 ,
|
||||
0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 ,
|
||||
0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff ,
|
||||
0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 ,
|
||||
0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 ,
|
||||
0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef ,
|
||||
0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 ,
|
||||
0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 ,
|
||||
0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 ,
|
||||
0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 ,
|
||||
0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 ,
|
||||
0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a ,
|
||||
0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 ,
|
||||
0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 ,
|
||||
0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 ,
|
||||
0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb ,
|
||||
0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a ,
|
||||
0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 ,
|
||||
0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c ,
|
||||
0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 ,
|
||||
0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 ,
|
||||
0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e ,
|
||||
0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 ,
|
||||
0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e ,
|
||||
0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 ,
|
||||
0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 ,
|
||||
0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 ,
|
||||
0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c ,
|
||||
0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 ,
|
||||
0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 ,
|
||||
0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c ,
|
||||
0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d ,
|
||||
0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b ,
|
||||
0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 ,
|
||||
0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 ,
|
||||
0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 ,
|
||||
0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee ,
|
||||
0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 ,
|
||||
0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 ,
|
||||
0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 ,
|
||||
0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 ,
|
||||
0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 ,
|
||||
0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b ,
|
||||
0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 ,
|
||||
0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf ,
|
||||
0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 ,
|
||||
0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e ,
|
||||
0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 ,
|
||||
0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 ,
|
||||
0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e ,
|
||||
0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 ,
|
||||
0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 ,
|
||||
0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 ,
|
||||
0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b ,
|
||||
0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e ,
|
||||
0xc001,0x00c9 ,0xc000,0x0065 };
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the Q14 radix-2 tables used in ARM9E optimization routines.
|
||||
*
|
||||
*/
|
||||
|
||||
extern const unsigned short t_Q14S_rad8[2];
|
||||
const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 };
|
||||
|
||||
//extern const int t_Q30S_rad8[2];
|
||||
//const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd };
|
||||
|
||||
extern const unsigned short t_Q14R_rad8[2];
|
||||
const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 };
|
||||
|
||||
//extern const int t_Q30R_rad8[2];
|
||||
//const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd };
|
@ -1,494 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the SPL unit_test.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "unit_test.h"
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
class SplEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
}
|
||||
virtual void TearDown() {
|
||||
}
|
||||
};
|
||||
|
||||
SplTest::SplTest()
|
||||
{
|
||||
}
|
||||
|
||||
void SplTest::SetUp() {
|
||||
}
|
||||
|
||||
void SplTest::TearDown() {
|
||||
}
|
||||
|
||||
TEST_F(SplTest, MacroTest) {
|
||||
// Macros with inputs.
|
||||
int A = 10;
|
||||
int B = 21;
|
||||
int a = -3;
|
||||
int b = WEBRTC_SPL_WORD32_MAX;
|
||||
int nr = 2;
|
||||
int d_ptr1 = 0;
|
||||
int d_ptr2 = 0;
|
||||
|
||||
EXPECT_EQ(10, WEBRTC_SPL_MIN(A, B));
|
||||
EXPECT_EQ(21, WEBRTC_SPL_MAX(A, B));
|
||||
|
||||
EXPECT_EQ(3, WEBRTC_SPL_ABS_W16(a));
|
||||
EXPECT_EQ(3, WEBRTC_SPL_ABS_W32(a));
|
||||
EXPECT_EQ(0, WEBRTC_SPL_GET_BYTE(&B, nr));
|
||||
WEBRTC_SPL_SET_BYTE(&d_ptr2, 1, nr);
|
||||
EXPECT_EQ(65536, d_ptr2);
|
||||
|
||||
EXPECT_EQ(-63, WEBRTC_SPL_MUL(a, B));
|
||||
EXPECT_EQ(-2147483645, WEBRTC_SPL_MUL(a, b));
|
||||
EXPECT_EQ(-2147483645, WEBRTC_SPL_UMUL(a, b));
|
||||
b = WEBRTC_SPL_WORD16_MAX >> 1;
|
||||
EXPECT_EQ(65535, WEBRTC_SPL_UMUL_RSFT16(a, b));
|
||||
EXPECT_EQ(1073627139, WEBRTC_SPL_UMUL_16_16(a, b));
|
||||
EXPECT_EQ(16382, WEBRTC_SPL_UMUL_16_16_RSFT16(a, b));
|
||||
EXPECT_EQ(-49149, WEBRTC_SPL_UMUL_32_16(a, b));
|
||||
EXPECT_EQ(65535, WEBRTC_SPL_UMUL_32_16_RSFT16(a, b));
|
||||
EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
|
||||
|
||||
a = b;
|
||||
b = -3;
|
||||
EXPECT_EQ(-5461, WEBRTC_SPL_DIV(a, b));
|
||||
EXPECT_EQ(0, WEBRTC_SPL_UDIV(a, b));
|
||||
|
||||
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
|
||||
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
|
||||
EXPECT_EQ(-3, WEBRTC_SPL_MUL_16_32_RSFT14(a, b));
|
||||
EXPECT_EQ(-24, WEBRTC_SPL_MUL_16_32_RSFT11(a, b));
|
||||
|
||||
int a32 = WEBRTC_SPL_WORD32_MAX;
|
||||
int a32a = (WEBRTC_SPL_WORD32_MAX >> 16);
|
||||
int a32b = (WEBRTC_SPL_WORD32_MAX & 0x0000ffff);
|
||||
EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, A));
|
||||
EXPECT_EQ(5, WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, A));
|
||||
|
||||
EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_16(a, b));
|
||||
EXPECT_EQ(-12288, WEBRTC_SPL_MUL_16_16_RSFT(a, b, 2));
|
||||
|
||||
EXPECT_EQ(-12287, WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, 2));
|
||||
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b));
|
||||
|
||||
EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W32(a, b));
|
||||
EXPECT_EQ(21, WEBRTC_SPL_SAT(a, A, B));
|
||||
EXPECT_EQ(21, WEBRTC_SPL_SAT(a, B, A));
|
||||
EXPECT_EQ(-49149, WEBRTC_SPL_MUL_32_16(a, b));
|
||||
|
||||
EXPECT_EQ(16386, WEBRTC_SPL_SUB_SAT_W32(a, b));
|
||||
EXPECT_EQ(16380, WEBRTC_SPL_ADD_SAT_W16(a, b));
|
||||
EXPECT_EQ(16386, WEBRTC_SPL_SUB_SAT_W16(a, b));
|
||||
|
||||
EXPECT_TRUE(WEBRTC_SPL_IS_NEG(b));
|
||||
|
||||
// Shifting with negative numbers allowed
|
||||
// Positive means left shift
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W16(a, 1));
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_SHIFT_W32(a, 1));
|
||||
|
||||
// Shifting with negative numbers not allowed
|
||||
// We cannot do casting here due to signed/unsigned problem
|
||||
EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W16(a, 1));
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W16(a, 1));
|
||||
EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W32(a, 1));
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
|
||||
|
||||
EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_U16(a, 1));
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_U16(a, 1));
|
||||
EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_U32(a, 1));
|
||||
EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_U32(a, 1));
|
||||
|
||||
EXPECT_EQ(1470, WEBRTC_SPL_RAND(A));
|
||||
}
|
||||
|
||||
TEST_F(SplTest, InlineTest) {
|
||||
|
||||
WebRtc_Word16 a = 121;
|
||||
WebRtc_Word16 b = -17;
|
||||
WebRtc_Word32 A = 111121;
|
||||
WebRtc_Word32 B = -1711;
|
||||
char bVersion[8];
|
||||
|
||||
EXPECT_EQ(104, WebRtcSpl_AddSatW16(a, b));
|
||||
EXPECT_EQ(138, WebRtcSpl_SubSatW16(a, b));
|
||||
|
||||
EXPECT_EQ(109410, WebRtcSpl_AddSatW32(A, B));
|
||||
EXPECT_EQ(112832, WebRtcSpl_SubSatW32(A, B));
|
||||
|
||||
EXPECT_EQ(17, WebRtcSpl_GetSizeInBits(A));
|
||||
EXPECT_EQ(14, WebRtcSpl_NormW32(A));
|
||||
EXPECT_EQ(4, WebRtcSpl_NormW16(B));
|
||||
EXPECT_EQ(15, WebRtcSpl_NormU32(A));
|
||||
|
||||
EXPECT_EQ(0, WebRtcSpl_get_version(bVersion, 8));
|
||||
}
|
||||
|
||||
TEST_F(SplTest, MathOperationsTest) {
|
||||
|
||||
int A = 117;
|
||||
WebRtc_Word32 num = 117;
|
||||
WebRtc_Word32 den = -5;
|
||||
WebRtc_UWord16 denU = 5;
|
||||
EXPECT_EQ(10, WebRtcSpl_Sqrt(A));
|
||||
EXPECT_EQ(10, WebRtcSpl_SqrtFloor(A));
|
||||
|
||||
|
||||
EXPECT_EQ(-91772805, WebRtcSpl_DivResultInQ31(den, num));
|
||||
EXPECT_EQ(-23, WebRtcSpl_DivW32W16ResW16(num, (WebRtc_Word16)den));
|
||||
EXPECT_EQ(-23, WebRtcSpl_DivW32W16(num, (WebRtc_Word16)den));
|
||||
EXPECT_EQ(23, WebRtcSpl_DivU32U16(num, denU));
|
||||
EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
|
||||
}
|
||||
|
||||
TEST_F(SplTest, BasicArrayOperationsTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
int B[] = {4, 12, 133, 1100};
|
||||
int Bs[] = {2, 6, 66, 550};
|
||||
WebRtc_UWord8 b8[kVectorSize];
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word32 b32[kVectorSize];
|
||||
|
||||
WebRtc_UWord8 bTmp8[kVectorSize];
|
||||
WebRtc_Word16 bTmp16[kVectorSize];
|
||||
WebRtc_Word32 bTmp32[kVectorSize];
|
||||
|
||||
WebRtcSpl_MemSetW16(b16, 3, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(3, b16[kk]);
|
||||
}
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW16(b16, kVectorSize));
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(0, b16[kk]);
|
||||
}
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW16(b16, kVectorSize));
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(1, b16[kk]);
|
||||
}
|
||||
WebRtcSpl_MemSetW32(b32, 3, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(3, b32[kk]);
|
||||
}
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_ZerosArrayW32(b32, kVectorSize));
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(0, b32[kk]);
|
||||
}
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_OnesArrayW32(b32, kVectorSize));
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(1, b32[kk]);
|
||||
}
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
bTmp8[kk] = (WebRtc_Word8)kk;
|
||||
bTmp16[kk] = (WebRtc_Word16)kk;
|
||||
bTmp32[kk] = (WebRtc_Word32)kk;
|
||||
}
|
||||
WEBRTC_SPL_MEMCPY_W8(b8, bTmp8, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(b8[kk], bTmp8[kk]);
|
||||
}
|
||||
WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(b16[kk], bTmp16[kk]);
|
||||
}
|
||||
// WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, kVectorSize);
|
||||
// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(b32[kk], bTmp32[kk]);
|
||||
// }
|
||||
EXPECT_EQ(2, WebRtcSpl_CopyFromEndW16(b16, kVectorSize, 2, bTmp16));
|
||||
for (int kk = 0; kk < 2; ++kk) {
|
||||
EXPECT_EQ(kk+2, bTmp16[kk]);
|
||||
}
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b32[kk] = B[kk];
|
||||
b16[kk] = (WebRtc_Word16)B[kk];
|
||||
}
|
||||
WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, kVectorSize, b32, 1);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_VectorBitShiftW16(bTmp16, kVectorSize, b16, 1);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_VectorBitShiftW32(bTmp32, kVectorSize, b32, 1);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((B[kk]>>1), bTmp32[kk]);
|
||||
}
|
||||
|
||||
WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(b16[3-kk], bTmp16[kk]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_F(SplTest, MinMaxOperationsTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
int B[] = {4, 12, 133, -1100};
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word32 b32[kVectorSize];
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b16[kk] = B[kk];
|
||||
b32[kk] = B[kk];
|
||||
}
|
||||
|
||||
EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW16(b16, kVectorSize));
|
||||
EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW32(b32, kVectorSize));
|
||||
EXPECT_EQ(133, WebRtcSpl_MaxValueW16(b16, kVectorSize));
|
||||
EXPECT_EQ(133, WebRtcSpl_MaxValueW32(b32, kVectorSize));
|
||||
EXPECT_EQ(3, WebRtcSpl_MaxAbsIndexW16(b16, kVectorSize));
|
||||
EXPECT_EQ(2, WebRtcSpl_MaxIndexW16(b16, kVectorSize));
|
||||
EXPECT_EQ(2, WebRtcSpl_MaxIndexW32(b32, kVectorSize));
|
||||
|
||||
EXPECT_EQ(-1100, WebRtcSpl_MinValueW16(b16, kVectorSize));
|
||||
EXPECT_EQ(-1100, WebRtcSpl_MinValueW32(b32, kVectorSize));
|
||||
EXPECT_EQ(3, WebRtcSpl_MinIndexW16(b16, kVectorSize));
|
||||
EXPECT_EQ(3, WebRtcSpl_MinIndexW32(b32, kVectorSize));
|
||||
|
||||
EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(SplTest, VectorOperationsTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
int B[] = {4, 12, 133, 1100};
|
||||
WebRtc_Word16 a16[kVectorSize];
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word32 b32[kVectorSize];
|
||||
WebRtc_Word16 bTmp16[kVectorSize];
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
a16[kk] = B[kk];
|
||||
b16[kk] = B[kk];
|
||||
}
|
||||
|
||||
WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((B[kk]*3+7)>>2, bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((B[kk]*3+B[kk]*2+2)>>2, bTmp16[kk]);
|
||||
}
|
||||
|
||||
WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
|
||||
}
|
||||
|
||||
WebRtcSpl_CrossCorrelation(b32, b16, bTmp16, kVectorSize, 2, 2, 0);
|
||||
for (int kk = 0; kk < 2; ++kk) {
|
||||
EXPECT_EQ(614236, b32[kk]);
|
||||
}
|
||||
// EXPECT_EQ(, WebRtcSpl_DotProduct(b16, bTmp16, 4));
|
||||
EXPECT_EQ(306962, WebRtcSpl_DotProductWithScale(b16, b16, kVectorSize, 2));
|
||||
|
||||
WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, kVectorSize, 2);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(((a16[kk]*13)>>2)+((b16[kk]*7)>>2), bTmp16[kk]);
|
||||
}
|
||||
|
||||
WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, kVectorSize, 2);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], kVectorSize, 2);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((a16[kk]*b16[3-kk])>>2, bTmp16[kk]);
|
||||
}
|
||||
WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, kVectorSize, 6);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ((a16[kk]*b16[kk])>>6, bTmp16[kk]);
|
||||
}
|
||||
|
||||
WebRtcSpl_SqrtOfOneMinusXSquared(b16, kVectorSize, bTmp16);
|
||||
for (int kk = 0; kk < kVectorSize - 1; ++kk) {
|
||||
EXPECT_EQ(32767, bTmp16[kk]);
|
||||
}
|
||||
EXPECT_EQ(32749, bTmp16[kVectorSize - 1]);
|
||||
}
|
||||
|
||||
TEST_F(SplTest, EstimatorsTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
int B[] = {4, 12, 133, 1100};
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word32 b32[kVectorSize];
|
||||
WebRtc_Word16 bTmp16[kVectorSize];
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b16[kk] = B[kk];
|
||||
b32[kk] = B[kk];
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(b32, b16, bTmp16, 2));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(SplTest, FilterTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
WebRtc_Word16 A[] = {1, 2, 33, 100};
|
||||
WebRtc_Word16 A5[] = {1, 2, 33, 100, -5};
|
||||
WebRtc_Word16 B[] = {4, 12, 133, 110};
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word16 bTmp16[kVectorSize];
|
||||
WebRtc_Word16 bTmp16Low[kVectorSize];
|
||||
WebRtc_Word16 bState[kVectorSize];
|
||||
WebRtc_Word16 bStateLow[kVectorSize];
|
||||
|
||||
WebRtcSpl_ZerosArrayW16(bState, kVectorSize);
|
||||
WebRtcSpl_ZerosArrayW16(bStateLow, kVectorSize);
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b16[kk] = A[kk];
|
||||
}
|
||||
|
||||
// MA filters
|
||||
WebRtcSpl_FilterMAFastQ12(b16, bTmp16, B, kVectorSize, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
//EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
|
||||
}
|
||||
// AR filters
|
||||
WebRtcSpl_FilterARFastQ12(b16, bTmp16, A, kVectorSize, kVectorSize);
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
|
||||
}
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_FilterAR(A5,
|
||||
5,
|
||||
b16,
|
||||
kVectorSize,
|
||||
bState,
|
||||
kVectorSize,
|
||||
bStateLow,
|
||||
kVectorSize,
|
||||
bTmp16,
|
||||
bTmp16Low,
|
||||
kVectorSize));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(SplTest, RandTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
WebRtc_Word16 BU[] = {3653, 12446, 8525, 30691};
|
||||
WebRtc_Word16 BN[] = {3459, -11689, -258, -3738};
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_UWord32 bSeed = 100000;
|
||||
|
||||
EXPECT_EQ(464449057, WebRtcSpl_IncreaseSeed(&bSeed));
|
||||
EXPECT_EQ(31565, WebRtcSpl_RandU(&bSeed));
|
||||
EXPECT_EQ(-9786, WebRtcSpl_RandN(&bSeed));
|
||||
EXPECT_EQ(kVectorSize, WebRtcSpl_RandUArray(b16, kVectorSize, &bSeed));
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
EXPECT_EQ(BU[kk], b16[kk]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SplTest, SignalProcessingTest) {
|
||||
|
||||
|
||||
const int kVectorSize = 4;
|
||||
int A[] = {1, 2, 33, 100};
|
||||
WebRtc_Word16 b16[kVectorSize];
|
||||
WebRtc_Word32 b32[kVectorSize];
|
||||
|
||||
WebRtc_Word16 bTmp16[kVectorSize];
|
||||
WebRtc_Word32 bTmp32[kVectorSize];
|
||||
|
||||
int bScale = 0;
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b16[kk] = A[kk];
|
||||
b32[kk] = A[kk];
|
||||
}
|
||||
|
||||
EXPECT_EQ(2, WebRtcSpl_AutoCorrelation(b16, kVectorSize, 1, bTmp32, &bScale));
|
||||
WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
|
||||
// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
|
||||
// }
|
||||
WebRtcSpl_LpcToReflCoef(bTmp16, kVectorSize, b16);
|
||||
// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(a16[kk], b16[kk]);
|
||||
// }
|
||||
WebRtcSpl_AutoCorrToReflCoef(b32, kVectorSize, bTmp16);
|
||||
// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
|
||||
// }
|
||||
WebRtcSpl_GetHanningWindow(bTmp16, kVectorSize);
|
||||
// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
|
||||
// }
|
||||
|
||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||
b16[kk] = A[kk];
|
||||
}
|
||||
EXPECT_EQ(11094 , WebRtcSpl_Energy(b16, kVectorSize, &bScale));
|
||||
EXPECT_EQ(0, bScale);
|
||||
}
|
||||
|
||||
TEST_F(SplTest, FFTTest) {
|
||||
|
||||
|
||||
WebRtc_Word16 B[] = {1, 2, 33, 100,
|
||||
2, 3, 34, 101,
|
||||
3, 4, 35, 102,
|
||||
4, 5, 36, 103};
|
||||
|
||||
EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
|
||||
// for (int kk = 0; kk < 16; ++kk) {
|
||||
// EXPECT_EQ(A[kk], B[kk]);
|
||||
// }
|
||||
EXPECT_EQ(0, WebRtcSpl_ComplexIFFT(B, 3, 1));
|
||||
// for (int kk = 0; kk < 16; ++kk) {
|
||||
// EXPECT_EQ(A[kk], B[kk]);
|
||||
// }
|
||||
WebRtcSpl_ComplexBitReverse(B, 3);
|
||||
for (int kk = 0; kk < 16; ++kk) {
|
||||
//EXPECT_EQ(A[kk], B[kk]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
SplEnvironment* env = new SplEnvironment;
|
||||
::testing::AddGlobalTestEnvironment(env);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file contains the function WebRtcSpl_CopyFromBeginU8().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SPL_UNIT_TEST_H_
|
||||
#define WEBRTC_SPL_UNIT_TEST_H_
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class SplTest: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
SplTest();
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
};
|
||||
|
||||
#endif // WEBRTC_SPL_UNIT_TEST_H_
|
@ -1,15 +0,0 @@
|
||||
noinst_LTLIBRARIES = libvad.la
|
||||
|
||||
libvad_la_SOURCES = main/interface/webrtc_vad.h \
|
||||
main/source/webrtc_vad.c \
|
||||
main/source/vad_core.c \
|
||||
main/source/vad_core.h \
|
||||
main/source/vad_defines.h \
|
||||
main/source/vad_filterbank.c \
|
||||
main/source/vad_filterbank.h \
|
||||
main/source/vad_gmm.c \
|
||||
main/source/vad_gmm.h \
|
||||
main/source/vad_sp.c \
|
||||
main/source/vad_sp.h
|
||||
libvad_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS) \
|
||||
-I$(top_srcdir)/src/common_audio/signal_processing_library/main/interface
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the VAD API calls. Specific function calls are given below.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_WEBRTC_VAD_H_
|
||||
#define WEBRTC_VAD_WEBRTC_VAD_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
typedef struct WebRtcVadInst VadInst;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_get_version(...)
|
||||
*
|
||||
* This function returns the version number of the code.
|
||||
*
|
||||
* Output:
|
||||
* - version : Pointer to a buffer where the version info will
|
||||
* be stored.
|
||||
* Input:
|
||||
* - size_bytes : Size of the buffer.
|
||||
*
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_get_version(char *version, size_t size_bytes);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_AssignSize(...)
|
||||
*
|
||||
* This functions get the size needed for storing the instance for encoder
|
||||
* and decoder, respectively
|
||||
*
|
||||
* Input/Output:
|
||||
* - size_in_bytes : Pointer to integer where the size is returned
|
||||
*
|
||||
* Return value : 0
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_AssignSize(int *size_in_bytes);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Assign(...)
|
||||
*
|
||||
* This functions Assigns memory for the instances.
|
||||
*
|
||||
* Input:
|
||||
* - vad_inst_addr : Address to where to assign memory
|
||||
* Output:
|
||||
* - vad_inst : Pointer to the instance that should be created
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_Assign(VadInst **vad_inst, void *vad_inst_addr);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Create(...)
|
||||
*
|
||||
* This function creates an instance to the VAD structure
|
||||
*
|
||||
* Input:
|
||||
* - vad_inst : Pointer to VAD instance that should be created
|
||||
*
|
||||
* Output:
|
||||
* - vad_inst : Pointer to created VAD instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_Create(VadInst **vad_inst);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Free(...)
|
||||
*
|
||||
* This function frees the dynamic memory of a specified VAD instance
|
||||
*
|
||||
* Input:
|
||||
* - vad_inst : Pointer to VAD instance that should be freed
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_Free(VadInst *vad_inst);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Init(...)
|
||||
*
|
||||
* This function initializes a VAD instance
|
||||
*
|
||||
* Input:
|
||||
* - vad_inst : Instance that should be initialized
|
||||
*
|
||||
* Output:
|
||||
* - vad_inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_Init(VadInst *vad_inst);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_set_mode(...)
|
||||
*
|
||||
* This function initializes a VAD instance
|
||||
*
|
||||
* Input:
|
||||
* - vad_inst : VAD instance
|
||||
* - mode : Aggressiveness setting (0, 1, 2, or 3)
|
||||
*
|
||||
* Output:
|
||||
* - vad_inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_set_mode(VadInst *vad_inst, WebRtc_Word16 mode);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Process(...)
|
||||
*
|
||||
* This functions does a VAD for the inserted speech frame
|
||||
*
|
||||
* Input
|
||||
* - vad_inst : VAD Instance. Needs to be initiated before call.
|
||||
* - fs : sampling frequency (Hz): 8000, 16000, or 32000
|
||||
* - speech_frame : Pointer to speech frame buffer
|
||||
* - frame_length : Length of speech frame buffer in number of samples
|
||||
*
|
||||
* Output:
|
||||
* - vad_inst : Updated VAD instance
|
||||
*
|
||||
* Return value : 1 - Active Voice
|
||||
* 0 - Non-active Voice
|
||||
* -1 - Error
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_Process(VadInst *vad_inst,
|
||||
WebRtc_Word16 fs,
|
||||
WebRtc_Word16 *speech_frame,
|
||||
WebRtc_Word16 frame_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_VAD_WEBRTC_VAD_H_
|
@ -1,46 +0,0 @@
|
||||
# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'vad',
|
||||
'type': '<(library)',
|
||||
'dependencies': [
|
||||
'spl',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../interface',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../interface',
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'../interface/webrtc_vad.h',
|
||||
'webrtc_vad.c',
|
||||
'vad_core.c',
|
||||
'vad_core.h',
|
||||
'vad_defines.h',
|
||||
'vad_filterbank.c',
|
||||
'vad_filterbank.h',
|
||||
'vad_gmm.c',
|
||||
'vad_gmm.h',
|
||||
'vad_sp.c',
|
||||
'vad_sp.h',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:2
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=2 shiftwidth=2:
|
@ -1,723 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the implementation of the core functionality in VAD.
|
||||
* For function description, see vad_core.h.
|
||||
*/
|
||||
|
||||
#include "vad_core.h"
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
#include "vad_defines.h"
|
||||
#include "vad_filterbank.h"
|
||||
#include "vad_gmm.h"
|
||||
#include "vad_sp.h"
|
||||
|
||||
// Spectrum Weighting
|
||||
static const WebRtc_Word16 kSpectrumWeight[6] = { 6, 8, 10, 12, 14, 16 };
|
||||
static const WebRtc_Word16 kNoiseUpdateConst = 655; // Q15
|
||||
static const WebRtc_Word16 kSpeechUpdateConst = 6554; // Q15
|
||||
static const WebRtc_Word16 kBackEta = 154; // Q8
|
||||
// Minimum difference between the two models, Q5
|
||||
static const WebRtc_Word16 kMinimumDifference[6] = {
|
||||
544, 544, 576, 576, 576, 576 };
|
||||
// Upper limit of mean value for speech model, Q7
|
||||
static const WebRtc_Word16 kMaximumSpeech[6] = {
|
||||
11392, 11392, 11520, 11520, 11520, 11520 };
|
||||
// Minimum value for mean value
|
||||
static const WebRtc_Word16 kMinimumMean[2] = { 640, 768 };
|
||||
// Upper limit of mean value for noise model, Q7
|
||||
static const WebRtc_Word16 kMaximumNoise[6] = {
|
||||
9216, 9088, 8960, 8832, 8704, 8576 };
|
||||
// Start values for the Gaussian models, Q7
|
||||
// Weights for the two Gaussians for the six channels (noise)
|
||||
static const WebRtc_Word16 kNoiseDataWeights[12] = {
|
||||
34, 62, 72, 66, 53, 25, 94, 66, 56, 62, 75, 103 };
|
||||
// Weights for the two Gaussians for the six channels (speech)
|
||||
static const WebRtc_Word16 kSpeechDataWeights[12] = {
|
||||
48, 82, 45, 87, 50, 47, 80, 46, 83, 41, 78, 81 };
|
||||
// Means for the two Gaussians for the six channels (noise)
|
||||
static const WebRtc_Word16 kNoiseDataMeans[12] = {
|
||||
6738, 4892, 7065, 6715, 6771, 3369, 7646, 3863, 7820, 7266, 5020, 4362 };
|
||||
// Means for the two Gaussians for the six channels (speech)
|
||||
static const WebRtc_Word16 kSpeechDataMeans[12] = {
|
||||
8306, 10085, 10078, 11823, 11843, 6309, 9473, 9571, 10879, 7581, 8180, 7483
|
||||
};
|
||||
// Stds for the two Gaussians for the six channels (noise)
|
||||
static const WebRtc_Word16 kNoiseDataStds[12] = {
|
||||
378, 1064, 493, 582, 688, 593, 474, 697, 475, 688, 421, 455 };
|
||||
// Stds for the two Gaussians for the six channels (speech)
|
||||
static const WebRtc_Word16 kSpeechDataStds[12] = {
|
||||
555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540, 1079, 850 };
|
||||
|
||||
static const int kInitCheck = 42;
|
||||
|
||||
// Initialize VAD
|
||||
int WebRtcVad_InitCore(VadInstT *inst, short mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Initialization of struct
|
||||
inst->vad = 1;
|
||||
inst->frame_counter = 0;
|
||||
inst->over_hang = 0;
|
||||
inst->num_of_speech = 0;
|
||||
|
||||
// Initialization of downsampling filter state
|
||||
inst->downsampling_filter_states[0] = 0;
|
||||
inst->downsampling_filter_states[1] = 0;
|
||||
inst->downsampling_filter_states[2] = 0;
|
||||
inst->downsampling_filter_states[3] = 0;
|
||||
|
||||
// Read initial PDF parameters
|
||||
for (i = 0; i < NUM_TABLE_VALUES; i++)
|
||||
{
|
||||
inst->noise_means[i] = kNoiseDataMeans[i];
|
||||
inst->speech_means[i] = kSpeechDataMeans[i];
|
||||
inst->noise_stds[i] = kNoiseDataStds[i];
|
||||
inst->speech_stds[i] = kSpeechDataStds[i];
|
||||
}
|
||||
|
||||
// Index and Minimum value vectors are initialized
|
||||
for (i = 0; i < 16 * NUM_CHANNELS; i++)
|
||||
{
|
||||
inst->low_value_vector[i] = 10000;
|
||||
inst->index_vector[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
inst->upper_state[i] = 0;
|
||||
inst->lower_state[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
inst->hp_filter_state[i] = 0;
|
||||
}
|
||||
|
||||
// Init mean value memory, for FindMin function
|
||||
inst->mean_value[0] = 1600;
|
||||
inst->mean_value[1] = 1600;
|
||||
inst->mean_value[2] = 1600;
|
||||
inst->mean_value[3] = 1600;
|
||||
inst->mean_value[4] = 1600;
|
||||
inst->mean_value[5] = 1600;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// Quality mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_Q;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_Q;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_Q;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_Q;
|
||||
inst->total[1] = TOTAL_20MS_Q;
|
||||
inst->total[2] = TOTAL_30MS_Q;
|
||||
} else if (mode == 1)
|
||||
{
|
||||
// Low bitrate mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_LBR;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_LBR;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_LBR;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_LBR;
|
||||
inst->total[1] = TOTAL_20MS_LBR;
|
||||
inst->total[2] = TOTAL_30MS_LBR;
|
||||
} else if (mode == 2)
|
||||
{
|
||||
// Aggressive mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_AGG;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_AGG;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_AGG;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_AGG;
|
||||
inst->total[1] = TOTAL_20MS_AGG;
|
||||
inst->total[2] = TOTAL_30MS_AGG;
|
||||
} else
|
||||
{
|
||||
// Very aggressive mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_VAG;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_VAG;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_VAG;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_VAG;
|
||||
inst->total[1] = TOTAL_20MS_VAG;
|
||||
inst->total[2] = TOTAL_30MS_VAG;
|
||||
}
|
||||
|
||||
inst->init_flag = kInitCheck;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set aggressiveness mode
|
||||
int WebRtcVad_set_mode_core(VadInstT *inst, short mode)
|
||||
{
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// Quality mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_Q;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_Q;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_Q;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_Q;
|
||||
inst->total[1] = TOTAL_20MS_Q;
|
||||
inst->total[2] = TOTAL_30MS_Q;
|
||||
} else if (mode == 1)
|
||||
{
|
||||
// Low bitrate mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_LBR;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_LBR;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_LBR;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_LBR;
|
||||
inst->total[1] = TOTAL_20MS_LBR;
|
||||
inst->total[2] = TOTAL_30MS_LBR;
|
||||
} else if (mode == 2)
|
||||
{
|
||||
// Aggressive mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_AGG;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_AGG;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_AGG;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_AGG;
|
||||
inst->total[1] = TOTAL_20MS_AGG;
|
||||
inst->total[2] = TOTAL_30MS_AGG;
|
||||
} else if (mode == 3)
|
||||
{
|
||||
// Very aggressive mode
|
||||
inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst
|
||||
inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst
|
||||
inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst
|
||||
|
||||
inst->individual[0] = INDIVIDUAL_10MS_VAG;
|
||||
inst->individual[1] = INDIVIDUAL_20MS_VAG;
|
||||
inst->individual[2] = INDIVIDUAL_30MS_VAG;
|
||||
|
||||
inst->total[0] = TOTAL_10MS_VAG;
|
||||
inst->total[1] = TOTAL_20MS_VAG;
|
||||
inst->total[2] = TOTAL_30MS_VAG;
|
||||
} else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate VAD decision by first extracting feature values and then calculate
|
||||
// probability for both speech and background noise.
|
||||
|
||||
WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT *inst, WebRtc_Word16 *speech_frame,
|
||||
int frame_length)
|
||||
{
|
||||
WebRtc_Word16 len, vad;
|
||||
WebRtc_Word16 speechWB[480]; // Downsampled speech frame: 960 samples (30ms in SWB)
|
||||
WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB)
|
||||
|
||||
|
||||
// Downsample signal 32->16->8 before doing VAD
|
||||
WebRtcVad_Downsampling(speech_frame, speechWB, &(inst->downsampling_filter_states[2]),
|
||||
frame_length);
|
||||
len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1);
|
||||
|
||||
WebRtcVad_Downsampling(speechWB, speechNB, inst->downsampling_filter_states, len);
|
||||
len = WEBRTC_SPL_RSHIFT_W16(len, 1);
|
||||
|
||||
// Do VAD on an 8 kHz signal
|
||||
vad = WebRtcVad_CalcVad8khz(inst, speechNB, len);
|
||||
|
||||
return vad;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT *inst, WebRtc_Word16 *speech_frame,
|
||||
int frame_length)
|
||||
{
|
||||
WebRtc_Word16 len, vad;
|
||||
WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB)
|
||||
|
||||
// Wideband: Downsample signal before doing VAD
|
||||
WebRtcVad_Downsampling(speech_frame, speechNB, inst->downsampling_filter_states,
|
||||
frame_length);
|
||||
|
||||
len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1);
|
||||
vad = WebRtcVad_CalcVad8khz(inst, speechNB, len);
|
||||
|
||||
return vad;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT *inst, WebRtc_Word16 *speech_frame,
|
||||
int frame_length)
|
||||
{
|
||||
WebRtc_Word16 feature_vector[NUM_CHANNELS], total_power;
|
||||
|
||||
// Get power in the bands
|
||||
total_power = WebRtcVad_get_features(inst, speech_frame, frame_length, feature_vector);
|
||||
|
||||
// Make a VAD
|
||||
inst->vad = WebRtcVad_GmmProbability(inst, feature_vector, total_power, frame_length);
|
||||
|
||||
return inst->vad;
|
||||
}
|
||||
|
||||
// Calculate probability for both speech and background noise, and perform a
|
||||
// hypothesis-test.
|
||||
WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT *inst, WebRtc_Word16 *feature_vector,
|
||||
WebRtc_Word16 total_power, int frame_length)
|
||||
{
|
||||
int n, k;
|
||||
WebRtc_Word16 backval;
|
||||
WebRtc_Word16 h0, h1;
|
||||
WebRtc_Word16 ratvec, xval;
|
||||
WebRtc_Word16 vadflag;
|
||||
WebRtc_Word16 shifts0, shifts1;
|
||||
WebRtc_Word16 tmp16, tmp16_1, tmp16_2;
|
||||
WebRtc_Word16 diff, nr, pos;
|
||||
WebRtc_Word16 nmk, nmk2, nmk3, smk, smk2, nsk, ssk;
|
||||
WebRtc_Word16 delt, ndelt;
|
||||
WebRtc_Word16 maxspe, maxmu;
|
||||
WebRtc_Word16 deltaN[NUM_TABLE_VALUES], deltaS[NUM_TABLE_VALUES];
|
||||
WebRtc_Word16 ngprvec[NUM_TABLE_VALUES], sgprvec[NUM_TABLE_VALUES];
|
||||
WebRtc_Word32 h0test, h1test;
|
||||
WebRtc_Word32 tmp32_1, tmp32_2;
|
||||
WebRtc_Word32 dotVal;
|
||||
WebRtc_Word32 nmid, smid;
|
||||
WebRtc_Word32 probn[NUM_MODELS], probs[NUM_MODELS];
|
||||
WebRtc_Word16 *nmean1ptr, *nmean2ptr, *smean1ptr, *smean2ptr, *nstd1ptr, *nstd2ptr,
|
||||
*sstd1ptr, *sstd2ptr;
|
||||
WebRtc_Word16 overhead1, overhead2, individualTest, totalTest;
|
||||
|
||||
// Set the thresholds to different values based on frame length
|
||||
if (frame_length == 80)
|
||||
{
|
||||
// 80 input samples
|
||||
overhead1 = inst->over_hang_max_1[0];
|
||||
overhead2 = inst->over_hang_max_2[0];
|
||||
individualTest = inst->individual[0];
|
||||
totalTest = inst->total[0];
|
||||
} else if (frame_length == 160)
|
||||
{
|
||||
// 160 input samples
|
||||
overhead1 = inst->over_hang_max_1[1];
|
||||
overhead2 = inst->over_hang_max_2[1];
|
||||
individualTest = inst->individual[1];
|
||||
totalTest = inst->total[1];
|
||||
} else
|
||||
{
|
||||
// 240 input samples
|
||||
overhead1 = inst->over_hang_max_1[2];
|
||||
overhead2 = inst->over_hang_max_2[2];
|
||||
individualTest = inst->individual[2];
|
||||
totalTest = inst->total[2];
|
||||
}
|
||||
|
||||
if (total_power > MIN_ENERGY)
|
||||
{ // If signal present at all
|
||||
|
||||
// Set pointers to the gaussian parameters
|
||||
nmean1ptr = &inst->noise_means[0];
|
||||
nmean2ptr = &inst->noise_means[NUM_CHANNELS];
|
||||
smean1ptr = &inst->speech_means[0];
|
||||
smean2ptr = &inst->speech_means[NUM_CHANNELS];
|
||||
nstd1ptr = &inst->noise_stds[0];
|
||||
nstd2ptr = &inst->noise_stds[NUM_CHANNELS];
|
||||
sstd1ptr = &inst->speech_stds[0];
|
||||
sstd2ptr = &inst->speech_stds[NUM_CHANNELS];
|
||||
|
||||
vadflag = 0;
|
||||
dotVal = 0;
|
||||
for (n = 0; n < NUM_CHANNELS; n++)
|
||||
{ // For all channels
|
||||
|
||||
pos = WEBRTC_SPL_LSHIFT_W16(n, 1);
|
||||
xval = feature_vector[n];
|
||||
|
||||
// Probability for Noise, Q7 * Q20 = Q27
|
||||
tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean1ptr++, *nstd1ptr++,
|
||||
&deltaN[pos]);
|
||||
probn[0] = (WebRtc_Word32)(kNoiseDataWeights[n] * tmp32_1);
|
||||
tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean2ptr++, *nstd2ptr++,
|
||||
&deltaN[pos + 1]);
|
||||
probn[1] = (WebRtc_Word32)(kNoiseDataWeights[n + NUM_CHANNELS] * tmp32_1);
|
||||
h0test = probn[0] + probn[1]; // Q27
|
||||
h0 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h0test, 12); // Q15
|
||||
|
||||
// Probability for Speech
|
||||
tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean1ptr++, *sstd1ptr++,
|
||||
&deltaS[pos]);
|
||||
probs[0] = (WebRtc_Word32)(kSpeechDataWeights[n] * tmp32_1);
|
||||
tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean2ptr++, *sstd2ptr++,
|
||||
&deltaS[pos + 1]);
|
||||
probs[1] = (WebRtc_Word32)(kSpeechDataWeights[n + NUM_CHANNELS] * tmp32_1);
|
||||
h1test = probs[0] + probs[1]; // Q27
|
||||
h1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h1test, 12); // Q15
|
||||
|
||||
// Get likelihood ratio. Approximate log2(H1/H0) with shifts0 - shifts1
|
||||
shifts0 = WebRtcSpl_NormW32(h0test);
|
||||
shifts1 = WebRtcSpl_NormW32(h1test);
|
||||
|
||||
if ((h0test > 0) && (h1test > 0))
|
||||
{
|
||||
ratvec = shifts0 - shifts1;
|
||||
} else if (h1test > 0)
|
||||
{
|
||||
ratvec = 31 - shifts1;
|
||||
} else if (h0test > 0)
|
||||
{
|
||||
ratvec = shifts0 - 31;
|
||||
} else
|
||||
{
|
||||
ratvec = 0;
|
||||
}
|
||||
|
||||
// VAD decision with spectrum weighting
|
||||
dotVal += WEBRTC_SPL_MUL_16_16(ratvec, kSpectrumWeight[n]);
|
||||
|
||||
// Individual channel test
|
||||
if ((ratvec << 2) > individualTest)
|
||||
{
|
||||
vadflag = 1;
|
||||
}
|
||||
|
||||
// Probabilities used when updating model
|
||||
if (h0 > 0)
|
||||
{
|
||||
tmp32_1 = probn[0] & 0xFFFFF000; // Q27
|
||||
tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2); // Q29
|
||||
ngprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h0);
|
||||
ngprvec[pos + 1] = 16384 - ngprvec[pos];
|
||||
} else
|
||||
{
|
||||
ngprvec[pos] = 16384;
|
||||
ngprvec[pos + 1] = 0;
|
||||
}
|
||||
|
||||
// Probabilities used when updating model
|
||||
if (h1 > 0)
|
||||
{
|
||||
tmp32_1 = probs[0] & 0xFFFFF000;
|
||||
tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2);
|
||||
sgprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h1);
|
||||
sgprvec[pos + 1] = 16384 - sgprvec[pos];
|
||||
} else
|
||||
{
|
||||
sgprvec[pos] = 0;
|
||||
sgprvec[pos + 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Overall test
|
||||
if (dotVal >= totalTest)
|
||||
{
|
||||
vadflag |= 1;
|
||||
}
|
||||
|
||||
// Set pointers to the means and standard deviations.
|
||||
nmean1ptr = &inst->noise_means[0];
|
||||
smean1ptr = &inst->speech_means[0];
|
||||
nstd1ptr = &inst->noise_stds[0];
|
||||
sstd1ptr = &inst->speech_stds[0];
|
||||
|
||||
maxspe = 12800;
|
||||
|
||||
// Update the model's parameters
|
||||
for (n = 0; n < NUM_CHANNELS; n++)
|
||||
{
|
||||
|
||||
pos = WEBRTC_SPL_LSHIFT_W16(n, 1);
|
||||
|
||||
// Get min value in past which is used for long term correction
|
||||
backval = WebRtcVad_FindMinimum(inst, feature_vector[n], n); // Q4
|
||||
|
||||
// Compute the "global" mean, that is the sum of the two means weighted
|
||||
nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr); // Q7 * Q7
|
||||
nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS],
|
||||
*(nmean1ptr+NUM_CHANNELS));
|
||||
tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 6); // Q8
|
||||
|
||||
for (k = 0; k < NUM_MODELS; k++)
|
||||
{
|
||||
|
||||
nr = pos + k;
|
||||
|
||||
nmean2ptr = nmean1ptr + k * NUM_CHANNELS;
|
||||
smean2ptr = smean1ptr + k * NUM_CHANNELS;
|
||||
nstd2ptr = nstd1ptr + k * NUM_CHANNELS;
|
||||
sstd2ptr = sstd1ptr + k * NUM_CHANNELS;
|
||||
nmk = *nmean2ptr;
|
||||
smk = *smean2ptr;
|
||||
nsk = *nstd2ptr;
|
||||
ssk = *sstd2ptr;
|
||||
|
||||
// Update noise mean vector if the frame consists of noise only
|
||||
nmk2 = nmk;
|
||||
if (!vadflag)
|
||||
{
|
||||
// deltaN = (x-mu)/sigma^2
|
||||
// ngprvec[k] = probn[k]/(probn[0] + probn[1])
|
||||
|
||||
delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ngprvec[nr],
|
||||
deltaN[nr], 11); // Q14*Q11
|
||||
nmk2 = nmk + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt,
|
||||
kNoiseUpdateConst,
|
||||
22); // Q7+(Q14*Q15>>22)
|
||||
}
|
||||
|
||||
// Long term correction of the noise mean
|
||||
ndelt = WEBRTC_SPL_LSHIFT_W16(backval, 4);
|
||||
ndelt -= tmp16_1; // Q8 - Q8
|
||||
nmk3 = nmk2 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ndelt,
|
||||
kBackEta,
|
||||
9); // Q7+(Q8*Q8)>>9
|
||||
|
||||
// Control that the noise mean does not drift to much
|
||||
tmp16 = WEBRTC_SPL_LSHIFT_W16(k+5, 7);
|
||||
if (nmk3 < tmp16)
|
||||
nmk3 = tmp16;
|
||||
tmp16 = WEBRTC_SPL_LSHIFT_W16(72+k-n, 7);
|
||||
if (nmk3 > tmp16)
|
||||
nmk3 = tmp16;
|
||||
*nmean2ptr = nmk3;
|
||||
|
||||
if (vadflag)
|
||||
{
|
||||
// Update speech mean vector:
|
||||
// deltaS = (x-mu)/sigma^2
|
||||
// sgprvec[k] = probn[k]/(probn[0] + probn[1])
|
||||
|
||||
delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sgprvec[nr],
|
||||
deltaS[nr],
|
||||
11); // (Q14*Q11)>>11=Q14
|
||||
tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt,
|
||||
kSpeechUpdateConst,
|
||||
21) + 1;
|
||||
smk2 = smk + (tmp16 >> 1); // Q7 + (Q14 * Q15 >> 22)
|
||||
|
||||
// Control that the speech mean does not drift to much
|
||||
maxmu = maxspe + 640;
|
||||
if (smk2 < kMinimumMean[k])
|
||||
smk2 = kMinimumMean[k];
|
||||
if (smk2 > maxmu)
|
||||
smk2 = maxmu;
|
||||
|
||||
*smean2ptr = smk2;
|
||||
|
||||
// (Q7>>3) = Q4
|
||||
tmp16 = WEBRTC_SPL_RSHIFT_W16((smk + 4), 3);
|
||||
|
||||
tmp16 = feature_vector[n] - tmp16; // Q4
|
||||
tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaS[nr], tmp16, 3);
|
||||
tmp32_2 = tmp32_1 - (WebRtc_Word32)4096; // Q12
|
||||
tmp16 = WEBRTC_SPL_RSHIFT_W16((sgprvec[nr]), 2);
|
||||
tmp32_1 = (WebRtc_Word32)(tmp16 * tmp32_2);// (Q15>>3)*(Q14>>2)=Q12*Q12=Q24
|
||||
|
||||
tmp32_2 = WEBRTC_SPL_RSHIFT_W32(tmp32_1, 4); // Q20
|
||||
|
||||
// 0.1 * Q20 / Q7 = Q13
|
||||
if (tmp32_2 > 0)
|
||||
tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, ssk * 10);
|
||||
else
|
||||
{
|
||||
tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_2, ssk * 10);
|
||||
tmp16 = -tmp16;
|
||||
}
|
||||
// divide by 4 giving an update factor of 0.025
|
||||
tmp16 += 128; // Rounding
|
||||
ssk += WEBRTC_SPL_RSHIFT_W16(tmp16, 8);
|
||||
// Division with 8 plus Q7
|
||||
if (ssk < MIN_STD)
|
||||
ssk = MIN_STD;
|
||||
*sstd2ptr = ssk;
|
||||
} else
|
||||
{
|
||||
// Update GMM variance vectors
|
||||
// deltaN * (feature_vector[n] - nmk) - 1, Q11 * Q4
|
||||
tmp16 = feature_vector[n] - WEBRTC_SPL_RSHIFT_W16(nmk, 3);
|
||||
|
||||
// (Q15>>3) * (Q14>>2) = Q12 * Q12 = Q24
|
||||
tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaN[nr], tmp16, 3) - 4096;
|
||||
tmp16 = WEBRTC_SPL_RSHIFT_W16((ngprvec[nr]+2), 2);
|
||||
tmp32_2 = (WebRtc_Word32)(tmp16 * tmp32_1);
|
||||
tmp32_1 = WEBRTC_SPL_RSHIFT_W32(tmp32_2, 14);
|
||||
// Q20 * approx 0.001 (2^-10=0.0009766)
|
||||
|
||||
// Q20 / Q7 = Q13
|
||||
tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk);
|
||||
if (tmp32_1 > 0)
|
||||
tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk);
|
||||
else
|
||||
{
|
||||
tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_1, nsk);
|
||||
tmp16 = -tmp16;
|
||||
}
|
||||
tmp16 += 32; // Rounding
|
||||
nsk += WEBRTC_SPL_RSHIFT_W16(tmp16, 6);
|
||||
|
||||
if (nsk < MIN_STD)
|
||||
nsk = MIN_STD;
|
||||
|
||||
*nstd2ptr = nsk;
|
||||
}
|
||||
}
|
||||
|
||||
// Separate models if they are too close - nmid in Q14
|
||||
nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr);
|
||||
nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS], *nmean2ptr);
|
||||
|
||||
// smid in Q14
|
||||
smid = WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n], *smean1ptr);
|
||||
smid += WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n+NUM_CHANNELS], *smean2ptr);
|
||||
|
||||
// diff = "global" speech mean - "global" noise mean
|
||||
diff = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 9);
|
||||
tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 9);
|
||||
diff -= tmp16;
|
||||
|
||||
if (diff < kMinimumDifference[n])
|
||||
{
|
||||
|
||||
tmp16 = kMinimumDifference[n] - diff; // Q5
|
||||
|
||||
// tmp16_1 = ~0.8 * (kMinimumDifference - diff) in Q7
|
||||
// tmp16_2 = ~0.2 * (kMinimumDifference - diff) in Q7
|
||||
tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(13, tmp16, 2);
|
||||
tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, tmp16, 2);
|
||||
|
||||
// First Gauss, speech model
|
||||
tmp16 = tmp16_1 + *smean1ptr;
|
||||
*smean1ptr = tmp16;
|
||||
smid = WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n]);
|
||||
|
||||
// Second Gauss, speech model
|
||||
tmp16 = tmp16_1 + *smean2ptr;
|
||||
*smean2ptr = tmp16;
|
||||
smid += WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n+NUM_CHANNELS]);
|
||||
|
||||
// First Gauss, noise model
|
||||
tmp16 = *nmean1ptr - tmp16_2;
|
||||
*nmean1ptr = tmp16;
|
||||
|
||||
nmid = WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n]);
|
||||
|
||||
// Second Gauss, noise model
|
||||
tmp16 = *nmean2ptr - tmp16_2;
|
||||
*nmean2ptr = tmp16;
|
||||
nmid += WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n+NUM_CHANNELS]);
|
||||
}
|
||||
|
||||
// Control that the speech & noise means do not drift to much
|
||||
maxspe = kMaximumSpeech[n];
|
||||
tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 7);
|
||||
if (tmp16_2 > maxspe)
|
||||
{ // Upper limit of speech model
|
||||
tmp16_2 -= maxspe;
|
||||
|
||||
*smean1ptr -= tmp16_2;
|
||||
*smean2ptr -= tmp16_2;
|
||||
}
|
||||
|
||||
tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 7);
|
||||
if (tmp16_2 > kMaximumNoise[n])
|
||||
{
|
||||
tmp16_2 -= kMaximumNoise[n];
|
||||
|
||||
*nmean1ptr -= tmp16_2;
|
||||
*nmean2ptr -= tmp16_2;
|
||||
}
|
||||
|
||||
nmean1ptr++;
|
||||
smean1ptr++;
|
||||
nstd1ptr++;
|
||||
sstd1ptr++;
|
||||
}
|
||||
inst->frame_counter++;
|
||||
} else
|
||||
{
|
||||
vadflag = 0;
|
||||
}
|
||||
|
||||
// Hangover smoothing
|
||||
if (!vadflag)
|
||||
{
|
||||
if (inst->over_hang > 0)
|
||||
{
|
||||
vadflag = 2 + inst->over_hang;
|
||||
inst->over_hang = inst->over_hang - 1;
|
||||
}
|
||||
inst->num_of_speech = 0;
|
||||
} else
|
||||
{
|
||||
inst->num_of_speech = inst->num_of_speech + 1;
|
||||
if (inst->num_of_speech > NSP_MAX)
|
||||
{
|
||||
inst->num_of_speech = NSP_MAX;
|
||||
inst->over_hang = overhead2;
|
||||
} else
|
||||
inst->over_hang = overhead1;
|
||||
}
|
||||
return vadflag;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the descriptions of the core VAD calls.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_CORE_H_
|
||||
#define WEBRTC_VAD_CORE_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "vad_defines.h"
|
||||
|
||||
typedef struct VadInstT_
|
||||
{
|
||||
|
||||
WebRtc_Word16 vad;
|
||||
WebRtc_Word32 downsampling_filter_states[4];
|
||||
WebRtc_Word16 noise_means[NUM_TABLE_VALUES];
|
||||
WebRtc_Word16 speech_means[NUM_TABLE_VALUES];
|
||||
WebRtc_Word16 noise_stds[NUM_TABLE_VALUES];
|
||||
WebRtc_Word16 speech_stds[NUM_TABLE_VALUES];
|
||||
WebRtc_Word32 frame_counter;
|
||||
WebRtc_Word16 over_hang; // Over Hang
|
||||
WebRtc_Word16 num_of_speech;
|
||||
WebRtc_Word16 index_vector[16 * NUM_CHANNELS];
|
||||
WebRtc_Word16 low_value_vector[16 * NUM_CHANNELS];
|
||||
WebRtc_Word16 mean_value[NUM_CHANNELS];
|
||||
WebRtc_Word16 upper_state[5];
|
||||
WebRtc_Word16 lower_state[5];
|
||||
WebRtc_Word16 hp_filter_state[4];
|
||||
WebRtc_Word16 over_hang_max_1[3];
|
||||
WebRtc_Word16 over_hang_max_2[3];
|
||||
WebRtc_Word16 individual[3];
|
||||
WebRtc_Word16 total[3];
|
||||
|
||||
short init_flag;
|
||||
|
||||
} VadInstT;
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_InitCore(...)
|
||||
*
|
||||
* This function initializes a VAD instance
|
||||
*
|
||||
* Input:
|
||||
* - inst : Instance that should be initialized
|
||||
* - mode : Aggressiveness degree
|
||||
* 0 (High quality) - 3 (Highly aggressive)
|
||||
*
|
||||
* Output:
|
||||
* - inst : Initialized instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
int WebRtcVad_InitCore(VadInstT* inst, short mode);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_set_mode_core(...)
|
||||
*
|
||||
* This function changes the VAD settings
|
||||
*
|
||||
* Input:
|
||||
* - inst : VAD instance
|
||||
* - mode : Aggressiveness degree
|
||||
* 0 (High quality) - 3 (Highly aggressive)
|
||||
*
|
||||
* Output:
|
||||
* - inst : Changed instance
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
int WebRtcVad_set_mode_core(VadInstT* inst, short mode);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_CalcVad32khz(...)
|
||||
* WebRtcVad_CalcVad16khz(...)
|
||||
* WebRtcVad_CalcVad8khz(...)
|
||||
*
|
||||
* Calculate probability for active speech and make VAD decision.
|
||||
*
|
||||
* Input:
|
||||
* - inst : Instance that should be initialized
|
||||
* - speech_frame : Input speech frame
|
||||
* - frame_length : Number of input samples
|
||||
*
|
||||
* Output:
|
||||
* - inst : Updated filter states etc.
|
||||
*
|
||||
* Return value : VAD decision
|
||||
* 0 - No active speech
|
||||
* 1-6 - Active speech
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT* inst, WebRtc_Word16* speech_frame,
|
||||
int frame_length);
|
||||
WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT* inst, WebRtc_Word16* speech_frame,
|
||||
int frame_length);
|
||||
WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT* inst, WebRtc_Word16* speech_frame,
|
||||
int frame_length);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_GmmProbability(...)
|
||||
*
|
||||
* This function calculates the probabilities for background noise and
|
||||
* speech using Gaussian Mixture Models. A hypothesis-test is performed to decide
|
||||
* which type of signal is most probable.
|
||||
*
|
||||
* Input:
|
||||
* - inst : Pointer to VAD instance
|
||||
* - feature_vector : Feature vector = log10(energy in frequency band)
|
||||
* - total_power : Total power in frame.
|
||||
* - frame_length : Number of input samples
|
||||
*
|
||||
* Output:
|
||||
* VAD decision : 0 - noise, 1 - speech
|
||||
*
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT* inst, WebRtc_Word16* feature_vector,
|
||||
WebRtc_Word16 total_power, int frame_length);
|
||||
|
||||
#endif // WEBRTC_VAD_CORE_H_
|
@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the implementation of the internal filterbank associated functions.
|
||||
* For function description, see vad_filterbank.h.
|
||||
*/
|
||||
|
||||
#include "vad_filterbank.h"
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
#include "vad_defines.h"
|
||||
|
||||
// Constant 160*log10(2) in Q9
|
||||
static const WebRtc_Word16 kLogConst = 24660;
|
||||
// Coefficients used by WebRtcVad_HpOutput, Q14
|
||||
static const WebRtc_Word16 kHpZeroCoefs[3] = {6631, -13262, 6631};
|
||||
static const WebRtc_Word16 kHpPoleCoefs[3] = {16384, -7756, 5620};
|
||||
// Allpass filter coefficients, upper and lower, in Q15
|
||||
// Upper: 0.64, Lower: 0.17
|
||||
static const WebRtc_Word16 kAllPassCoefsQ15[2] = {20972, 5571};
|
||||
// Adjustment for division with two in WebRtcVad_SplitFilter
|
||||
static const WebRtc_Word16 kOffsetVector[6] = {368, 368, 272, 176, 176, 176};
|
||||
|
||||
void WebRtcVad_HpOutput(WebRtc_Word16 *in_vector,
|
||||
WebRtc_Word16 in_vector_length,
|
||||
WebRtc_Word16 *out_vector,
|
||||
WebRtc_Word16 *filter_state)
|
||||
{
|
||||
WebRtc_Word16 i, *pi, *outPtr;
|
||||
WebRtc_Word32 tmpW32;
|
||||
|
||||
pi = &in_vector[0];
|
||||
outPtr = &out_vector[0];
|
||||
|
||||
// The sum of the absolute values of the impulse response:
|
||||
// The zero/pole-filter has a max amplification of a single sample of: 1.4546
|
||||
// Impulse response: 0.4047 -0.6179 -0.0266 0.1993 0.1035 -0.0194
|
||||
// The all-zero section has a max amplification of a single sample of: 1.6189
|
||||
// Impulse response: 0.4047 -0.8094 0.4047 0 0 0
|
||||
// The all-pole section has a max amplification of a single sample of: 1.9931
|
||||
// Impulse response: 1.0000 0.4734 -0.1189 -0.2187 -0.0627 0.04532
|
||||
|
||||
for (i = 0; i < in_vector_length; i++)
|
||||
{
|
||||
// all-zero section (filter coefficients in Q14)
|
||||
tmpW32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[0], (*pi));
|
||||
tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[1], filter_state[0]);
|
||||
tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[2], filter_state[1]); // Q14
|
||||
filter_state[1] = filter_state[0];
|
||||
filter_state[0] = *pi++;
|
||||
|
||||
// all-pole section
|
||||
tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[1], filter_state[2]); // Q14
|
||||
tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[2], filter_state[3]);
|
||||
filter_state[3] = filter_state[2];
|
||||
filter_state[2] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32 (tmpW32, 14);
|
||||
*outPtr++ = filter_state[2];
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcVad_Allpass(WebRtc_Word16 *in_vector,
|
||||
WebRtc_Word16 *out_vector,
|
||||
WebRtc_Word16 filter_coefficients,
|
||||
int vector_length,
|
||||
WebRtc_Word16 *filter_state)
|
||||
{
|
||||
// The filter can only cause overflow (in the w16 output variable)
|
||||
// if more than 4 consecutive input numbers are of maximum value and
|
||||
// has the the same sign as the impulse responses first taps.
|
||||
// First 6 taps of the impulse response: 0.6399 0.5905 -0.3779
|
||||
// 0.2418 -0.1547 0.0990
|
||||
|
||||
int n;
|
||||
WebRtc_Word16 tmp16;
|
||||
WebRtc_Word32 tmp32, in32, state32;
|
||||
|
||||
state32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*filter_state)), 16); // Q31
|
||||
|
||||
for (n = 0; n < vector_length; n++)
|
||||
{
|
||||
|
||||
tmp32 = state32 + WEBRTC_SPL_MUL_16_16(filter_coefficients, (*in_vector));
|
||||
tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
|
||||
*out_vector++ = tmp16;
|
||||
in32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*in_vector)), 14);
|
||||
state32 = in32 - WEBRTC_SPL_MUL_16_16(filter_coefficients, tmp16);
|
||||
state32 = WEBRTC_SPL_LSHIFT_W32(state32, 1);
|
||||
in_vector += 2;
|
||||
}
|
||||
|
||||
*filter_state = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(state32, 16);
|
||||
}
|
||||
|
||||
void WebRtcVad_SplitFilter(WebRtc_Word16 *in_vector,
|
||||
WebRtc_Word16 *out_vector_hp,
|
||||
WebRtc_Word16 *out_vector_lp,
|
||||
WebRtc_Word16 *upper_state,
|
||||
WebRtc_Word16 *lower_state,
|
||||
int in_vector_length)
|
||||
{
|
||||
WebRtc_Word16 tmpOut;
|
||||
int k, halflen;
|
||||
|
||||
// Downsampling by 2 and get two branches
|
||||
halflen = WEBRTC_SPL_RSHIFT_W16(in_vector_length, 1);
|
||||
|
||||
// All-pass filtering upper branch
|
||||
WebRtcVad_Allpass(&in_vector[0], out_vector_hp, kAllPassCoefsQ15[0], halflen, upper_state);
|
||||
|
||||
// All-pass filtering lower branch
|
||||
WebRtcVad_Allpass(&in_vector[1], out_vector_lp, kAllPassCoefsQ15[1], halflen, lower_state);
|
||||
|
||||
// Make LP and HP signals
|
||||
for (k = 0; k < halflen; k++)
|
||||
{
|
||||
tmpOut = *out_vector_hp;
|
||||
*out_vector_hp++ -= *out_vector_lp;
|
||||
*out_vector_lp++ += tmpOut;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcVad_get_features(VadInstT *inst,
|
||||
WebRtc_Word16 *in_vector,
|
||||
int frame_size,
|
||||
WebRtc_Word16 *out_vector)
|
||||
{
|
||||
int curlen, filtno;
|
||||
WebRtc_Word16 vecHP1[120], vecLP1[120];
|
||||
WebRtc_Word16 vecHP2[60], vecLP2[60];
|
||||
WebRtc_Word16 *ptin;
|
||||
WebRtc_Word16 *hptout, *lptout;
|
||||
WebRtc_Word16 power = 0;
|
||||
|
||||
// Split at 2000 Hz and downsample
|
||||
filtno = 0;
|
||||
ptin = in_vector;
|
||||
hptout = vecHP1;
|
||||
lptout = vecLP1;
|
||||
curlen = frame_size;
|
||||
WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
|
||||
&inst->lower_state[filtno], curlen);
|
||||
|
||||
// Split at 3000 Hz and downsample
|
||||
filtno = 1;
|
||||
ptin = vecHP1;
|
||||
hptout = vecHP2;
|
||||
lptout = vecLP2;
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1);
|
||||
|
||||
WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
|
||||
&inst->lower_state[filtno], curlen);
|
||||
|
||||
// Energy in 3000 Hz - 4000 Hz
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
|
||||
WebRtcVad_LogOfEnergy(vecHP2, &out_vector[5], &power, kOffsetVector[5], curlen);
|
||||
|
||||
// Energy in 2000 Hz - 3000 Hz
|
||||
WebRtcVad_LogOfEnergy(vecLP2, &out_vector[4], &power, kOffsetVector[4], curlen);
|
||||
|
||||
// Split at 1000 Hz and downsample
|
||||
filtno = 2;
|
||||
ptin = vecLP1;
|
||||
hptout = vecHP2;
|
||||
lptout = vecLP2;
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1);
|
||||
WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
|
||||
&inst->lower_state[filtno], curlen);
|
||||
|
||||
// Energy in 1000 Hz - 2000 Hz
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
|
||||
WebRtcVad_LogOfEnergy(vecHP2, &out_vector[3], &power, kOffsetVector[3], curlen);
|
||||
|
||||
// Split at 500 Hz
|
||||
filtno = 3;
|
||||
ptin = vecLP2;
|
||||
hptout = vecHP1;
|
||||
lptout = vecLP1;
|
||||
|
||||
WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
|
||||
&inst->lower_state[filtno], curlen);
|
||||
|
||||
// Energy in 500 Hz - 1000 Hz
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
|
||||
WebRtcVad_LogOfEnergy(vecHP1, &out_vector[2], &power, kOffsetVector[2], curlen);
|
||||
// Split at 250 Hz
|
||||
filtno = 4;
|
||||
ptin = vecLP1;
|
||||
hptout = vecHP2;
|
||||
lptout = vecLP2;
|
||||
|
||||
WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
|
||||
&inst->lower_state[filtno], curlen);
|
||||
|
||||
// Energy in 250 Hz - 500 Hz
|
||||
curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
|
||||
WebRtcVad_LogOfEnergy(vecHP2, &out_vector[1], &power, kOffsetVector[1], curlen);
|
||||
|
||||
// Remove DC and LFs
|
||||
WebRtcVad_HpOutput(vecLP2, curlen, vecHP1, inst->hp_filter_state);
|
||||
|
||||
// Power in 80 Hz - 250 Hz
|
||||
WebRtcVad_LogOfEnergy(vecHP1, &out_vector[0], &power, kOffsetVector[0], curlen);
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
void WebRtcVad_LogOfEnergy(WebRtc_Word16 *vector,
|
||||
WebRtc_Word16 *enerlogval,
|
||||
WebRtc_Word16 *power,
|
||||
WebRtc_Word16 offset,
|
||||
int vector_length)
|
||||
{
|
||||
WebRtc_Word16 enerSum = 0;
|
||||
WebRtc_Word16 zeros, frac, log2;
|
||||
WebRtc_Word32 energy;
|
||||
|
||||
int shfts = 0, shfts2;
|
||||
|
||||
energy = WebRtcSpl_Energy(vector, vector_length, &shfts);
|
||||
|
||||
if (energy > 0)
|
||||
{
|
||||
|
||||
shfts2 = 16 - WebRtcSpl_NormW32(energy);
|
||||
shfts += shfts2;
|
||||
// "shfts" is the total number of right shifts that has been done to enerSum.
|
||||
enerSum = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(energy, -shfts2);
|
||||
|
||||
// Find:
|
||||
// 160*log10(enerSum*2^shfts) = 160*log10(2)*log2(enerSum*2^shfts) =
|
||||
// 160*log10(2)*(log2(enerSum) + log2(2^shfts)) =
|
||||
// 160*log10(2)*(log2(enerSum) + shfts)
|
||||
|
||||
zeros = WebRtcSpl_NormU32(enerSum);
|
||||
frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_Word32)(enerSum) << zeros)
|
||||
& 0x7FFFFFFF) >> 21);
|
||||
log2 = (WebRtc_Word16)(((31 - zeros) << 10) + frac);
|
||||
|
||||
*enerlogval = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kLogConst, log2, 19)
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(shfts, kLogConst, 9);
|
||||
|
||||
if (*enerlogval < 0)
|
||||
{
|
||||
*enerlogval = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
*enerlogval = 0;
|
||||
shfts = -15;
|
||||
enerSum = 0;
|
||||
}
|
||||
|
||||
*enerlogval += offset;
|
||||
|
||||
// Total power in frame
|
||||
if (*power <= MIN_ENERGY)
|
||||
{
|
||||
if (shfts > 0)
|
||||
{
|
||||
*power += MIN_ENERGY + 1;
|
||||
} else if (WEBRTC_SPL_SHIFT_W16(enerSum, shfts) > MIN_ENERGY)
|
||||
{
|
||||
*power += MIN_ENERGY + 1;
|
||||
} else
|
||||
{
|
||||
*power += WEBRTC_SPL_SHIFT_W16(enerSum, shfts);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the description of the internal VAD call
|
||||
* WebRtcVad_GaussianProbability.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_FILTERBANK_H_
|
||||
#define WEBRTC_VAD_FILTERBANK_H_
|
||||
|
||||
#include "vad_core.h"
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_HpOutput(...)
|
||||
*
|
||||
* This function removes DC from the lowest frequency band
|
||||
*
|
||||
* Input:
|
||||
* - in_vector : Samples in the frequency interval 0 - 250 Hz
|
||||
* - in_vector_length : Length of input and output vector
|
||||
* - filter_state : Current state of the filter
|
||||
*
|
||||
* Output:
|
||||
* - out_vector : Samples in the frequency interval 80 - 250 Hz
|
||||
* - filter_state : Updated state of the filter
|
||||
*
|
||||
*/
|
||||
void WebRtcVad_HpOutput(WebRtc_Word16* in_vector,
|
||||
WebRtc_Word16 in_vector_length,
|
||||
WebRtc_Word16* out_vector,
|
||||
WebRtc_Word16* filter_state);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Allpass(...)
|
||||
*
|
||||
* This function is used when before splitting a speech file into
|
||||
* different frequency bands
|
||||
*
|
||||
* Note! Do NOT let the arrays in_vector and out_vector correspond to the same address.
|
||||
*
|
||||
* Input:
|
||||
* - in_vector : (Q0)
|
||||
* - filter_coefficients : (Q15)
|
||||
* - vector_length : Length of input and output vector
|
||||
* - filter_state : Current state of the filter (Q(-1))
|
||||
*
|
||||
* Output:
|
||||
* - out_vector : Output speech signal (Q(-1))
|
||||
* - filter_state : Updated state of the filter (Q(-1))
|
||||
*
|
||||
*/
|
||||
void WebRtcVad_Allpass(WebRtc_Word16* in_vector,
|
||||
WebRtc_Word16* outw16,
|
||||
WebRtc_Word16 filter_coefficients,
|
||||
int vector_length,
|
||||
WebRtc_Word16* filter_state);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_SplitFilter(...)
|
||||
*
|
||||
* This function is used when before splitting a speech file into
|
||||
* different frequency bands
|
||||
*
|
||||
* Input:
|
||||
* - in_vector : Input signal to be split into two frequency bands.
|
||||
* - upper_state : Current state of the upper filter
|
||||
* - lower_state : Current state of the lower filter
|
||||
* - in_vector_length : Length of input vector
|
||||
*
|
||||
* Output:
|
||||
* - out_vector_hp : Upper half of the spectrum
|
||||
* - out_vector_lp : Lower half of the spectrum
|
||||
* - upper_state : Updated state of the upper filter
|
||||
* - lower_state : Updated state of the lower filter
|
||||
*
|
||||
*/
|
||||
void WebRtcVad_SplitFilter(WebRtc_Word16* in_vector,
|
||||
WebRtc_Word16* out_vector_hp,
|
||||
WebRtc_Word16* out_vector_lp,
|
||||
WebRtc_Word16* upper_state,
|
||||
WebRtc_Word16* lower_state,
|
||||
int in_vector_length);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_get_features(...)
|
||||
*
|
||||
* This function is used to get the logarithm of the power of each of the
|
||||
* 6 frequency bands used by the VAD:
|
||||
* 80 Hz - 250 Hz
|
||||
* 250 Hz - 500 Hz
|
||||
* 500 Hz - 1000 Hz
|
||||
* 1000 Hz - 2000 Hz
|
||||
* 2000 Hz - 3000 Hz
|
||||
* 3000 Hz - 4000 Hz
|
||||
*
|
||||
* Input:
|
||||
* - inst : Pointer to VAD instance
|
||||
* - in_vector : Input speech signal
|
||||
* - frame_size : Frame size, in number of samples
|
||||
*
|
||||
* Output:
|
||||
* - out_vector : 10*log10(power in each freq. band), Q4
|
||||
*
|
||||
* Return: total power in the signal (NOTE! This value is not exact since it
|
||||
* is only used in a comparison.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_get_features(VadInstT* inst,
|
||||
WebRtc_Word16* in_vector,
|
||||
int frame_size,
|
||||
WebRtc_Word16* out_vector);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_LogOfEnergy(...)
|
||||
*
|
||||
* This function is used to get the logarithm of the power of one frequency band.
|
||||
*
|
||||
* Input:
|
||||
* - vector : Input speech samples for one frequency band
|
||||
* - offset : Offset value for the current frequency band
|
||||
* - vector_length : Length of input vector
|
||||
*
|
||||
* Output:
|
||||
* - enerlogval : 10*log10(energy);
|
||||
* - power : Update total power in speech frame. NOTE! This value
|
||||
* is not exact since it is only used in a comparison.
|
||||
*
|
||||
*/
|
||||
void WebRtcVad_LogOfEnergy(WebRtc_Word16* vector,
|
||||
WebRtc_Word16* enerlogval,
|
||||
WebRtc_Word16* power,
|
||||
WebRtc_Word16 offset,
|
||||
int vector_length);
|
||||
|
||||
#endif // WEBRTC_VAD_FILTERBANK_H_
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the implementation of the internal VAD call
|
||||
* WebRtcVad_GaussianProbability. For function description, see vad_gmm.h.
|
||||
*/
|
||||
|
||||
#include "vad_gmm.h"
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
static const WebRtc_Word32 kCompVar = 22005;
|
||||
// Constant log2(exp(1)) in Q12
|
||||
static const WebRtc_Word16 kLog10Const = 5909;
|
||||
|
||||
WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample,
|
||||
WebRtc_Word16 mean,
|
||||
WebRtc_Word16 std,
|
||||
WebRtc_Word16 *delta)
|
||||
{
|
||||
WebRtc_Word16 tmp16, tmpDiv, tmpDiv2, expVal, tmp16_1, tmp16_2;
|
||||
WebRtc_Word32 tmp32, y32;
|
||||
|
||||
// Calculate tmpDiv=1/std, in Q10
|
||||
tmp32 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W16(std,1) + (WebRtc_Word32)131072; // 1 in Q17
|
||||
tmpDiv = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32, std); // Q17/Q7 = Q10
|
||||
|
||||
// Calculate tmpDiv2=1/std^2, in Q14
|
||||
tmp16 = WEBRTC_SPL_RSHIFT_W16(tmpDiv, 2); // From Q10 to Q8
|
||||
tmpDiv2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 2); // (Q8 * Q8)>>2 = Q14
|
||||
|
||||
tmp16 = WEBRTC_SPL_LSHIFT_W16(in_sample, 3); // Q7
|
||||
tmp16 = tmp16 - mean; // Q7 - Q7 = Q7
|
||||
|
||||
// To be used later, when updating noise/speech model
|
||||
// delta = (x-m)/std^2, in Q11
|
||||
*delta = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmpDiv2, tmp16, 10); //(Q14*Q7)>>10 = Q11
|
||||
|
||||
// Calculate tmp32=(x-m)^2/(2*std^2), in Q10
|
||||
tmp32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT(*delta, tmp16, 9); // One shift for /2
|
||||
|
||||
// Calculate expVal ~= exp(-(x-m)^2/(2*std^2)) ~= exp2(-log2(exp(1))*tmp32)
|
||||
if (tmp32 < kCompVar)
|
||||
{
|
||||
// Calculate tmp16 = log2(exp(1))*tmp32 , in Q10
|
||||
tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)tmp32,
|
||||
kLog10Const, 12);
|
||||
tmp16 = -tmp16;
|
||||
tmp16_2 = (WebRtc_Word16)(0x0400 | (tmp16 & 0x03FF));
|
||||
tmp16_1 = (WebRtc_Word16)(tmp16 ^ 0xFFFF);
|
||||
tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(tmp16_1, 10);
|
||||
tmp16 += 1;
|
||||
// Calculate expVal=log2(-tmp32), in Q10
|
||||
expVal = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)tmp16_2, tmp16);
|
||||
|
||||
} else
|
||||
{
|
||||
expVal = 0;
|
||||
}
|
||||
|
||||
// Calculate y32=(1/std)*exp(-(x-m)^2/(2*std^2)), in Q20
|
||||
y32 = WEBRTC_SPL_MUL_16_16(tmpDiv, expVal); // Q10 * Q10 = Q20
|
||||
|
||||
return y32; // Q20
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the description of the internal VAD call
|
||||
* WebRtcVad_GaussianProbability.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_GMM_H_
|
||||
#define WEBRTC_VAD_GMM_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_GaussianProbability(...)
|
||||
*
|
||||
* This function calculates the probability for the value 'in_sample', given that in_sample
|
||||
* comes from a normal distribution with mean 'mean' and standard deviation 'std'.
|
||||
*
|
||||
* Input:
|
||||
* - in_sample : Input sample in Q4
|
||||
* - mean : mean value in the statistical model, Q7
|
||||
* - std : standard deviation, Q7
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* - delta : Value used when updating the model, Q11
|
||||
*
|
||||
* Return:
|
||||
* - out : out = 1/std * exp(-(x-m)^2/(2*std^2));
|
||||
* Probability for x.
|
||||
*
|
||||
*/
|
||||
WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample,
|
||||
WebRtc_Word16 mean,
|
||||
WebRtc_Word16 std,
|
||||
WebRtc_Word16 *delta);
|
||||
|
||||
#endif // WEBRTC_VAD_GMM_H_
|
@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the implementation of the VAD internal calls for
|
||||
* Downsampling and FindMinimum.
|
||||
* For function call descriptions; See vad_sp.h.
|
||||
*/
|
||||
|
||||
#include "vad_sp.h"
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
#include "vad_defines.h"
|
||||
|
||||
// Allpass filter coefficients, upper and lower, in Q13
|
||||
// Upper: 0.64, Lower: 0.17
|
||||
static const WebRtc_Word16 kAllPassCoefsQ13[2] = {5243, 1392}; // Q13
|
||||
|
||||
// Downsampling filter based on the splitting filter and the allpass functions
|
||||
// in vad_filterbank.c
|
||||
void WebRtcVad_Downsampling(WebRtc_Word16* signal_in,
|
||||
WebRtc_Word16* signal_out,
|
||||
WebRtc_Word32* filter_state,
|
||||
int inlen)
|
||||
{
|
||||
WebRtc_Word16 tmp16_1, tmp16_2;
|
||||
WebRtc_Word32 tmp32_1, tmp32_2;
|
||||
int n, halflen;
|
||||
|
||||
// Downsampling by 2 and get two branches
|
||||
halflen = WEBRTC_SPL_RSHIFT_W16(inlen, 1);
|
||||
|
||||
tmp32_1 = filter_state[0];
|
||||
tmp32_2 = filter_state[1];
|
||||
|
||||
// Filter coefficients in Q13, filter state in Q0
|
||||
for (n = 0; n < halflen; n++)
|
||||
{
|
||||
// All-pass filtering upper branch
|
||||
tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_1, 1)
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]),
|
||||
*signal_in, 14);
|
||||
*signal_out = tmp16_1;
|
||||
tmp32_1 = (WebRtc_Word32)(*signal_in++)
|
||||
- (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), tmp16_1, 12);
|
||||
|
||||
// All-pass filtering lower branch
|
||||
tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_2, 1)
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]),
|
||||
*signal_in, 14);
|
||||
*signal_out++ += tmp16_2;
|
||||
tmp32_2 = (WebRtc_Word32)(*signal_in++)
|
||||
- (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), tmp16_2, 12);
|
||||
}
|
||||
filter_state[0] = tmp32_1;
|
||||
filter_state[1] = tmp32_2;
|
||||
}
|
||||
|
||||
WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst,
|
||||
WebRtc_Word16 x,
|
||||
int n)
|
||||
{
|
||||
int i, j, k, II = -1, offset;
|
||||
WebRtc_Word16 meanV, alpha;
|
||||
WebRtc_Word32 tmp32, tmp32_1;
|
||||
WebRtc_Word16 *valptr, *idxptr, *p1, *p2, *p3;
|
||||
|
||||
// Offset to beginning of the 16 minimum values in memory
|
||||
offset = WEBRTC_SPL_LSHIFT_W16(n, 4);
|
||||
|
||||
// Pointer to memory for the 16 minimum values and the age of each value
|
||||
idxptr = &inst->index_vector[offset];
|
||||
valptr = &inst->low_value_vector[offset];
|
||||
|
||||
// Each value in low_value_vector is getting 1 loop older.
|
||||
// Update age of each value in indexVal, and remove old values.
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
p3 = idxptr + i;
|
||||
if (*p3 != 100)
|
||||
{
|
||||
*p3 += 1;
|
||||
} else
|
||||
{
|
||||
p1 = valptr + i + 1;
|
||||
p2 = p3 + 1;
|
||||
for (j = i; j < 16; j++)
|
||||
{
|
||||
*(valptr + j) = *p1++;
|
||||
*(idxptr + j) = *p2++;
|
||||
}
|
||||
*(idxptr + 15) = 101;
|
||||
*(valptr + 15) = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if x smaller than any of the values in low_value_vector.
|
||||
// If so, find position.
|
||||
if (x < *(valptr + 7))
|
||||
{
|
||||
if (x < *(valptr + 3))
|
||||
{
|
||||
if (x < *(valptr + 1))
|
||||
{
|
||||
if (x < *valptr)
|
||||
{
|
||||
II = 0;
|
||||
} else
|
||||
{
|
||||
II = 1;
|
||||
}
|
||||
} else if (x < *(valptr + 2))
|
||||
{
|
||||
II = 2;
|
||||
} else
|
||||
{
|
||||
II = 3;
|
||||
}
|
||||
} else if (x < *(valptr + 5))
|
||||
{
|
||||
if (x < *(valptr + 4))
|
||||
{
|
||||
II = 4;
|
||||
} else
|
||||
{
|
||||
II = 5;
|
||||
}
|
||||
} else if (x < *(valptr + 6))
|
||||
{
|
||||
II = 6;
|
||||
} else
|
||||
{
|
||||
II = 7;
|
||||
}
|
||||
} else if (x < *(valptr + 15))
|
||||
{
|
||||
if (x < *(valptr + 11))
|
||||
{
|
||||
if (x < *(valptr + 9))
|
||||
{
|
||||
if (x < *(valptr + 8))
|
||||
{
|
||||
II = 8;
|
||||
} else
|
||||
{
|
||||
II = 9;
|
||||
}
|
||||
} else if (x < *(valptr + 10))
|
||||
{
|
||||
II = 10;
|
||||
} else
|
||||
{
|
||||
II = 11;
|
||||
}
|
||||
} else if (x < *(valptr + 13))
|
||||
{
|
||||
if (x < *(valptr + 12))
|
||||
{
|
||||
II = 12;
|
||||
} else
|
||||
{
|
||||
II = 13;
|
||||
}
|
||||
} else if (x < *(valptr + 14))
|
||||
{
|
||||
II = 14;
|
||||
} else
|
||||
{
|
||||
II = 15;
|
||||
}
|
||||
}
|
||||
|
||||
// Put new min value on right position and shift bigger values up
|
||||
if (II > -1)
|
||||
{
|
||||
for (i = 15; i > II; i--)
|
||||
{
|
||||
k = i - 1;
|
||||
*(valptr + i) = *(valptr + k);
|
||||
*(idxptr + i) = *(idxptr + k);
|
||||
}
|
||||
*(valptr + II) = x;
|
||||
*(idxptr + II) = 1;
|
||||
}
|
||||
|
||||
meanV = 0;
|
||||
if ((inst->frame_counter) > 4)
|
||||
{
|
||||
j = 5;
|
||||
} else
|
||||
{
|
||||
j = inst->frame_counter;
|
||||
}
|
||||
|
||||
if (j > 2)
|
||||
{
|
||||
meanV = *(valptr + 2);
|
||||
} else if (j > 0)
|
||||
{
|
||||
meanV = *valptr;
|
||||
} else
|
||||
{
|
||||
meanV = 1600;
|
||||
}
|
||||
|
||||
if (inst->frame_counter > 0)
|
||||
{
|
||||
if (meanV < inst->mean_value[n])
|
||||
{
|
||||
alpha = (WebRtc_Word16)ALPHA1; // 0.2 in Q15
|
||||
} else
|
||||
{
|
||||
alpha = (WebRtc_Word16)ALPHA2; // 0.99 in Q15
|
||||
}
|
||||
} else
|
||||
{
|
||||
alpha = 0;
|
||||
}
|
||||
|
||||
tmp32 = WEBRTC_SPL_MUL_16_16((alpha+1), inst->mean_value[n]);
|
||||
tmp32_1 = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX - alpha, meanV);
|
||||
tmp32 += tmp32_1;
|
||||
tmp32 += 16384;
|
||||
inst->mean_value[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 15);
|
||||
|
||||
return inst->mean_value[n];
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the VAD internal calls for Downsampling and FindMinimum.
|
||||
* Specific function calls are given below.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_SP_H_
|
||||
#define WEBRTC_VAD_SP_H_
|
||||
|
||||
#include "vad_core.h"
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_Downsampling(...)
|
||||
*
|
||||
* Downsamples the signal a factor 2, eg. 32->16 or 16->8
|
||||
*
|
||||
* Input:
|
||||
* - signal_in : Input signal
|
||||
* - in_length : Length of input signal in samples
|
||||
*
|
||||
* Input & Output:
|
||||
* - filter_state : Filter state for first all-pass filters
|
||||
*
|
||||
* Output:
|
||||
* - signal_out : Downsampled signal (of length len/2)
|
||||
*/
|
||||
void WebRtcVad_Downsampling(WebRtc_Word16* signal_in,
|
||||
WebRtc_Word16* signal_out,
|
||||
WebRtc_Word32* filter_state,
|
||||
int in_length);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcVad_FindMinimum(...)
|
||||
*
|
||||
* Find the five lowest values of x in 100 frames long window. Return a mean
|
||||
* value of these five values.
|
||||
*
|
||||
* Input:
|
||||
* - feature_value : Feature value
|
||||
* - channel : Channel number
|
||||
*
|
||||
* Input & Output:
|
||||
* - inst : State information
|
||||
*
|
||||
* Output:
|
||||
* return value : Weighted minimum value for a moving window.
|
||||
*/
|
||||
WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst, WebRtc_Word16 feature_value, int channel);
|
||||
|
||||
#endif // WEBRTC_VAD_SP_H_
|
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the VAD API calls. For a specific function call description,
|
||||
* see webrtc_vad.h
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes the implementation of the VAD unit tests.
|
||||
*/
|
||||
|
||||
#include <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();
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file includes the declaration of the VAD unit test.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VAD_UNIT_TEST_H_
|
||||
#define WEBRTC_VAD_UNIT_TEST_H_
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class VadTest : public ::testing::Test {
|
||||
protected:
|
||||
VadTest();
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
};
|
||||
|
||||
#endif // WEBRTC_VAD_UNIT_TEST_H_
|
@ -1,610 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_COMMON_TYPES_H
|
||||
#define WEBRTC_COMMON_TYPES_H
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
#ifdef WEBRTC_EXPORT
|
||||
#define WEBRTC_DLLEXPORT _declspec(dllexport)
|
||||
#elif WEBRTC_DLL
|
||||
#define WEBRTC_DLLEXPORT _declspec(dllimport)
|
||||
#else
|
||||
#define WEBRTC_DLLEXPORT
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class InStream
|
||||
{
|
||||
public:
|
||||
virtual int Read(void *buf,int len) = 0;
|
||||
virtual int Rewind() {return -1;}
|
||||
virtual ~InStream() {}
|
||||
protected:
|
||||
InStream() {}
|
||||
};
|
||||
|
||||
class OutStream
|
||||
{
|
||||
public:
|
||||
virtual bool Write(const void *buf,int len) = 0;
|
||||
virtual int Rewind() {return -1;}
|
||||
virtual ~OutStream() {}
|
||||
protected:
|
||||
OutStream() {}
|
||||
};
|
||||
|
||||
enum TraceModule
|
||||
{
|
||||
// not a module, triggered from the engine code
|
||||
kTraceVoice = 0x0001,
|
||||
// not a module, triggered from the engine code
|
||||
kTraceVideo = 0x0002,
|
||||
// not a module, triggered from the utility code
|
||||
kTraceUtility = 0x0003,
|
||||
kTraceRtpRtcp = 0x0004,
|
||||
kTraceTransport = 0x0005,
|
||||
kTraceSrtp = 0x0006,
|
||||
kTraceAudioCoding = 0x0007,
|
||||
kTraceAudioMixerServer = 0x0008,
|
||||
kTraceAudioMixerClient = 0x0009,
|
||||
kTraceFile = 0x000a,
|
||||
kTraceAudioProcessing = 0x000b,
|
||||
kTraceVideoCoding = 0x0010,
|
||||
kTraceVideoMixer = 0x0011,
|
||||
kTraceAudioDevice = 0x0012,
|
||||
kTraceVideoRenderer = 0x0014,
|
||||
kTraceVideoCapture = 0x0015,
|
||||
kTraceVideoPreocessing = 0x0016
|
||||
};
|
||||
|
||||
enum TraceLevel
|
||||
{
|
||||
kTraceNone = 0x0000, // no trace
|
||||
kTraceStateInfo = 0x0001,
|
||||
kTraceWarning = 0x0002,
|
||||
kTraceError = 0x0004,
|
||||
kTraceCritical = 0x0008,
|
||||
kTraceApiCall = 0x0010,
|
||||
kTraceDefault = 0x00ff,
|
||||
|
||||
kTraceModuleCall = 0x0020,
|
||||
kTraceMemory = 0x0100, // memory info
|
||||
kTraceTimer = 0x0200, // timing info
|
||||
kTraceStream = 0x0400, // "continuous" stream of data
|
||||
|
||||
// used for debug purposes
|
||||
kTraceDebug = 0x0800, // debug
|
||||
kTraceInfo = 0x1000, // debug info
|
||||
|
||||
kTraceAll = 0xffff
|
||||
};
|
||||
|
||||
// External Trace API
|
||||
class TraceCallback
|
||||
{
|
||||
public:
|
||||
virtual void Print(const TraceLevel level,
|
||||
const char *traceString,
|
||||
const int length) = 0;
|
||||
protected:
|
||||
virtual ~TraceCallback() {}
|
||||
TraceCallback() {}
|
||||
};
|
||||
|
||||
|
||||
enum FileFormats
|
||||
{
|
||||
kFileFormatWavFile = 1,
|
||||
kFileFormatCompressedFile = 2,
|
||||
kFileFormatAviFile = 3,
|
||||
kFileFormatPreencodedFile = 4,
|
||||
kFileFormatPcm16kHzFile = 7,
|
||||
kFileFormatPcm8kHzFile = 8,
|
||||
kFileFormatPcm32kHzFile = 9
|
||||
};
|
||||
|
||||
|
||||
enum ProcessingTypes
|
||||
{
|
||||
kPlaybackPerChannel = 0,
|
||||
kPlaybackAllChannelsMixed,
|
||||
kRecordingPerChannel,
|
||||
kRecordingAllChannelsMixed
|
||||
};
|
||||
|
||||
// Encryption enums
|
||||
enum CipherTypes
|
||||
{
|
||||
kCipherNull = 0,
|
||||
kCipherAes128CounterMode = 1
|
||||
};
|
||||
|
||||
enum AuthenticationTypes
|
||||
{
|
||||
kAuthNull = 0,
|
||||
kAuthHmacSha1 = 3
|
||||
};
|
||||
|
||||
enum SecurityLevels
|
||||
{
|
||||
kNoProtection = 0,
|
||||
kEncryption = 1,
|
||||
kAuthentication = 2,
|
||||
kEncryptionAndAuthentication = 3
|
||||
};
|
||||
|
||||
class Encryption
|
||||
{
|
||||
public:
|
||||
virtual void encrypt(
|
||||
int channel_no,
|
||||
unsigned char* in_data,
|
||||
unsigned char* out_data,
|
||||
int bytes_in,
|
||||
int* bytes_out) = 0;
|
||||
|
||||
virtual void decrypt(
|
||||
int channel_no,
|
||||
unsigned char* in_data,
|
||||
unsigned char* out_data,
|
||||
int bytes_in,
|
||||
int* bytes_out) = 0;
|
||||
|
||||
virtual void encrypt_rtcp(
|
||||
int channel_no,
|
||||
unsigned char* in_data,
|
||||
unsigned char* out_data,
|
||||
int bytes_in,
|
||||
int* bytes_out) = 0;
|
||||
|
||||
virtual void decrypt_rtcp(
|
||||
int channel_no,
|
||||
unsigned char* in_data,
|
||||
unsigned char* out_data,
|
||||
int bytes_in,
|
||||
int* bytes_out) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Encryption() {}
|
||||
Encryption() {}
|
||||
};
|
||||
|
||||
// External transport callback interface
|
||||
class Transport
|
||||
{
|
||||
public:
|
||||
virtual int SendPacket(int channel, const void *data, int len) = 0;
|
||||
virtual int SendRTCPPacket(int channel, const void *data, int len) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Transport() {}
|
||||
Transport() {}
|
||||
};
|
||||
|
||||
// ==================================================================
|
||||
// Voice specific types
|
||||
// ==================================================================
|
||||
|
||||
// Each codec supported can be described by this structure.
|
||||
struct CodecInst
|
||||
{
|
||||
int pltype;
|
||||
char plname[32];
|
||||
int plfreq;
|
||||
int pacsize;
|
||||
int channels;
|
||||
int rate;
|
||||
};
|
||||
|
||||
enum FrameType
|
||||
{
|
||||
kFrameEmpty = 0,
|
||||
kAudioFrameSpeech = 1,
|
||||
kAudioFrameCN = 2,
|
||||
kVideoFrameKey = 3, // independent frame
|
||||
kVideoFrameDelta = 4, // depends on the previus frame
|
||||
kVideoFrameGolden = 5, // depends on a old known previus frame
|
||||
kVideoFrameAltRef = 6
|
||||
};
|
||||
|
||||
// RTP
|
||||
enum {kRtpCsrcSize = 15}; // RFC 3550 page 13
|
||||
|
||||
enum RTPDirections
|
||||
{
|
||||
kRtpIncoming = 0,
|
||||
kRtpOutgoing
|
||||
};
|
||||
|
||||
enum PayloadFrequencies
|
||||
{
|
||||
kFreq8000Hz = 8000,
|
||||
kFreq16000Hz = 16000,
|
||||
kFreq32000Hz = 32000
|
||||
};
|
||||
|
||||
enum VadModes // degree of bandwidth reduction
|
||||
{
|
||||
kVadConventional = 0, // lowest reduction
|
||||
kVadAggressiveLow,
|
||||
kVadAggressiveMid,
|
||||
kVadAggressiveHigh // highest reduction
|
||||
};
|
||||
|
||||
struct NetworkStatistics // NETEQ statistics
|
||||
{
|
||||
// current jitter buffer size in ms
|
||||
WebRtc_UWord16 currentBufferSize;
|
||||
// preferred (optimal) buffer size in ms
|
||||
WebRtc_UWord16 preferredBufferSize;
|
||||
// loss rate (network + late) in percent (in Q14)
|
||||
WebRtc_UWord16 currentPacketLossRate;
|
||||
// late loss rate in percent (in Q14)
|
||||
WebRtc_UWord16 currentDiscardRate;
|
||||
// fraction (of original stream) of synthesized speech inserted through
|
||||
// expansion (in Q14)
|
||||
WebRtc_UWord16 currentExpandRate;
|
||||
// fraction of synthesized speech inserted through pre-emptive expansion
|
||||
// (in Q14)
|
||||
WebRtc_UWord16 currentPreemptiveRate;
|
||||
// fraction of data removed through acceleration (in Q14)
|
||||
WebRtc_UWord16 currentAccelerateRate;
|
||||
};
|
||||
|
||||
struct JitterStatistics
|
||||
{
|
||||
// smallest Jitter Buffer size during call in ms
|
||||
WebRtc_UWord32 jbMinSize;
|
||||
// largest Jitter Buffer size during call in ms
|
||||
WebRtc_UWord32 jbMaxSize;
|
||||
// the average JB size, measured over time - ms
|
||||
WebRtc_UWord32 jbAvgSize;
|
||||
// number of times the Jitter Buffer changed (using Accelerate or
|
||||
// Pre-emptive Expand)
|
||||
WebRtc_UWord32 jbChangeCount;
|
||||
// amount (in ms) of audio data received late
|
||||
WebRtc_UWord32 lateLossMs;
|
||||
// milliseconds removed to reduce jitter buffer size
|
||||
WebRtc_UWord32 accelerateMs;
|
||||
// milliseconds discarded through buffer flushing
|
||||
WebRtc_UWord32 flushedMs;
|
||||
// milliseconds of generated silence
|
||||
WebRtc_UWord32 generatedSilentMs;
|
||||
// milliseconds of synthetic audio data (non-background noise)
|
||||
WebRtc_UWord32 interpolatedVoiceMs;
|
||||
// milliseconds of synthetic audio data (background noise level)
|
||||
WebRtc_UWord32 interpolatedSilentMs;
|
||||
// count of tiny expansions in output audio
|
||||
WebRtc_UWord32 countExpandMoreThan120ms;
|
||||
// count of small expansions in output audio
|
||||
WebRtc_UWord32 countExpandMoreThan250ms;
|
||||
// count of medium expansions in output audio
|
||||
WebRtc_UWord32 countExpandMoreThan500ms;
|
||||
// count of long expansions in output audio
|
||||
WebRtc_UWord32 countExpandMoreThan2000ms;
|
||||
// duration of longest audio drop-out
|
||||
WebRtc_UWord32 longestExpandDurationMs;
|
||||
// count of times we got small network outage (inter-arrival time in
|
||||
// [500, 1000) ms)
|
||||
WebRtc_UWord32 countIAT500ms;
|
||||
// count of times we got medium network outage (inter-arrival time in
|
||||
// [1000, 2000) ms)
|
||||
WebRtc_UWord32 countIAT1000ms;
|
||||
// count of times we got large network outage (inter-arrival time >=
|
||||
// 2000 ms)
|
||||
WebRtc_UWord32 countIAT2000ms;
|
||||
// longest packet inter-arrival time in ms
|
||||
WebRtc_UWord32 longestIATms;
|
||||
// min time incoming Packet "waited" to be played
|
||||
WebRtc_UWord32 minPacketDelayMs;
|
||||
// max time incoming Packet "waited" to be played
|
||||
WebRtc_UWord32 maxPacketDelayMs;
|
||||
// avg time incoming Packet "waited" to be played
|
||||
WebRtc_UWord32 avgPacketDelayMs;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int min; // minumum
|
||||
int max; // maximum
|
||||
int average; // average
|
||||
} StatVal;
|
||||
|
||||
typedef struct // All levels are reported in dBm0
|
||||
{
|
||||
StatVal speech_rx; // long-term speech levels on receiving side
|
||||
StatVal speech_tx; // long-term speech levels on transmitting side
|
||||
StatVal noise_rx; // long-term noise/silence levels on receiving side
|
||||
StatVal noise_tx; // long-term noise/silence levels on transmitting side
|
||||
} LevelStatistics;
|
||||
|
||||
typedef struct // All levels are reported in dB
|
||||
{
|
||||
StatVal erl; // Echo Return Loss
|
||||
StatVal erle; // Echo Return Loss Enhancement
|
||||
StatVal rerl; // RERL = ERL + ERLE
|
||||
// Echo suppression inside EC at the point just before its NLP
|
||||
StatVal a_nlp;
|
||||
} EchoStatistics;
|
||||
|
||||
enum TelephoneEventDetectionMethods
|
||||
{
|
||||
kInBand = 0,
|
||||
kOutOfBand = 1,
|
||||
kInAndOutOfBand = 2
|
||||
};
|
||||
|
||||
enum NsModes // type of Noise Suppression
|
||||
{
|
||||
kNsUnchanged = 0, // previously set mode
|
||||
kNsDefault, // platform default
|
||||
kNsConference, // conferencing default
|
||||
kNsLowSuppression, // lowest suppression
|
||||
kNsModerateSuppression,
|
||||
kNsHighSuppression,
|
||||
kNsVeryHighSuppression, // highest suppression
|
||||
};
|
||||
|
||||
enum AgcModes // type of Automatic Gain Control
|
||||
{
|
||||
kAgcUnchanged = 0, // previously set mode
|
||||
kAgcDefault, // platform default
|
||||
// adaptive mode for use when analog volume control exists (e.g. for
|
||||
// PC softphone)
|
||||
kAgcAdaptiveAnalog,
|
||||
// scaling takes place in the digital domain (e.g. for conference servers
|
||||
// and embedded devices)
|
||||
kAgcAdaptiveDigital,
|
||||
// can be used on embedded devices where the the capture signal is level
|
||||
// is predictable
|
||||
kAgcFixedDigital
|
||||
};
|
||||
|
||||
// EC modes
|
||||
enum EcModes // type of Echo Control
|
||||
{
|
||||
kEcUnchanged = 0, // previously set mode
|
||||
kEcDefault, // platform default
|
||||
kEcConference, // conferencing default (aggressive AEC)
|
||||
kEcAec, // Acoustic Echo Cancellation
|
||||
kEcAecm, // AEC mobile
|
||||
};
|
||||
|
||||
// AECM modes
|
||||
enum AecmModes // mode of AECM
|
||||
{
|
||||
kAecmQuietEarpieceOrHeadset = 0,
|
||||
// Quiet earpiece or headset use
|
||||
kAecmEarpiece, // most earpiece use
|
||||
kAecmLoudEarpiece, // Loud earpiece or quiet speakerphone use
|
||||
kAecmSpeakerphone, // most speakerphone use (default)
|
||||
kAecmLoudSpeakerphone // Loud speakerphone
|
||||
};
|
||||
|
||||
// AGC configuration
|
||||
typedef struct
|
||||
{
|
||||
unsigned short targetLeveldBOv;
|
||||
unsigned short digitalCompressionGaindB;
|
||||
bool limiterEnable;
|
||||
} AgcConfig; // AGC configuration parameters
|
||||
|
||||
enum StereoChannel
|
||||
{
|
||||
kStereoLeft = 0,
|
||||
kStereoRight,
|
||||
kStereoBoth
|
||||
};
|
||||
|
||||
// Audio device layers
|
||||
enum AudioLayers
|
||||
{
|
||||
kAudioPlatformDefault = 0,
|
||||
kAudioWindowsWave = 1,
|
||||
kAudioWindowsCore = 2,
|
||||
kAudioLinuxAlsa = 3,
|
||||
kAudioLinuxPulse = 4
|
||||
};
|
||||
|
||||
enum NetEqModes // NetEQ playout configurations
|
||||
{
|
||||
// Optimized trade-off between low delay and jitter robustness for two-way
|
||||
// communication.
|
||||
kNetEqDefault = 0,
|
||||
// Improved jitter robustness at the cost of increased delay. Can be
|
||||
// used in one-way communication.
|
||||
kNetEqStreaming = 1,
|
||||
// Optimzed for decodability of fax signals rather than for perceived audio
|
||||
// quality.
|
||||
kNetEqFax = 2,
|
||||
};
|
||||
|
||||
enum NetEqBgnModes // NetEQ Background Noise (BGN) configurations
|
||||
{
|
||||
// BGN is always on and will be generated when the incoming RTP stream
|
||||
// stops (default).
|
||||
kBgnOn = 0,
|
||||
// The BGN is faded to zero (complete silence) after a few seconds.
|
||||
kBgnFade = 1,
|
||||
// BGN is not used at all. Silence is produced after speech extrapolation
|
||||
// has faded.
|
||||
kBgnOff = 2,
|
||||
};
|
||||
|
||||
enum OnHoldModes // On Hold direction
|
||||
{
|
||||
kHoldSendAndPlay = 0, // Put both sending and playing in on-hold state.
|
||||
kHoldSendOnly, // Put only sending in on-hold state.
|
||||
kHoldPlayOnly // Put only playing in on-hold state.
|
||||
};
|
||||
|
||||
enum AmrMode
|
||||
{
|
||||
kRfc3267BwEfficient = 0,
|
||||
kRfc3267OctetAligned = 1,
|
||||
kRfc3267FileStorage = 2,
|
||||
};
|
||||
|
||||
// ==================================================================
|
||||
// Video specific types
|
||||
// ==================================================================
|
||||
|
||||
// Raw video types
|
||||
enum RawVideoType
|
||||
{
|
||||
kVideoI420 = 0,
|
||||
kVideoYV12 = 1,
|
||||
kVideoYUY2 = 2,
|
||||
kVideoUYVY = 3,
|
||||
kVideoIYUV = 4,
|
||||
kVideoARGB = 5,
|
||||
kVideoRGB24 = 6,
|
||||
kVideoRGB565 = 7,
|
||||
kVideoARGB4444 = 8,
|
||||
kVideoARGB1555 = 9,
|
||||
kVideoMJPEG = 10,
|
||||
kVideoNV12 = 11,
|
||||
kVideoNV21 = 12,
|
||||
kVideoUnknown = 99
|
||||
};
|
||||
|
||||
// Video codec
|
||||
enum { kConfigParameterSize = 128};
|
||||
enum { kPayloadNameSize = 32};
|
||||
enum { kMaxSimulcastStreams = 4};
|
||||
|
||||
// H.263 specific
|
||||
struct VideoCodecH263
|
||||
{
|
||||
char quality;
|
||||
};
|
||||
|
||||
// H.264 specific
|
||||
enum H264Packetization
|
||||
{
|
||||
kH264SingleMode = 0,
|
||||
kH264NonInterleavedMode = 1
|
||||
};
|
||||
|
||||
enum VideoCodecComplexity
|
||||
{
|
||||
kComplexityNormal = 0,
|
||||
kComplexityHigh = 1,
|
||||
kComplexityHigher = 2,
|
||||
kComplexityMax = 3
|
||||
};
|
||||
|
||||
enum VideoCodecProfile
|
||||
{
|
||||
kProfileBase = 0x00,
|
||||
kProfileMain = 0x01
|
||||
};
|
||||
|
||||
struct VideoCodecH264
|
||||
{
|
||||
H264Packetization packetization;
|
||||
VideoCodecComplexity complexity;
|
||||
VideoCodecProfile profile;
|
||||
char level;
|
||||
char quality;
|
||||
|
||||
bool useFMO;
|
||||
|
||||
unsigned char configParameters[kConfigParameterSize];
|
||||
unsigned char configParametersSize;
|
||||
};
|
||||
|
||||
// VP8 specific
|
||||
struct VideoCodecVP8
|
||||
{
|
||||
bool pictureLossIndicationOn;
|
||||
bool feedbackModeOn;
|
||||
VideoCodecComplexity complexity;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
};
|
||||
|
||||
// MPEG-4 specific
|
||||
struct VideoCodecMPEG4
|
||||
{
|
||||
unsigned char configParameters[kConfigParameterSize];
|
||||
unsigned char configParametersSize;
|
||||
char level;
|
||||
};
|
||||
|
||||
// Unknown specific
|
||||
struct VideoCodecGeneric
|
||||
{
|
||||
};
|
||||
|
||||
// Video codec types
|
||||
enum VideoCodecType
|
||||
{
|
||||
kVideoCodecH263,
|
||||
kVideoCodecH264,
|
||||
kVideoCodecVP8,
|
||||
kVideoCodecMPEG4,
|
||||
kVideoCodecI420,
|
||||
kVideoCodecRED,
|
||||
kVideoCodecULPFEC,
|
||||
kVideoCodecUnknown
|
||||
};
|
||||
|
||||
union VideoCodecUnion
|
||||
{
|
||||
VideoCodecH263 H263;
|
||||
VideoCodecH264 H264;
|
||||
VideoCodecVP8 VP8;
|
||||
VideoCodecMPEG4 MPEG4;
|
||||
VideoCodecGeneric Generic;
|
||||
};
|
||||
|
||||
/*
|
||||
* Simulcast is when the same stream is encoded multiple times with different
|
||||
* settings such as resolution.
|
||||
*/
|
||||
struct SimulcastStream
|
||||
{
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
unsigned int maxBitrate;
|
||||
unsigned int qpMax; // minimum quality
|
||||
};
|
||||
|
||||
// Common video codec properties
|
||||
struct VideoCodec
|
||||
{
|
||||
VideoCodecType codecType;
|
||||
char plName[kPayloadNameSize];
|
||||
unsigned char plType;
|
||||
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
|
||||
unsigned int startBitrate;
|
||||
unsigned int maxBitrate;
|
||||
unsigned int minBitrate;
|
||||
unsigned char maxFramerate;
|
||||
|
||||
VideoCodecUnion codecSpecific;
|
||||
|
||||
unsigned int qpMax;
|
||||
unsigned char numberOfSimulcastStreams;
|
||||
SimulcastStream simulcastStream[kMaxSimulcastStreams];
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_COMMON_TYPES_H
|
@ -1,7 +0,0 @@
|
||||
henrike@webrtc.org
|
||||
pwestin@webrtc.org
|
||||
perkj@webrtc.org
|
||||
henrika@webrtc.org
|
||||
henrikg@webrtc.org
|
||||
mflodman@webrtc.org
|
||||
niklas.enbom@webrtc.org
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
|
||||
|
||||
// If the critical section is heavily contended it may be beneficial to use
|
||||
// read/write locks instead.
|
||||
|
||||
#include "common_types.h"
|
||||
|
||||
namespace webrtc {
|
||||
class CriticalSectionWrapper
|
||||
{
|
||||
public:
|
||||
// Factory method, constructor disabled
|
||||
static CriticalSectionWrapper* CreateCriticalSection();
|
||||
|
||||
virtual ~CriticalSectionWrapper() {}
|
||||
|
||||
// Tries to grab lock, beginning of a critical section. Will wait for the
|
||||
// lock to become available if the grab failed.
|
||||
virtual void Enter() = 0;
|
||||
|
||||
// Returns a grabbed lock, end of critical section.
|
||||
virtual void Leave() = 0;
|
||||
};
|
||||
|
||||
// RAII extension of the critical section. Prevents Enter/Leave missmatches and
|
||||
// provides more compact critical section syntax.
|
||||
class CriticalSectionScoped
|
||||
{
|
||||
public:
|
||||
CriticalSectionScoped(CriticalSectionWrapper& critsec)
|
||||
:
|
||||
_ptrCritSec(&critsec)
|
||||
{
|
||||
_ptrCritSec->Enter();
|
||||
}
|
||||
|
||||
~CriticalSectionScoped()
|
||||
{
|
||||
if (_ptrCritSec)
|
||||
{
|
||||
Leave();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Leave()
|
||||
{
|
||||
_ptrCritSec->Leave();
|
||||
_ptrCritSec = 0;
|
||||
}
|
||||
|
||||
CriticalSectionWrapper* _ptrCritSec;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
|
142
src/typedefs.h
142
src/typedefs.h
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// This file contains platform-specific typedefs and defines.
|
||||
|
||||
#ifndef WEBRTC_TYPEDEFS_H_
|
||||
#define WEBRTC_TYPEDEFS_H_
|
||||
|
||||
// Reserved words definitions
|
||||
// TODO(andrew): Look at removing these.
|
||||
#define WEBRTC_EXTERN extern
|
||||
#define G_CONST const
|
||||
#define WEBRTC_INLINE extern __inline
|
||||
|
||||
// Define WebRTC preprocessor identifiers based on the current build platform.
|
||||
// TODO(andrew): Clean these up. We can probably remove everything in this
|
||||
// block.
|
||||
// - TARGET_MAC_INTEL and TARGET_MAC aren't used anywhere.
|
||||
// - In the few places where TARGET_PC is used, it should be replaced by
|
||||
// something more specific.
|
||||
// - Do we really support PowerPC? Probably not. Remove WEBRTC_MAC_INTEL
|
||||
// from build/common.gypi as well.
|
||||
#if defined(WIN32)
|
||||
// Windows & Windows Mobile.
|
||||
#if !defined(WEBRTC_TARGET_PC)
|
||||
#define WEBRTC_TARGET_PC
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
// Mac OS X.
|
||||
#if defined(__LITTLE_ENDIAN__ )
|
||||
#if !defined(WEBRTC_TARGET_MAC_INTEL)
|
||||
#define WEBRTC_TARGET_MAC_INTEL
|
||||
#endif
|
||||
#else
|
||||
#if !defined(WEBRTC_TARGET_MAC)
|
||||
#define WEBRTC_TARGET_MAC
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
// Linux etc.
|
||||
#if !defined(WEBRTC_TARGET_PC)
|
||||
#define WEBRTC_TARGET_PC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Derived from Chromium's build/build_config.h
|
||||
// Processor architecture detection. For more info on what's defined, see:
|
||||
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
|
||||
// http://www.agner.org/optimize/calling_conventions.pdf
|
||||
// or with gcc, run: "echo | gcc -E -dM -"
|
||||
// TODO(andrew): replace WEBRTC_LITTLE_ENDIAN with WEBRTC_ARCH_LITTLE_ENDIAN?
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define WEBRTC_ARCH_X86_FAMILY
|
||||
#define WEBRTC_ARCH_X86_64
|
||||
#define WEBRTC_ARCH_64_BITS
|
||||
#define WEBRTC_ARCH_LITTLE_ENDIAN
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
#define WEBRTC_ARCH_X86_FAMILY
|
||||
#define WEBRTC_ARCH_X86
|
||||
#define WEBRTC_ARCH_32_BITS
|
||||
#define WEBRTC_ARCH_LITTLE_ENDIAN
|
||||
#elif defined(__ARMEL__)
|
||||
// TODO(andrew): We'd prefer to control platform defines here, but this is
|
||||
// currently provided by the Android makefiles. Commented to avoid duplicate
|
||||
// definition warnings.
|
||||
//#define WEBRTC_ARCH_ARM
|
||||
// TODO(andrew): Chromium uses the following two defines. Should we switch?
|
||||
//#define WEBRTC_ARCH_ARM_FAMILY
|
||||
//#define WEBRTC_ARCH_ARMEL
|
||||
#define WEBRTC_ARCH_32_BITS
|
||||
#define WEBRTC_ARCH_LITTLE_ENDIAN
|
||||
#else
|
||||
#error Please add support for your architecture in typedefs.h
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__) || defined(_MSC_VER)
|
||||
#define WEBRTC_USE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(WEBRTC_TARGET_PC)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <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_
|
227
webrtc/base/checks.h
Normal file
227
webrtc/base/checks.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2006 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_CHECKS_H_
|
||||
#define WEBRTC_BASE_CHECKS_H_
|
||||
|
||||
#include <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_
|
34
webrtc/base/constructormagic.h
Normal file
34
webrtc/base/constructormagic.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_CONSTRUCTORMAGIC_H_
|
||||
#define WEBRTC_BASE_CONSTRUCTORMAGIC_H_
|
||||
|
||||
// Put this in the declarations for a class to be unassignable.
|
||||
#define RTC_DISALLOW_ASSIGN(TypeName) \
|
||||
void operator=(const TypeName&) = delete
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions. This should
|
||||
// be used in the declarations for a class.
|
||||
#define RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&) = delete; \
|
||||
RTC_DISALLOW_ASSIGN(TypeName)
|
||||
|
||||
// A macro to disallow all the implicit constructors, namely the default
|
||||
// constructor, copy constructor and operator= functions.
|
||||
//
|
||||
// This should be used in the declarations for a class that wants to prevent
|
||||
// anyone from instantiating it. This is especially useful for classes
|
||||
// containing only static methods.
|
||||
#define RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
|
||||
TypeName() = delete; \
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(TypeName)
|
||||
|
||||
#endif // WEBRTC_BASE_CONSTRUCTORMAGIC_H_
|
636
webrtc/base/scoped_ptr.h
Normal file
636
webrtc/base/scoped_ptr.h
Normal file
@ -0,0 +1,636 @@
|
||||
/*
|
||||
* Copyright 2012 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// Borrowed from Chromium's src/base/memory/scoped_ptr.h.
|
||||
|
||||
// Scopers help you manage ownership of a pointer, helping you easily manage a
|
||||
// pointer within a scope, and automatically destroying the pointer at the end
|
||||
// of a scope. There are two main classes you will use, which correspond to the
|
||||
// operators new/delete and new[]/delete[].
|
||||
//
|
||||
// Example usage (scoped_ptr<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__
|
114
webrtc/base/template_util.h
Normal file
114
webrtc/base/template_util.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// Borrowed from Chromium's src/base/template_util.h.
|
||||
|
||||
#ifndef WEBRTC_BASE_TEMPLATE_UTIL_H_
|
||||
#define WEBRTC_BASE_TEMPLATE_UTIL_H_
|
||||
|
||||
#include <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_
|
243
webrtc/common_audio/BUILD.gn
Normal file
243
webrtc/common_audio/BUILD.gn
Normal file
@ -0,0 +1,243 @@
|
||||
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("//build/config/arm.gni")
|
||||
import("../build/webrtc.gni")
|
||||
|
||||
config("common_audio_config") {
|
||||
include_dirs = [
|
||||
"resampler/include",
|
||||
"signal_processing/include",
|
||||
"vad/include",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("common_audio") {
|
||||
sources = [
|
||||
"audio_converter.cc",
|
||||
"audio_converter.h",
|
||||
"audio_ring_buffer.cc",
|
||||
"audio_ring_buffer.h",
|
||||
"audio_util.cc",
|
||||
"blocker.cc",
|
||||
"blocker.h",
|
||||
"channel_buffer.cc",
|
||||
"channel_buffer.h",
|
||||
"fft4g.c",
|
||||
"fft4g.h",
|
||||
"fir_filter.cc",
|
||||
"fir_filter.h",
|
||||
"fir_filter_neon.h",
|
||||
"fir_filter_sse.h",
|
||||
"include/audio_util.h",
|
||||
"lapped_transform.cc",
|
||||
"lapped_transform.h",
|
||||
"real_fourier.cc",
|
||||
"real_fourier.h",
|
||||
"real_fourier_ooura.cc",
|
||||
"real_fourier_ooura.h",
|
||||
"resampler/include/push_resampler.h",
|
||||
"resampler/include/resampler.h",
|
||||
"resampler/push_resampler.cc",
|
||||
"resampler/push_sinc_resampler.cc",
|
||||
"resampler/push_sinc_resampler.h",
|
||||
"resampler/resampler.cc",
|
||||
"resampler/sinc_resampler.cc",
|
||||
"resampler/sinc_resampler.h",
|
||||
"ring_buffer.c",
|
||||
"ring_buffer.h",
|
||||
"signal_processing/auto_corr_to_refl_coef.c",
|
||||
"signal_processing/auto_correlation.c",
|
||||
"signal_processing/complex_fft_tables.h",
|
||||
"signal_processing/copy_set_operations.c",
|
||||
"signal_processing/cross_correlation.c",
|
||||
"signal_processing/division_operations.c",
|
||||
"signal_processing/dot_product_with_scale.c",
|
||||
"signal_processing/downsample_fast.c",
|
||||
"signal_processing/energy.c",
|
||||
"signal_processing/filter_ar.c",
|
||||
"signal_processing/filter_ma_fast_q12.c",
|
||||
"signal_processing/get_hanning_window.c",
|
||||
"signal_processing/get_scaling_square.c",
|
||||
"signal_processing/ilbc_specific_functions.c",
|
||||
"signal_processing/include/real_fft.h",
|
||||
"signal_processing/include/signal_processing_library.h",
|
||||
"signal_processing/include/spl_inl.h",
|
||||
"signal_processing/levinson_durbin.c",
|
||||
"signal_processing/lpc_to_refl_coef.c",
|
||||
"signal_processing/min_max_operations.c",
|
||||
"signal_processing/randomization_functions.c",
|
||||
"signal_processing/real_fft.c",
|
||||
"signal_processing/refl_coef_to_lpc.c",
|
||||
"signal_processing/resample.c",
|
||||
"signal_processing/resample_48khz.c",
|
||||
"signal_processing/resample_by_2.c",
|
||||
"signal_processing/resample_by_2_internal.c",
|
||||
"signal_processing/resample_by_2_internal.h",
|
||||
"signal_processing/resample_fractional.c",
|
||||
"signal_processing/spl_init.c",
|
||||
"signal_processing/spl_sqrt.c",
|
||||
"signal_processing/splitting_filter.c",
|
||||
"signal_processing/sqrt_of_one_minus_x_squared.c",
|
||||
"signal_processing/vector_scaling_operations.c",
|
||||
"sparse_fir_filter.cc",
|
||||
"sparse_fir_filter.h",
|
||||
"vad/include/vad.h",
|
||||
"vad/include/webrtc_vad.h",
|
||||
"vad/vad.cc",
|
||||
"vad/vad_core.c",
|
||||
"vad/vad_core.h",
|
||||
"vad/vad_filterbank.c",
|
||||
"vad/vad_filterbank.h",
|
||||
"vad/vad_gmm.c",
|
||||
"vad/vad_gmm.h",
|
||||
"vad/vad_sp.c",
|
||||
"vad/vad_sp.h",
|
||||
"vad/webrtc_vad.c",
|
||||
"wav_file.cc",
|
||||
"wav_file.h",
|
||||
"wav_header.cc",
|
||||
"wav_header.h",
|
||||
"window_generator.cc",
|
||||
"window_generator.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"../system_wrappers",
|
||||
]
|
||||
|
||||
defines = []
|
||||
if (rtc_use_openmax_dl) {
|
||||
sources += [
|
||||
"real_fourier_openmax.cc",
|
||||
"real_fourier_openmax.h",
|
||||
]
|
||||
defines += [ "RTC_USE_OPENMAX_DL" ]
|
||||
if (rtc_build_openmax_dl) {
|
||||
deps += [ "//third_party/openmax_dl/dl" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (current_cpu == "arm") {
|
||||
sources += [
|
||||
"signal_processing/complex_bit_reverse_arm.S",
|
||||
"signal_processing/spl_sqrt_floor_arm.S",
|
||||
]
|
||||
|
||||
if (arm_version >= 7) {
|
||||
sources += [ "signal_processing/filter_ar_fast_q12_armv7.S" ]
|
||||
} else {
|
||||
sources += [ "signal_processing/filter_ar_fast_q12.c" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (rtc_build_with_neon) {
|
||||
deps += [ ":common_audio_neon" ]
|
||||
}
|
||||
|
||||
if (current_cpu == "mipsel") {
|
||||
sources += [
|
||||
"signal_processing/complex_bit_reverse_mips.c",
|
||||
"signal_processing/complex_fft_mips.c",
|
||||
"signal_processing/cross_correlation_mips.c",
|
||||
"signal_processing/downsample_fast_mips.c",
|
||||
"signal_processing/filter_ar_fast_q12_mips.c",
|
||||
"signal_processing/include/spl_inl_mips.h",
|
||||
"signal_processing/min_max_operations_mips.c",
|
||||
"signal_processing/resample_by_2_mips.c",
|
||||
"signal_processing/spl_sqrt_floor_mips.c",
|
||||
]
|
||||
if (mips_dsp_rev > 0) {
|
||||
sources += [ "signal_processing/vector_scaling_operations_mips.c" ]
|
||||
}
|
||||
} else {
|
||||
sources += [ "signal_processing/complex_fft.c" ]
|
||||
}
|
||||
|
||||
if (current_cpu != "arm" && current_cpu != "mipsel") {
|
||||
sources += [
|
||||
"signal_processing/complex_bit_reverse.c",
|
||||
"signal_processing/filter_ar_fast_q12.c",
|
||||
"signal_processing/spl_sqrt_floor.c",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
cflags = [ "/wd4334" ] # Ignore warning on shift operator promotion.
|
||||
}
|
||||
|
||||
configs += [ "..:common_config" ]
|
||||
|
||||
public_configs = [
|
||||
"..:common_inherited_config",
|
||||
":common_audio_config",
|
||||
]
|
||||
|
||||
if (is_clang) {
|
||||
# Suppress warnings from Chrome's Clang plugins.
|
||||
# See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
|
||||
configs -= [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
|
||||
if (current_cpu == "x86" || current_cpu == "x64") {
|
||||
deps += [ ":common_audio_sse2" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (current_cpu == "x86" || current_cpu == "x64") {
|
||||
source_set("common_audio_sse2") {
|
||||
sources = [
|
||||
"fir_filter_sse.cc",
|
||||
"resampler/sinc_resampler_sse.cc",
|
||||
]
|
||||
|
||||
if (is_posix) {
|
||||
cflags = [ "-msse2" ]
|
||||
}
|
||||
|
||||
configs += [ "..:common_inherited_config" ]
|
||||
|
||||
if (is_clang) {
|
||||
# Suppress warnings from Chrome's Clang plugins.
|
||||
# See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
|
||||
configs -= [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rtc_build_with_neon) {
|
||||
source_set("common_audio_neon") {
|
||||
sources = [
|
||||
"fir_filter_neon.cc",
|
||||
"resampler/sinc_resampler_neon.cc",
|
||||
"signal_processing/cross_correlation_neon.c",
|
||||
"signal_processing/downsample_fast_neon.c",
|
||||
"signal_processing/min_max_operations_neon.c",
|
||||
]
|
||||
|
||||
if (current_cpu != "arm64") {
|
||||
# Enable compilation for the NEON instruction set. This is needed
|
||||
# since //build/config/arm.gni only enables NEON for iOS, not Android.
|
||||
# This provides the same functionality as webrtc/build/arm_neon.gypi.
|
||||
configs -= [ "//build/config/compiler:compiler_arm_fpu" ]
|
||||
cflags = [ "-mfpu=neon" ]
|
||||
}
|
||||
|
||||
# Disable LTO on NEON targets due to compiler bug.
|
||||
# TODO(fdegans): Enable this. See crbug.com/408997.
|
||||
if (rtc_use_lto) {
|
||||
cflags -= [
|
||||
"-flto",
|
||||
"-ffat-lto-objects",
|
||||
]
|
||||
}
|
||||
|
||||
configs += [ "..:common_config" ]
|
||||
public_configs = [ "..:common_inherited_config" ]
|
||||
}
|
||||
}
|
74
webrtc/common_audio/Makefile.am
Normal file
74
webrtc/common_audio/Makefile.am
Normal file
@ -0,0 +1,74 @@
|
||||
noinst_LTLIBRARIES = libcommon_audio.la
|
||||
|
||||
libcommon_audio_la_SOURCES = signal_processing/include/real_fft.h \
|
||||
signal_processing/include/signal_processing_library.h \
|
||||
signal_processing/include/spl_inl.h \
|
||||
signal_processing/include/spl_inl_armv7.h \
|
||||
signal_processing/include/spl_inl_mips.h \
|
||||
signal_processing/auto_corr_to_refl_coef.c \
|
||||
signal_processing/auto_correlation.c \
|
||||
signal_processing/complex_bit_reverse.c \
|
||||
signal_processing/complex_fft.c \
|
||||
signal_processing/complex_fft_tables.h \
|
||||
signal_processing/copy_set_operations.c \
|
||||
signal_processing/cross_correlation.c \
|
||||
signal_processing/division_operations.c \
|
||||
signal_processing/dot_product_with_scale.c \
|
||||
signal_processing/downsample_fast.c \
|
||||
signal_processing/energy.c \
|
||||
signal_processing/filter_ar.c \
|
||||
signal_processing/filter_ar_fast_q12.c \
|
||||
signal_processing/filter_ma_fast_q12.c \
|
||||
signal_processing/get_hanning_window.c \
|
||||
signal_processing/get_scaling_square.c \
|
||||
signal_processing/ilbc_specific_functions.c \
|
||||
signal_processing/levinson_durbin.c \
|
||||
signal_processing/lpc_to_refl_coef.c \
|
||||
signal_processing/min_max_operations.c \
|
||||
signal_processing/randomization_functions.c \
|
||||
signal_processing/real_fft.c \
|
||||
signal_processing/refl_coef_to_lpc.c \
|
||||
signal_processing/resample.c \
|
||||
signal_processing/resample_48khz.c \
|
||||
signal_processing/resample_by_2.c \
|
||||
signal_processing/resample_by_2_internal.c \
|
||||
signal_processing/resample_by_2_internal.h \
|
||||
signal_processing/resample_fractional.c \
|
||||
signal_processing/spl_init.c \
|
||||
signal_processing/spl_sqrt.c \
|
||||
signal_processing/spl_sqrt_floor.c \
|
||||
signal_processing/splitting_filter.c \
|
||||
signal_processing/sqrt_of_one_minus_x_squared.c \
|
||||
signal_processing/vector_scaling_operations.c \
|
||||
vad/include/vad.h \
|
||||
vad/include/webrtc_vad.h \
|
||||
vad/vad.cc \
|
||||
vad/vad_core.c \
|
||||
vad/vad_core.h \
|
||||
vad/vad_filterbank.c \
|
||||
vad/vad_filterbank.h \
|
||||
vad/vad_gmm.c \
|
||||
vad/vad_gmm.h \
|
||||
vad/vad_sp.c \
|
||||
vad/vad_sp.h \
|
||||
vad/webrtc_vad.c
|
||||
|
||||
libcommon_audio_la_CFLAGS = $(AM_CFLAGS) $(COMMON_CFLAGS)
|
||||
libcommon_audio_la_CXXFLAGS = $(AM_CXXFLAGS) $(COMMON_CXXFLAGS)
|
||||
|
||||
# FIXME:
|
||||
# if ARM - signal_processing/complex_bit_reverse_arm.S
|
||||
# signal_processing/spl_sqrt_floor_arm.S
|
||||
# ARM7 - signal_processing/filter_ar_fast_q12_armv7.S
|
||||
# NEON - signal_processing/cross_correlation_neon.c
|
||||
# signal_processing/downsample_fast_neon.c
|
||||
# signal_processing/min_max_operations_neon.c
|
||||
# if MIPS - signal_processing/complex_bit_reverse_mips.c
|
||||
# signal_processing/complex_fft_mips.c
|
||||
# signal_processing/cross_correlation_mips.c
|
||||
# signal_processing/downsample_fast_mips.c
|
||||
# signal_processing/filter_ar_fast_q12_mips.c
|
||||
# signal_processing/min_max_operations_mips.c
|
||||
# signal_processing/resample_by_2_mips.c
|
||||
# signal_processing/spl_sqrt_floor_mips.c
|
||||
# signal_processing/vector_scaling_operations_mips.c
|
@ -15,15 +15,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K)
|
||||
void WebRtcSpl_AutoCorrToReflCoef(const int32_t *R, int use_order, int16_t *K)
|
||||
{
|
||||
int i, n;
|
||||
WebRtc_Word16 tmp;
|
||||
G_CONST WebRtc_Word32 *rptr;
|
||||
WebRtc_Word32 L_num, L_den;
|
||||
WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
|
||||
int16_t tmp;
|
||||
const int32_t *rptr;
|
||||
int32_t L_num, L_den;
|
||||
int16_t *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
|
||||
P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
|
||||
|
||||
// Initialize loop and pointers.
|
||||
@ -36,13 +36,13 @@ void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRt
|
||||
|
||||
// First loop; n=0. Determine shifting.
|
||||
tmp = WebRtcSpl_NormW32(*R);
|
||||
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
|
||||
*acfptr = (int16_t)((*rptr++ << tmp) >> 16);
|
||||
*pptr++ = *acfptr++;
|
||||
|
||||
// Initialize ACF, P and W.
|
||||
for (i = 1; i <= use_order; i++)
|
||||
{
|
||||
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
|
||||
*acfptr = (int16_t)((*rptr++ << tmp) >> 16);
|
||||
*wptr++ = *acfptr;
|
||||
*pptr++ = *acfptr++;
|
||||
}
|
||||
@ -87,16 +87,16 @@ void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRt
|
||||
// Schur recursion.
|
||||
pptr = P;
|
||||
wptr = w1ptr;
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );
|
||||
tmp = (int16_t)(((int32_t)*p1ptr * (int32_t)*K + 16384) >> 15);
|
||||
*pptr = WebRtcSpl_AddSatW16(*pptr, tmp);
|
||||
pptr++;
|
||||
for (i = 1; i <= use_order - n; i++)
|
||||
{
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );
|
||||
tmp = (int16_t)(((int32_t)*wptr * (int32_t)*K + 16384) >> 15);
|
||||
*pptr = WebRtcSpl_AddSatW16(*(pptr + 1), tmp);
|
||||
pptr++;
|
||||
tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);
|
||||
*wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
|
||||
tmp = (int16_t)(((int32_t)*pptr * (int32_t)*K + 16384) >> 15);
|
||||
*wptr = WebRtcSpl_AddSatW16(*wptr, tmp);
|
||||
wptr++;
|
||||
}
|
||||
}
|
65
webrtc/common_audio/signal_processing/auto_correlation.c
Normal file
65
webrtc/common_audio/signal_processing/auto_correlation.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#include <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;
|
||||
}
|
108
webrtc/common_audio/signal_processing/complex_bit_reverse.c
Normal file
108
webrtc/common_audio/signal_processing/complex_bit_reverse.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
/* Tables for data buffer indexes that are bit reversed and thus need to be
|
||||
* swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap
|
||||
* operations, while index_7[{1, 3, 5, ...}] are for the right side of the
|
||||
* operation. Same for index_8.
|
||||
*/
|
||||
|
||||
/* Indexes for the case of stages == 7. */
|
||||
static const int16_t index_7[112] = {
|
||||
1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104,
|
||||
12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52,
|
||||
23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98,
|
||||
37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70,
|
||||
51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69,
|
||||
81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125,
|
||||
103, 115, 111, 123
|
||||
};
|
||||
|
||||
/* Indexes for the case of stages == 8. */
|
||||
static const int16_t index_8[240] = {
|
||||
1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80,
|
||||
11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20,
|
||||
40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184,
|
||||
30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41,
|
||||
148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76,
|
||||
51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62,
|
||||
124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82,
|
||||
75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87,
|
||||
234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101,
|
||||
166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142,
|
||||
115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131,
|
||||
193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201,
|
||||
149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171,
|
||||
213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227,
|
||||
203, 211, 207, 243, 215, 235, 223, 251, 239, 247
|
||||
};
|
||||
|
||||
void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) {
|
||||
/* For any specific value of stages, we know exactly the indexes that are
|
||||
* bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of
|
||||
* stages are 7 and 8, so we use tables to save unnecessary iterations and
|
||||
* calculations for these two cases.
|
||||
*/
|
||||
if (stages == 7 || stages == 8) {
|
||||
int m = 0;
|
||||
int length = 112;
|
||||
const int16_t* index = index_7;
|
||||
|
||||
if (stages == 8) {
|
||||
length = 240;
|
||||
index = index_8;
|
||||
}
|
||||
|
||||
/* Decimation in time. Swap the elements with bit-reversed indexes. */
|
||||
for (m = 0; m < length; m += 2) {
|
||||
/* We declare a int32_t* type pointer, to load both the 16-bit real
|
||||
* and imaginary elements from complex_data in one instruction, reducing
|
||||
* complexity.
|
||||
*/
|
||||
int32_t* complex_data_ptr = (int32_t*)complex_data;
|
||||
int32_t temp = 0;
|
||||
|
||||
temp = complex_data_ptr[index[m]]; /* Real and imaginary */
|
||||
complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]];
|
||||
complex_data_ptr[index[m + 1]] = temp;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int m = 0, mr = 0, l = 0;
|
||||
int n = 1 << stages;
|
||||
int nn = n - 1;
|
||||
|
||||
/* Decimation in time - re-order data */
|
||||
for (m = 1; m <= nn; ++m) {
|
||||
int32_t* complex_data_ptr = (int32_t*)complex_data;
|
||||
int32_t temp = 0;
|
||||
|
||||
/* Find out indexes that are bit-reversed. */
|
||||
l = n;
|
||||
do {
|
||||
l >>= 1;
|
||||
} while (l > nn - mr);
|
||||
mr = (mr & (l - 1)) + l;
|
||||
|
||||
if (mr <= m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Swap the elements with bit-reversed indexes.
|
||||
* This is similar to the loop in the stages == 7 or 8 cases.
|
||||
*/
|
||||
temp = complex_data_ptr[m]; /* Real and imaginary */
|
||||
complex_data_ptr[m] = complex_data_ptr[mr];
|
||||
complex_data_ptr[mr] = temp;
|
||||
}
|
||||
}
|
||||
}
|
119
webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S
Normal file
119
webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S
Normal file
@ -0,0 +1,119 @@
|
||||
@
|
||||
@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
@
|
||||
@ Use of this source code is governed by a BSD-style license
|
||||
@ that can be found in the LICENSE file in the root of the source
|
||||
@ tree. An additional intellectual property rights grant can be found
|
||||
@ in the file PATENTS. All contributing project authors may
|
||||
@ be found in the AUTHORS file in the root of the source tree.
|
||||
@
|
||||
|
||||
@ This file contains the function WebRtcSpl_ComplexBitReverse(), optimized
|
||||
@ for ARMv5 platforms.
|
||||
@ Reference C code is in file complex_bit_reverse.c. Bit-exact.
|
||||
|
||||
#include "webrtc/system_wrappers/interface/asm_defines.h"
|
||||
|
||||
GLOBAL_FUNCTION WebRtcSpl_ComplexBitReverse
|
||||
.align 2
|
||||
DEFINE_FUNCTION WebRtcSpl_ComplexBitReverse
|
||||
push {r4-r7}
|
||||
|
||||
cmp r1, #7
|
||||
adr r3, index_7 @ Table pointer.
|
||||
mov r4, #112 @ Number of interations.
|
||||
beq PRE_LOOP_STAGES_7_OR_8
|
||||
|
||||
cmp r1, #8
|
||||
adr r3, index_8 @ Table pointer.
|
||||
mov r4, #240 @ Number of interations.
|
||||
beq PRE_LOOP_STAGES_7_OR_8
|
||||
|
||||
mov r3, #1 @ Initialize m.
|
||||
mov r1, r3, asl r1 @ n = 1 << stages;
|
||||
subs r6, r1, #1 @ nn = n - 1;
|
||||
ble END
|
||||
|
||||
mov r5, r0 @ &complex_data
|
||||
mov r4, #0 @ ml
|
||||
|
||||
LOOP_GENERIC:
|
||||
rsb r12, r4, r6 @ l > nn - mr
|
||||
mov r2, r1 @ n
|
||||
|
||||
LOOP_SHIFT:
|
||||
asr r2, #1 @ l >>= 1;
|
||||
cmp r2, r12
|
||||
bgt LOOP_SHIFT
|
||||
|
||||
sub r12, r2, #1
|
||||
and r4, r12, r4
|
||||
add r4, r2 @ mr = (mr & (l - 1)) + l;
|
||||
cmp r4, r3 @ mr <= m ?
|
||||
ble UPDATE_REGISTERS
|
||||
|
||||
mov r12, r4, asl #2
|
||||
ldr r7, [r5, #4] @ complex_data[2 * m, 2 * m + 1].
|
||||
@ Offset 4 due to m incrementing from 1.
|
||||
ldr r2, [r0, r12] @ complex_data[2 * mr, 2 * mr + 1].
|
||||
str r7, [r0, r12]
|
||||
str r2, [r5, #4]
|
||||
|
||||
UPDATE_REGISTERS:
|
||||
add r3, r3, #1
|
||||
add r5, #4
|
||||
cmp r3, r1
|
||||
bne LOOP_GENERIC
|
||||
|
||||
b END
|
||||
|
||||
PRE_LOOP_STAGES_7_OR_8:
|
||||
add r4, r3, r4, asl #1
|
||||
|
||||
LOOP_STAGES_7_OR_8:
|
||||
ldrsh r2, [r3], #2 @ index[m]
|
||||
ldrsh r5, [r3], #2 @ index[m + 1]
|
||||
ldr r1, [r0, r2] @ complex_data[index[m], index[m] + 1]
|
||||
ldr r12, [r0, r5] @ complex_data[index[m + 1], index[m + 1] + 1]
|
||||
cmp r3, r4
|
||||
str r1, [r0, r5]
|
||||
str r12, [r0, r2]
|
||||
bne LOOP_STAGES_7_OR_8
|
||||
|
||||
END:
|
||||
pop {r4-r7}
|
||||
bx lr
|
||||
|
||||
@ The index tables. Note the values are doubles of the actual indexes for 16-bit
|
||||
@ elements, different from the generic C code. It actually provides byte offsets
|
||||
@ for the indexes.
|
||||
|
||||
.align 2
|
||||
index_7: @ Indexes for stages == 7.
|
||||
.short 4, 256, 8, 128, 12, 384, 16, 64, 20, 320, 24, 192, 28, 448, 36, 288
|
||||
.short 40, 160, 44, 416, 48, 96, 52, 352, 56, 224, 60, 480, 68, 272, 72, 144
|
||||
.short 76, 400, 84, 336, 88, 208, 92, 464, 100, 304, 104, 176, 108, 432, 116
|
||||
.short 368, 120, 240, 124, 496, 132, 264, 140, 392, 148, 328, 152, 200, 156
|
||||
.short 456, 164, 296, 172, 424, 180, 360, 184, 232, 188, 488, 196, 280, 204
|
||||
.short 408, 212, 344, 220, 472, 228, 312, 236, 440, 244, 376, 252, 504, 268
|
||||
.short 388, 276, 324, 284, 452, 300, 420, 308, 356, 316, 484, 332, 404, 348
|
||||
.short 468, 364, 436, 380, 500, 412, 460, 444, 492
|
||||
|
||||
index_8: @ Indexes for stages == 8.
|
||||
.short 4, 512, 8, 256, 12, 768, 16, 128, 20, 640, 24, 384, 28, 896, 32, 64
|
||||
.short 36, 576, 40, 320, 44, 832, 48, 192, 52, 704, 56, 448, 60, 960, 68, 544
|
||||
.short 72, 288, 76, 800, 80, 160, 84, 672, 88, 416, 92, 928, 100, 608, 104
|
||||
.short 352, 108, 864, 112, 224, 116, 736, 120, 480, 124, 992, 132, 528, 136
|
||||
.short 272, 140, 784, 148, 656, 152, 400, 156, 912, 164, 592, 168, 336, 172
|
||||
.short 848, 176, 208, 180, 720, 184, 464, 188, 976, 196, 560, 200, 304, 204
|
||||
.short 816, 212, 688, 216, 432, 220, 944, 228, 624, 232, 368, 236, 880, 244
|
||||
.short 752, 248, 496, 252, 1008, 260, 520, 268, 776, 276, 648, 280, 392, 284
|
||||
.short 904, 292, 584, 296, 328, 300, 840, 308, 712, 312, 456, 316, 968, 324
|
||||
.short 552, 332, 808, 340, 680, 344, 424, 348, 936, 356, 616, 364, 872, 372
|
||||
.short 744, 376, 488, 380, 1000, 388, 536, 396, 792, 404, 664, 412, 920, 420
|
||||
.short 600, 428, 856, 436, 728, 440, 472, 444, 984, 452, 568, 460, 824, 468
|
||||
.short 696, 476, 952, 484, 632, 492, 888, 500, 760, 508, 1016, 524, 772, 532
|
||||
.short 644, 540, 900, 548, 580, 556, 836, 564, 708, 572, 964, 588, 804, 596
|
||||
.short 676, 604, 932, 620, 868, 628, 740, 636, 996, 652, 788, 668, 916, 684
|
||||
.short 852, 692, 724, 700, 980, 716, 820, 732, 948, 748, 884, 764, 1012, 796
|
||||
.short 908, 812, 844, 828, 972, 860, 940, 892, 1004, 956, 988
|
176
webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c
Normal file
176
webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
static int16_t coefTable_7[] = {
|
||||
4, 256, 8, 128, 12, 384, 16, 64,
|
||||
20, 320, 24, 192, 28, 448, 36, 288,
|
||||
40, 160, 44, 416, 48, 96, 52, 352,
|
||||
56, 224, 60, 480, 68, 272, 72, 144,
|
||||
76, 400, 84, 336, 88, 208, 92, 464,
|
||||
100, 304, 104, 176, 108, 432, 116, 368,
|
||||
120, 240, 124, 496, 132, 264, 140, 392,
|
||||
148, 328, 152, 200, 156, 456, 164, 296,
|
||||
172, 424, 180, 360, 184, 232, 188, 488,
|
||||
196, 280, 204, 408, 212, 344, 220, 472,
|
||||
228, 312, 236, 440, 244, 376, 252, 504,
|
||||
268, 388, 276, 324, 284, 452, 300, 420,
|
||||
308, 356, 316, 484, 332, 404, 348, 468,
|
||||
364, 436, 380, 500, 412, 460, 444, 492
|
||||
};
|
||||
|
||||
static int16_t coefTable_8[] = {
|
||||
4, 512, 8, 256, 12, 768, 16, 128,
|
||||
20, 640, 24, 384, 28, 896, 32, 64,
|
||||
36, 576, 40, 320, 44, 832, 48, 192,
|
||||
52, 704, 56, 448, 60, 960, 68, 544,
|
||||
72, 288, 76, 800, 80, 160, 84, 672,
|
||||
88, 416, 92, 928, 100, 608, 104, 352,
|
||||
108, 864, 112, 224, 116, 736, 120, 480,
|
||||
124, 992, 132, 528, 136, 272, 140, 784,
|
||||
148, 656, 152, 400, 156, 912, 164, 592,
|
||||
168, 336, 172, 848, 176, 208, 180, 720,
|
||||
184, 464, 188, 976, 196, 560, 200, 304,
|
||||
204, 816, 212, 688, 216, 432, 220, 944,
|
||||
228, 624, 232, 368, 236, 880, 244, 752,
|
||||
248, 496, 252, 1008, 260, 520, 268, 776,
|
||||
276, 648, 280, 392, 284, 904, 292, 584,
|
||||
296, 328, 300, 840, 308, 712, 312, 456,
|
||||
316, 968, 324, 552, 332, 808, 340, 680,
|
||||
344, 424, 348, 936, 356, 616, 364, 872,
|
||||
372, 744, 376, 488, 380, 1000, 388, 536,
|
||||
396, 792, 404, 664, 412, 920, 420, 600,
|
||||
428, 856, 436, 728, 440, 472, 444, 984,
|
||||
452, 568, 460, 824, 468, 696, 476, 952,
|
||||
484, 632, 492, 888, 500, 760, 508, 1016,
|
||||
524, 772, 532, 644, 540, 900, 548, 580,
|
||||
556, 836, 564, 708, 572, 964, 588, 804,
|
||||
596, 676, 604, 932, 620, 868, 628, 740,
|
||||
636, 996, 652, 788, 668, 916, 684, 852,
|
||||
692, 724, 700, 980, 716, 820, 732, 948,
|
||||
748, 884, 764, 1012, 796, 908, 812, 844,
|
||||
828, 972, 860, 940, 892, 1004, 956, 988
|
||||
};
|
||||
|
||||
void WebRtcSpl_ComplexBitReverse(int16_t frfi[], int stages) {
|
||||
int l;
|
||||
int16_t tr, ti;
|
||||
int32_t tmp1, tmp2, tmp3, tmp4;
|
||||
int32_t* ptr_i;
|
||||
int32_t* ptr_j;
|
||||
|
||||
if (stages == 8) {
|
||||
int16_t* pcoeftable_8 = coefTable_8;
|
||||
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"addiu %[l], $zero, 120 \n\t"
|
||||
"1: \n\t"
|
||||
"addiu %[l], %[l], -4 \n\t"
|
||||
"lh %[tr], 0(%[pcoeftable_8]) \n\t"
|
||||
"lh %[ti], 2(%[pcoeftable_8]) \n\t"
|
||||
"lh %[tmp3], 4(%[pcoeftable_8]) \n\t"
|
||||
"lh %[tmp4], 6(%[pcoeftable_8]) \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tr] \n\t"
|
||||
"addu %[ptr_j], %[frfi], %[ti] \n\t"
|
||||
"addu %[tr], %[frfi], %[tmp3] \n\t"
|
||||
"addu %[ti], %[frfi], %[tmp4] \n\t"
|
||||
"ulw %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"ulw %[tmp2], 0(%[ptr_j]) \n\t"
|
||||
"ulw %[tmp3], 0(%[tr]) \n\t"
|
||||
"ulw %[tmp4], 0(%[ti]) \n\t"
|
||||
"usw %[tmp1], 0(%[ptr_j]) \n\t"
|
||||
"usw %[tmp2], 0(%[ptr_i]) \n\t"
|
||||
"usw %[tmp4], 0(%[tr]) \n\t"
|
||||
"usw %[tmp3], 0(%[ti]) \n\t"
|
||||
"lh %[tmp1], 8(%[pcoeftable_8]) \n\t"
|
||||
"lh %[tmp2], 10(%[pcoeftable_8]) \n\t"
|
||||
"lh %[tr], 12(%[pcoeftable_8]) \n\t"
|
||||
"lh %[ti], 14(%[pcoeftable_8]) \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
||||
"addu %[ptr_j], %[frfi], %[tmp2] \n\t"
|
||||
"addu %[tr], %[frfi], %[tr] \n\t"
|
||||
"addu %[ti], %[frfi], %[ti] \n\t"
|
||||
"ulw %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"ulw %[tmp2], 0(%[ptr_j]) \n\t"
|
||||
"ulw %[tmp3], 0(%[tr]) \n\t"
|
||||
"ulw %[tmp4], 0(%[ti]) \n\t"
|
||||
"usw %[tmp1], 0(%[ptr_j]) \n\t"
|
||||
"usw %[tmp2], 0(%[ptr_i]) \n\t"
|
||||
"usw %[tmp4], 0(%[tr]) \n\t"
|
||||
"usw %[tmp3], 0(%[ti]) \n\t"
|
||||
"bgtz %[l], 1b \n\t"
|
||||
" addiu %[pcoeftable_8], %[pcoeftable_8], 16 \n\t"
|
||||
".set pop \n\t"
|
||||
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i),
|
||||
[ptr_j] "=&r" (ptr_j), [tr] "=&r" (tr), [l] "=&r" (l),
|
||||
[tmp3] "=&r" (tmp3), [pcoeftable_8] "+r" (pcoeftable_8),
|
||||
[ti] "=&r" (ti), [tmp4] "=&r" (tmp4)
|
||||
: [frfi] "r" (frfi)
|
||||
: "memory"
|
||||
);
|
||||
} else if (stages == 7) {
|
||||
int16_t* pcoeftable_7 = coefTable_7;
|
||||
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"addiu %[l], $zero, 56 \n\t"
|
||||
"1: \n\t"
|
||||
"addiu %[l], %[l], -4 \n\t"
|
||||
"lh %[tr], 0(%[pcoeftable_7]) \n\t"
|
||||
"lh %[ti], 2(%[pcoeftable_7]) \n\t"
|
||||
"lh %[tmp3], 4(%[pcoeftable_7]) \n\t"
|
||||
"lh %[tmp4], 6(%[pcoeftable_7]) \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tr] \n\t"
|
||||
"addu %[ptr_j], %[frfi], %[ti] \n\t"
|
||||
"addu %[tr], %[frfi], %[tmp3] \n\t"
|
||||
"addu %[ti], %[frfi], %[tmp4] \n\t"
|
||||
"ulw %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"ulw %[tmp2], 0(%[ptr_j]) \n\t"
|
||||
"ulw %[tmp3], 0(%[tr]) \n\t"
|
||||
"ulw %[tmp4], 0(%[ti]) \n\t"
|
||||
"usw %[tmp1], 0(%[ptr_j]) \n\t"
|
||||
"usw %[tmp2], 0(%[ptr_i]) \n\t"
|
||||
"usw %[tmp4], 0(%[tr]) \n\t"
|
||||
"usw %[tmp3], 0(%[ti]) \n\t"
|
||||
"lh %[tmp1], 8(%[pcoeftable_7]) \n\t"
|
||||
"lh %[tmp2], 10(%[pcoeftable_7]) \n\t"
|
||||
"lh %[tr], 12(%[pcoeftable_7]) \n\t"
|
||||
"lh %[ti], 14(%[pcoeftable_7]) \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
||||
"addu %[ptr_j], %[frfi], %[tmp2] \n\t"
|
||||
"addu %[tr], %[frfi], %[tr] \n\t"
|
||||
"addu %[ti], %[frfi], %[ti] \n\t"
|
||||
"ulw %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"ulw %[tmp2], 0(%[ptr_j]) \n\t"
|
||||
"ulw %[tmp3], 0(%[tr]) \n\t"
|
||||
"ulw %[tmp4], 0(%[ti]) \n\t"
|
||||
"usw %[tmp1], 0(%[ptr_j]) \n\t"
|
||||
"usw %[tmp2], 0(%[ptr_i]) \n\t"
|
||||
"usw %[tmp4], 0(%[tr]) \n\t"
|
||||
"usw %[tmp3], 0(%[ti]) \n\t"
|
||||
"bgtz %[l], 1b \n\t"
|
||||
" addiu %[pcoeftable_7], %[pcoeftable_7], 16 \n\t"
|
||||
".set pop \n\t"
|
||||
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i),
|
||||
[ptr_j] "=&r" (ptr_j), [ti] "=&r" (ti), [tr] "=&r" (tr),
|
||||
[l] "=&r" (l), [pcoeftable_7] "+r" (pcoeftable_7),
|
||||
[tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4)
|
||||
: [frfi] "r" (frfi)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
}
|
298
webrtc/common_audio/signal_processing/complex_fft.c
Normal file
298
webrtc/common_audio/signal_processing/complex_fft.c
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_ComplexFFT().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/complex_fft_tables.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#define CFFTSFT 14
|
||||
#define CFFTRND 1
|
||||
#define CFFTRND2 16384
|
||||
|
||||
#define CIFFTSFT 14
|
||||
#define CIFFTRND 1
|
||||
|
||||
|
||||
int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
|
||||
{
|
||||
int i, j, l, k, istep, n, m;
|
||||
int16_t wr, wi;
|
||||
int32_t tr32, ti32, qr32, qi32;
|
||||
|
||||
/* The 1024-value is a constant given from the size of kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = -kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
|
||||
|
||||
ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
|
||||
|
||||
qr32 = (int32_t)frfi[2 * i];
|
||||
qi32 = (int32_t)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (int16_t)((qr32 - tr32) >> 1);
|
||||
frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> 1);
|
||||
frfi[2 * i] = (int16_t)((qr32 + tr32) >> 1);
|
||||
frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
while (l < n)
|
||||
{
|
||||
istep = l << 1;
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = -kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7
|
||||
int32_t wri = 0;
|
||||
__asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((int32_t)wr), "r"((int32_t)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7
|
||||
register int32_t frfi_r;
|
||||
__asm __volatile(
|
||||
"pkhbt %[frfi_r], %[frfi_even], %[frfi_odd],"
|
||||
" lsl #16\n\t"
|
||||
"smlsd %[tr32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
|
||||
"smladx %[ti32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
|
||||
:[frfi_r]"=&r"(frfi_r),
|
||||
[tr32]"=&r"(tr32),
|
||||
[ti32]"=r"(ti32)
|
||||
:[frfi_even]"r"((int32_t)frfi[2*j]),
|
||||
[frfi_odd]"r"((int32_t)frfi[2*j +1]),
|
||||
[wri]"r"(wri),
|
||||
[cfftrnd]"r"(CFFTRND));
|
||||
#else
|
||||
tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CFFTRND;
|
||||
|
||||
ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CFFTRND;
|
||||
#endif
|
||||
|
||||
tr32 >>= 15 - CFFTSFT;
|
||||
ti32 >>= 15 - CFFTSFT;
|
||||
|
||||
qr32 = ((int32_t)frfi[2 * i]) << CFFTSFT;
|
||||
qi32 = ((int32_t)frfi[2 * i + 1]) << CFFTSFT;
|
||||
|
||||
frfi[2 * j] = (int16_t)(
|
||||
(qr32 - tr32 + CFFTRND2) >> (1 + CFFTSFT));
|
||||
frfi[2 * j + 1] = (int16_t)(
|
||||
(qi32 - ti32 + CFFTRND2) >> (1 + CFFTSFT));
|
||||
frfi[2 * i] = (int16_t)(
|
||||
(qr32 + tr32 + CFFTRND2) >> (1 + CFFTSFT));
|
||||
frfi[2 * i + 1] = (int16_t)(
|
||||
(qi32 + ti32 + CFFTRND2) >> (1 + CFFTSFT));
|
||||
}
|
||||
}
|
||||
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
|
||||
{
|
||||
size_t i, j, l, istep, n, m;
|
||||
int k, scale, shift;
|
||||
int16_t wr, wi;
|
||||
int32_t tr32, ti32, qr32, qi32;
|
||||
int32_t tmp32, round2;
|
||||
|
||||
/* The 1024-value is a constant given from the size of kSinTable1024[],
|
||||
* and should not be changed depending on the input parameter 'stages'
|
||||
*/
|
||||
n = 1 << stages;
|
||||
if (n > 1024)
|
||||
return -1;
|
||||
|
||||
scale = 0;
|
||||
|
||||
l = 1;
|
||||
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
|
||||
depending on the input parameter 'stages' */
|
||||
|
||||
while (l < n)
|
||||
{
|
||||
// variable scaling, depending upon data
|
||||
shift = 0;
|
||||
round2 = 8192;
|
||||
|
||||
tmp32 = WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
|
||||
if (tmp32 > 13573)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
if (tmp32 > 27146)
|
||||
{
|
||||
shift++;
|
||||
scale++;
|
||||
round2 <<= 1;
|
||||
}
|
||||
|
||||
istep = l << 1;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
// mode==0: Low-complexity and Low-accuracy mode
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = kSinTable1024[j];
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
|
||||
|
||||
ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
|
||||
|
||||
qr32 = (int32_t)frfi[2 * i];
|
||||
qi32 = (int32_t)frfi[2 * i + 1];
|
||||
frfi[2 * j] = (int16_t)((qr32 - tr32) >> shift);
|
||||
frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> shift);
|
||||
frfi[2 * i] = (int16_t)((qr32 + tr32) >> shift);
|
||||
frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> shift);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
// mode==1: High-complexity and High-accuracy mode
|
||||
|
||||
for (m = 0; m < l; ++m)
|
||||
{
|
||||
j = m << k;
|
||||
|
||||
/* The 256-value is a constant given as 1/4 of the size of
|
||||
* kSinTable1024[], and should not be changed depending on the input
|
||||
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
|
||||
*/
|
||||
wr = kSinTable1024[j + 256];
|
||||
wi = kSinTable1024[j];
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7
|
||||
int32_t wri = 0;
|
||||
__asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
|
||||
"r"((int32_t)wr), "r"((int32_t)wi));
|
||||
#endif
|
||||
|
||||
for (i = m; i < n; i += istep)
|
||||
{
|
||||
j = i + l;
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7
|
||||
register int32_t frfi_r;
|
||||
__asm __volatile(
|
||||
"pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t"
|
||||
"smlsd %[tr32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
|
||||
"smladx %[ti32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
|
||||
:[frfi_r]"=&r"(frfi_r),
|
||||
[tr32]"=&r"(tr32),
|
||||
[ti32]"=r"(ti32)
|
||||
:[frfi_even]"r"((int32_t)frfi[2*j]),
|
||||
[frfi_odd]"r"((int32_t)frfi[2*j +1]),
|
||||
[wri]"r"(wri),
|
||||
[cifftrnd]"r"(CIFFTRND)
|
||||
);
|
||||
#else
|
||||
|
||||
tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CIFFTRND;
|
||||
|
||||
ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CIFFTRND;
|
||||
#endif
|
||||
tr32 >>= 15 - CIFFTSFT;
|
||||
ti32 >>= 15 - CIFFTSFT;
|
||||
|
||||
qr32 = ((int32_t)frfi[2 * i]) << CIFFTSFT;
|
||||
qi32 = ((int32_t)frfi[2 * i + 1]) << CIFFTSFT;
|
||||
|
||||
frfi[2 * j] = (int16_t)(
|
||||
(qr32 - tr32 + round2) >> (shift + CIFFTSFT));
|
||||
frfi[2 * j + 1] = (int16_t)(
|
||||
(qi32 - ti32 + round2) >> (shift + CIFFTSFT));
|
||||
frfi[2 * i] = (int16_t)(
|
||||
(qr32 + tr32 + round2) >> (shift + CIFFTSFT));
|
||||
frfi[2 * i + 1] = (int16_t)(
|
||||
(qi32 + ti32 + round2) >> (shift + CIFFTSFT));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
--k;
|
||||
l = istep;
|
||||
}
|
||||
return scale;
|
||||
}
|
328
webrtc/common_audio/signal_processing/complex_fft_mips.c
Normal file
328
webrtc/common_audio/signal_processing/complex_fft_mips.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/complex_fft_tables.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#define CFFTSFT 14
|
||||
#define CFFTRND 1
|
||||
#define CFFTRND2 16384
|
||||
|
||||
#define CIFFTSFT 14
|
||||
#define CIFFTRND 1
|
||||
|
||||
int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) {
|
||||
int i = 0;
|
||||
int l = 0;
|
||||
int k = 0;
|
||||
int istep = 0;
|
||||
int n = 0;
|
||||
int m = 0;
|
||||
int32_t wr = 0, wi = 0;
|
||||
int32_t tmp1 = 0;
|
||||
int32_t tmp2 = 0;
|
||||
int32_t tmp3 = 0;
|
||||
int32_t tmp4 = 0;
|
||||
int32_t tmp5 = 0;
|
||||
int32_t tmp6 = 0;
|
||||
int32_t tmp = 0;
|
||||
int16_t* ptr_j = NULL;
|
||||
int16_t* ptr_i = NULL;
|
||||
|
||||
n = 1 << stages;
|
||||
if (n > 1024) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
|
||||
"addiu %[k], $zero, 10 \n\t"
|
||||
"addiu %[l], $zero, 1 \n\t"
|
||||
"3: \n\t"
|
||||
"sll %[istep], %[l], 1 \n\t"
|
||||
"move %[m], $zero \n\t"
|
||||
"sll %[tmp], %[l], 2 \n\t"
|
||||
"move %[i], $zero \n\t"
|
||||
"2: \n\t"
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
"sllv %[tmp3], %[m], %[k] \n\t"
|
||||
"addiu %[tmp2], %[tmp3], 512 \n\t"
|
||||
"addiu %[m], %[m], 1 \n\t"
|
||||
"lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t"
|
||||
"lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t"
|
||||
#else // #if defined(MIPS_DSP_R1_LE)
|
||||
"sllv %[tmp3], %[m], %[k] \n\t"
|
||||
"addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t"
|
||||
"addiu %[ptr_i], %[ptr_j], 512 \n\t"
|
||||
"addiu %[m], %[m], 1 \n\t"
|
||||
"lh %[wi], 0(%[ptr_j]) \n\t"
|
||||
"lh %[wr], 0(%[ptr_i]) \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R1_LE)
|
||||
"1: \n\t"
|
||||
"sll %[tmp1], %[i], 2 \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
||||
"addu %[ptr_j], %[ptr_i], %[tmp] \n\t"
|
||||
"lh %[tmp6], 0(%[ptr_i]) \n\t"
|
||||
"lh %[tmp5], 2(%[ptr_i]) \n\t"
|
||||
"lh %[tmp3], 0(%[ptr_j]) \n\t"
|
||||
"lh %[tmp4], 2(%[ptr_j]) \n\t"
|
||||
"addu %[i], %[i], %[istep] \n\t"
|
||||
#if defined(MIPS_DSP_R2_LE)
|
||||
"mult %[wr], %[tmp3] \n\t"
|
||||
"madd %[wi], %[tmp4] \n\t"
|
||||
"mult $ac1, %[wr], %[tmp4] \n\t"
|
||||
"msub $ac1, %[wi], %[tmp3] \n\t"
|
||||
"mflo %[tmp1] \n\t"
|
||||
"mflo %[tmp2], $ac1 \n\t"
|
||||
"sll %[tmp6], %[tmp6], 14 \n\t"
|
||||
"sll %[tmp5], %[tmp5], 14 \n\t"
|
||||
"shra_r.w %[tmp1], %[tmp1], 1 \n\t"
|
||||
"shra_r.w %[tmp2], %[tmp2], 1 \n\t"
|
||||
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
||||
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
||||
"shra_r.w %[tmp1], %[tmp1], 15 \n\t"
|
||||
"shra_r.w %[tmp6], %[tmp6], 15 \n\t"
|
||||
"shra_r.w %[tmp4], %[tmp4], 15 \n\t"
|
||||
"shra_r.w %[tmp5], %[tmp5], 15 \n\t"
|
||||
#else // #if defined(MIPS_DSP_R2_LE)
|
||||
"mul %[tmp2], %[wr], %[tmp4] \n\t"
|
||||
"mul %[tmp1], %[wr], %[tmp3] \n\t"
|
||||
"mul %[tmp4], %[wi], %[tmp4] \n\t"
|
||||
"mul %[tmp3], %[wi], %[tmp3] \n\t"
|
||||
"sll %[tmp6], %[tmp6], 14 \n\t"
|
||||
"sll %[tmp5], %[tmp5], 14 \n\t"
|
||||
"addiu %[tmp6], %[tmp6], 16384 \n\t"
|
||||
"addiu %[tmp5], %[tmp5], 16384 \n\t"
|
||||
"addu %[tmp1], %[tmp1], %[tmp4] \n\t"
|
||||
"subu %[tmp2], %[tmp2], %[tmp3] \n\t"
|
||||
"addiu %[tmp1], %[tmp1], 1 \n\t"
|
||||
"addiu %[tmp2], %[tmp2], 1 \n\t"
|
||||
"sra %[tmp1], %[tmp1], 1 \n\t"
|
||||
"sra %[tmp2], %[tmp2], 1 \n\t"
|
||||
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
||||
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
||||
"sra %[tmp4], %[tmp4], 15 \n\t"
|
||||
"sra %[tmp1], %[tmp1], 15 \n\t"
|
||||
"sra %[tmp6], %[tmp6], 15 \n\t"
|
||||
"sra %[tmp5], %[tmp5], 15 \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R2_LE)
|
||||
"sh %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"sh %[tmp6], 2(%[ptr_i]) \n\t"
|
||||
"sh %[tmp4], 0(%[ptr_j]) \n\t"
|
||||
"blt %[i], %[n], 1b \n\t"
|
||||
" sh %[tmp5], 2(%[ptr_j]) \n\t"
|
||||
"blt %[m], %[l], 2b \n\t"
|
||||
" addu %[i], $zero, %[m] \n\t"
|
||||
"move %[l], %[istep] \n\t"
|
||||
"blt %[l], %[n], 3b \n\t"
|
||||
" addiu %[k], %[k], -1 \n\t"
|
||||
|
||||
".set pop \n\t"
|
||||
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
||||
[tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
|
||||
[ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [wi] "=&r" (wi), [wr] "=&r" (wr),
|
||||
[m] "=&r" (m), [istep] "=&r" (istep), [l] "=&r" (l), [k] "=&r" (k),
|
||||
[ptr_j] "=&r" (ptr_j), [tmp] "=&r" (tmp)
|
||||
: [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
|
||||
: "hi", "lo", "memory"
|
||||
#if defined(MIPS_DSP_R2_LE)
|
||||
, "$ac1hi", "$ac1lo"
|
||||
#endif // #if defined(MIPS_DSP_R2_LE)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) {
|
||||
int i = 0, l = 0, k = 0;
|
||||
int istep = 0, n = 0, m = 0;
|
||||
int scale = 0, shift = 0;
|
||||
int32_t wr = 0, wi = 0;
|
||||
int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
|
||||
int32_t tmp5 = 0, tmp6 = 0, tmp = 0, tempMax = 0, round2 = 0;
|
||||
int16_t* ptr_j = NULL;
|
||||
int16_t* ptr_i = NULL;
|
||||
|
||||
n = 1 << stages;
|
||||
if (n > 1024) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
|
||||
"addiu %[k], $zero, 10 \n\t"
|
||||
"addiu %[l], $zero, 1 \n\t"
|
||||
"move %[scale], $zero \n\t"
|
||||
"3: \n\t"
|
||||
"addiu %[shift], $zero, 14 \n\t"
|
||||
"addiu %[round2], $zero, 8192 \n\t"
|
||||
"move %[ptr_i], %[frfi] \n\t"
|
||||
"move %[tempMax], $zero \n\t"
|
||||
"addu %[i], %[n], %[n] \n\t"
|
||||
"5: \n\t"
|
||||
"lh %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"lh %[tmp2], 2(%[ptr_i]) \n\t"
|
||||
"lh %[tmp3], 4(%[ptr_i]) \n\t"
|
||||
"lh %[tmp4], 6(%[ptr_i]) \n\t"
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
"absq_s.w %[tmp1], %[tmp1] \n\t"
|
||||
"absq_s.w %[tmp2], %[tmp2] \n\t"
|
||||
"absq_s.w %[tmp3], %[tmp3] \n\t"
|
||||
"absq_s.w %[tmp4], %[tmp4] \n\t"
|
||||
#else // #if defined(MIPS_DSP_R1_LE)
|
||||
"slt %[tmp5], %[tmp1], $zero \n\t"
|
||||
"subu %[tmp6], $zero, %[tmp1] \n\t"
|
||||
"movn %[tmp1], %[tmp6], %[tmp5] \n\t"
|
||||
"slt %[tmp5], %[tmp2], $zero \n\t"
|
||||
"subu %[tmp6], $zero, %[tmp2] \n\t"
|
||||
"movn %[tmp2], %[tmp6], %[tmp5] \n\t"
|
||||
"slt %[tmp5], %[tmp3], $zero \n\t"
|
||||
"subu %[tmp6], $zero, %[tmp3] \n\t"
|
||||
"movn %[tmp3], %[tmp6], %[tmp5] \n\t"
|
||||
"slt %[tmp5], %[tmp4], $zero \n\t"
|
||||
"subu %[tmp6], $zero, %[tmp4] \n\t"
|
||||
"movn %[tmp4], %[tmp6], %[tmp5] \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R1_LE)
|
||||
"slt %[tmp5], %[tempMax], %[tmp1] \n\t"
|
||||
"movn %[tempMax], %[tmp1], %[tmp5] \n\t"
|
||||
"addiu %[i], %[i], -4 \n\t"
|
||||
"slt %[tmp5], %[tempMax], %[tmp2] \n\t"
|
||||
"movn %[tempMax], %[tmp2], %[tmp5] \n\t"
|
||||
"slt %[tmp5], %[tempMax], %[tmp3] \n\t"
|
||||
"movn %[tempMax], %[tmp3], %[tmp5] \n\t"
|
||||
"slt %[tmp5], %[tempMax], %[tmp4] \n\t"
|
||||
"movn %[tempMax], %[tmp4], %[tmp5] \n\t"
|
||||
"bgtz %[i], 5b \n\t"
|
||||
" addiu %[ptr_i], %[ptr_i], 8 \n\t"
|
||||
"addiu %[tmp1], $zero, 13573 \n\t"
|
||||
"addiu %[tmp2], $zero, 27146 \n\t"
|
||||
#if !defined(MIPS32_R2_LE)
|
||||
"sll %[tempMax], %[tempMax], 16 \n\t"
|
||||
"sra %[tempMax], %[tempMax], 16 \n\t"
|
||||
#else // #if !defined(MIPS32_R2_LE)
|
||||
"seh %[tempMax] \n\t"
|
||||
#endif // #if !defined(MIPS32_R2_LE)
|
||||
"slt %[tmp1], %[tmp1], %[tempMax] \n\t"
|
||||
"slt %[tmp2], %[tmp2], %[tempMax] \n\t"
|
||||
"addu %[tmp1], %[tmp1], %[tmp2] \n\t"
|
||||
"addu %[shift], %[shift], %[tmp1] \n\t"
|
||||
"addu %[scale], %[scale], %[tmp1] \n\t"
|
||||
"sllv %[round2], %[round2], %[tmp1] \n\t"
|
||||
"sll %[istep], %[l], 1 \n\t"
|
||||
"move %[m], $zero \n\t"
|
||||
"sll %[tmp], %[l], 2 \n\t"
|
||||
"2: \n\t"
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
"sllv %[tmp3], %[m], %[k] \n\t"
|
||||
"addiu %[tmp2], %[tmp3], 512 \n\t"
|
||||
"addiu %[m], %[m], 1 \n\t"
|
||||
"lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t"
|
||||
"lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t"
|
||||
#else // #if defined(MIPS_DSP_R1_LE)
|
||||
"sllv %[tmp3], %[m], %[k] \n\t"
|
||||
"addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t"
|
||||
"addiu %[ptr_i], %[ptr_j], 512 \n\t"
|
||||
"addiu %[m], %[m], 1 \n\t"
|
||||
"lh %[wi], 0(%[ptr_j]) \n\t"
|
||||
"lh %[wr], 0(%[ptr_i]) \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R1_LE)
|
||||
"1: \n\t"
|
||||
"sll %[tmp1], %[i], 2 \n\t"
|
||||
"addu %[ptr_i], %[frfi], %[tmp1] \n\t"
|
||||
"addu %[ptr_j], %[ptr_i], %[tmp] \n\t"
|
||||
"lh %[tmp3], 0(%[ptr_j]) \n\t"
|
||||
"lh %[tmp4], 2(%[ptr_j]) \n\t"
|
||||
"lh %[tmp6], 0(%[ptr_i]) \n\t"
|
||||
"lh %[tmp5], 2(%[ptr_i]) \n\t"
|
||||
"addu %[i], %[i], %[istep] \n\t"
|
||||
#if defined(MIPS_DSP_R2_LE)
|
||||
"mult %[wr], %[tmp3] \n\t"
|
||||
"msub %[wi], %[tmp4] \n\t"
|
||||
"mult $ac1, %[wr], %[tmp4] \n\t"
|
||||
"madd $ac1, %[wi], %[tmp3] \n\t"
|
||||
"mflo %[tmp1] \n\t"
|
||||
"mflo %[tmp2], $ac1 \n\t"
|
||||
"sll %[tmp6], %[tmp6], 14 \n\t"
|
||||
"sll %[tmp5], %[tmp5], 14 \n\t"
|
||||
"shra_r.w %[tmp1], %[tmp1], 1 \n\t"
|
||||
"shra_r.w %[tmp2], %[tmp2], 1 \n\t"
|
||||
"addu %[tmp6], %[tmp6], %[round2] \n\t"
|
||||
"addu %[tmp5], %[tmp5], %[round2] \n\t"
|
||||
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
||||
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
||||
"srav %[tmp4], %[tmp4], %[shift] \n\t"
|
||||
"srav %[tmp1], %[tmp1], %[shift] \n\t"
|
||||
"srav %[tmp6], %[tmp6], %[shift] \n\t"
|
||||
"srav %[tmp5], %[tmp5], %[shift] \n\t"
|
||||
#else // #if defined(MIPS_DSP_R2_LE)
|
||||
"mul %[tmp1], %[wr], %[tmp3] \n\t"
|
||||
"mul %[tmp2], %[wr], %[tmp4] \n\t"
|
||||
"mul %[tmp4], %[wi], %[tmp4] \n\t"
|
||||
"mul %[tmp3], %[wi], %[tmp3] \n\t"
|
||||
"sll %[tmp6], %[tmp6], 14 \n\t"
|
||||
"sll %[tmp5], %[tmp5], 14 \n\t"
|
||||
"sub %[tmp1], %[tmp1], %[tmp4] \n\t"
|
||||
"addu %[tmp2], %[tmp2], %[tmp3] \n\t"
|
||||
"addiu %[tmp1], %[tmp1], 1 \n\t"
|
||||
"addiu %[tmp2], %[tmp2], 1 \n\t"
|
||||
"sra %[tmp2], %[tmp2], 1 \n\t"
|
||||
"sra %[tmp1], %[tmp1], 1 \n\t"
|
||||
"addu %[tmp6], %[tmp6], %[round2] \n\t"
|
||||
"addu %[tmp5], %[tmp5], %[round2] \n\t"
|
||||
"subu %[tmp4], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp1], %[tmp6], %[tmp1] \n\t"
|
||||
"addu %[tmp6], %[tmp5], %[tmp2] \n\t"
|
||||
"subu %[tmp5], %[tmp5], %[tmp2] \n\t"
|
||||
"sra %[tmp4], %[tmp4], %[shift] \n\t"
|
||||
"sra %[tmp1], %[tmp1], %[shift] \n\t"
|
||||
"sra %[tmp6], %[tmp6], %[shift] \n\t"
|
||||
"sra %[tmp5], %[tmp5], %[shift] \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R2_LE)
|
||||
"sh %[tmp1], 0(%[ptr_i]) \n\t"
|
||||
"sh %[tmp6], 2(%[ptr_i]) \n\t"
|
||||
"sh %[tmp4], 0(%[ptr_j]) \n\t"
|
||||
"blt %[i], %[n], 1b \n\t"
|
||||
" sh %[tmp5], 2(%[ptr_j]) \n\t"
|
||||
"blt %[m], %[l], 2b \n\t"
|
||||
" addu %[i], $zero, %[m] \n\t"
|
||||
"move %[l], %[istep] \n\t"
|
||||
"blt %[l], %[n], 3b \n\t"
|
||||
" addiu %[k], %[k], -1 \n\t"
|
||||
|
||||
".set pop \n\t"
|
||||
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
||||
[tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
|
||||
[ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [m] "=&r" (m), [tmp] "=&r" (tmp),
|
||||
[istep] "=&r" (istep), [wi] "=&r" (wi), [wr] "=&r" (wr), [l] "=&r" (l),
|
||||
[k] "=&r" (k), [round2] "=&r" (round2), [ptr_j] "=&r" (ptr_j),
|
||||
[shift] "=&r" (shift), [scale] "=&r" (scale), [tempMax] "=&r" (tempMax)
|
||||
: [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
|
||||
: "hi", "lo", "memory"
|
||||
#if defined(MIPS_DSP_R2_LE)
|
||||
, "$ac1hi", "$ac1lo"
|
||||
#endif // #if defined(MIPS_DSP_R2_LE)
|
||||
);
|
||||
|
||||
return scale;
|
||||
|
||||
}
|
148
webrtc/common_audio/signal_processing/complex_fft_tables.h
Normal file
148
webrtc/common_audio/signal_processing/complex_fft_tables.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
|
||||
#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
static const int16_t kSinTable1024[] = {
|
||||
0, 201, 402, 603, 804, 1005, 1206, 1406,
|
||||
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
|
||||
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
|
||||
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
|
||||
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
|
||||
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
|
||||
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
|
||||
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
|
||||
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
|
||||
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
|
||||
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
|
||||
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
|
||||
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
|
||||
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
|
||||
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
|
||||
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
|
||||
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
|
||||
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
|
||||
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
|
||||
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
|
||||
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
|
||||
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
|
||||
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
|
||||
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
|
||||
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
|
||||
30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297,
|
||||
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
|
||||
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
|
||||
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
|
||||
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
|
||||
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
|
||||
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
|
||||
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
|
||||
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
|
||||
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
|
||||
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
|
||||
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
|
||||
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
|
||||
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
|
||||
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
|
||||
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
|
||||
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
|
||||
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
|
||||
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
|
||||
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
|
||||
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
|
||||
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
|
||||
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
|
||||
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
|
||||
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
|
||||
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
|
||||
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
|
||||
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
|
||||
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
|
||||
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
|
||||
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
|
||||
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
|
||||
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
|
||||
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
|
||||
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
|
||||
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
|
||||
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
|
||||
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
|
||||
1607, 1406, 1206, 1005, 804, 603, 402, 201,
|
||||
0, -201, -402, -603, -804, -1005, -1206, -1406,
|
||||
-1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
|
||||
-3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
|
||||
-4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
|
||||
-6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
|
||||
-7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
|
||||
-9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
|
||||
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
|
||||
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
|
||||
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
|
||||
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
|
||||
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
|
||||
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
|
||||
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
|
||||
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
|
||||
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
|
||||
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
|
||||
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
|
||||
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
|
||||
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
|
||||
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
|
||||
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
|
||||
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
|
||||
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
|
||||
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
|
||||
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
|
||||
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
|
||||
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
|
||||
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
|
||||
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
|
||||
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
|
||||
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
|
||||
-32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736,
|
||||
-32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628,
|
||||
-32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
|
||||
-32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176,
|
||||
-32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833,
|
||||
-31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413,
|
||||
-31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918,
|
||||
-30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349,
|
||||
-30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706,
|
||||
-29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992,
|
||||
-28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208,
|
||||
-28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
|
||||
-27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437,
|
||||
-26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456,
|
||||
-25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413,
|
||||
-24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311,
|
||||
-23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153,
|
||||
-22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942,
|
||||
-20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680,
|
||||
-19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371,
|
||||
-18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
|
||||
-16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623,
|
||||
-15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191,
|
||||
-14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724,
|
||||
-12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227,
|
||||
-11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703,
|
||||
-9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156,
|
||||
-7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589,
|
||||
-6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006,
|
||||
-4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
|
||||
-3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808,
|
||||
-1607, -1406, -1206, -1005, -804, -603, -402, -201
|
||||
};
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
|
82
webrtc/common_audio/signal_processing/copy_set_operations.c
Normal file
82
webrtc/common_audio/signal_processing/copy_set_operations.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the implementation of functions
|
||||
* WebRtcSpl_MemSetW16()
|
||||
* WebRtcSpl_MemSetW32()
|
||||
* WebRtcSpl_MemCpyReversedOrder()
|
||||
* WebRtcSpl_CopyFromEndW16()
|
||||
* WebRtcSpl_ZerosArrayW16()
|
||||
* WebRtcSpl_ZerosArrayW32()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
30
webrtc/common_audio/signal_processing/cross_correlation.c
Normal file
30
webrtc/common_audio/signal_processing/cross_correlation.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
/* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */
|
||||
void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
|
||||
const int16_t* seq1,
|
||||
const int16_t* seq2,
|
||||
size_t dim_seq,
|
||||
size_t dim_cross_correlation,
|
||||
int right_shifts,
|
||||
int step_seq2) {
|
||||
size_t i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < dim_cross_correlation; i++) {
|
||||
int32_t corr = 0;
|
||||
for (j = 0; j < dim_seq; j++)
|
||||
corr += (seq1[j] * seq2[j]) >> right_shifts;
|
||||
seq2 += step_seq2;
|
||||
*cross_correlation++ = corr;
|
||||
}
|
||||
}
|
104
webrtc/common_audio/signal_processing/cross_correlation_mips.c
Normal file
104
webrtc/common_audio/signal_processing/cross_correlation_mips.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_CrossCorrelation_mips(int32_t* cross_correlation,
|
||||
const int16_t* seq1,
|
||||
const int16_t* seq2,
|
||||
size_t dim_seq,
|
||||
size_t dim_cross_correlation,
|
||||
int right_shifts,
|
||||
int step_seq2) {
|
||||
|
||||
int32_t t0 = 0, t1 = 0, t2 = 0, t3 = 0, sum = 0;
|
||||
int16_t *pseq2 = NULL;
|
||||
int16_t *pseq1 = NULL;
|
||||
int16_t *pseq1_0 = (int16_t*)&seq1[0];
|
||||
int16_t *pseq2_0 = (int16_t*)&seq2[0];
|
||||
int k = 0;
|
||||
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"sll %[step_seq2], %[step_seq2], 1 \n\t"
|
||||
"andi %[t0], %[dim_seq], 1 \n\t"
|
||||
"bgtz %[t0], 3f \n\t"
|
||||
" nop \n\t"
|
||||
"1: \n\t"
|
||||
"move %[pseq1], %[pseq1_0] \n\t"
|
||||
"move %[pseq2], %[pseq2_0] \n\t"
|
||||
"sra %[k], %[dim_seq], 1 \n\t"
|
||||
"addiu %[dim_cc], %[dim_cc], -1 \n\t"
|
||||
"xor %[sum], %[sum], %[sum] \n\t"
|
||||
"2: \n\t"
|
||||
"lh %[t0], 0(%[pseq1]) \n\t"
|
||||
"lh %[t1], 0(%[pseq2]) \n\t"
|
||||
"lh %[t2], 2(%[pseq1]) \n\t"
|
||||
"lh %[t3], 2(%[pseq2]) \n\t"
|
||||
"mul %[t0], %[t0], %[t1] \n\t"
|
||||
"addiu %[k], %[k], -1 \n\t"
|
||||
"mul %[t2], %[t2], %[t3] \n\t"
|
||||
"addiu %[pseq1], %[pseq1], 4 \n\t"
|
||||
"addiu %[pseq2], %[pseq2], 4 \n\t"
|
||||
"srav %[t0], %[t0], %[right_shifts] \n\t"
|
||||
"addu %[sum], %[sum], %[t0] \n\t"
|
||||
"srav %[t2], %[t2], %[right_shifts] \n\t"
|
||||
"bgtz %[k], 2b \n\t"
|
||||
" addu %[sum], %[sum], %[t2] \n\t"
|
||||
"addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t"
|
||||
"sw %[sum], 0(%[cc]) \n\t"
|
||||
"bgtz %[dim_cc], 1b \n\t"
|
||||
" addiu %[cc], %[cc], 4 \n\t"
|
||||
"b 6f \n\t"
|
||||
" nop \n\t"
|
||||
"3: \n\t"
|
||||
"move %[pseq1], %[pseq1_0] \n\t"
|
||||
"move %[pseq2], %[pseq2_0] \n\t"
|
||||
"sra %[k], %[dim_seq], 1 \n\t"
|
||||
"addiu %[dim_cc], %[dim_cc], -1 \n\t"
|
||||
"beqz %[k], 5f \n\t"
|
||||
" xor %[sum], %[sum], %[sum] \n\t"
|
||||
"4: \n\t"
|
||||
"lh %[t0], 0(%[pseq1]) \n\t"
|
||||
"lh %[t1], 0(%[pseq2]) \n\t"
|
||||
"lh %[t2], 2(%[pseq1]) \n\t"
|
||||
"lh %[t3], 2(%[pseq2]) \n\t"
|
||||
"mul %[t0], %[t0], %[t1] \n\t"
|
||||
"addiu %[k], %[k], -1 \n\t"
|
||||
"mul %[t2], %[t2], %[t3] \n\t"
|
||||
"addiu %[pseq1], %[pseq1], 4 \n\t"
|
||||
"addiu %[pseq2], %[pseq2], 4 \n\t"
|
||||
"srav %[t0], %[t0], %[right_shifts] \n\t"
|
||||
"addu %[sum], %[sum], %[t0] \n\t"
|
||||
"srav %[t2], %[t2], %[right_shifts] \n\t"
|
||||
"bgtz %[k], 4b \n\t"
|
||||
" addu %[sum], %[sum], %[t2] \n\t"
|
||||
"5: \n\t"
|
||||
"lh %[t0], 0(%[pseq1]) \n\t"
|
||||
"lh %[t1], 0(%[pseq2]) \n\t"
|
||||
"mul %[t0], %[t0], %[t1] \n\t"
|
||||
"srav %[t0], %[t0], %[right_shifts] \n\t"
|
||||
"addu %[sum], %[sum], %[t0] \n\t"
|
||||
"addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t"
|
||||
"sw %[sum], 0(%[cc]) \n\t"
|
||||
"bgtz %[dim_cc], 3b \n\t"
|
||||
" addiu %[cc], %[cc], 4 \n\t"
|
||||
"6: \n\t"
|
||||
".set pop \n\t"
|
||||
: [step_seq2] "+r" (step_seq2), [t0] "=&r" (t0), [t1] "=&r" (t1),
|
||||
[t2] "=&r" (t2), [t3] "=&r" (t3), [pseq1] "=&r" (pseq1),
|
||||
[pseq2] "=&r" (pseq2), [pseq1_0] "+r" (pseq1_0), [pseq2_0] "+r" (pseq2_0),
|
||||
[k] "=&r" (k), [dim_cc] "+r" (dim_cross_correlation), [sum] "=&r" (sum),
|
||||
[cc] "+r" (cross_correlation)
|
||||
: [dim_seq] "r" (dim_seq), [right_shifts] "r" (right_shifts)
|
||||
: "hi", "lo", "memory"
|
||||
);
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#include <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++;
|
||||
}
|
||||
}
|
138
webrtc/common_audio/signal_processing/division_operations.c
Normal file
138
webrtc/common_audio/signal_processing/division_operations.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the divisions
|
||||
* WebRtcSpl_DivU32U16()
|
||||
* WebRtcSpl_DivW32W16()
|
||||
* WebRtcSpl_DivW32W16ResW16()
|
||||
* WebRtcSpl_DivResultInQ31()
|
||||
* WebRtcSpl_DivW32HiLow()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (uint32_t)(num / den);
|
||||
} else
|
||||
{
|
||||
return (uint32_t)0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (int32_t)(num / den);
|
||||
} else
|
||||
{
|
||||
return (int32_t)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
|
||||
{
|
||||
// Guard against division with 0
|
||||
if (den != 0)
|
||||
{
|
||||
return (int16_t)(num / den);
|
||||
} else
|
||||
{
|
||||
return (int16_t)0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
|
||||
{
|
||||
int32_t L_num = num;
|
||||
int32_t L_den = den;
|
||||
int32_t div = 0;
|
||||
int k = 31;
|
||||
int change_sign = 0;
|
||||
|
||||
if (num == 0)
|
||||
return 0;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_num = -num;
|
||||
}
|
||||
if (den < 0)
|
||||
{
|
||||
change_sign++;
|
||||
L_den = -den;
|
||||
}
|
||||
while (k--)
|
||||
{
|
||||
div <<= 1;
|
||||
L_num <<= 1;
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num -= L_den;
|
||||
div++;
|
||||
}
|
||||
}
|
||||
if (change_sign == 1)
|
||||
{
|
||||
div = -div;
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
|
||||
{
|
||||
int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
|
||||
int32_t tmpW32;
|
||||
|
||||
approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
|
||||
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
|
||||
|
||||
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
|
||||
tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1);
|
||||
// tmpW32 = den * approx
|
||||
|
||||
tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
|
||||
|
||||
// Store tmpW32 in hi and low format
|
||||
tmp_hi = (int16_t)(tmpW32 >> 16);
|
||||
tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
|
||||
|
||||
// tmpW32 = 1/den in Q29
|
||||
tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1;
|
||||
|
||||
// 1/den in hi and low format
|
||||
tmp_hi = (int16_t)(tmpW32 >> 16);
|
||||
tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
|
||||
|
||||
// Store num in hi and low format
|
||||
num_hi = (int16_t)(num >> 16);
|
||||
num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
|
||||
|
||||
// num * (1/den) by 32 bit multiplication (result in Q28)
|
||||
|
||||
tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) +
|
||||
(num_low * tmp_hi >> 15);
|
||||
|
||||
// Put result in Q31 (convert from Q28)
|
||||
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
|
||||
|
||||
return tmpW32;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
|
||||
const int16_t* vector2,
|
||||
size_t length,
|
||||
int scaling) {
|
||||
int32_t sum = 0;
|
||||
size_t i = 0;
|
||||
|
||||
/* Unroll the loop to improve performance. */
|
||||
for (i = 0; i + 3 < length; i += 4) {
|
||||
sum += (vector1[i + 0] * vector2[i + 0]) >> scaling;
|
||||
sum += (vector1[i + 1] * vector2[i + 1]) >> scaling;
|
||||
sum += (vector1[i + 2] * vector2[i + 2]) >> scaling;
|
||||
sum += (vector1[i + 3] * vector2[i + 3]) >> scaling;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
sum += (vector1[i] * vector2[i]) >> scaling;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
48
webrtc/common_audio/signal_processing/downsample_fast.c
Normal file
48
webrtc/common_audio/signal_processing/downsample_fast.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
// TODO(Bjornv): Change the function parameter order to WebRTC code style.
|
||||
// C version of WebRtcSpl_DownsampleFast() for generic platforms.
|
||||
int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
|
||||
size_t data_in_length,
|
||||
int16_t* data_out,
|
||||
size_t data_out_length,
|
||||
const int16_t* __restrict coefficients,
|
||||
size_t coefficients_length,
|
||||
int factor,
|
||||
size_t delay) {
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
int32_t out_s32 = 0;
|
||||
size_t endpos = delay + factor * (data_out_length - 1) + 1;
|
||||
|
||||
// Return error if any of the running conditions doesn't meet.
|
||||
if (data_out_length == 0 || coefficients_length == 0
|
||||
|| data_in_length < endpos) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = delay; i < endpos; i += factor) {
|
||||
out_s32 = 2048; // Round value, 0.5 in Q12.
|
||||
|
||||
for (j = 0; j < coefficients_length; j++) {
|
||||
out_s32 += coefficients[j] * data_in[i - j]; // Q12.
|
||||
}
|
||||
|
||||
out_s32 >>= 12; // Q0.
|
||||
|
||||
// Saturate and store the output.
|
||||
*data_out++ = WebRtcSpl_SatW32ToW16(out_s32);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
169
webrtc/common_audio/signal_processing/downsample_fast_mips.c
Normal file
169
webrtc/common_audio/signal_processing/downsample_fast_mips.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
// Version of WebRtcSpl_DownsampleFast() for MIPS platforms.
|
||||
int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in,
|
||||
size_t data_in_length,
|
||||
int16_t* data_out,
|
||||
size_t data_out_length,
|
||||
const int16_t* __restrict coefficients,
|
||||
size_t coefficients_length,
|
||||
int factor,
|
||||
size_t delay) {
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
int32_t out_s32 = 0;
|
||||
size_t endpos = delay + factor * (data_out_length - 1) + 1;
|
||||
|
||||
int32_t tmp1, tmp2, tmp3, tmp4, factor_2;
|
||||
int16_t* p_coefficients;
|
||||
int16_t* p_data_in;
|
||||
int16_t* p_data_in_0 = (int16_t*)&data_in[delay];
|
||||
int16_t* p_coefficients_0 = (int16_t*)&coefficients[0];
|
||||
#if !defined(MIPS_DSP_R1_LE)
|
||||
int32_t max_16 = 0x7FFF;
|
||||
int32_t min_16 = 0xFFFF8000;
|
||||
#endif // #if !defined(MIPS_DSP_R1_LE)
|
||||
|
||||
// Return error if any of the running conditions doesn't meet.
|
||||
if (data_out_length == 0 || coefficients_length == 0
|
||||
|| data_in_length < endpos) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(MIPS_DSP_R2_LE)
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"subu %[i], %[endpos], %[delay] \n\t"
|
||||
"sll %[factor_2], %[factor], 1 \n\t"
|
||||
"1: \n\t"
|
||||
"move %[p_data_in], %[p_data_in_0] \n\t"
|
||||
"mult $zero, $zero \n\t"
|
||||
"move %[p_coefs], %[p_coefs_0] \n\t"
|
||||
"sra %[j], %[coef_length], 2 \n\t"
|
||||
"beq %[j], $zero, 3f \n\t"
|
||||
" andi %[k], %[coef_length], 3 \n\t"
|
||||
"2: \n\t"
|
||||
"lwl %[tmp1], 1(%[p_data_in]) \n\t"
|
||||
"lwl %[tmp2], 3(%[p_coefs]) \n\t"
|
||||
"lwl %[tmp3], -3(%[p_data_in]) \n\t"
|
||||
"lwl %[tmp4], 7(%[p_coefs]) \n\t"
|
||||
"lwr %[tmp1], -2(%[p_data_in]) \n\t"
|
||||
"lwr %[tmp2], 0(%[p_coefs]) \n\t"
|
||||
"lwr %[tmp3], -6(%[p_data_in]) \n\t"
|
||||
"lwr %[tmp4], 4(%[p_coefs]) \n\t"
|
||||
"packrl.ph %[tmp1], %[tmp1], %[tmp1] \n\t"
|
||||
"packrl.ph %[tmp3], %[tmp3], %[tmp3] \n\t"
|
||||
"dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t"
|
||||
"dpa.w.ph $ac0, %[tmp3], %[tmp4] \n\t"
|
||||
"addiu %[j], %[j], -1 \n\t"
|
||||
"addiu %[p_data_in], %[p_data_in], -8 \n\t"
|
||||
"bgtz %[j], 2b \n\t"
|
||||
" addiu %[p_coefs], %[p_coefs], 8 \n\t"
|
||||
"3: \n\t"
|
||||
"beq %[k], $zero, 5f \n\t"
|
||||
" nop \n\t"
|
||||
"4: \n\t"
|
||||
"lhu %[tmp1], 0(%[p_data_in]) \n\t"
|
||||
"lhu %[tmp2], 0(%[p_coefs]) \n\t"
|
||||
"addiu %[p_data_in], %[p_data_in], -2 \n\t"
|
||||
"addiu %[k], %[k], -1 \n\t"
|
||||
"dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t"
|
||||
"bgtz %[k], 4b \n\t"
|
||||
" addiu %[p_coefs], %[p_coefs], 2 \n\t"
|
||||
"5: \n\t"
|
||||
"extr_r.w %[out_s32], $ac0, 12 \n\t"
|
||||
"addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t"
|
||||
"subu %[i], %[i], %[factor] \n\t"
|
||||
"shll_s.w %[out_s32], %[out_s32], 16 \n\t"
|
||||
"sra %[out_s32], %[out_s32], 16 \n\t"
|
||||
"sh %[out_s32], 0(%[data_out]) \n\t"
|
||||
"bgtz %[i], 1b \n\t"
|
||||
" addiu %[data_out], %[data_out], 2 \n\t"
|
||||
".set pop \n\t"
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
||||
[tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in),
|
||||
[p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
|
||||
[j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
|
||||
[i] "=&r" (i), [k] "=&r" (k)
|
||||
: [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
|
||||
[p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
|
||||
[delay] "r" (delay), [factor] "r" (factor)
|
||||
: "memory", "hi", "lo"
|
||||
);
|
||||
#else // #if defined(MIPS_DSP_R2_LE)
|
||||
__asm __volatile (
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"sll %[factor_2], %[factor], 1 \n\t"
|
||||
"subu %[i], %[endpos], %[delay] \n\t"
|
||||
"1: \n\t"
|
||||
"move %[p_data_in], %[p_data_in_0] \n\t"
|
||||
"addiu %[out_s32], $zero, 2048 \n\t"
|
||||
"move %[p_coefs], %[p_coefs_0] \n\t"
|
||||
"sra %[j], %[coef_length], 1 \n\t"
|
||||
"beq %[j], $zero, 3f \n\t"
|
||||
" andi %[k], %[coef_length], 1 \n\t"
|
||||
"2: \n\t"
|
||||
"lh %[tmp1], 0(%[p_data_in]) \n\t"
|
||||
"lh %[tmp2], 0(%[p_coefs]) \n\t"
|
||||
"lh %[tmp3], -2(%[p_data_in]) \n\t"
|
||||
"lh %[tmp4], 2(%[p_coefs]) \n\t"
|
||||
"mul %[tmp1], %[tmp1], %[tmp2] \n\t"
|
||||
"addiu %[p_coefs], %[p_coefs], 4 \n\t"
|
||||
"mul %[tmp3], %[tmp3], %[tmp4] \n\t"
|
||||
"addiu %[j], %[j], -1 \n\t"
|
||||
"addiu %[p_data_in], %[p_data_in], -4 \n\t"
|
||||
"addu %[tmp1], %[tmp1], %[tmp3] \n\t"
|
||||
"bgtz %[j], 2b \n\t"
|
||||
" addu %[out_s32], %[out_s32], %[tmp1] \n\t"
|
||||
"3: \n\t"
|
||||
"beq %[k], $zero, 4f \n\t"
|
||||
" nop \n\t"
|
||||
"lh %[tmp1], 0(%[p_data_in]) \n\t"
|
||||
"lh %[tmp2], 0(%[p_coefs]) \n\t"
|
||||
"mul %[tmp1], %[tmp1], %[tmp2] \n\t"
|
||||
"addu %[out_s32], %[out_s32], %[tmp1] \n\t"
|
||||
"4: \n\t"
|
||||
"sra %[out_s32], %[out_s32], 12 \n\t"
|
||||
"addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t"
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
"shll_s.w %[out_s32], %[out_s32], 16 \n\t"
|
||||
"sra %[out_s32], %[out_s32], 16 \n\t"
|
||||
#else // #if defined(MIPS_DSP_R1_LE)
|
||||
"slt %[tmp1], %[max_16], %[out_s32] \n\t"
|
||||
"movn %[out_s32], %[max_16], %[tmp1] \n\t"
|
||||
"slt %[tmp1], %[out_s32], %[min_16] \n\t"
|
||||
"movn %[out_s32], %[min_16], %[tmp1] \n\t"
|
||||
#endif // #if defined(MIPS_DSP_R1_LE)
|
||||
"subu %[i], %[i], %[factor] \n\t"
|
||||
"sh %[out_s32], 0(%[data_out]) \n\t"
|
||||
"bgtz %[i], 1b \n\t"
|
||||
" addiu %[data_out], %[data_out], 2 \n\t"
|
||||
".set pop \n\t"
|
||||
: [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
|
||||
[tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k),
|
||||
[p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
|
||||
[j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
|
||||
[i] "=&r" (i)
|
||||
: [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
|
||||
[p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
|
||||
#if !defined(MIPS_DSP_R1_LE)
|
||||
[max_16] "r" (max_16), [min_16] "r" (min_16),
|
||||
#endif // #if !defined(MIPS_DSP_R1_LE)
|
||||
[delay] "r" (delay), [factor] "r" (factor)
|
||||
: "memory", "hi", "lo"
|
||||
);
|
||||
#endif // #if defined(MIPS_DSP_R2_LE)
|
||||
return 0;
|
||||
}
|
217
webrtc/common_audio/signal_processing/downsample_fast_neon.c
Normal file
217
webrtc/common_audio/signal_processing/downsample_fast_neon.c
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#include <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;
|
||||
}
|
@ -15,19 +15,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#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);
|
||||
en += (*vectorptr * *vectorptr) >> scaling;
|
||||
vectorptr++;
|
||||
}
|
||||
*scale_factor = scaling;
|
89
webrtc/common_audio/signal_processing/filter_ar.c
Normal file
89
webrtc/common_audio/signal_processing/filter_ar.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_FilterAR().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
size_t WebRtcSpl_FilterAR(const int16_t* a,
|
||||
size_t a_length,
|
||||
const int16_t* x,
|
||||
size_t x_length,
|
||||
int16_t* state,
|
||||
size_t state_length,
|
||||
int16_t* state_low,
|
||||
size_t state_low_length,
|
||||
int16_t* filtered,
|
||||
int16_t* filtered_low,
|
||||
size_t filtered_low_length)
|
||||
{
|
||||
int32_t o;
|
||||
int32_t oLOW;
|
||||
size_t i, j, stop;
|
||||
const int16_t* x_ptr = &x[0];
|
||||
int16_t* filteredFINAL_ptr = filtered;
|
||||
int16_t* filteredFINAL_LOW_ptr = filtered_low;
|
||||
|
||||
for (i = 0; i < x_length; i++)
|
||||
{
|
||||
// Calculate filtered[i] and filtered_low[i]
|
||||
const int16_t* a_ptr = &a[1];
|
||||
int16_t* filtered_ptr = &filtered[i - 1];
|
||||
int16_t* filtered_low_ptr = &filtered_low[i - 1];
|
||||
int16_t* state_ptr = &state[state_length - 1];
|
||||
int16_t* state_low_ptr = &state_low[state_length - 1];
|
||||
|
||||
o = (int32_t)(*x_ptr++) << 12;
|
||||
oLOW = (int32_t)0;
|
||||
|
||||
stop = (i < a_length) ? i + 1 : a_length;
|
||||
for (j = 1; j < stop; j++)
|
||||
{
|
||||
o -= *a_ptr * *filtered_ptr--;
|
||||
oLOW -= *a_ptr++ * *filtered_low_ptr--;
|
||||
}
|
||||
for (j = i + 1; j < a_length; j++)
|
||||
{
|
||||
o -= *a_ptr * *state_ptr--;
|
||||
oLOW -= *a_ptr++ * *state_low_ptr--;
|
||||
}
|
||||
|
||||
o += (oLOW >> 12);
|
||||
*filteredFINAL_ptr = (int16_t)((o + (int32_t)2048) >> 12);
|
||||
*filteredFINAL_LOW_ptr++ = (int16_t)(o - ((int32_t)(*filteredFINAL_ptr++)
|
||||
<< 12));
|
||||
}
|
||||
|
||||
// Save the filter state
|
||||
if (x_length >= state_length)
|
||||
{
|
||||
WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state);
|
||||
WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low);
|
||||
} else
|
||||
{
|
||||
for (i = 0; i < state_length - x_length; i++)
|
||||
{
|
||||
state[i] = state[i + x_length];
|
||||
state_low[i] = state_low[i + x_length];
|
||||
}
|
||||
for (i = 0; i < x_length; i++)
|
||||
{
|
||||
state[state_length - x_length + i] = filtered[i];
|
||||
state[state_length - x_length + i] = filtered_low[i];
|
||||
}
|
||||
}
|
||||
|
||||
return x_length;
|
||||
}
|
42
webrtc/common_audio/signal_processing/filter_ar_fast_q12.c
Normal file
42
webrtc/common_audio/signal_processing/filter_ar_fast_q12.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <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);
|
||||
}
|
||||
}
|
218
webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S
Normal file
218
webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S
Normal file
@ -0,0 +1,218 @@
|
||||
@
|
||||
@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
@
|
||||
@ Use of this source code is governed by a BSD-style license
|
||||
@ that can be found in the LICENSE file in the root of the source
|
||||
@ tree. An additional intellectual property rights grant can be found
|
||||
@ in the file PATENTS. All contributing project authors may
|
||||
@ be found in the AUTHORS file in the root of the source tree.
|
||||
@
|
||||
|
||||
@ This file contains the function WebRtcSpl_FilterARFastQ12(), optimized for
|
||||
@ ARMv7 platform. The description header can be found in
|
||||
@ signal_processing_library.h
|
||||
@
|
||||
@ Output is bit-exact with the generic C code as in filter_ar_fast_q12.c, and
|
||||
@ the reference C code at end of this file.
|
||||
|
||||
@ Assumptions:
|
||||
@ (1) data_length > 0
|
||||
@ (2) coefficients_length > 1
|
||||
|
||||
@ Register usage:
|
||||
@
|
||||
@ r0: &data_in[i]
|
||||
@ r1: &data_out[i], for result ouput
|
||||
@ r2: &coefficients[0]
|
||||
@ r3: coefficients_length
|
||||
@ r4: Iteration counter for the outer loop.
|
||||
@ r5: data_out[j] as multiplication inputs
|
||||
@ r6: Calculated value for output data_out[]; interation counter for inner loop
|
||||
@ r7: Partial sum of a filtering multiplication results
|
||||
@ r8: Partial sum of a filtering multiplication results
|
||||
@ r9: &data_out[], for filtering input; data_in[i]
|
||||
@ r10: coefficients[j]
|
||||
@ r11: Scratch
|
||||
@ r12: &coefficients[j]
|
||||
|
||||
#include "webrtc/system_wrappers/interface/asm_defines.h"
|
||||
|
||||
GLOBAL_FUNCTION WebRtcSpl_FilterARFastQ12
|
||||
.align 2
|
||||
DEFINE_FUNCTION WebRtcSpl_FilterARFastQ12
|
||||
push {r4-r11}
|
||||
|
||||
ldrsh r12, [sp, #32] @ data_length
|
||||
subs r4, r12, #1
|
||||
beq ODD_LENGTH @ jump if data_length == 1
|
||||
|
||||
LOOP_LENGTH:
|
||||
add r12, r2, r3, lsl #1
|
||||
sub r12, #4 @ &coefficients[coefficients_length - 2]
|
||||
sub r9, r1, r3, lsl #1
|
||||
add r9, #2 @ &data_out[i - coefficients_length + 1]
|
||||
ldr r5, [r9], #4 @ data_out[i - coefficients_length + {1,2}]
|
||||
|
||||
mov r7, #0 @ sum1
|
||||
mov r8, #0 @ sum2
|
||||
subs r6, r3, #3 @ Iteration counter for inner loop.
|
||||
beq ODD_A_LENGTH @ branch if coefficients_length == 3
|
||||
blt POST_LOOP_A_LENGTH @ branch if coefficients_length == 2
|
||||
|
||||
LOOP_A_LENGTH:
|
||||
ldr r10, [r12], #-4 @ coefficients[j - 1], coefficients[j]
|
||||
subs r6, #2
|
||||
smlatt r8, r10, r5, r8 @ sum2 += coefficients[j] * data_out[i - j + 1];
|
||||
smlatb r7, r10, r5, r7 @ sum1 += coefficients[j] * data_out[i - j];
|
||||
smlabt r7, r10, r5, r7 @ coefficients[j - 1] * data_out[i - j + 1];
|
||||
ldr r5, [r9], #4 @ data_out[i - j + 2], data_out[i - j + 3]
|
||||
smlabb r8, r10, r5, r8 @ coefficients[j - 1] * data_out[i - j + 2];
|
||||
bgt LOOP_A_LENGTH
|
||||
blt POST_LOOP_A_LENGTH
|
||||
|
||||
ODD_A_LENGTH:
|
||||
ldrsh r10, [r12, #2] @ Filter coefficients coefficients[2]
|
||||
sub r12, #2 @ &coefficients[0]
|
||||
smlabb r7, r10, r5, r7 @ sum1 += coefficients[2] * data_out[i - 2];
|
||||
smlabt r8, r10, r5, r8 @ sum2 += coefficients[2] * data_out[i - 1];
|
||||
ldr r5, [r9, #-2] @ data_out[i - 1], data_out[i]
|
||||
|
||||
POST_LOOP_A_LENGTH:
|
||||
ldr r10, [r12] @ coefficients[0], coefficients[1]
|
||||
smlatb r7, r10, r5, r7 @ sum1 += coefficients[1] * data_out[i - 1];
|
||||
|
||||
ldr r9, [r0], #4 @ data_in[i], data_in[i + 1]
|
||||
smulbb r6, r10, r9 @ output1 = coefficients[0] * data_in[i];
|
||||
sub r6, r7 @ output1 -= sum1;
|
||||
|
||||
sbfx r11, r6, #12, #16
|
||||
ssat r7, #16, r6, asr #12
|
||||
cmp r7, r11
|
||||
addeq r6, r6, #2048
|
||||
ssat r6, #16, r6, asr #12
|
||||
strh r6, [r1], #2 @ Store data_out[i]
|
||||
|
||||
smlatb r8, r10, r6, r8 @ sum2 += coefficients[1] * data_out[i];
|
||||
smulbt r6, r10, r9 @ output2 = coefficients[0] * data_in[i + 1];
|
||||
sub r6, r8 @ output1 -= sum1;
|
||||
|
||||
sbfx r11, r6, #12, #16
|
||||
ssat r7, #16, r6, asr #12
|
||||
cmp r7, r11
|
||||
addeq r6, r6, #2048
|
||||
ssat r6, #16, r6, asr #12
|
||||
strh r6, [r1], #2 @ Store data_out[i + 1]
|
||||
|
||||
subs r4, #2
|
||||
bgt LOOP_LENGTH
|
||||
blt END @ For even data_length, it's done. Jump to END.
|
||||
|
||||
@ Process i = data_length -1, for the case of an odd length.
|
||||
ODD_LENGTH:
|
||||
add r12, r2, r3, lsl #1
|
||||
sub r12, #4 @ &coefficients[coefficients_length - 2]
|
||||
sub r9, r1, r3, lsl #1
|
||||
add r9, #2 @ &data_out[i - coefficients_length + 1]
|
||||
mov r7, #0 @ sum1
|
||||
mov r8, #0 @ sum1
|
||||
subs r6, r3, #2 @ inner loop counter
|
||||
beq EVEN_A_LENGTH @ branch if coefficients_length == 2
|
||||
|
||||
LOOP2_A_LENGTH:
|
||||
ldr r10, [r12], #-4 @ coefficients[j - 1], coefficients[j]
|
||||
ldr r5, [r9], #4 @ data_out[i - j], data_out[i - j + 1]
|
||||
subs r6, #2
|
||||
smlatb r7, r10, r5, r7 @ sum1 += coefficients[j] * data_out[i - j];
|
||||
smlabt r8, r10, r5, r8 @ coefficients[j - 1] * data_out[i - j + 1];
|
||||
bgt LOOP2_A_LENGTH
|
||||
addlt r12, #2
|
||||
blt POST_LOOP2_A_LENGTH
|
||||
|
||||
EVEN_A_LENGTH:
|
||||
ldrsh r10, [r12, #2] @ Filter coefficients coefficients[1]
|
||||
ldrsh r5, [r9] @ data_out[i - 1]
|
||||
smlabb r7, r10, r5, r7 @ sum1 += coefficients[1] * data_out[i - 1];
|
||||
|
||||
POST_LOOP2_A_LENGTH:
|
||||
ldrsh r10, [r12] @ Filter coefficients coefficients[0]
|
||||
ldrsh r9, [r0] @ data_in[i]
|
||||
smulbb r6, r10, r9 @ output1 = coefficients[0] * data_in[i];
|
||||
sub r6, r7 @ output1 -= sum1;
|
||||
sub r6, r8 @ output1 -= sum1;
|
||||
sbfx r8, r6, #12, #16
|
||||
ssat r7, #16, r6, asr #12
|
||||
cmp r7, r8
|
||||
addeq r6, r6, #2048
|
||||
ssat r6, #16, r6, asr #12
|
||||
strh r6, [r1] @ Store the data_out[i]
|
||||
|
||||
END:
|
||||
pop {r4-r11}
|
||||
bx lr
|
||||
|
||||
@Reference C code:
|
||||
@
|
||||
@void WebRtcSpl_FilterARFastQ12(int16_t* data_in,
|
||||
@ int16_t* data_out,
|
||||
@ int16_t* __restrict coefficients,
|
||||
@ size_t coefficients_length,
|
||||
@ size_t data_length) {
|
||||
@ size_t i = 0;
|
||||
@ size_t j = 0;
|
||||
@
|
||||
@ assert(data_length > 0);
|
||||
@ assert(coefficients_length > 1);
|
||||
@
|
||||
@ for (i = 0; i < data_length - 1; i += 2) {
|
||||
@ int32_t output1 = 0;
|
||||
@ int32_t sum1 = 0;
|
||||
@ int32_t output2 = 0;
|
||||
@ int32_t sum2 = 0;
|
||||
@
|
||||
@ for (j = coefficients_length - 1; j > 2; j -= 2) {
|
||||
@ sum1 += coefficients[j] * data_out[i - j];
|
||||
@ sum1 += coefficients[j - 1] * data_out[i - j + 1];
|
||||
@ sum2 += coefficients[j] * data_out[i - j + 1];
|
||||
@ sum2 += coefficients[j - 1] * data_out[i - j + 2];
|
||||
@ }
|
||||
@
|
||||
@ if (j == 2) {
|
||||
@ sum1 += coefficients[2] * data_out[i - 2];
|
||||
@ sum2 += coefficients[2] * data_out[i - 1];
|
||||
@ }
|
||||
@
|
||||
@ sum1 += coefficients[1] * data_out[i - 1];
|
||||
@ output1 = coefficients[0] * data_in[i];
|
||||
@ output1 -= sum1;
|
||||
@ // Saturate and store the output.
|
||||
@ output1 = WEBRTC_SPL_SAT(134215679, output1, -134217728);
|
||||
@ data_out[i] = (int16_t)((output1 + 2048) >> 12);
|
||||
@
|
||||
@ sum2 += coefficients[1] * data_out[i];
|
||||
@ output2 = coefficients[0] * data_in[i + 1];
|
||||
@ output2 -= sum2;
|
||||
@ // Saturate and store the output.
|
||||
@ output2 = WEBRTC_SPL_SAT(134215679, output2, -134217728);
|
||||
@ data_out[i + 1] = (int16_t)((output2 + 2048) >> 12);
|
||||
@ }
|
||||
@
|
||||
@ if (i == data_length - 1) {
|
||||
@ int32_t output1 = 0;
|
||||
@ int32_t sum1 = 0;
|
||||
@
|
||||
@ for (j = coefficients_length - 1; j > 1; j -= 2) {
|
||||
@ sum1 += coefficients[j] * data_out[i - j];
|
||||
@ sum1 += coefficients[j - 1] * data_out[i - j + 1];
|
||||
@ }
|
||||
@
|
||||
@ if (j == 1) {
|
||||
@ sum1 += coefficients[1] * data_out[i - 1];
|
||||
@ }
|
||||
@
|
||||
@ output1 = coefficients[0] * data_in[i];
|
||||
@ output1 -= sum1;
|
||||
@ // Saturate and store the output.
|
||||
@ output1 = WEBRTC_SPL_SAT(134215679, output1, -134217728);
|
||||
@ data_out[i] = (int16_t)((output1 + 2048) >> 12);
|
||||
@ }
|
||||
@}
|
140
webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c
Normal file
140
webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <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"
|
||||
);
|
||||
}
|
||||
|
@ -15,35 +15,31 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_ptr,
|
||||
WebRtc_Word16* out_ptr,
|
||||
WebRtc_Word16* B,
|
||||
WebRtc_Word16 B_length,
|
||||
WebRtc_Word16 length)
|
||||
void WebRtcSpl_FilterMAFastQ12(const int16_t* in_ptr,
|
||||
int16_t* out_ptr,
|
||||
const int16_t* B,
|
||||
size_t B_length,
|
||||
size_t length)
|
||||
{
|
||||
WebRtc_Word32 o;
|
||||
int i, j;
|
||||
size_t i, j;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
G_CONST WebRtc_Word16* b_ptr = &B[0];
|
||||
G_CONST WebRtc_Word16* x_ptr = &in_ptr[i];
|
||||
|
||||
o = (WebRtc_Word32)0;
|
||||
int32_t o = 0;
|
||||
|
||||
for (j = 0; j < B_length; j++)
|
||||
{
|
||||
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
|
||||
o += B[j] * in_ptr[i - j];
|
||||
}
|
||||
|
||||
// If output is higher than 32768, saturate it. Same with negative side
|
||||
// 2^27 = 134217728, which corresponds to 32768 in Q12
|
||||
|
||||
// Saturate the output
|
||||
o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);
|
||||
o = WEBRTC_SPL_SAT((int32_t)134215679, o, (int32_t)-134217728);
|
||||
|
||||
*out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
|
||||
*out_ptr++ = (int16_t)((o + (int32_t)2048) >> 12);
|
||||
}
|
||||
return;
|
||||
}
|
@ -10,14 +10,15 @@
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the Hanning table with 256 entries.
|
||||
* This file contains the function WebRtcSpl_GetHanningWindow().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
// Hanning table with 256 entries
|
||||
WebRtc_Word16 WebRtcSpl_kHanningTable[] = {
|
||||
static const int16_t kHanningTable[] = {
|
||||
1, 2, 6, 10, 15, 22, 30, 39,
|
||||
50, 62, 75, 89, 104, 121, 138, 157,
|
||||
178, 199, 222, 246, 271, 297, 324, 353,
|
||||
@ -51,3 +52,26 @@ WebRtc_Word16 WebRtcSpl_kHanningTable[] = {
|
||||
16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345,
|
||||
16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384
|
||||
};
|
||||
|
||||
void WebRtcSpl_GetHanningWindow(int16_t *v, size_t size)
|
||||
{
|
||||
size_t jj;
|
||||
int16_t *vptr1;
|
||||
|
||||
int32_t index;
|
||||
int32_t factor = ((int32_t)0x40000000);
|
||||
|
||||
factor = WebRtcSpl_DivW32W16(factor, (int16_t)size);
|
||||
if (size < 513)
|
||||
index = (int32_t)-0x200000;
|
||||
else
|
||||
index = (int32_t)-0x100000;
|
||||
vptr1 = v;
|
||||
|
||||
for (jj = 0; jj < size; jj++)
|
||||
{
|
||||
index += factor;
|
||||
(*vptr1++) = kHanningTable[index >> 22];
|
||||
}
|
||||
|
||||
}
|
@ -15,17 +15,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times)
|
||||
int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector,
|
||||
size_t in_vector_length,
|
||||
size_t times)
|
||||
{
|
||||
int nbits = WebRtcSpl_GetSizeInBits(times);
|
||||
int i;
|
||||
WebRtc_Word16 smax = -1;
|
||||
WebRtc_Word16 sabs;
|
||||
WebRtc_Word16 *sptr = in_vector;
|
||||
int t;
|
||||
int looptimes = in_vector_length;
|
||||
int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t)times);
|
||||
size_t i;
|
||||
int16_t smax = -1;
|
||||
int16_t sabs;
|
||||
int16_t *sptr = in_vector;
|
||||
int16_t t;
|
||||
size_t looptimes = in_vector_length;
|
||||
|
||||
for (i = looptimes; i > 0; i--)
|
||||
{
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains implementations of the iLBC specific functions
|
||||
* WebRtcSpl_ReverseOrderMultArrayElements()
|
||||
* WebRtcSpl_ElementwiseVectorMult()
|
||||
* WebRtcSpl_AddVectorsAndShift()
|
||||
* WebRtcSpl_AddAffineVectorToVector()
|
||||
* WebRtcSpl_AffineTransformVector()
|
||||
*
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_ReverseOrderMultArrayElements(int16_t *out, const int16_t *in,
|
||||
const int16_t *win,
|
||||
size_t vector_length,
|
||||
int16_t right_shifts)
|
||||
{
|
||||
size_t i;
|
||||
int16_t *outptr = out;
|
||||
const int16_t *inptr = in;
|
||||
const int16_t *winptr = win;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
*outptr++ = (int16_t)((*inptr++ * *winptr--) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_ElementwiseVectorMult(int16_t *out, const int16_t *in,
|
||||
const int16_t *win, size_t vector_length,
|
||||
int16_t right_shifts)
|
||||
{
|
||||
size_t i;
|
||||
int16_t *outptr = out;
|
||||
const int16_t *inptr = in;
|
||||
const int16_t *winptr = win;
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
*outptr++ = (int16_t)((*inptr++ * *winptr++) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AddVectorsAndShift(int16_t *out, const int16_t *in1,
|
||||
const int16_t *in2, size_t vector_length,
|
||||
int16_t right_shifts)
|
||||
{
|
||||
size_t i;
|
||||
int16_t *outptr = out;
|
||||
const int16_t *in1ptr = in1;
|
||||
const int16_t *in2ptr = in2;
|
||||
for (i = vector_length; i > 0; i--)
|
||||
{
|
||||
(*outptr++) = (int16_t)(((*in1ptr++) + (*in2ptr++)) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AddAffineVectorToVector(int16_t *out, int16_t *in,
|
||||
int16_t gain, int32_t add_constant,
|
||||
int16_t right_shifts,
|
||||
size_t vector_length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
out[i] += (int16_t)((in[i] * gain + add_constant) >> right_shifts);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSpl_AffineTransformVector(int16_t *out, int16_t *in,
|
||||
int16_t gain, int32_t add_constant,
|
||||
int16_t right_shifts, size_t vector_length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < vector_length; i++)
|
||||
{
|
||||
out[i] = (int16_t)((in[i] * gain + add_constant) >> right_shifts);
|
||||
}
|
||||
}
|
97
webrtc/common_audio/signal_processing/include/real_fft.h
Normal file
97
webrtc/common_audio/signal_processing/include/real_fft.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
|
||||
#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
// For ComplexFFT(), the maximum fft order is 10;
|
||||
// for OpenMax FFT in ARM, it is 12;
|
||||
// WebRTC APM uses orders of only 7 and 8.
|
||||
enum {kMaxFFTOrder = 10};
|
||||
|
||||
struct RealFFT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
|
||||
void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
|
||||
|
||||
// Compute an FFT for a real-valued signal of length of 2^order,
|
||||
// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
|
||||
// specification structure, which must be initialized prior to calling the FFT
|
||||
// function with WebRtcSpl_CreateRealFFT().
|
||||
// The relationship between the input and output sequences can
|
||||
// be expressed in terms of the DFT, i.e.:
|
||||
// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
|
||||
// n=0,1,2,...N-1
|
||||
// N=2^order.
|
||||
// The conjugate-symmetric output sequence is represented using a CCS vector,
|
||||
// which is of length N+2, and is organized as follows:
|
||||
// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
|
||||
// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
|
||||
// where R[n] and I[n], respectively, denote the real and imaginary components
|
||||
// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
|
||||
// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
|
||||
// the foldover frequency.
|
||||
//
|
||||
// Input Arguments:
|
||||
// self - pointer to preallocated and initialized FFT specification structure.
|
||||
// real_data_in - the input signal. For an ARM Neon platform, it must be
|
||||
// aligned on a 32-byte boundary.
|
||||
//
|
||||
// Output Arguments:
|
||||
// complex_data_out - the output complex signal with (2^order + 2) 16-bit
|
||||
// elements. For an ARM Neon platform, it must be different
|
||||
// from real_data_in, and aligned on a 32-byte boundary.
|
||||
//
|
||||
// Return Value:
|
||||
// 0 - FFT calculation is successful.
|
||||
// -1 - Error with bad arguments (NULL pointers).
|
||||
int WebRtcSpl_RealForwardFFT(struct RealFFT* self,
|
||||
const int16_t* real_data_in,
|
||||
int16_t* complex_data_out);
|
||||
|
||||
// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
|
||||
// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
|
||||
// the specification structure, which must be initialized prior to calling the
|
||||
// FFT function with WebRtcSpl_CreateRealFFT().
|
||||
// For a transform of length M, the input sequence is represented using a packed
|
||||
// CCS vector of length M+2, which is explained in the comments for
|
||||
// WebRtcSpl_RealForwardFFTC above.
|
||||
//
|
||||
// Input Arguments:
|
||||
// self - pointer to preallocated and initialized FFT specification structure.
|
||||
// complex_data_in - the input complex signal with (2^order + 2) 16-bit
|
||||
// elements. For an ARM Neon platform, it must be aligned on
|
||||
// a 32-byte boundary.
|
||||
//
|
||||
// Output Arguments:
|
||||
// real_data_out - the output real signal. For an ARM Neon platform, it must
|
||||
// be different to complex_data_in, and aligned on a 32-byte
|
||||
// boundary.
|
||||
//
|
||||
// Return Value:
|
||||
// 0 or a positive number - a value that the elements in the |real_data_out|
|
||||
// should be shifted left with in order to get
|
||||
// correct physical values.
|
||||
// -1 - Error with bad arguments (NULL pointers).
|
||||
int WebRtcSpl_RealInverseFFT(struct RealFFT* self,
|
||||
const int16_t* complex_data_in,
|
||||
int16_t* real_data_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
|
File diff suppressed because it is too large
Load Diff
173
webrtc/common_audio/signal_processing/include/spl_inl.h
Normal file
173
webrtc/common_audio/signal_processing/include/spl_inl.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
// This header file includes the inline functions in
|
||||
// the fix point signal processing library.
|
||||
|
||||
#ifndef WEBRTC_SPL_SPL_INL_H_
|
||||
#define WEBRTC_SPL_SPL_INL_H_
|
||||
|
||||
#ifdef WEBRTC_ARCH_ARM_V7
|
||||
#include "webrtc/common_audio/signal_processing/include/spl_inl_armv7.h"
|
||||
#else
|
||||
|
||||
#if defined(MIPS32_LE)
|
||||
#include "webrtc/common_audio/signal_processing/include/spl_inl_mips.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MIPS_DSP_R1_LE)
|
||||
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
|
||||
int16_t out16 = (int16_t) value32;
|
||||
|
||||
if (value32 > 32767)
|
||||
out16 = 32767;
|
||||
else if (value32 < -32768)
|
||||
out16 = -32768;
|
||||
|
||||
return out16;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_sum;
|
||||
|
||||
// Perform long addition
|
||||
l_sum = l_var1 + l_var2;
|
||||
|
||||
if (l_var1 < 0) { // Check for underflow.
|
||||
if ((l_var2 < 0) && (l_sum >= 0)) {
|
||||
l_sum = (int32_t)0x80000000;
|
||||
}
|
||||
} else { // Check for overflow.
|
||||
if ((l_var2 > 0) && (l_sum < 0)) {
|
||||
l_sum = (int32_t)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
return l_sum;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_diff;
|
||||
|
||||
// Perform subtraction.
|
||||
l_diff = l_var1 - l_var2;
|
||||
|
||||
if (l_var1 < 0) { // Check for underflow.
|
||||
if ((l_var2 > 0) && (l_diff > 0)) {
|
||||
l_diff = (int32_t)0x80000000;
|
||||
}
|
||||
} else { // Check for overflow.
|
||||
if ((l_var2 < 0) && (l_diff < 0)) {
|
||||
l_diff = (int32_t)0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
return l_diff;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
|
||||
return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b);
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
|
||||
return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2);
|
||||
}
|
||||
#endif // #if !defined(MIPS_DSP_R1_LE)
|
||||
|
||||
#if !defined(MIPS32_LE)
|
||||
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
|
||||
int16_t bits;
|
||||
|
||||
if (0xFFFF0000 & n) {
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 0;
|
||||
}
|
||||
if (0x0000FF00 & (n >> bits)) bits += 8;
|
||||
if (0x000000F0 & (n >> bits)) bits += 4;
|
||||
if (0x0000000C & (n >> bits)) bits += 2;
|
||||
if (0x00000002 & (n >> bits)) bits += 1;
|
||||
if (0x00000001 & (n >> bits)) bits += 1;
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
|
||||
int16_t zeros;
|
||||
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (a < 0) {
|
||||
a = ~a;
|
||||
}
|
||||
|
||||
if (!(0xFFFF8000 & a)) {
|
||||
zeros = 16;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xFF800000 & (a << zeros))) zeros += 8;
|
||||
if (!(0xF8000000 & (a << zeros))) zeros += 4;
|
||||
if (!(0xE0000000 & (a << zeros))) zeros += 2;
|
||||
if (!(0xC0000000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
|
||||
int16_t zeros;
|
||||
|
||||
if (a == 0) return 0;
|
||||
|
||||
if (!(0xFFFF0000 & a)) {
|
||||
zeros = 16;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xFF000000 & (a << zeros))) zeros += 8;
|
||||
if (!(0xF0000000 & (a << zeros))) zeros += 4;
|
||||
if (!(0xC0000000 & (a << zeros))) zeros += 2;
|
||||
if (!(0x80000000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
|
||||
int16_t zeros;
|
||||
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (a < 0) {
|
||||
a = ~a;
|
||||
}
|
||||
|
||||
if (!(0xFF80 & a)) {
|
||||
zeros = 8;
|
||||
} else {
|
||||
zeros = 0;
|
||||
}
|
||||
if (!(0xF800 & (a << zeros))) zeros += 4;
|
||||
if (!(0xE000 & (a << zeros))) zeros += 2;
|
||||
if (!(0xC000 & (a << zeros))) zeros += 1;
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
|
||||
return (a * b + c);
|
||||
}
|
||||
#endif // #if !defined(MIPS32_LE)
|
||||
|
||||
#endif // WEBRTC_ARCH_ARM_V7
|
||||
|
||||
#endif // WEBRTC_SPL_SPL_INL_H_
|
136
webrtc/common_audio/signal_processing/include/spl_inl_armv7.h
Normal file
136
webrtc/common_audio/signal_processing/include/spl_inl_armv7.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/* This header file includes the inline functions for ARM processors in
|
||||
* the fix point signal processing library.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SPL_SPL_INL_ARMV7_H_
|
||||
#define WEBRTC_SPL_SPL_INL_ARMV7_H_
|
||||
|
||||
/* TODO(kma): Replace some assembly code with GCC intrinsics
|
||||
* (e.g. __builtin_clz).
|
||||
*/
|
||||
|
||||
/* This function produces result that is not bit exact with that by the generic
|
||||
* C version in some cases, although the former is at least as accurate as the
|
||||
* later.
|
||||
*/
|
||||
static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) {
|
||||
int32_t tmp = 0;
|
||||
__asm __volatile ("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline int32_t WEBRTC_SPL_MUL_16_16(int16_t a, int16_t b) {
|
||||
int32_t tmp = 0;
|
||||
__asm __volatile ("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// TODO(kma): add unit test.
|
||||
static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
|
||||
int32_t tmp = 0;
|
||||
__asm __volatile ("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
|
||||
int32_t s_sum = 0;
|
||||
|
||||
__asm __volatile ("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b));
|
||||
|
||||
return (int16_t) s_sum;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_sum = 0;
|
||||
|
||||
__asm __volatile ("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2));
|
||||
|
||||
return l_sum;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_sub = 0;
|
||||
|
||||
__asm __volatile ("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2));
|
||||
|
||||
return l_sub;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
|
||||
int32_t s_sub = 0;
|
||||
|
||||
__asm __volatile ("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2));
|
||||
|
||||
return (int16_t)s_sub;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
|
||||
int32_t tmp = 0;
|
||||
|
||||
__asm __volatile ("clz %0, %1":"=r"(tmp):"r"(n));
|
||||
|
||||
return (int16_t)(32 - tmp);
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
|
||||
int32_t tmp = 0;
|
||||
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (a < 0) {
|
||||
a ^= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
__asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a));
|
||||
|
||||
return (int16_t)(tmp - 1);
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
|
||||
int tmp = 0;
|
||||
|
||||
if (a == 0) return 0;
|
||||
|
||||
__asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a));
|
||||
|
||||
return (int16_t)tmp;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
|
||||
int32_t tmp = 0;
|
||||
int32_t a_32 = a;
|
||||
|
||||
if (a_32 == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (a_32 < 0) {
|
||||
a_32 ^= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
__asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a_32));
|
||||
|
||||
return (int16_t)(tmp - 17);
|
||||
}
|
||||
|
||||
// TODO(kma): add unit test.
|
||||
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
|
||||
int32_t out = 0;
|
||||
|
||||
__asm __volatile ("ssat %0, #16, %1" : "=r"(out) : "r"(value32));
|
||||
|
||||
return (int16_t)out;
|
||||
}
|
||||
|
||||
#endif // WEBRTC_SPL_SPL_INL_ARMV7_H_
|
225
webrtc/common_audio/signal_processing/include/spl_inl_mips.h
Normal file
225
webrtc/common_audio/signal_processing/include/spl_inl_mips.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
// This header file includes the inline functions in
|
||||
// the fix point signal processing library.
|
||||
|
||||
#ifndef WEBRTC_SPL_SPL_INL_MIPS_H_
|
||||
#define WEBRTC_SPL_SPL_INL_MIPS_H_
|
||||
|
||||
static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a,
|
||||
int32_t b) {
|
||||
int32_t value32 = 0;
|
||||
int32_t a1 = 0, b1 = 0;
|
||||
|
||||
__asm __volatile(
|
||||
#if defined(MIPS32_R2_LE)
|
||||
"seh %[a1], %[a] \n\t"
|
||||
"seh %[b1], %[b] \n\t"
|
||||
#else
|
||||
"sll %[a1], %[a], 16 \n\t"
|
||||
"sll %[b1], %[b], 16 \n\t"
|
||||
"sra %[a1], %[a1], 16 \n\t"
|
||||
"sra %[b1], %[b1], 16 \n\t"
|
||||
#endif
|
||||
"mul %[value32], %[a1], %[b1] \n\t"
|
||||
: [value32] "=r" (value32), [a1] "=&r" (a1), [b1] "=&r" (b1)
|
||||
: [a] "r" (a), [b] "r" (b)
|
||||
: "hi", "lo"
|
||||
);
|
||||
return value32;
|
||||
}
|
||||
|
||||
static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a,
|
||||
int32_t b) {
|
||||
int32_t value32 = 0, b1 = 0, b2 = 0;
|
||||
int32_t a1 = 0;
|
||||
|
||||
__asm __volatile(
|
||||
#if defined(MIPS32_R2_LE)
|
||||
"seh %[a1], %[a] \n\t"
|
||||
#else
|
||||
"sll %[a1], %[a], 16 \n\t"
|
||||
"sra %[a1], %[a1], 16 \n\t"
|
||||
#endif
|
||||
"andi %[b2], %[b], 0xFFFF \n\t"
|
||||
"sra %[b1], %[b], 16 \n\t"
|
||||
"sra %[b2], %[b2], 1 \n\t"
|
||||
"mul %[value32], %[a1], %[b1] \n\t"
|
||||
"mul %[b2], %[a1], %[b2] \n\t"
|
||||
"addiu %[b2], %[b2], 0x4000 \n\t"
|
||||
"sra %[b2], %[b2], 15 \n\t"
|
||||
"addu %[value32], %[value32], %[b2] \n\t"
|
||||
: [value32] "=&r" (value32), [b1] "=&r" (b1), [b2] "=&r" (b2),
|
||||
[a1] "=&r" (a1)
|
||||
: [a] "r" (a), [b] "r" (b)
|
||||
: "hi", "lo"
|
||||
);
|
||||
return value32;
|
||||
}
|
||||
|
||||
#if defined(MIPS_DSP_R1_LE)
|
||||
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
|
||||
__asm __volatile(
|
||||
"shll_s.w %[value32], %[value32], 16 \n\t"
|
||||
"sra %[value32], %[value32], 16 \n\t"
|
||||
: [value32] "+r" (value32)
|
||||
:
|
||||
);
|
||||
int16_t out16 = (int16_t)value32;
|
||||
return out16;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
|
||||
int32_t value32 = 0;
|
||||
|
||||
__asm __volatile(
|
||||
"addq_s.ph %[value32], %[a], %[b] \n\t"
|
||||
: [value32] "=r" (value32)
|
||||
: [a] "r" (a), [b] "r" (b)
|
||||
);
|
||||
return (int16_t)value32;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_sum;
|
||||
|
||||
__asm __volatile(
|
||||
"addq_s.w %[l_sum], %[l_var1], %[l_var2] \n\t"
|
||||
: [l_sum] "=r" (l_sum)
|
||||
: [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
|
||||
);
|
||||
|
||||
return l_sum;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
|
||||
int32_t value32;
|
||||
|
||||
__asm __volatile(
|
||||
"subq_s.ph %[value32], %[var1], %[var2] \n\t"
|
||||
: [value32] "=r" (value32)
|
||||
: [var1] "r" (var1), [var2] "r" (var2)
|
||||
);
|
||||
|
||||
return (int16_t)value32;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
|
||||
int32_t l_diff;
|
||||
|
||||
__asm __volatile(
|
||||
"subq_s.w %[l_diff], %[l_var1], %[l_var2] \n\t"
|
||||
: [l_diff] "=r" (l_diff)
|
||||
: [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
|
||||
);
|
||||
|
||||
return l_diff;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
|
||||
int bits = 0;
|
||||
int i32 = 32;
|
||||
|
||||
__asm __volatile(
|
||||
"clz %[bits], %[n] \n\t"
|
||||
"subu %[bits], %[i32], %[bits] \n\t"
|
||||
: [bits] "=&r" (bits)
|
||||
: [n] "r" (n), [i32] "r" (i32)
|
||||
);
|
||||
|
||||
return (int16_t)bits;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
|
||||
int zeros = 0;
|
||||
|
||||
__asm __volatile(
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"bnez %[a], 1f \n\t"
|
||||
" sra %[zeros], %[a], 31 \n\t"
|
||||
"b 2f \n\t"
|
||||
" move %[zeros], $zero \n\t"
|
||||
"1: \n\t"
|
||||
"xor %[zeros], %[a], %[zeros] \n\t"
|
||||
"clz %[zeros], %[zeros] \n\t"
|
||||
"addiu %[zeros], %[zeros], -1 \n\t"
|
||||
"2: \n\t"
|
||||
".set pop \n\t"
|
||||
: [zeros]"=&r"(zeros)
|
||||
: [a] "r" (a)
|
||||
);
|
||||
|
||||
return (int16_t)zeros;
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
|
||||
int zeros = 0;
|
||||
|
||||
__asm __volatile(
|
||||
"clz %[zeros], %[a] \n\t"
|
||||
: [zeros] "=r" (zeros)
|
||||
: [a] "r" (a)
|
||||
);
|
||||
|
||||
return (int16_t)(zeros & 0x1f);
|
||||
}
|
||||
|
||||
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
|
||||
int zeros = 0;
|
||||
int a0 = a << 16;
|
||||
|
||||
__asm __volatile(
|
||||
".set push \n\t"
|
||||
".set noreorder \n\t"
|
||||
"bnez %[a0], 1f \n\t"
|
||||
" sra %[zeros], %[a0], 31 \n\t"
|
||||
"b 2f \n\t"
|
||||
" move %[zeros], $zero \n\t"
|
||||
"1: \n\t"
|
||||
"xor %[zeros], %[a0], %[zeros] \n\t"
|
||||
"clz %[zeros], %[zeros] \n\t"
|
||||
"addiu %[zeros], %[zeros], -1 \n\t"
|
||||
"2: \n\t"
|
||||
".set pop \n\t"
|
||||
: [zeros]"=&r"(zeros)
|
||||
: [a0] "r" (a0)
|
||||
);
|
||||
|
||||
return (int16_t)zeros;
|
||||
}
|
||||
|
||||
static __inline int32_t WebRtc_MulAccumW16(int16_t a,
|
||||
int16_t b,
|
||||
int32_t c) {
|
||||
int32_t res = 0, c1 = 0;
|
||||
__asm __volatile(
|
||||
#if defined(MIPS32_R2_LE)
|
||||
"seh %[a], %[a] \n\t"
|
||||
"seh %[b], %[b] \n\t"
|
||||
#else
|
||||
"sll %[a], %[a], 16 \n\t"
|
||||
"sll %[b], %[b], 16 \n\t"
|
||||
"sra %[a], %[a], 16 \n\t"
|
||||
"sra %[b], %[b], 16 \n\t"
|
||||
#endif
|
||||
"mul %[res], %[a], %[b] \n\t"
|
||||
"addu %[c1], %[c], %[res] \n\t"
|
||||
: [c1] "=r" (c1), [res] "=&r" (res)
|
||||
: [a] "r" (a), [b] "r" (b), [c] "r" (c)
|
||||
: "hi", "lo"
|
||||
);
|
||||
return (c1);
|
||||
}
|
||||
|
||||
#endif // WEBRTC_SPL_SPL_INL_MIPS_H_
|
246
webrtc/common_audio/signal_processing/levinson_durbin.c
Normal file
246
webrtc/common_audio/signal_processing/levinson_durbin.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains the function WebRtcSpl_LevinsonDurbin().
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#define SPL_LEVINSON_MAXORDER 20
|
||||
|
||||
int16_t WebRtcSpl_LevinsonDurbin(const int32_t* R, int16_t* A, int16_t* K,
|
||||
size_t order)
|
||||
{
|
||||
size_t i, j;
|
||||
// Auto-correlation coefficients in high precision
|
||||
int16_t R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// LPC coefficients in high precision
|
||||
int16_t A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// LPC coefficients for next iteration
|
||||
int16_t A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1];
|
||||
// Reflection coefficient in high precision
|
||||
int16_t K_hi, K_low;
|
||||
// Prediction gain Alpha in high precision and with scale factor
|
||||
int16_t Alpha_hi, Alpha_low, Alpha_exp;
|
||||
int16_t tmp_hi, tmp_low;
|
||||
int32_t temp1W32, temp2W32, temp3W32;
|
||||
int16_t norm;
|
||||
|
||||
// Normalize the autocorrelation R[0]...R[order+1]
|
||||
|
||||
norm = WebRtcSpl_NormW32(R[0]);
|
||||
|
||||
for (i = 0; i <= order; ++i)
|
||||
{
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
|
||||
// Put R in hi and low format
|
||||
R_hi[i] = (int16_t)(temp1W32 >> 16);
|
||||
R_low[i] = (int16_t)((temp1W32 - ((int32_t)R_hi[i] << 16)) >> 1);
|
||||
}
|
||||
|
||||
// K = A[1] = -R[1] / R[0]
|
||||
|
||||
temp2W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[1],16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((int32_t)R_low[1],1); // R[1] in Q31
|
||||
temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1]
|
||||
temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31
|
||||
// Put back the sign on R[1]
|
||||
if (temp2W32 > 0)
|
||||
{
|
||||
temp1W32 = -temp1W32;
|
||||
}
|
||||
|
||||
// Put K in hi and low format
|
||||
K_hi = (int16_t)(temp1W32 >> 16);
|
||||
K_low = (int16_t)((temp1W32 - ((int32_t)K_hi << 16)) >> 1);
|
||||
|
||||
// Store first reflection coefficient
|
||||
K[0] = K_hi;
|
||||
|
||||
temp1W32 >>= 4; // A[1] in Q27.
|
||||
|
||||
// Put A[1] in hi and low format
|
||||
A_hi[1] = (int16_t)(temp1W32 >> 16);
|
||||
A_low[1] = (int16_t)((temp1W32 - ((int32_t)A_hi[1] << 16)) >> 1);
|
||||
|
||||
// Alpha = R[0] * (1-K^2)
|
||||
|
||||
temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) << 1; // = k^2 in Q31
|
||||
|
||||
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
|
||||
temp1W32 = (int32_t)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31
|
||||
|
||||
// Store temp1W32 = 1 - K[0]*K[0] on hi and low format
|
||||
tmp_hi = (int16_t)(temp1W32 >> 16);
|
||||
tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
|
||||
|
||||
// Calculate Alpha in Q31
|
||||
temp1W32 = (R_hi[0] * tmp_hi + (R_hi[0] * tmp_low >> 15) +
|
||||
(R_low[0] * tmp_hi >> 15)) << 1;
|
||||
|
||||
// Normalize Alpha and put it in hi and low format
|
||||
|
||||
Alpha_exp = WebRtcSpl_NormW32(temp1W32);
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
|
||||
Alpha_hi = (int16_t)(temp1W32 >> 16);
|
||||
Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);
|
||||
|
||||
// Perform the iterative calculations in the Levinson-Durbin algorithm
|
||||
|
||||
for (i = 2; i <= order; i++)
|
||||
{
|
||||
/* ----
|
||||
temp1W32 = R[i] + > R[j]*A[i-j]
|
||||
/
|
||||
----
|
||||
j=1..i-1
|
||||
*/
|
||||
|
||||
temp1W32 = 0;
|
||||
|
||||
for (j = 1; j < i; j++)
|
||||
{
|
||||
// temp1W32 is in Q31
|
||||
temp1W32 += (R_hi[j] * A_hi[i - j] << 1) +
|
||||
(((R_hi[j] * A_low[i - j] >> 15) +
|
||||
(R_low[j] * A_hi[i - j] >> 15)) << 1);
|
||||
}
|
||||
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);
|
||||
temp1W32 += (WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[i], 16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((int32_t)R_low[i], 1));
|
||||
|
||||
// K = -temp1W32 / Alpha
|
||||
temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32)
|
||||
temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha
|
||||
|
||||
// Put the sign of temp1W32 back again
|
||||
if (temp1W32 > 0)
|
||||
{
|
||||
temp3W32 = -temp3W32;
|
||||
}
|
||||
|
||||
// Use the Alpha shifts from earlier to de-normalize
|
||||
norm = WebRtcSpl_NormW32(temp3W32);
|
||||
if ((Alpha_exp <= norm) || (temp3W32 == 0))
|
||||
{
|
||||
temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp);
|
||||
} else
|
||||
{
|
||||
if (temp3W32 > 0)
|
||||
{
|
||||
temp3W32 = (int32_t)0x7fffffffL;
|
||||
} else
|
||||
{
|
||||
temp3W32 = (int32_t)0x80000000L;
|
||||
}
|
||||
}
|
||||
|
||||
// Put K on hi and low format
|
||||
K_hi = (int16_t)(temp3W32 >> 16);
|
||||
K_low = (int16_t)((temp3W32 - ((int32_t)K_hi << 16)) >> 1);
|
||||
|
||||
// Store Reflection coefficient in Q15
|
||||
K[i - 1] = K_hi;
|
||||
|
||||
// Test for unstable filter.
|
||||
// If unstable return 0 and let the user decide what to do in that case
|
||||
|
||||
if ((int32_t)WEBRTC_SPL_ABS_W16(K_hi) > (int32_t)32750)
|
||||
{
|
||||
return 0; // Unstable filter
|
||||
}
|
||||
|
||||
/*
|
||||
Compute updated LPC coefficient: Anew[i]
|
||||
Anew[j]= A[j] + K*A[i-j] for j=1..i-1
|
||||
Anew[i]= K
|
||||
*/
|
||||
|
||||
for (j = 1; j < i; j++)
|
||||
{
|
||||
// temp1W32 = A[j] in Q27
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[j],16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[j],1);
|
||||
|
||||
// temp1W32 += K*A[i-j] in Q27
|
||||
temp1W32 += (K_hi * A_hi[i - j] + (K_hi * A_low[i - j] >> 15) +
|
||||
(K_low * A_hi[i - j] >> 15)) << 1;
|
||||
|
||||
// Put Anew in hi and low format
|
||||
A_upd_hi[j] = (int16_t)(temp1W32 >> 16);
|
||||
A_upd_low[j] = (int16_t)(
|
||||
(temp1W32 - ((int32_t)A_upd_hi[j] << 16)) >> 1);
|
||||
}
|
||||
|
||||
// temp3W32 = K in Q27 (Convert from Q31 to Q27)
|
||||
temp3W32 >>= 4;
|
||||
|
||||
// Store Anew in hi and low format
|
||||
A_upd_hi[i] = (int16_t)(temp3W32 >> 16);
|
||||
A_upd_low[i] = (int16_t)(
|
||||
(temp3W32 - ((int32_t)A_upd_hi[i] << 16)) >> 1);
|
||||
|
||||
// Alpha = Alpha * (1-K^2)
|
||||
|
||||
temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) << 1; // K*K in Q31
|
||||
|
||||
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
|
||||
temp1W32 = (int32_t)0x7fffffffL - temp1W32; // 1 - K*K in Q31
|
||||
|
||||
// Convert 1- K^2 in hi and low format
|
||||
tmp_hi = (int16_t)(temp1W32 >> 16);
|
||||
tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
|
||||
|
||||
// Calculate Alpha = Alpha * (1-K^2) in Q31
|
||||
temp1W32 = (Alpha_hi * tmp_hi + (Alpha_hi * tmp_low >> 15) +
|
||||
(Alpha_low * tmp_hi >> 15)) << 1;
|
||||
|
||||
// Normalize Alpha and store it on hi and low format
|
||||
|
||||
norm = WebRtcSpl_NormW32(temp1W32);
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
|
||||
|
||||
Alpha_hi = (int16_t)(temp1W32 >> 16);
|
||||
Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);
|
||||
|
||||
// Update the total normalization of Alpha
|
||||
Alpha_exp = Alpha_exp + norm;
|
||||
|
||||
// Update A[]
|
||||
|
||||
for (j = 1; j <= i; j++)
|
||||
{
|
||||
A_hi[j] = A_upd_hi[j];
|
||||
A_low[j] = A_upd_low[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set A[0] to 1.0 and store the A[i] i=1...order in Q12
|
||||
(Convert from Q27 and use rounding)
|
||||
*/
|
||||
|
||||
A[0] = 4096;
|
||||
|
||||
for (i = 1; i <= order; i++)
|
||||
{
|
||||
// temp1W32 in Q27
|
||||
temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[i], 16)
|
||||
+ WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[i], 1);
|
||||
// Round and store upper word
|
||||
A[i] = (int16_t)(((temp1W32 << 1) + 32768) >> 16);
|
||||
}
|
||||
return 1; // Stable filters
|
||||
}
|
@ -15,43 +15,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50
|
||||
|
||||
void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16)
|
||||
void WebRtcSpl_LpcToReflCoef(int16_t* a16, int use_order, int16_t* k16)
|
||||
{
|
||||
int m, k;
|
||||
WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER];
|
||||
WebRtc_Word32 tmp_inv_denom32;
|
||||
WebRtc_Word16 tmp_inv_denom16;
|
||||
int32_t tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER];
|
||||
int32_t tmp_inv_denom32;
|
||||
int16_t tmp_inv_denom16;
|
||||
|
||||
k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15
|
||||
k16[use_order - 1] = a16[use_order] << 3; // Q12<<3 => Q15
|
||||
for (m = use_order - 1; m > 0; m--)
|
||||
{
|
||||
// (1 - k^2) in Q30
|
||||
tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]);
|
||||
tmp_inv_denom32 = 1073741823 - k16[m] * k16[m];
|
||||
// (1 - k^2) in Q15
|
||||
tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15);
|
||||
tmp_inv_denom16 = (int16_t)(tmp_inv_denom32 >> 15);
|
||||
|
||||
for (k = 1; k <= m; k++)
|
||||
{
|
||||
// tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]);
|
||||
|
||||
// [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28
|
||||
tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16)
|
||||
- WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);
|
||||
tmp32[k] = (a16[k] << 16) - (k16[m] * a16[m - k + 1] << 1);
|
||||
|
||||
tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13
|
||||
}
|
||||
|
||||
for (k = 1; k < m; k++)
|
||||
{
|
||||
a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12
|
||||
a16[k] = (int16_t)(tmp32[k] >> 1); // Q13>>1 => Q12
|
||||
}
|
||||
|
||||
tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);
|
||||
k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15
|
||||
k16[m - 1] = (int16_t)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15
|
||||
}
|
||||
return;
|
||||
}
|
224
webrtc/common_audio/signal_processing/min_max_operations.c
Normal file
224
webrtc/common_audio/signal_processing/min_max_operations.c
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the implementation of functions
|
||||
* WebRtcSpl_MaxAbsValueW16C()
|
||||
* WebRtcSpl_MaxAbsValueW32C()
|
||||
* WebRtcSpl_MaxValueW16C()
|
||||
* WebRtcSpl_MaxValueW32C()
|
||||
* WebRtcSpl_MinValueW16C()
|
||||
* WebRtcSpl_MinValueW32C()
|
||||
* WebRtcSpl_MaxAbsIndexW16()
|
||||
* WebRtcSpl_MaxIndexW16()
|
||||
* WebRtcSpl_MaxIndexW32()
|
||||
* WebRtcSpl_MinIndexW16()
|
||||
* WebRtcSpl_MinIndexW32()
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
376
webrtc/common_audio/signal_processing/min_max_operations_mips.c
Normal file
376
webrtc/common_audio/signal_processing/min_max_operations_mips.c
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the implementation of function
|
||||
* WebRtcSpl_MaxAbsValueW16()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
283
webrtc/common_audio/signal_processing/min_max_operations_neon.c
Normal file
283
webrtc/common_audio/signal_processing/min_max_operations_neon.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
||||
|
@ -10,14 +10,20 @@
|
||||
|
||||
|
||||
/*
|
||||
* Table with 512 samples from a normal distribution with mean 1 and std 1
|
||||
* The values are shifted up 13 steps (multiplied by 8192)
|
||||
* This file contains implementations of the randomization functions
|
||||
* WebRtcSpl_RandU()
|
||||
* WebRtcSpl_RandN()
|
||||
* WebRtcSpl_RandUArray()
|
||||
*
|
||||
* The description header can be found in signal_processing_library.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
WebRtc_Word16 WebRtcSpl_kRandNTable[] =
|
||||
{
|
||||
static const uint32_t kMaxSeedUsed = 0x80000000;
|
||||
|
||||
static const int16_t kRandNTable[] = {
|
||||
9178, -7260, 40, 10189, 4894, -3531, -13779, 14764,
|
||||
-4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817,
|
||||
-9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361,
|
||||
@ -83,3 +89,27 @@ WebRtc_Word16 WebRtcSpl_kRandNTable[] =
|
||||
2406, 7703, -951, 11196, -564, 3406, 2217, 4806,
|
||||
2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492
|
||||
};
|
||||
|
||||
static uint32_t IncreaseSeed(uint32_t* seed) {
|
||||
seed[0] = (seed[0] * ((int32_t)69069) + 1) & (kMaxSeedUsed - 1);
|
||||
return seed[0];
|
||||
}
|
||||
|
||||
int16_t WebRtcSpl_RandU(uint32_t* seed) {
|
||||
return (int16_t)(IncreaseSeed(seed) >> 16);
|
||||
}
|
||||
|
||||
int16_t WebRtcSpl_RandN(uint32_t* seed) {
|
||||
return kRandNTable[IncreaseSeed(seed) >> 23];
|
||||
}
|
||||
|
||||
// Creates an array of uniformly distributed variables.
|
||||
int16_t WebRtcSpl_RandUArray(int16_t* vector,
|
||||
int16_t vector_length,
|
||||
uint32_t* seed) {
|
||||
int i;
|
||||
for (i = 0; i < vector_length; i++) {
|
||||
vector[i] = WebRtcSpl_RandU(seed);
|
||||
}
|
||||
return vector_length;
|
||||
}
|
102
webrtc/common_audio/signal_processing/real_fft.c
Normal file
102
webrtc/common_audio/signal_processing/real_fft.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/real_fft.h"
|
||||
|
||||
#include <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;
|
||||
}
|
@ -15,19 +15,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a)
|
||||
void WebRtcSpl_ReflCoefToLpc(const int16_t *k, int use_order, int16_t *a)
|
||||
{
|
||||
WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
|
||||
WebRtc_Word16 *aptr, *aptr2, *anyptr;
|
||||
G_CONST WebRtc_Word16 *kptr;
|
||||
int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
|
||||
int16_t *aptr, *aptr2, *anyptr;
|
||||
const int16_t *kptr;
|
||||
int m, i;
|
||||
|
||||
kptr = k;
|
||||
*a = 4096; // i.e., (Word16_MAX >> 3)+1.
|
||||
*any = *a;
|
||||
a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3);
|
||||
a[1] = *k >> 3;
|
||||
|
||||
for (m = 1; m < use_order; m++)
|
||||
{
|
||||
@ -38,11 +38,10 @@ void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Wor
|
||||
anyptr = any;
|
||||
anyptr++;
|
||||
|
||||
any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3);
|
||||
any[m + 1] = *kptr >> 3;
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
*anyptr = (*aptr)
|
||||
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15);
|
||||
*anyptr = *aptr + (int16_t)((*aptr2 * *kptr) >> 15);
|
||||
anyptr++;
|
||||
aptr++;
|
||||
aptr2--;
|
@ -15,18 +15,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "resample_by_2_internal.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h"
|
||||
|
||||
// Declaration of internally used functions
|
||||
static void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, WebRtc_Word16 *Out,
|
||||
const WebRtc_Word32 K);
|
||||
static void WebRtcSpl_32khzTo22khzIntToShort(const int32_t *In, int16_t *Out,
|
||||
int32_t K);
|
||||
|
||||
void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
|
||||
const WebRtc_Word32 K);
|
||||
void WebRtcSpl_32khzTo22khzIntToInt(const int32_t *In, int32_t *Out,
|
||||
int32_t K);
|
||||
|
||||
// interpolation coefficients
|
||||
static const WebRtc_Word16 kCoefficients32To22[5][9] = {
|
||||
static const int16_t kCoefficients32To22[5][9] = {
|
||||
{127, -712, 2359, -6333, 23456, 16775, -3695, 945, -154},
|
||||
{-39, 230, -830, 2785, 32366, -2324, 760, -218, 38},
|
||||
{117, -663, 2222, -6133, 26634, 13070, -3174, 831, -137},
|
||||
@ -42,8 +42,8 @@ static const WebRtc_Word16 kCoefficients32To22[5][9] = {
|
||||
#define SUB_BLOCKS_22_16 5
|
||||
|
||||
// 22 -> 16 resampler
|
||||
void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_State22khzTo16khz* state, WebRtc_Word32* tmpmem)
|
||||
void WebRtcSpl_Resample22khzTo16khz(const int16_t* in, int16_t* out,
|
||||
WebRtcSpl_State22khzTo16khz* state, int32_t* tmpmem)
|
||||
{
|
||||
int k;
|
||||
|
||||
@ -51,14 +51,14 @@ void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
for (k = 0; k < SUB_BLOCKS_22_16; k++)
|
||||
{
|
||||
///// 22 --> 44 /////
|
||||
// WebRtc_Word16 in[220/SUB_BLOCKS_22_16]
|
||||
// WebRtc_Word32 out[440/SUB_BLOCKS_22_16]
|
||||
// int16_t in[220/SUB_BLOCKS_22_16]
|
||||
// int32_t out[440/SUB_BLOCKS_22_16]
|
||||
/////
|
||||
WebRtcSpl_UpBy2ShortToInt(in, 220 / SUB_BLOCKS_22_16, tmpmem + 16, state->S_22_44);
|
||||
|
||||
///// 44 --> 32 /////
|
||||
// WebRtc_Word32 in[440/SUB_BLOCKS_22_16]
|
||||
// WebRtc_Word32 out[320/SUB_BLOCKS_22_16]
|
||||
// int32_t in[440/SUB_BLOCKS_22_16]
|
||||
// int32_t out[320/SUB_BLOCKS_22_16]
|
||||
/////
|
||||
// copy state to and from input array
|
||||
tmpmem[8] = state->S_44_32[0];
|
||||
@ -81,8 +81,8 @@ void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 40 / SUB_BLOCKS_22_16);
|
||||
|
||||
///// 32 --> 16 /////
|
||||
// WebRtc_Word32 in[320/SUB_BLOCKS_22_16]
|
||||
// WebRtc_Word32 out[160/SUB_BLOCKS_22_16]
|
||||
// int32_t in[320/SUB_BLOCKS_22_16]
|
||||
// int32_t out[160/SUB_BLOCKS_22_16]
|
||||
/////
|
||||
WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16);
|
||||
|
||||
@ -112,8 +112,8 @@ void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state)
|
||||
#define SUB_BLOCKS_16_22 4
|
||||
|
||||
// 16 -> 22 resampler
|
||||
void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_State16khzTo22khz* state, WebRtc_Word32* tmpmem)
|
||||
void WebRtcSpl_Resample16khzTo22khz(const int16_t* in, int16_t* out,
|
||||
WebRtcSpl_State16khzTo22khz* state, int32_t* tmpmem)
|
||||
{
|
||||
int k;
|
||||
|
||||
@ -121,14 +121,14 @@ void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
for (k = 0; k < SUB_BLOCKS_16_22; k++)
|
||||
{
|
||||
///// 16 --> 32 /////
|
||||
// WebRtc_Word16 in[160/SUB_BLOCKS_16_22]
|
||||
// WebRtc_Word32 out[320/SUB_BLOCKS_16_22]
|
||||
// int16_t in[160/SUB_BLOCKS_16_22]
|
||||
// int32_t out[320/SUB_BLOCKS_16_22]
|
||||
/////
|
||||
WebRtcSpl_UpBy2ShortToInt(in, 160 / SUB_BLOCKS_16_22, tmpmem + 8, state->S_16_32);
|
||||
|
||||
///// 32 --> 22 /////
|
||||
// WebRtc_Word32 in[320/SUB_BLOCKS_16_22]
|
||||
// WebRtc_Word32 out[220/SUB_BLOCKS_16_22]
|
||||
// int32_t in[320/SUB_BLOCKS_16_22]
|
||||
// int32_t out[220/SUB_BLOCKS_16_22]
|
||||
/////
|
||||
// copy state to and from input array
|
||||
tmpmem[0] = state->S_32_22[0];
|
||||
@ -175,8 +175,8 @@ void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state)
|
||||
#define SUB_BLOCKS_22_8 2
|
||||
|
||||
// 22 -> 8 resampler
|
||||
void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_State22khzTo8khz* state, WebRtc_Word32* tmpmem)
|
||||
void WebRtcSpl_Resample22khzTo8khz(const int16_t* in, int16_t* out,
|
||||
WebRtcSpl_State22khzTo8khz* state, int32_t* tmpmem)
|
||||
{
|
||||
int k;
|
||||
|
||||
@ -184,14 +184,14 @@ void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
for (k = 0; k < SUB_BLOCKS_22_8; k++)
|
||||
{
|
||||
///// 22 --> 22 lowpass /////
|
||||
// WebRtc_Word16 in[220/SUB_BLOCKS_22_8]
|
||||
// WebRtc_Word32 out[220/SUB_BLOCKS_22_8]
|
||||
// int16_t in[220/SUB_BLOCKS_22_8]
|
||||
// int32_t out[220/SUB_BLOCKS_22_8]
|
||||
/////
|
||||
WebRtcSpl_LPBy2ShortToInt(in, 220 / SUB_BLOCKS_22_8, tmpmem + 16, state->S_22_22);
|
||||
|
||||
///// 22 --> 16 /////
|
||||
// WebRtc_Word32 in[220/SUB_BLOCKS_22_8]
|
||||
// WebRtc_Word32 out[160/SUB_BLOCKS_22_8]
|
||||
// int32_t in[220/SUB_BLOCKS_22_8]
|
||||
// int32_t out[160/SUB_BLOCKS_22_8]
|
||||
/////
|
||||
// copy state to and from input array
|
||||
tmpmem[8] = state->S_22_16[0];
|
||||
@ -214,8 +214,8 @@ void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 20 / SUB_BLOCKS_22_8);
|
||||
|
||||
///// 16 --> 8 /////
|
||||
// WebRtc_Word32 in[160/SUB_BLOCKS_22_8]
|
||||
// WebRtc_Word32 out[80/SUB_BLOCKS_22_8]
|
||||
// int32_t in[160/SUB_BLOCKS_22_8]
|
||||
// int32_t out[80/SUB_BLOCKS_22_8]
|
||||
/////
|
||||
WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8);
|
||||
|
||||
@ -246,8 +246,8 @@ void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state)
|
||||
#define SUB_BLOCKS_8_22 2
|
||||
|
||||
// 8 -> 22 resampler
|
||||
void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_State8khzTo22khz* state, WebRtc_Word32* tmpmem)
|
||||
void WebRtcSpl_Resample8khzTo22khz(const int16_t* in, int16_t* out,
|
||||
WebRtcSpl_State8khzTo22khz* state, int32_t* tmpmem)
|
||||
{
|
||||
int k;
|
||||
|
||||
@ -255,14 +255,14 @@ void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
for (k = 0; k < SUB_BLOCKS_8_22; k++)
|
||||
{
|
||||
///// 8 --> 16 /////
|
||||
// WebRtc_Word16 in[80/SUB_BLOCKS_8_22]
|
||||
// WebRtc_Word32 out[160/SUB_BLOCKS_8_22]
|
||||
// int16_t in[80/SUB_BLOCKS_8_22]
|
||||
// int32_t out[160/SUB_BLOCKS_8_22]
|
||||
/////
|
||||
WebRtcSpl_UpBy2ShortToInt(in, 80 / SUB_BLOCKS_8_22, tmpmem + 18, state->S_8_16);
|
||||
|
||||
///// 16 --> 11 /////
|
||||
// WebRtc_Word32 in[160/SUB_BLOCKS_8_22]
|
||||
// WebRtc_Word32 out[110/SUB_BLOCKS_8_22]
|
||||
// int32_t in[160/SUB_BLOCKS_8_22]
|
||||
// int32_t out[110/SUB_BLOCKS_8_22]
|
||||
/////
|
||||
// copy state to and from input array
|
||||
tmpmem[10] = state->S_16_11[0];
|
||||
@ -285,8 +285,8 @@ void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out,
|
||||
WebRtcSpl_32khzTo22khzIntToInt(tmpmem + 10, tmpmem, 10 / SUB_BLOCKS_8_22);
|
||||
|
||||
///// 11 --> 22 /////
|
||||
// WebRtc_Word32 in[110/SUB_BLOCKS_8_22]
|
||||
// WebRtc_Word16 out[220/SUB_BLOCKS_8_22]
|
||||
// int32_t in[110/SUB_BLOCKS_8_22]
|
||||
// int16_t out[220/SUB_BLOCKS_8_22]
|
||||
/////
|
||||
WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22);
|
||||
|
||||
@ -309,13 +309,13 @@ void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state)
|
||||
}
|
||||
|
||||
// compute two inner-products and store them to output array
|
||||
static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Word32* in2,
|
||||
const WebRtc_Word16* coef_ptr, WebRtc_Word32* out1,
|
||||
WebRtc_Word32* out2)
|
||||
static void WebRtcSpl_DotProdIntToInt(const int32_t* in1, const int32_t* in2,
|
||||
const int16_t* coef_ptr, int32_t* out1,
|
||||
int32_t* out2)
|
||||
{
|
||||
WebRtc_Word32 tmp1 = 16384;
|
||||
WebRtc_Word32 tmp2 = 16384;
|
||||
WebRtc_Word16 coef;
|
||||
int32_t tmp1 = 16384;
|
||||
int32_t tmp2 = 16384;
|
||||
int16_t coef;
|
||||
|
||||
coef = coef_ptr[0];
|
||||
tmp1 += coef * in1[0];
|
||||
@ -355,13 +355,13 @@ static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Wor
|
||||
}
|
||||
|
||||
// compute two inner-products and store them to output array
|
||||
static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_Word32* in2,
|
||||
const WebRtc_Word16* coef_ptr, WebRtc_Word16* out1,
|
||||
WebRtc_Word16* out2)
|
||||
static void WebRtcSpl_DotProdIntToShort(const int32_t* in1, const int32_t* in2,
|
||||
const int16_t* coef_ptr, int16_t* out1,
|
||||
int16_t* out2)
|
||||
{
|
||||
WebRtc_Word32 tmp1 = 16384;
|
||||
WebRtc_Word32 tmp2 = 16384;
|
||||
WebRtc_Word16 coef;
|
||||
int32_t tmp1 = 16384;
|
||||
int32_t tmp2 = 16384;
|
||||
int16_t coef;
|
||||
|
||||
coef = coef_ptr[0];
|
||||
tmp1 += coef * in1[0];
|
||||
@ -401,39 +401,39 @@ static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_W
|
||||
|
||||
// scale down, round and saturate
|
||||
tmp1 >>= 15;
|
||||
if (tmp1 > (WebRtc_Word32)0x00007FFF)
|
||||
if (tmp1 > (int32_t)0x00007FFF)
|
||||
tmp1 = 0x00007FFF;
|
||||
if (tmp1 < (WebRtc_Word32)0xFFFF8000)
|
||||
if (tmp1 < (int32_t)0xFFFF8000)
|
||||
tmp1 = 0xFFFF8000;
|
||||
tmp2 >>= 15;
|
||||
if (tmp2 > (WebRtc_Word32)0x00007FFF)
|
||||
if (tmp2 > (int32_t)0x00007FFF)
|
||||
tmp2 = 0x00007FFF;
|
||||
if (tmp2 < (WebRtc_Word32)0xFFFF8000)
|
||||
if (tmp2 < (int32_t)0xFFFF8000)
|
||||
tmp2 = 0xFFFF8000;
|
||||
*out1 = (WebRtc_Word16)tmp1;
|
||||
*out2 = (WebRtc_Word16)tmp2;
|
||||
*out1 = (int16_t)tmp1;
|
||||
*out2 = (int16_t)tmp2;
|
||||
}
|
||||
|
||||
// Resampling ratio: 11/16
|
||||
// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K
|
||||
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 11 * K
|
||||
// input: int32_t (normalized, not saturated) :: size 16 * K
|
||||
// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 11 * K
|
||||
// K: Number of blocks
|
||||
|
||||
void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In,
|
||||
WebRtc_Word32* Out,
|
||||
const WebRtc_Word32 K)
|
||||
void WebRtcSpl_32khzTo22khzIntToInt(const int32_t* In,
|
||||
int32_t* Out,
|
||||
int32_t K)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Filter operation:
|
||||
//
|
||||
// Perform resampling (16 input samples -> 11 output samples);
|
||||
// process in sub blocks of size 16 samples.
|
||||
WebRtc_Word32 m;
|
||||
int32_t m;
|
||||
|
||||
for (m = 0; m < K; m++)
|
||||
{
|
||||
// first output sample
|
||||
Out[0] = ((WebRtc_Word32)In[3] << 15) + (1 << 14);
|
||||
Out[0] = ((int32_t)In[3] << 15) + (1 << 14);
|
||||
|
||||
// sum and accumulate filter coefficients and input samples
|
||||
WebRtcSpl_DotProdIntToInt(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]);
|
||||
@ -457,31 +457,31 @@ void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In,
|
||||
}
|
||||
|
||||
// Resampling ratio: 11/16
|
||||
// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K
|
||||
// output: WebRtc_Word16 (saturated) :: size 11 * K
|
||||
// input: int32_t (normalized, not saturated) :: size 16 * K
|
||||
// output: int16_t (saturated) :: size 11 * K
|
||||
// K: Number of blocks
|
||||
|
||||
void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In,
|
||||
WebRtc_Word16 *Out,
|
||||
const WebRtc_Word32 K)
|
||||
void WebRtcSpl_32khzTo22khzIntToShort(const int32_t *In,
|
||||
int16_t *Out,
|
||||
int32_t K)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Filter operation:
|
||||
//
|
||||
// Perform resampling (16 input samples -> 11 output samples);
|
||||
// process in sub blocks of size 16 samples.
|
||||
WebRtc_Word32 tmp;
|
||||
WebRtc_Word32 m;
|
||||
int32_t tmp;
|
||||
int32_t m;
|
||||
|
||||
for (m = 0; m < K; m++)
|
||||
{
|
||||
// first output sample
|
||||
tmp = In[3];
|
||||
if (tmp > (WebRtc_Word32)0x00007FFF)
|
||||
if (tmp > (int32_t)0x00007FFF)
|
||||
tmp = 0x00007FFF;
|
||||
if (tmp < (WebRtc_Word32)0xFFFF8000)
|
||||
if (tmp < (int32_t)0xFFFF8000)
|
||||
tmp = 0xFFFF8000;
|
||||
Out[0] = (WebRtc_Word16)tmp;
|
||||
Out[0] = (int16_t)tmp;
|
||||
|
||||
// sum and accumulate filter coefficients and input samples
|
||||
WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user