git-svn-id: http://webrtc.googlecode.com/svn/trunk@156 4adac7df-926f-26a2-2b94-8c16560cd09d

This commit is contained in:
niklase@google.com 2011-07-07 08:21:25 +00:00
parent f0a476bf76
commit 470e71d364
1648 changed files with 544173 additions and 0 deletions

13
src/README.chromium Normal file
View File

@ -0,0 +1,13 @@
Name: WebRTC
URL: http://www.webrtc.org
Version: 90
License: BSD
License File: LICENSE
Description:
WebRTC provides real time voice and video processing
functionality to enable the implementation of
PeerConnection/MediaStream.
Third party code used in this project is described
in the file LICENSE_THIRD_PARTY.

74
src/build/common.gypi Normal file
View File

@ -0,0 +1,74 @@
# 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 common settings for building WebRTC components.
{
'variables': {
# TODO(ajm): use webrtc_standalone to match NaCl?
'build_with_chromium%': 1, # 1 to build webrtc with chromium
# Selects fixed-point code where possible.
# TODO(ajm): we'd like to set this based on the target OS/architecture.
'prefer_fixed_point%': 0,
'conditions': [
['OS=="win"', {
# TODO(ajm, perkj): does this need to be here?
# Path needed to build Direct Show base classes on Windows.
# The code is included in the Windows SDK.
'direct_show_base_classes':
'C:/Program Files/Microsoft SDKs/Windows/v7.1/Samples/multimedia/directshow/baseclasses/',
}],
], # conditions
},
'target_defaults': {
'include_dirs': [
'..', # common_types.h, typedefs.h
],
'conditions': [
['OS=="linux"', {
'defines': [
'WEBRTC_TARGET_PC',
'WEBRTC_LINUX',
'WEBRTC_THREAD_RR',
# TODO(ajm): can we select this automatically?
# Define this if the Linux system does not support CLOCK_MONOTONIC.
#'WEBRTC_CLOCK_TYPE_REALTIME',
],
}],
['OS=="mac"', {
# TODO(ajm): what about PowerPC?
# Setup for Intel
'defines': [
'WEBRTC_TARGET_MAC_INTEL',
'WEBRTC_MAC_INTEL',
'WEBRTC_MAC',
'WEBRTC_THREAD_RR',
'WEBRTC_CLOCK_TYPE_REALTIME',
],
}],
['OS=="win"', {
'defines': [
'WEBRTC_TARGET_PC',
],
}],
['build_with_chromium==1', {
'defines': [
'WEBRTC_VIDEO_EXTERNAL_CAPTURE_AND_RENDER',
],
}],
], # conditions
}, # target_defaults
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,97 @@
# 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 is included when gyp_webrtc is run, and provides the settings
# necessary for a standalone WebRTC build.
{
'variables': {
# .gyp files or targets should set webrtc_code to 1 if they build
# WebRTC-specific code, as opposed to external code. This variable is
# used to control such things as the set of warnings to enable, and
# whether warnings are treated as errors.
'webrtc_code%': 0,
'variables': {
# Compute the architecture that we're building on.
'conditions': [
['OS=="win" or OS=="mac"', {
'host_arch%': 'ia32',
}, {
# This handles the Unix platforms for which there is some support.
# Anything else gets passed through, which probably won't work very
# well; such hosts should pass an explicit target_arch to gyp.
'host_arch%':
'<!(uname -m | sed -e "s/i.86/ia32/;s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/i86pc/ia32/")',
}],
# A flag for POSIX platforms
['OS=="win"', {
'os_posix%': 0,
}, {
'os_posix%': 1,
}],
], # conditions
# Workaround for libjpeg_turbo pulled from Chromium.
'chromeos%': 0,
},
# Copy conditionally-set variables out one scope.
'host_arch%': '<(host_arch)',
'chromeos%': '<(chromeos)',
'os_posix%': '<(os_posix)',
# Workaround for GTest pulled from Chromium.
# TODO(ajm): would be nice to support Clang though...
#
# Set this to true when building with Clang.
# See http://code.google.com/p/chromium/wiki/Clang for details.
# TODO: eventually clang should behave identically to gcc, and this
# won't be necessary.
'clang%': 0,
# Default architecture we're building for is the architecture we're
# building on.
'target_arch%': '<(host_arch)',
'library%': 'static_library',
},
'target_defaults': {
'include_dirs': [
'..', # common_types.h, typedefs.h
],
'conditions': [
['OS=="linux"', {
'cflags': [
'-Wall',
'-Wextra',
# TODO(ajm): enable when possible.
#'-Werror',
],
}],
], # conditions
}, # target_defaults
'conditions': [
['webrtc_code==0', {
# This section must follow the other conditon sections above because
# external_code.gypi expects to be merged into those settings.
'includes': [
'external_code.gypi',
],
}],
], # conditions
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,50 @@
# 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 is included for external code which may require different warning
# settings than the internal WebRTC code.
# TODO(ajm): remove these when possible.
{
'conditions': [
['OS=="linux"', {
'target_defaults': {
'cflags!': [
'-Wall',
'-Wextra',
'-Werror',
],
},
}],
['OS=="win"', {
'target_defaults': {
'defines': [
'_CRT_SECURE_NO_DEPRECATE',
'_CRT_NONSTDC_NO_WARNINGS',
'_CRT_NONSTDC_NO_DEPRECATE',
'_SCL_SECURE_NO_DEPRECATE',
],
'msvs_disabled_warnings': [4800],
'msvs_settings': {
'VCCLCompilerTool': {
'WarnAsError': 'false',
'Detect64BitPortabilityProblems': 'false',
},
},
},
}],
['OS=="mac"', {
'target_defaults': {
'xcode_settings': {
'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO',
'WARNING_CFLAGS!': ['-Wall'],
},
},
}],
],
}

91
src/build/gyp_webrtc Executable file
View File

@ -0,0 +1,91 @@
#!/usr/bin/env python
# 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 is a gyp wrapper for WebRTC that adds some support for how gyp
# is invoked beyond what can be done in the gclient hooks.
import glob
import os
import shlex
import sys
script_dir = os.path.dirname(__file__)
webrtc_src = os.path.abspath(os.path.join(script_dir, os.pardir))
sys.path.append(os.path.join(webrtc_src, '../', 'tools', 'gyp', 'pylib'))
import gyp
def additional_include_files(args=[]):
"""
Returns a list of additional (.gypi) files to include, without
duplicating ones that are already specified on the command line.
"""
# Determine the include files specified on the command line.
# This doesn't cover all the different option formats you can use,
# but it's mainly intended to avoid duplicating flags on the automatic
# makefile regeneration which only uses this format.
specified_includes = set()
for arg in args:
if arg.startswith('-I') and len(arg) > 2:
specified_includes.add(os.path.realpath(arg[2:]))
result = []
def AddInclude(path):
if os.path.realpath(path) not in specified_includes:
result.append(path)
# Always include common.gypi & features_override.gypi
AddInclude(os.path.join(script_dir, 'common_standalone.gypi'))
#AddInclude(os.path.join(script_dir, 'features_override.gypi'))
# Optionally add supplemental .gypi files if present.
supplements = glob.glob(os.path.join(webrtc_src, '*', 'supplement.gypi'))
for supplement in supplements:
AddInclude(supplement)
return result
if __name__ == '__main__':
args = sys.argv[1:]
# This could give false positives since it doesn't actually do real option
# parsing. Oh well.
gyp_file_specified = False
for arg in args:
if arg.endswith('.gyp'):
gyp_file_specified = True
break
# If we didn't get a file, check an env var, and then fall back to
# assuming 'all.gyp' from the same directory as the script.
if not gyp_file_specified:
gyp_file = os.environ.get('WEBRTC_GYP_FILE')
if gyp_file:
# Note that CHROMIUM_GYP_FILE values can't have backslashes as
# path separators even on Windows due to the use of shlex.split().
args.extend(shlex.split(gyp_file))
else:
# TODO(ajm): move webrtc.gyp to script_dir?
args.append(os.path.join(webrtc_src, 'webrtc.gyp'))
args.extend(['-I' + i for i in additional_include_files(args)])
# Pick depth explicitly.
args += ['--depth', '.']
#Building WebRTC as standalone (not as part of Chrome)
#args += ['-D', 'webrtc_standalone=1']
args += ['-D', 'build_with_chromium=0']
print 'Updating projects from gyp files...'
sys.stdout.flush()
# Off we go...
sys.exit(gyp.main(args))

1
src/common_audio/OWNERS Normal file
View File

@ -0,0 +1 @@
bjornv@google.com

View File

@ -0,0 +1,3 @@
bjornv@google.com
tlegrand@google.com
jks@google.com

View File

@ -0,0 +1,110 @@
/*
* 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.
*/
/*
* A wrapper for resampling a numerous amount of sampling combinations.
*/
#ifndef WEBRTC_RESAMPLER_RESAMPLER_H_
#define WEBRTC_RESAMPLER_RESAMPLER_H_
#include "typedefs.h"
namespace webrtc
{
enum ResamplerType
{
// 4 MSB = Number of channels
// 4 LSB = Synchronous or asynchronous
kResamplerSynchronous = 0x10,
kResamplerAsynchronous = 0x11,
kResamplerSynchronousStereo = 0x20,
kResamplerAsynchronousStereo = 0x21,
kResamplerInvalid = 0xff
};
enum ResamplerMode
{
kResamplerMode1To1,
kResamplerMode1To2,
kResamplerMode1To3,
kResamplerMode1To4,
kResamplerMode1To6,
kResamplerMode2To3,
kResamplerMode2To11,
kResamplerMode4To11,
kResamplerMode8To11,
kResamplerMode11To16,
kResamplerMode11To32,
kResamplerMode2To1,
kResamplerMode3To1,
kResamplerMode4To1,
kResamplerMode6To1,
kResamplerMode3To2,
kResamplerMode11To2,
kResamplerMode11To4,
kResamplerMode11To8
};
class Resampler
{
public:
Resampler();
Resampler(int inFreq, int outFreq, ResamplerType type);
~Resampler();
// Reset all states
int Reset(int inFreq, int outFreq, ResamplerType type);
// Reset all states if any parameter has changed
int ResetIfNeeded(int inFreq, int outFreq, ResamplerType type);
// Synchronous resampling, all output samples are written to samplesOut
int Push(const WebRtc_Word16* samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
int maxLen, int &outLen);
// Asynchronous resampling, input
int Insert(WebRtc_Word16* samplesIn, int lengthIn);
// Asynchronous resampling output, remaining samples are buffered
int Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen);
private:
// Generic pointers since we don't know what states we'll need
void* state1_;
void* state2_;
void* state3_;
// Storage if needed
WebRtc_Word16* in_buffer_;
WebRtc_Word16* out_buffer_;
int in_buffer_size_;
int out_buffer_size_;
int in_buffer_size_max_;
int out_buffer_size_max_;
// State
int my_in_frequency_khz_;
int my_out_frequency_khz_;
ResamplerMode my_mode_;
ResamplerType my_type_;
// Extra instance for stereo
Resampler* slave_left_;
Resampler* slave_right_;
};
} // namespace webrtc
#endif // WEBRTC_RESAMPLER_RESAMPLER_H_

View File

@ -0,0 +1,58 @@
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libwebrtc_resampler
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
LOCAL_SRC_FILES := resampler.cc
# Flags passed to both C and C++ files.
MY_CFLAGS :=
MY_CFLAGS_C :=
MY_DEFS := '-DNO_TCMALLOC' \
'-DNO_HEAPCHECKER' \
'-DWEBRTC_TARGET_PC' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DANDROID'
LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../interface \
$(LOCAL_PATH)/../../../signal_processing_library/main/interface
# Flags passed to only C++ (and not C) files.
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := libcutils \
libdl \
libstlport
LOCAL_ADDITIONAL_DEPENDENCIES :=
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl -lpthread
endif
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
endif
include external/stlport/libstlport.mk
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,981 @@
/*
* 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.
*/
/*
* A wrapper for resampling a numerous amount of sampling combinations.
*/
#include <stdlib.h>
#include <string.h>
#include "signal_processing_library.h"
#include "resampler.h"
namespace webrtc
{
Resampler::Resampler()
{
state1_ = NULL;
state2_ = NULL;
state3_ = NULL;
in_buffer_ = NULL;
out_buffer_ = NULL;
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// we need a reset before we will work
my_in_frequency_khz_ = 0;
my_out_frequency_khz_ = 0;
my_mode_ = kResamplerMode1To1;
my_type_ = kResamplerInvalid;
slave_left_ = NULL;
slave_right_ = NULL;
}
Resampler::Resampler(int inFreq, int outFreq, ResamplerType type)
{
state1_ = NULL;
state2_ = NULL;
state3_ = NULL;
in_buffer_ = NULL;
out_buffer_ = NULL;
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// we need a reset before we will work
my_in_frequency_khz_ = 0;
my_out_frequency_khz_ = 0;
my_mode_ = kResamplerMode1To1;
my_type_ = kResamplerInvalid;
slave_left_ = NULL;
slave_right_ = NULL;
int res = Reset(inFreq, outFreq, type);
}
Resampler::~Resampler()
{
if (state1_)
{
free(state1_);
}
if (state2_)
{
free(state2_);
}
if (state3_)
{
free(state3_);
}
if (in_buffer_)
{
free(in_buffer_);
}
if (out_buffer_)
{
free(out_buffer_);
}
if (slave_left_)
{
delete slave_left_;
}
if (slave_right_)
{
delete slave_right_;
}
}
int Resampler::ResetIfNeeded(int inFreq, int outFreq, ResamplerType type)
{
int tmpInFreq_kHz = inFreq / 1000;
int tmpOutFreq_kHz = outFreq / 1000;
if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_)
|| (type != my_type_))
{
return Reset(inFreq, outFreq, type);
} else
{
return 0;
}
}
int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
{
if (state1_)
{
free(state1_);
state1_ = NULL;
}
if (state2_)
{
free(state2_);
state2_ = NULL;
}
if (state3_)
{
free(state3_);
state3_ = NULL;
}
if (in_buffer_)
{
free(in_buffer_);
in_buffer_ = NULL;
}
if (out_buffer_)
{
free(out_buffer_);
out_buffer_ = NULL;
}
if (slave_left_)
{
delete slave_left_;
slave_left_ = NULL;
}
if (slave_right_)
{
delete slave_right_;
slave_right_ = NULL;
}
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// This might be overridden if parameters are not accepted.
my_type_ = type;
// Start with a math exercise, Euclid's algorithm to find the gcd:
int a = inFreq;
int b = outFreq;
int c = a % b;
while (c != 0)
{
a = b;
b = c;
c = a % b;
}
// b is now the gcd;
// We need to track what domain we're in.
my_in_frequency_khz_ = inFreq / 1000;
my_out_frequency_khz_ = outFreq / 1000;
// Scale with GCD
inFreq = inFreq / b;
outFreq = outFreq / b;
// Do we need stereo?
if ((my_type_ & 0xf0) == 0x20)
{
// Change type to mono
type = (ResamplerType)((int)type & 0x0f + 0x10);
slave_left_ = new Resampler(inFreq, outFreq, type);
slave_right_ = new Resampler(inFreq, outFreq, type);
}
if (inFreq == outFreq)
{
my_mode_ = kResamplerMode1To1;
} else if (inFreq == 1)
{
switch (outFreq)
{
case 2:
my_mode_ = kResamplerMode1To2;
break;
case 3:
my_mode_ = kResamplerMode1To3;
break;
case 4:
my_mode_ = kResamplerMode1To4;
break;
case 6:
my_mode_ = kResamplerMode1To6;
break;
default:
my_type_ = kResamplerInvalid;
break;
}
} else if (outFreq == 1)
{
switch (inFreq)
{
case 2:
my_mode_ = kResamplerMode2To1;
break;
case 3:
my_mode_ = kResamplerMode3To1;
break;
case 4:
my_mode_ = kResamplerMode4To1;
break;
case 6:
my_mode_ = kResamplerMode6To1;
break;
default:
my_type_ = kResamplerInvalid;
break;
}
} else if ((inFreq == 2) && (outFreq == 3))
{
my_mode_ = kResamplerMode2To3;
} else if ((inFreq == 2) && (outFreq == 11))
{
my_mode_ = kResamplerMode2To11;
} else if ((inFreq == 4) && (outFreq == 11))
{
my_mode_ = kResamplerMode4To11;
} else if ((inFreq == 8) && (outFreq == 11))
{
my_mode_ = kResamplerMode8To11;
} else if ((inFreq == 3) && (outFreq == 2))
{
my_mode_ = kResamplerMode3To2;
} else if ((inFreq == 11) && (outFreq == 2))
{
my_mode_ = kResamplerMode11To2;
} else if ((inFreq == 11) && (outFreq == 4))
{
my_mode_ = kResamplerMode11To4;
} else if ((inFreq == 11) && (outFreq == 16))
{
my_mode_ = kResamplerMode11To16;
} else if ((inFreq == 11) && (outFreq == 32))
{
my_mode_ = kResamplerMode11To32;
} else if ((inFreq == 11) && (outFreq == 8))
{
my_mode_ = kResamplerMode11To8;
} else
{
my_type_ = kResamplerInvalid;
return -1;
}
// Now create the states we need
switch (my_mode_)
{
case kResamplerMode1To1:
// No state needed;
break;
case kResamplerMode1To2:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode1To3:
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
break;
case kResamplerMode1To4:
// 1:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:4
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode1To6:
// 1:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:6
state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
break;
case kResamplerMode2To3:
// 2:6
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
// 6:3
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode2To11:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_);
break;
case kResamplerMode4To11:
state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_);
break;
case kResamplerMode8To11:
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz));
WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_);
break;
case kResamplerMode11To16:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
break;
case kResamplerMode11To32:
// 11 -> 22
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 22 -> 16
state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
// 16 -> 32
state3_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state3_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode2To1:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode3To1:
state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
break;
case kResamplerMode4To1:
// 4:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:1
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode6To1:
// 6:2
state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
// 2:1
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode3To2:
// 3:6
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 6:2
state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_);
break;
case kResamplerMode11To2:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode11To4:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
break;
case kResamplerMode11To8:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_);
break;
}
return 0;
}
// Synchronous resampling, all output samples are written to samplesOut
int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
int maxLen, int &outLen)
{
// Check that the resampler is not in asynchronous mode
if (my_type_ & 0x0f)
{
return -1;
}
// Do we have a stereo signal?
if ((my_type_ & 0xf0) == 0x20)
{
// Split up the signal and call the slave object for each channel
WebRtc_Word16* left = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
WebRtc_Word16* right = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
WebRtc_Word16* out_left = (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
WebRtc_Word16* out_right =
(WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
int res = 0;
for (int i = 0; i < lengthIn; i += 2)
{
left[i >> 1] = samplesIn[i];
right[i >> 1] = samplesIn[i + 1];
}
// It's OK to overwrite the local parameter, since it's just a copy
lengthIn = lengthIn / 2;
int actualOutLen_left = 0;
int actualOutLen_right = 0;
// Do resampling for right channel
res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left);
res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right);
if (res || (actualOutLen_left != actualOutLen_right))
{
free(left);
free(right);
free(out_left);
free(out_right);
return -1;
}
// Reassemble the signal
for (int i = 0; i < actualOutLen_left; i++)
{
samplesOut[i * 2] = out_left[i];
samplesOut[i * 2 + 1] = out_right[i];
}
outLen = 2 * actualOutLen_left;
free(left);
free(right);
free(out_left);
free(out_right);
return 0;
}
// Container for temp samples
WebRtc_Word16* tmp;
// tmp data for resampling routines
WebRtc_Word32* tmp_mem;
switch (my_mode_)
{
case kResamplerMode1To1:
memcpy(samplesOut, samplesIn, lengthIn * sizeof(WebRtc_Word16));
outLen = lengthIn;
break;
case kResamplerMode1To2:
if (maxLen < (lengthIn * 2))
{
return -1;
}
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
outLen = lengthIn * 2;
return 0;
case kResamplerMode1To3:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
if (maxLen < (lengthIn * 3))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3,
(WebRtcSpl_State16khzTo48khz *)state1_,
tmp_mem);
}
outLen = lengthIn * 3;
free(tmp_mem);
return 0;
case kResamplerMode1To4:
if (maxLen < (lengthIn * 4))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
// 1:2
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
// 2:4
WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn * 4;
free(tmp);
return 0;
case kResamplerMode1To6:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < (lengthIn * 6))
{
return -1;
}
//1:2
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
outLen = lengthIn * 2;
for (int i = 0; i < outLen; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
(WebRtcSpl_State16khzTo48khz *)state2_,
tmp_mem);
}
outLen = outLen * 3;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode2To3:
if (maxLen < (lengthIn * 3 / 2))
{
return -1;
}
// 2:6
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 3));
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3,
(WebRtcSpl_State16khzTo48khz *)state1_,
tmp_mem);
}
lengthIn = lengthIn * 3;
// 6:3
WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 2;
free(tmp);
free(tmp_mem);
return 0;
case kResamplerMode2To11:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 2))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
// 1:2
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
lengthIn *= 2;
tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 80)
{
WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4,
(WebRtcSpl_State8khzTo22khz *)state2_,
tmp_mem);
}
outLen = (lengthIn * 11) / 4;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode4To11:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 4))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 80)
{
WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4,
(WebRtcSpl_State8khzTo22khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 11) / 4;
free(tmp_mem);
return 0;
case kResamplerMode8To11:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 8))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(88 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8,
(WebRtcSpl_State16khzTo22khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 11) / 8;
free(tmp_mem);
return 0;
case kResamplerMode11To16:
// We can only handle blocks of 110 samples
if ((lengthIn % 110) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 16) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
for (int i = 0; i < (lengthIn * 2); i += 220)
{
WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160,
(WebRtcSpl_State22khzTo16khz *)state2_,
tmp_mem);
}
outLen = (lengthIn * 16) / 11;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode11To32:
// We can only handle blocks of 110 samples
if ((lengthIn % 110) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 32) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
// 11 -> 22 kHz in samplesOut
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
// 22 -> 16 in tmp
for (int i = 0; i < (lengthIn * 2); i += 220)
{
WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160,
(WebRtcSpl_State22khzTo16khz *)state2_,
tmp_mem);
}
// 16 -> 32 in samplesOut
WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
(WebRtc_Word32*)state3_);
outLen = (lengthIn * 32) / 11;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode2To1:
if (maxLen < (lengthIn / 2))
{
return -1;
}
WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
outLen = lengthIn / 2;
return 0;
case kResamplerMode3To1:
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
return -1;
}
if (maxLen < (lengthIn / 3))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3,
(WebRtcSpl_State48khzTo16khz *)state1_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp_mem);
return 0;
case kResamplerMode4To1:
if (maxLen < (lengthIn / 4))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * lengthIn / 2);
// 4:2
WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
// 2:1
WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 4;
free(tmp);
return 0;
case kResamplerMode6To1:
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
return -1;
}
if (maxLen < (lengthIn / 6))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn) / 3);
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
(WebRtcSpl_State48khzTo16khz *)state1_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp_mem);
WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (WebRtc_Word32*)state2_);
free(tmp);
outLen = outLen / 2;
return 0;
case kResamplerMode3To2:
if (maxLen < (lengthIn * 2 / 3))
{
return -1;
}
// 3:6
tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 2));
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
lengthIn *= 2;
// 6:2
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
free(tmp);
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3,
(WebRtcSpl_State48khzTo16khz *)state2_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp);
free(tmp_mem);
return 0;
case kResamplerMode11To2:
// We can only handle blocks of 220 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 2) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((lengthIn * 4) / 11 * sizeof(WebRtc_Word16));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11,
(WebRtcSpl_State22khzTo8khz *)state1_,
tmp_mem);
}
lengthIn = (lengthIn * 4) / 11;
WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 2;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode11To4:
// We can only handle blocks of 220 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 4) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11,
(WebRtcSpl_State22khzTo8khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 4) / 11;
free(tmp_mem);
return 0;
case kResamplerMode11To8:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 8) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11,
(WebRtcSpl_State22khzTo16khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 8) / 11;
free(tmp_mem);
return 0;
break;
}
return 0;
}
// Asynchronous resampling, input
int Resampler::Insert(WebRtc_Word16 * samplesIn, int lengthIn)
{
if (my_type_ != kResamplerAsynchronous)
{
return -1;
}
int sizeNeeded, tenMsblock;
// Determine need for size of outBuffer
sizeNeeded = out_buffer_size_ + ((lengthIn + in_buffer_size_) * my_out_frequency_khz_)
/ my_in_frequency_khz_;
if (sizeNeeded > out_buffer_size_max_)
{
// Round the value upwards to complete 10 ms blocks
tenMsblock = my_out_frequency_khz_ * 10;
sizeNeeded = (sizeNeeded / tenMsblock + 1) * tenMsblock;
out_buffer_ = (WebRtc_Word16*)realloc(out_buffer_, sizeNeeded * sizeof(WebRtc_Word16));
out_buffer_size_max_ = sizeNeeded;
}
// If we need to use inBuffer, make sure all input data fits there.
tenMsblock = my_in_frequency_khz_ * 10;
if (in_buffer_size_ || (lengthIn % tenMsblock))
{
// Check if input buffer size is enough
if ((in_buffer_size_ + lengthIn) > in_buffer_size_max_)
{
// Round the value upwards to complete 10 ms blocks
sizeNeeded = ((in_buffer_size_ + lengthIn) / tenMsblock + 1) * tenMsblock;
in_buffer_ = (WebRtc_Word16*)realloc(in_buffer_,
sizeNeeded * sizeof(WebRtc_Word16));
in_buffer_size_max_ = sizeNeeded;
}
// Copy in data to input buffer
memcpy(in_buffer_ + in_buffer_size_, samplesIn, lengthIn * sizeof(WebRtc_Word16));
// Resample all available 10 ms blocks
int lenOut;
int dataLenToResample = (in_buffer_size_ / tenMsblock) * tenMsblock;
Push(in_buffer_, dataLenToResample, out_buffer_ + out_buffer_size_,
out_buffer_size_max_ - out_buffer_size_, lenOut);
out_buffer_size_ += lenOut;
// Save the rest
memmove(in_buffer_, in_buffer_ + dataLenToResample,
(in_buffer_size_ - dataLenToResample) * sizeof(WebRtc_Word16));
in_buffer_size_ -= dataLenToResample;
} else
{
// Just resample
int lenOut;
Push(in_buffer_, lengthIn, out_buffer_ + out_buffer_size_,
out_buffer_size_max_ - out_buffer_size_, lenOut);
out_buffer_size_ += lenOut;
}
return 0;
}
// Asynchronous resampling output, remaining samples are buffered
int Resampler::Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen)
{
if (my_type_ != kResamplerAsynchronous)
{
return -1;
}
// Check that we have enough data
if (desiredLen <= out_buffer_size_)
{
// Give out the date
memcpy(samplesOut, out_buffer_, desiredLen * sizeof(WebRtc_Word32));
// Shuffle down remaining
memmove(out_buffer_, out_buffer_ + desiredLen,
(out_buffer_size_ - desiredLen) * sizeof(WebRtc_Word16));
// Update remaining size
out_buffer_size_ -= desiredLen;
return 0;
} else
{
return -1;
}
}
} // namespace webrtc

View File

@ -0,0 +1,40 @@
# 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.
{
'includes': [
'../../../../common_settings.gypi', # Common settings
],
'targets': [
{
'target_name': 'resampler',
'type': '<(library)',
'dependencies': [
'../../../signal_processing_library/main/source/spl.gyp:spl',
],
'include_dirs': [
'../interface',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
],
},
'sources': [
'../interface/resampler.h',
'resampler.cc',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,3 @@
bjornv@google.com
tlegrand@google.com
jks@google.com

View File

@ -0,0 +1,293 @@
/*
* 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_SPL_INLINE_CALLS
#ifdef WEBRTC_ANDROID
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL(WebRtc_Word32 a, WebRtc_Word32 b)
{
WebRtc_Word32 tmp;
__asm__("mul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
return tmp;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n)
{
WebRtc_Word32 tmp;
__asm__("clz %0, %1":"=r"(tmp):"r"(n));
return (WebRtc_Word16)(32 - tmp);
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a)
{
int tmp;
if (a == 0) return 0;
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
return tmp;
}
#else
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a,
WebRtc_Word16 b)
{
WebRtc_Word32 s_sum = (WebRtc_Word32) a + (WebRtc_Word32) b;
if (s_sum > WEBRTC_SPL_WORD16_MAX)
s_sum = WEBRTC_SPL_WORD16_MAX;
else if (s_sum < WEBRTC_SPL_WORD16_MIN)
s_sum = WEBRTC_SPL_WORD16_MIN;
return (WebRtc_Word16)s_sum;
}
WEBRTC_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;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16( WebRtc_Word16 var1,
WebRtc_Word16 var2)
{
WebRtc_Word32 l_diff;
WebRtc_Word16 s_diff;
// perform subtraction
l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2;
// default setting
s_diff = (WebRtc_Word16) l_diff;
// check for overflow
if (l_diff > (WebRtc_Word32)32767)
s_diff = (WebRtc_Word16)32767;
// check for underflow
if (l_diff < (WebRtc_Word32)-32768)
s_diff = (WebRtc_Word16)-32768;
return s_diff;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
WEBRTC_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;
}
#endif // WEBRTC_ANDROID
#endif // WEBRTC_SPL_INLINE_CALLS
#endif // WEBRTC_SPL_SPL_INL_H_

View File

@ -0,0 +1,106 @@
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libwebrtc_spl
LOCAL_MODULE_TAGS := optional
LOCAL_GENERATED_SOURCES :=
LOCAL_SRC_FILES := add_sat_w16.c \
add_sat_w32.c \
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 \
get_size_in_bits.c \
hanning_table.c \
ilbc_specific_functions.c \
levinson_durbin.c \
lpc_to_refl_coef.c \
min_max_operations.c \
norm_u32.c \
norm_w16.c \
norm_w32.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_fractional.c \
sin_table.c \
sin_table_1024.c \
spl_version.c \
splitting_filter.c \
sqrt_of_one_minus_x_squared.c \
sub_sat_w16.c \
sub_sat_w32.c \
vector_scaling_operations.c
ifeq ($(TARGET_ARCH), arm)
LOCAL_SRC_FILES += \
spl_sqrt.s
else
LOCAL_SRC_FILES += \
spl_sqrt.c
endif
# Flags passed to both C and C++ files.
MY_CFLAGS :=
MY_CFLAGS_C :=
MY_DEFS := '-DNO_TCMALLOC' \
'-DNO_HEAPCHECKER' \
'-DWEBRTC_TARGET_PC' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DANDROID'
LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../interface
# Flags passed to only C++ (and not C) files.
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := libstlport
LOCAL_ADDITIONAL_DEPENDENCIES :=
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl -lpthread
endif
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
endif
include external/stlport/libstlport.mk
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,34 @@
/*
* 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_AddSatW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2)
{
WebRtc_Word32 s_sum = (WebRtc_Word32)var1 + (WebRtc_Word32)var2;
if (s_sum > WEBRTC_SPL_WORD16_MAX)
s_sum = WEBRTC_SPL_WORD16_MAX;
else if (s_sum < WEBRTC_SPL_WORD16_MIN)
s_sum = WEBRTC_SPL_WORD16_MIN;
return (WebRtc_Word16)s_sum;
}
#endif

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the function WebRtcSpl_AddSatW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2)
{
WebRtc_Word32 l_sum;
// perform long addition
l_sum = var1 + var2;
// check for under or overflow
if (WEBRTC_SPL_IS_NEG(var1))
{
if (WEBRTC_SPL_IS_NEG(var2) && !WEBRTC_SPL_IS_NEG(l_sum))
{
l_sum = (WebRtc_Word32)0x80000000;
}
} else
{
if (!WEBRTC_SPL_IS_NEG(var2) && WEBRTC_SPL_IS_NEG(l_sum))
{
l_sum = (WebRtc_Word32)0x7FFFFFFF;
}
}
return l_sum;
}
#endif

View File

@ -0,0 +1,103 @@
/*
* 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_AutoCorrToReflCoef().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *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],
P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
// Initialize loop and pointers.
acfptr = ACF;
rptr = R;
pptr = P;
p1ptr = &P[1];
w1ptr = &W[1];
wptr = w1ptr;
// First loop; n=0. Determine shifting.
tmp = WebRtcSpl_NormW32(*R);
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
*pptr++ = *acfptr++;
// Initialize ACF, P and W.
for (i = 1; i <= use_order; i++)
{
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
*wptr++ = *acfptr;
*pptr++ = *acfptr++;
}
// Compute reflection coefficients.
for (n = 1; n <= use_order; n++, K++)
{
tmp = WEBRTC_SPL_ABS_W16(*p1ptr);
if (*P < tmp)
{
for (i = n; i <= use_order; i++)
*K++ = 0;
return;
}
// Division: WebRtcSpl_div(tmp, *P)
*K = 0;
if (tmp != 0)
{
L_num = tmp;
L_den = *P;
i = 15;
while (i--)
{
(*K) <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
(*K)++;
}
}
if (*p1ptr > 0)
*K = -*K;
}
// Last iteration; don't do Schur recursion.
if (n == use_order)
return;
// 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 );
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 );
pptr++;
tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);
*wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
wptr++;
}
}
}

View File

@ -0,0 +1,141 @@
/*
* 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;
}

View File

@ -0,0 +1,51 @@
/*
* 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;
}
}

View File

@ -0,0 +1,140 @@
/*
* 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
#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT)
extern "C" int FFT_4OFQ14(void *src, void *dest, int NC, int shift);
// For detailed description of the fft functions, check the readme files in fft_ARM9E folder.
int WebRtcSpl_ComplexFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode)
{
return FFT_4OFQ14(frfi, frfiOut, 1 << stages, 0);
}
#endif
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];
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]) + CFFTRND),
15 - CFFTSFT);
ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND), 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;
}

View File

@ -0,0 +1,155 @@
/*
* 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
#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT)
extern "C" int FFT_4OIQ14(void *src, void *dest, int NC, int shift);
// For detailed description of the fft functions, check the readme files in fft_ARM9E folder.
int WebRtcSpl_ComplexIFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode)
{
FFT_4OIQ14(frfi, frfiOut, 1 << stages, 0);
return 0;
}
#endif
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];
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) + CIFFTRND),
15 - CIFFTSFT);
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)
+ CIFFTRND), 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;
}

View File

@ -0,0 +1,108 @@
/*
* 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;
}

View File

@ -0,0 +1,60 @@
/*
* 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
};

View File

@ -0,0 +1,267 @@
/*
* 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
}

View File

@ -0,0 +1,144 @@
/*
* 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;
}

View File

@ -0,0 +1,91 @@
/*
* 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;
}

View File

@ -0,0 +1,59 @@
/*
* 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++ = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, o, -32768);
}
return 0;
}

View File

@ -0,0 +1,36 @@
/*
* 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_Energy().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int 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;
for (i = 0; i < looptimes; i++)
{
en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling);
vectorptr++;
}
*scale_factor = scaling;
return en;
}

View File

@ -0,0 +1,51 @@
;// Optimised ARM assembler multi-radix FFT
INCLUDE fft_main_forward.h
MACRO
GENERATE_FFT_FUNCTION $flags
; first work out a readable function name
; based on the flags
FFT_OPTIONS_STRING $flags, name
; Entry:
; r0 = input array
; r1 = output array
; r2 = number of points in FFT
; r3 = pre-scale shift
;
; Exit:
; r0 = 0 if successful
; = 1 if table too small
;
EXPORT FFT_$name
FFT_4OFQ14
STMFD sp!, {r4-r11, r14}
IF "$radix"="4O"
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT s_$tablename
LDR lr, =s_$tablename
LDR lr,[lr]
CMP N, lr
MOVGT r0, #1
LDMGTFD sp!, {r4-r11, pc}
GENERATE_FFT $flags
MOV r0, #0
LDMFD sp!, {r4-r11, pc}
LTORG
MEND
AREA FFTCODE, CODE, READONLY
GENERATE_FFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_FORWARD ; +FFT_REVERSED
END

View File

@ -0,0 +1,51 @@
;// Optimised ARM assembler multi-radix FFT
INCLUDE fft_main_inverse.h
MACRO
GENERATE_IFFT_FUNCTION $flags
; first work out a readable function name
; based on the flags
FFT_OPTIONS_STRING $flags, name
; Entry:
; r0 = input array
; r1 = output array
; r2 = number of points in FFT
; r3 = pre-scale shift
;
; Exit:
; r0 = 0 if successful
; = 1 if table too small
;
EXPORT FFT_$name
FFT_4OIQ14
STMFD sp!, {r4-r11, r14}
IF "$radix"="4O"
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT s_$tablename
LDR lr, =s_$tablename
LDR lr,[lr]
CMP N, lr
MOVGT r0, #1
LDMGTFD sp!, {r4-r11, pc}
GENERATE_FFT $flags
MOV r0, #0
LDMFD sp!, {r4-r11, pc}
LTORG
MEND
AREA FFTCODE, CODE, READONLY
GENERATE_IFFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_INVERSE +FFT_NONORM ; +FFT_REVERSED
END

View File

@ -0,0 +1,774 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_mac.h,v
; Revision: 1.14
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; Shared macros and interface definition file.
; NB: All the algorithms in this code are Decimation in Time. ARM
; is much better at Decimation in Time (as opposed to Decimation
; in Frequency) due to the position of the barrel shifter. Decimation
; in time has the twiddeling at the start of the butterfly, where as
; decimation in frequency has it at the end of the butterfly. The
; post multiply shifts can be hidden for Decimation in Time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; FIRST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The FIRST STAGE macros "FS_RAD<R>" have the following interface:
;
; ON ENTRY:
; REGISTERS:
; r0 = inptr => points to the input buffer consisting of N complex
; numbers of size (1<<datainlog) bytes each
; r1 = dptr => points to the output buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = N => is the number of points in the transform
; r3 = pscale => shift to prescale input by (if applicable)
; ASSEMBLER VARIABLES:
; reversed => logical variable, true if input data is already bit reversed
; The data needs to be bit reversed otherwise
;
; ACTION:
; The routine should
; (1) Bit reverse the data as required for the whole FFT (unless
; the reversed flag is set)
; (2) Prescale the input data by
; (3) Perform a radix R first stage on the data
; (4) Place the processed data in the output array pointed to be dptr
;
; ON EXIT:
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage
; this is: R<<datalog
; r3 = count => number of radix-R blocks or groups processed in this stage
; this is: N/R
; r0,r4-r12,r14 corrupted
inptr RN 0 ; input buffer
dptr RN 1 ; output/scratch buffer
N RN 2 ; size of the FFT
dptr RN 1 ; data pointer - points to end (load in reverse order)
dinc RN 2 ; bytes between data elements at this level of FFT
count RN 3 ; (elements per block<<16) | (blocks per stage)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; GENERAL STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The GENERAL STAGE macros "GS_RAD<R>" have the following interface.
;
; To describe the arguments, suppose this routine is called as stage j
; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (R1*R2*...*R(j-1))<<datalog
; r3 = count => number of blocks or Groups in the last stage:
; count = Rj*R(j+1)*...*Rk
; NB dinc*count = N<<datalog
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to the end of the coefficients for the stage
; (the coefficients for the next stage will usually follow)
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R
; r3 = count => number of radix-R blocks or groups processed in this stage
; count = R(j+1)*...*Rk = (input count)/R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
count RN 3 ; number of blocks/groups at this stage
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LAST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The LAST STAGE macros "LS_RAD<R>" have the following interface.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; There is a possible stride between the coefficients
; specified by cinc
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (N/R)<<datalog
; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a (last stage optimised) radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to point to real-to-complex conversion coefficients
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = N<<datalog = (input dinc)*R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
cinc RN 3 ; stride between twiddle coefficients in bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; COMPLEX TO REAL CONVERSION INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface.
;
; Suppose that 'w' is the N'th root of unity being used for the real FFT
; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for
; the inverse transform).
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage
; This consists of (1,w,w^2,w^3,...,w^(N/4-1)).
; There is a stride between each coeficient specified by cinc
; r1 = dptr => points to the working buffer consisting of N/2 complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes
; r3 = cinc => Bytes between twiddle value in array pointed to by cptr
; r4 = dout => Output buffer (usually the same as dptr)
;
; ACTION:
; The routine should take the output of an N/2 point complex FFT and convert
; it to the output of an N point real FFT, assuming that the real input
; inputs were packed up into the real,imag,real,imag,... buffers of the complex
; input. The output is N/2 complex numbers of the form:
; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1]
; where y[0],...,y[N-1] is the output from a complex transform of the N
; real inputs.
;
; ON EXIT:
; r0-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes
cinc RN 3 ; bytes between twiddle values in the coefficient buffer
dout RN 4 ; address to write the output (normally the same as dptr)
;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first stage/outer loop level
;inptr RN 0
;dptr RN 1
;N RN 2 ; size of FFT
;dinc RN 2 ; bytes between block size when bit reversed (scaling of N)
bitrev RN 3
; inner loop level
;cptr RN 0 ; coefficient pointer for this level
;dptr RN 1 ; data pointer - points to end (load in reverse order)
;dinc RN 2 ; bytes between data elements at this level of FFT
;count RN 3 ; (elements per block<<16) | (blocks per stage)
; data registers
x0r RN 4
x0i RN 5
x1r RN 6
x1i RN 7
x2r RN 8
x2i RN 9
x3r RN 10
x3i RN 11
t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's
t1 RN 14
MACRO
SETREG $prefix,$v0,$v1
GBLS $prefix.r
GBLS $prefix.i
$prefix.r SETS "$v0"
$prefix.i SETS "$v1"
MEND
MACRO
SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
SETREG $prefix.2,$v4,$v5
SETREG $prefix.3,$v6,$v7
MEND
MACRO
SET2REGS $prefix,$v0,$v1,$v2,$v3
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
MEND
; Macro to load twiddle coeficients
; Customise according to coeficient format
; Load next 3 complex coeficients into thr given registers
; Update the coeficient pointer
MACRO
LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i
IF "$coefformat"="W"
; one word per scalar
LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i}
MEXIT
ENDIF
IF "$coefformat"="H"
; one half word per scalar
LDRSH $c0r, [$cp], #2
LDRSH $c0i, [$cp], #2
LDRSH $c1r, [$cp], #2
LDRSH $c1i, [$cp], #2
LDRSH $c2r, [$cp], #2
LDRSH $c2i, [$cp], #2
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEF $cp, $ci, $re, $im
IF "$coefformat"="W"
LDR $im, [$cp, #4]
LDR $re, [$cp], $ci
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $im, [$cp, #2]
LDRSH $re, [$cp], $ci
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one component of one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEFR $cp, $re
IF "$coefformat"="W"
LDR $re, [$cp]
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $re, [$cp]
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load data elements in the given format
; $dp = address to load complex data
; $di = post index to make to address after load
MACRO
LOADDATAF $dp, $di, $re, $im, $format
IF "$format"="W"
LDR $im, [$dp, #4]
LDR $re, [$dp], $di
MEXIT
ENDIF
IF "$format"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
MACRO
LOADDATAZ $dp, $re, $im
IF "$datainformat"="W"
LDMIA $dp, {$re,$im}
MEXIT
ENDIF
IF "$datainformat"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp]
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
; Load a complex data element from the working array
MACRO
LOADDATA $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $dataformat
MEND
; Load a complex data element from the input array
MACRO
LOADDATAI $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $datainformat
MEND
MACRO
LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3
IF "$datainformat"="W"
LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3}
ELSE
LOADDATAI $dp, #1<<$datalog, $re0,$im0
LOADDATAI $dp, #1<<$datalog, $re1,$im1
LOADDATAI $dp, #1<<$datalog, $re2,$im2
LOADDATAI $dp, #1<<$datalog, $re3,$im3
ENDIF
MEND
; Shift data after load
MACRO
SHIFTDATA $dr, $di
IF "$postldshift"<>""
IF "$di"<>""
MOV $di, $di $postldshift
ENDIF
MOV $dr, $dr $postldshift
ENDIF
MEND
; Store a complex data item in the output data buffer
MACRO
STORE $dp, $di, $re, $im
IF "$dataformat"="W"
STR $im, [$dp, #4]
STR $re, [$dp], $di
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; Store a complex data item in the output data buffer
MACRO
STOREP $dp, $re, $im
IF "$dataformat"="W"
STMIA $dp!, {$re,$im}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
MACRO
STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2
IF "$dataformat"="W"
STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im0, [$dp, #2]
STRH $re0, [$dp], #4
STRH $im1, [$dp, #2]
STRH $re1, [$dp], #4
STRH $im2, [$dp, #2]
STRH $re2, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; do different command depending on forward/inverse FFT
MACRO
DOi $for, $bac, $d, $s1, $s2, $shift
IF "$shift"=""
$for $d, $s1, $s2
ELSE
$for $d, $s1, $s2, $shift
ENDIF
MEND
; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
ADDi $d, $s1, $s2, $shift
DOi SUB, ADD, $d, $s1, $s2, $shift
MEND
; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
SUBi $d, $s1, $s2, $shift
DOi ADD, SUB, $d, $s1, $s2, $shift
MEND
; check that $val is in the range -$max to +$max-1
; set carry flag (sicky) if not (2 cycles)
; has the advantage of not needing a separate register
; to store the overflow state
MACRO
CHECKOV $val, $tmp, $max
EOR $tmp, $val, $val, ASR#31
CMPCC $tmp, $max
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Macro's to perform the twiddle stage (complex multiply by coefficient)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The coefficients are stored in different formats according to the
; precision and processor architecture. The coefficients required
; will be of the form:
;
; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N )
;
; c(k) + i*s(k) = exp(+2*pi*k*i/N)
;
; for some k's. The storage formats are:
;
; Format Data
; Q14S (c-s, s) in Q14 format, 16-bits per real
; Q14R (c, s) in Q14 format, 16-bits per real
; Q30S (c-s, s) in Q30 format, 32-bits per real
;
; The operation to be performed is one of:
;
; a+i*b = (x+i*y)*(c-i*s) => forward transform
; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform
;
; For the R format the operation is quite simple - requiring 4 muls
; and 2 adds:
;
; Forward: a = x*c+y*s, b = y*c-x*s
; Inverse: a = x*c-y*s, b = y*c+x*s
;
; For the S format the operations is more complex but only requires
; three multiplies, and is simpler to schedule:
;
; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s
; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s
;
; Inverse: a = (x-y)*s + x*(c-s)
; b = (x-y)*s + y*(c+s)
;
; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA
; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL
; So S wins except for a very fast multiplier (eg 9E)
;
; NB The coefficients must always be the second operand on processor that
; take a variable number of cycles per multiply - so the FFT time remains constant
; This twiddle takes unpacked real and imaginary values
; Expects (cr,ci) = (c-s,s) on input
; Sets (cr,ci) = (a,b) on output
MACRO
TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1
IF qshift>=0 :LAND: qshift<32
SUB $t1, $xi, $xr ; y-x
MUL $t0, $t1, $ci ; (y-x)*s
ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s allow mul to finish on SA
MLA $ci, $xi, $cr, $t0 ; b
MLA $cr, $xr, $t1, $t0 ; a
ELSE
ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s
SMULL $cr, $t0, $xi, $cr ; t0 = y*(c-s)
SUB $xi, $xi, $xr ; xr = y-x + allow mul to finish on SA
SMULL $ci, $cr, $xi, $ci ; cr = (y-x)*s
ADD $ci, $cr, $t0 ; b + allow mul to finish on SA
SMLAL $t0, $cr, $xr, $t1 ; a
ENDIF
MEND
; The following twiddle variant is similar to the above
; except that it is for an "E" processor varient. A standard
; 4 multiply twiddle is used as it requires the same number
; of cycles and needs less intermediate precision
;
; $co = coeficent real and imaginary (c,s) (packed)
; $xx = input data real and imaginary part (packed)
;
; $xr = destination register for real part of product
; $xi = destination register for imaginary part of product
;
; All registers should be distinct
;
MACRO
TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi
SMULBT $t0, $xx, $c0
SMULBB $xr, $xx, $c0
IF "$xxi"=""
SMULTB $xi, $xx, $c0
SMLATT $xr, $xx, $c0, $xr
ELSE
SMULBB $xi, $xxi, $c0
SMLABT $xr, $xxi, $c0, $xr
ENDIF
SUB $xi, $xi, $t0
MEND
; Scale data value in by the coefficient, writing result to out
; The coeficient must be the second multiplicand
; The post mul shift need not be done so in most cases this
; is just a multiply (unless you need higher precision)
; coef must be preserved
MACRO
SCALE $out, $in, $coef, $tmp
IF qshift>=0 :LAND: qshift<32
MUL $out, $in, $coef
ELSE
SMULL $tmp, $out, $in, $coef
ENDIF
MEND
MACRO
DECODEFORMAT $out, $format
GBLS $out.log
GBLS $out.format
$out.format SETS "$format"
IF "$format"="B"
$out.log SETS "1"
MEXIT
ENDIF
IF "$format"="H"
$out.log SETS "2"
MEXIT
ENDIF
IF "$format"="W"
$out.log SETS "3"
MEXIT
ENDIF
ERROR "Unrecognised format for $out: $format"
MEND
; generate a string in $var of the correct right shift
; amount - negative values = left shift
MACRO
SETSHIFT $var, $value
LCLA svalue
svalue SETA $value
$var SETS ""
IF svalue>0 :LAND: svalue<32
$var SETS ",ASR #0x$svalue"
ENDIF
svalue SETA -svalue
IF svalue>0 :LAND: svalue<32
$var SETS ",LSL #0x$svalue"
ENDIF
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; CODE to decipher the FFT options ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The $flags variable specifies the FFT options
; The global string $name is set to a textual version
; The global string $table is set the table name
MACRO
FFT_OPTIONS_STRING $flags, $name
GBLS $name
GBLS qname ; name of the precision (eg Q14, Q30)
GBLS direction ; name of the direction (eg I, F)
GBLS radix ; name of the radix (2, 4E, 4B, 4O etc)
GBLS intype ; name of input data type (if real)
GBLS prescale ; flag to indicate prescale
GBLS outpos ; position for the output data
GBLS datainformat ; bytes per input data item
GBLS dataformat ; bytes per working item
GBLS coefformat ; bytes per coefficient working item
GBLS coeforder ; R=(c,s) S=(c-s,s) storage format
GBLA datainlog ; shift to bytes per input complex
GBLA datalog ; shift to bytes per working complex
GBLA coeflog ; shift to bytes per coefficient complex
GBLA qshift ; right shift after multiply
GBLA norm
GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E)
GBLS cdshift
GBLS postmulshift
GBLS postldshift
GBLS postmulshift1
GBLS postldshift1
GBLL reversed ; flag to indicate input is already bit reversed
GBLS tablename
; find what sort of processor we are building the FFT for
architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc)
;qname SETS {CPU}
; P $qname
IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6"))
architecture SETA 5 ; Architecture 5 (ARM9E, E extensions)
; P arch E
ENDIF
reversed SETL {FALSE}
; decode input order
IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED
reversed SETL {TRUE}
ENDIF
; decode radix type to $radix
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4
radix SETS "4E"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F
radix SETS "4O"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L
radix SETS "4B"
ENDIF
; decode direction to $direction
direction SETS "F"
; decode data size to $qname, and *log's
IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit
qname SETS "Q30"
datainlog SETA 3 ; 8 bytes per complex
datalog SETA 3
coeflog SETA 3
datainformat SETS "W"
dataformat SETS "W"
coefformat SETS "W"
qshift SETA -2 ; shift left top word of 32 bit result
ENDIF
IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit
qname SETS "Q14"
datainlog SETA 2
datalog SETA 2
coeflog SETA 2
datainformat SETS "H"
dataformat SETS "H"
coefformat SETS "H"
qshift SETA 14
ENDIF
; find the coefficient ordering
coeforder SETS "S"
IF (architecture>=5):LAND:(qshift<16)
coeforder SETS "R"
ENDIF
; decode real vs complex input data type
intype SETS ""
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
intype SETS "R"
ENDIF
; decode on outpos
outpos SETS ""
IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF
outpos SETS "I"
ENDIF
; decode on prescale
prescale SETS ""
IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE
prescale SETS "P"
ENDIF
; decode on output scale
norm SETA 1
IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM
norm SETA 0
ENDIF
; calculate shift to convert data offsets to coefficient offsets
SETSHIFT cdshift, ($datalog)-($coeflog)
$name SETS "$radix$direction$qname$intype$outpos$prescale"
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; FFT GENERATOR ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FFT options bitfield
FFT_DIRECTION EQU 0x00000001 ; direction select bit
FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT
FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT
FFT_INPUTORDER EQU 0x00000002 ; input order select field
FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse)
FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed
FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data
FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data
FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount
FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data
FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points
FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT
FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed?
FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer
FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer
FFT_RADIX EQU 0x00000F00 ; radix select
FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even)
FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage
FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage
FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value
FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm
FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale)
FFT_DATA_SIZES EQU 0x000F0000
FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs
FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs
END

View File

@ -0,0 +1,774 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_mac.h,v
; Revision: 1.14
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; Shared macros and interface definition file.
; NB: All the algorithms in this code are Decimation in Time. ARM
; is much better at Decimation in Time (as opposed to Decimation
; in Frequency) due to the position of the barrel shifter. Decimation
; in time has the twiddeling at the start of the butterfly, where as
; decimation in frequency has it at the end of the butterfly. The
; post multiply shifts can be hidden for Decimation in Time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; FIRST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The FIRST STAGE macros "FS_RAD<R>" have the following interface:
;
; ON ENTRY:
; REGISTERS:
; r0 = inptr => points to the input buffer consisting of N complex
; numbers of size (1<<datainlog) bytes each
; r1 = dptr => points to the output buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = N => is the number of points in the transform
; r3 = pscale => shift to prescale input by (if applicable)
; ASSEMBLER VARIABLES:
; reversed => logical variable, true if input data is already bit reversed
; The data needs to be bit reversed otherwise
;
; ACTION:
; The routine should
; (1) Bit reverse the data as required for the whole FFT (unless
; the reversed flag is set)
; (2) Prescale the input data by
; (3) Perform a radix R first stage on the data
; (4) Place the processed data in the output array pointed to be dptr
;
; ON EXIT:
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage
; this is: R<<datalog
; r3 = count => number of radix-R blocks or groups processed in this stage
; this is: N/R
; r0,r4-r12,r14 corrupted
inptr RN 0 ; input buffer
dptr RN 1 ; output/scratch buffer
N RN 2 ; size of the FFT
dptr RN 1 ; data pointer - points to end (load in reverse order)
dinc RN 2 ; bytes between data elements at this level of FFT
count RN 3 ; (elements per block<<16) | (blocks per stage)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; GENERAL STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The GENERAL STAGE macros "GS_RAD<R>" have the following interface.
;
; To describe the arguments, suppose this routine is called as stage j
; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (R1*R2*...*R(j-1))<<datalog
; r3 = count => number of blocks or Groups in the last stage:
; count = Rj*R(j+1)*...*Rk
; NB dinc*count = N<<datalog
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to the end of the coefficients for the stage
; (the coefficients for the next stage will usually follow)
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R
; r3 = count => number of radix-R blocks or groups processed in this stage
; count = R(j+1)*...*Rk = (input count)/R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
count RN 3 ; number of blocks/groups at this stage
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LAST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The LAST STAGE macros "LS_RAD<R>" have the following interface.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; There is a possible stride between the coefficients
; specified by cinc
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (N/R)<<datalog
; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a (last stage optimised) radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to point to real-to-complex conversion coefficients
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = N<<datalog = (input dinc)*R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
cinc RN 3 ; stride between twiddle coefficients in bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; COMPLEX TO REAL CONVERSION INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface.
;
; Suppose that 'w' is the N'th root of unity being used for the real FFT
; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for
; the inverse transform).
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage
; This consists of (1,w,w^2,w^3,...,w^(N/4-1)).
; There is a stride between each coeficient specified by cinc
; r1 = dptr => points to the working buffer consisting of N/2 complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes
; r3 = cinc => Bytes between twiddle value in array pointed to by cptr
; r4 = dout => Output buffer (usually the same as dptr)
;
; ACTION:
; The routine should take the output of an N/2 point complex FFT and convert
; it to the output of an N point real FFT, assuming that the real input
; inputs were packed up into the real,imag,real,imag,... buffers of the complex
; input. The output is N/2 complex numbers of the form:
; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1]
; where y[0],...,y[N-1] is the output from a complex transform of the N
; real inputs.
;
; ON EXIT:
; r0-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes
cinc RN 3 ; bytes between twiddle values in the coefficient buffer
dout RN 4 ; address to write the output (normally the same as dptr)
;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first stage/outer loop level
;inptr RN 0
;dptr RN 1
;N RN 2 ; size of FFT
;dinc RN 2 ; bytes between block size when bit reversed (scaling of N)
bitrev RN 3
; inner loop level
;cptr RN 0 ; coefficient pointer for this level
;dptr RN 1 ; data pointer - points to end (load in reverse order)
;dinc RN 2 ; bytes between data elements at this level of FFT
;count RN 3 ; (elements per block<<16) | (blocks per stage)
; data registers
x0r RN 4
x0i RN 5
x1r RN 6
x1i RN 7
x2r RN 8
x2i RN 9
x3r RN 10
x3i RN 11
t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's
t1 RN 14
MACRO
SETREG $prefix,$v0,$v1
GBLS $prefix.r
GBLS $prefix.i
$prefix.r SETS "$v0"
$prefix.i SETS "$v1"
MEND
MACRO
SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
SETREG $prefix.2,$v4,$v5
SETREG $prefix.3,$v6,$v7
MEND
MACRO
SET2REGS $prefix,$v0,$v1,$v2,$v3
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
MEND
; Macro to load twiddle coeficients
; Customise according to coeficient format
; Load next 3 complex coeficients into thr given registers
; Update the coeficient pointer
MACRO
LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i
IF "$coefformat"="W"
; one word per scalar
LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i}
MEXIT
ENDIF
IF "$coefformat"="H"
; one half word per scalar
LDRSH $c0r, [$cp], #2
LDRSH $c0i, [$cp], #2
LDRSH $c1r, [$cp], #2
LDRSH $c1i, [$cp], #2
LDRSH $c2r, [$cp], #2
LDRSH $c2i, [$cp], #2
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEF $cp, $ci, $re, $im
IF "$coefformat"="W"
LDR $im, [$cp, #4]
LDR $re, [$cp], $ci
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $im, [$cp, #2]
LDRSH $re, [$cp], $ci
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one component of one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEFR $cp, $re
IF "$coefformat"="W"
LDR $re, [$cp]
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $re, [$cp]
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load data elements in the given format
; $dp = address to load complex data
; $di = post index to make to address after load
MACRO
LOADDATAF $dp, $di, $re, $im, $format
IF "$format"="W"
LDR $im, [$dp, #4]
LDR $re, [$dp], $di
MEXIT
ENDIF
IF "$format"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
MACRO
LOADDATAZ $dp, $re, $im
IF "$datainformat"="W"
LDMIA $dp, {$re,$im}
MEXIT
ENDIF
IF "$datainformat"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp]
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
; Load a complex data element from the working array
MACRO
LOADDATA $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $dataformat
MEND
; Load a complex data element from the input array
MACRO
LOADDATAI $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $datainformat
MEND
MACRO
LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3
IF "$datainformat"="W"
LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3}
ELSE
LOADDATAI $dp, #1<<$datalog, $re0,$im0
LOADDATAI $dp, #1<<$datalog, $re1,$im1
LOADDATAI $dp, #1<<$datalog, $re2,$im2
LOADDATAI $dp, #1<<$datalog, $re3,$im3
ENDIF
MEND
; Shift data after load
MACRO
SHIFTDATA $dr, $di
IF "$postldshift"<>""
IF "$di"<>""
MOV $di, $di $postldshift
ENDIF
MOV $dr, $dr $postldshift
ENDIF
MEND
; Store a complex data item in the output data buffer
MACRO
STORE $dp, $di, $re, $im
IF "$dataformat"="W"
STR $im, [$dp, #4]
STR $re, [$dp], $di
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; Store a complex data item in the output data buffer
MACRO
STOREP $dp, $re, $im
IF "$dataformat"="W"
STMIA $dp!, {$re,$im}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
MACRO
STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2
IF "$dataformat"="W"
STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im0, [$dp, #2]
STRH $re0, [$dp], #4
STRH $im1, [$dp, #2]
STRH $re1, [$dp], #4
STRH $im2, [$dp, #2]
STRH $re2, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; do different command depending on forward/inverse FFT
MACRO
DOi $for, $bac, $d, $s1, $s2, $shift
IF "$shift"=""
$bac $d, $s1, $s2
ELSE
$bac $d, $s1, $s2, $shift
ENDIF
MEND
; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
ADDi $d, $s1, $s2, $shift
DOi SUB, ADD, $d, $s1, $s2, $shift
MEND
; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
SUBi $d, $s1, $s2, $shift
DOi ADD, SUB, $d, $s1, $s2, $shift
MEND
; check that $val is in the range -$max to +$max-1
; set carry flag (sicky) if not (2 cycles)
; has the advantage of not needing a separate register
; to store the overflow state
MACRO
CHECKOV $val, $tmp, $max
EOR $tmp, $val, $val, ASR#31
CMPCC $tmp, $max
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Macro's to perform the twiddle stage (complex multiply by coefficient)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The coefficients are stored in different formats according to the
; precision and processor architecture. The coefficients required
; will be of the form:
;
; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N )
;
; c(k) + i*s(k) = exp(+2*pi*k*i/N)
;
; for some k's. The storage formats are:
;
; Format Data
; Q14S (c-s, s) in Q14 format, 16-bits per real
; Q14R (c, s) in Q14 format, 16-bits per real
; Q30S (c-s, s) in Q30 format, 32-bits per real
;
; The operation to be performed is one of:
;
; a+i*b = (x+i*y)*(c-i*s) => forward transform
; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform
;
; For the R format the operation is quite simple - requiring 4 muls
; and 2 adds:
;
; Forward: a = x*c+y*s, b = y*c-x*s
; Inverse: a = x*c-y*s, b = y*c+x*s
;
; For the S format the operations is more complex but only requires
; three multiplies, and is simpler to schedule:
;
; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s
; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s
;
; Inverse: a = (x-y)*s + x*(c-s)
; b = (x-y)*s + y*(c+s)
;
; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA
; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL
; So S wins except for a very fast multiplier (eg 9E)
;
; NB The coefficients must always be the second operand on processor that
; take a variable number of cycles per multiply - so the FFT time remains constant
; This twiddle takes unpacked real and imaginary values
; Expects (cr,ci) = (c-s,s) on input
; Sets (cr,ci) = (a,b) on output
MACRO
TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1
IF qshift>=0 :LAND: qshift<32
SUB $t1, $xr, $xi ; x-y
MUL $t0, $t1, $ci ; (x-y)*s
ADD $ci, $cr, $ci, LSL #1 ; ci = c+s allow mul to finish on SA
MLA $cr, $xr, $cr, $t0 ; a
MLA $ci, $xi, $ci, $t0 ; b
ELSE
ADD $t1, $cr, $ci, LSL #1 ; c+s
SMULL $t0, $cr, $xr, $cr ; x*(c-s)
SUB $xr, $xr, $xi ; x-y + allow mul to finish on SA
SMULL $t0, $ci, $xr, $ci ; (x-y)*s
ADD $cr, $cr, $ci ; a + allow mul to finish on SA
SMLAL $t0, $ci, $xi, $t1 ; b
ENDIF
MEND
; The following twiddle variant is similar to the above
; except that it is for an "E" processor varient. A standard
; 4 multiply twiddle is used as it requires the same number
; of cycles and needs less intermediate precision
;
; $co = coeficent real and imaginary (c,s) (packed)
; $xx = input data real and imaginary part (packed)
;
; $xr = destination register for real part of product
; $xi = destination register for imaginary part of product
;
; All registers should be distinct
;
MACRO
TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi
SMULBB $t0, $xx, $c0
SMULBT $xi, $xx, $c0
IF "$xxi"=""
SMULTT $xr, $xx, $c0
SMLATB $xi, $xx, $c0, $xi
ELSE
SMULBT $xr, $xxi, $c0
SMLABB $xi, $xxi, $c0, $xi
ENDIF
SUB $xr, $t0, $xr
MEND
; Scale data value in by the coefficient, writing result to out
; The coeficient must be the second multiplicand
; The post mul shift need not be done so in most cases this
; is just a multiply (unless you need higher precision)
; coef must be preserved
MACRO
SCALE $out, $in, $coef, $tmp
IF qshift>=0 :LAND: qshift<32
MUL $out, $in, $coef
ELSE
SMULL $tmp, $out, $in, $coef
ENDIF
MEND
MACRO
DECODEFORMAT $out, $format
GBLS $out.log
GBLS $out.format
$out.format SETS "$format"
IF "$format"="B"
$out.log SETS "1"
MEXIT
ENDIF
IF "$format"="H"
$out.log SETS "2"
MEXIT
ENDIF
IF "$format"="W"
$out.log SETS "3"
MEXIT
ENDIF
ERROR "Unrecognised format for $out: $format"
MEND
; generate a string in $var of the correct right shift
; amount - negative values = left shift
MACRO
SETSHIFT $var, $value
LCLA svalue
svalue SETA $value
$var SETS ""
IF svalue>0 :LAND: svalue<32
$var SETS ",ASR #0x$svalue"
ENDIF
svalue SETA -svalue
IF svalue>0 :LAND: svalue<32
$var SETS ",LSL #0x$svalue"
ENDIF
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; CODE to decipher the FFT options ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The $flags variable specifies the FFT options
; The global string $name is set to a textual version
; The global string $table is set the table name
MACRO
FFT_OPTIONS_STRING $flags, $name
GBLS $name
GBLS qname ; name of the precision (eg Q14, Q30)
GBLS direction ; name of the direction (eg I, F)
GBLS radix ; name of the radix (2, 4E, 4B, 4O etc)
GBLS intype ; name of input data type (if real)
GBLS prescale ; flag to indicate prescale
GBLS outpos ; position for the output data
GBLS datainformat ; bytes per input data item
GBLS dataformat ; bytes per working item
GBLS coefformat ; bytes per coefficient working item
GBLS coeforder ; R=(c,s) S=(c-s,s) storage format
GBLA datainlog ; shift to bytes per input complex
GBLA datalog ; shift to bytes per working complex
GBLA coeflog ; shift to bytes per coefficient complex
GBLA qshift ; right shift after multiply
GBLA norm
GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E)
GBLS cdshift
GBLS postmulshift
GBLS postldshift
GBLS postmulshift1
GBLS postldshift1
GBLL reversed ; flag to indicate input is already bit reversed
GBLS tablename
; find what sort of processor we are building the FFT for
architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc)
;qname SETS {CPU}
; P $qname
IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6"))
architecture SETA 5 ; Architecture 5 (ARM9E, E extensions)
; P arch E
ENDIF
reversed SETL {FALSE}
; decode input order
IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED
reversed SETL {TRUE}
ENDIF
; decode radix type to $radix
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4
radix SETS "4E"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F
radix SETS "4O"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L
radix SETS "4B"
ENDIF
; decode direction to $direction
direction SETS "I"
; decode data size to $qname, and *log's
IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit
qname SETS "Q30"
datainlog SETA 3 ; 8 bytes per complex
datalog SETA 3
coeflog SETA 3
datainformat SETS "W"
dataformat SETS "W"
coefformat SETS "W"
qshift SETA -2 ; shift left top word of 32 bit result
ENDIF
IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit
qname SETS "Q14"
datainlog SETA 2
datalog SETA 2
coeflog SETA 2
datainformat SETS "H"
dataformat SETS "H"
coefformat SETS "H"
qshift SETA 14
ENDIF
; find the coefficient ordering
coeforder SETS "S"
IF (architecture>=5):LAND:(qshift<16)
coeforder SETS "R"
ENDIF
; decode real vs complex input data type
intype SETS ""
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
intype SETS "R"
ENDIF
; decode on outpos
outpos SETS ""
IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF
outpos SETS "I"
ENDIF
; decode on prescale
prescale SETS ""
IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE
prescale SETS "P"
ENDIF
; decode on output scale
norm SETA 1
IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM
norm SETA 0
ENDIF
; calculate shift to convert data offsets to coefficient offsets
SETSHIFT cdshift, ($datalog)-($coeflog)
$name SETS "$radix$direction$qname$intype$outpos$prescale"
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; FFT GENERATOR ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FFT options bitfield
FFT_DIRECTION EQU 0x00000001 ; direction select bit
FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT
FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT
FFT_INPUTORDER EQU 0x00000002 ; input order select field
FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse)
FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed
FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data
FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data
FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount
FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data
FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points
FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT
FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed?
FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer
FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer
FFT_RADIX EQU 0x00000F00 ; radix select
FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even)
FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage
FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage
FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value
FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm
FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale)
FFT_DATA_SIZES EQU 0x000F0000
FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs
FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs
END

View File

@ -0,0 +1,101 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_main.h,v
; Revision: 1.10
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
INCLUDE fft_mac_forward.h ; general macros
INCLUDE fs_rad8_forward.h ; first stage, radix 8 macros
INCLUDE gs_rad4.h ; general stage, radix 4 macros
; The macro in this file generates a whole FFT by glueing together
; FFT stage macros. It is designed to handle a range of power-of-2
; FFT's, the power of 2 set at run time.
; The following should be set up:
;
; $flags = a 32-bit integer indicating what FFT code to generate
; formed by a bitmask of the above FFT_* flag definitions
; (see fft_mac.h)
;
; r0 = inptr = address of the input buffer
; r1 = dptr = address of the output buffer
; r2 = N = the number of points in the FFT
; r3 = = optional pre-left shift to apply to the input data
;
; The contents of the input buffer are preserved (provided that the
; input and output buffer are different, which must be the case unless
; no bitreversal is required and the input is provided pre-reversed).
MACRO
GENERATE_FFT $flags
; decode the options word
FFT_OPTIONS_STRING $flags, name
IF "$outpos"<>""
; stack the input buffer address for later on
STMFD sp!, {inptr}
ENDIF
; Do first stage - radix 4 or radix 8 depending on parity
IF "$radix"="4O"
FS_RAD8
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
FS_RAD4
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT t_$tablename
LDR cptr, =t_$tablename ; coefficient table
CMP count, #1
BEQ %FT10 ; exit for small case
12 ; General stage loop
GS_RAD4
CMP count, #2
BGT %BT12
IF "$radix"="4B"
; support odd parity as well
;BLT %FT10 ; less than 2 left (ie, finished)
;LS_RAD2 ; finish off with a radix 2 stage
ENDIF
10 ; we've finished the complex FFT
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
; convert to a real FFT
IF "$outpos"="I"
LDMFD sp!, {dout}
ELSE
MOV dout, dptr
ENDIF
; dinc = (N/2) >> datalog where N is the number of real points
IMPORT s_$tablename
LDR t0, = s_$tablename
LDR t0, [t0] ; max N handled by the table
MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle
CMP t0, t1
MOV cinc, #3<<$coeflog ; radix 4 table stage
MOVEQ cinc, #1<<$coeflog ; radix 4 table stage
LS_ZTOR
ENDIF
MEND
END

View File

@ -0,0 +1,101 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_main.h,v
; Revision: 1.10
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
INCLUDE fft_mac_inverse.h ; general macros
INCLUDE fs_rad8_inverse.h ; first stage, radix 8 macros
INCLUDE gs_rad4.h ; general stage, radix 4 macros
; The macro in this file generates a whole FFT by glueing together
; FFT stage macros. It is designed to handle a range of power-of-2
; FFT's, the power of 2 set at run time.
; The following should be set up:
;
; $flags = a 32-bit integer indicating what FFT code to generate
; formed by a bitmask of the above FFT_* flag definitions
; (see fft_mac.h)
;
; r0 = inptr = address of the input buffer
; r1 = dptr = address of the output buffer
; r2 = N = the number of points in the FFT
; r3 = = optional pre-left shift to apply to the input data
;
; The contents of the input buffer are preserved (provided that the
; input and output buffer are different, which must be the case unless
; no bitreversal is required and the input is provided pre-reversed).
MACRO
GENERATE_FFT $flags
; decode the options word
FFT_OPTIONS_STRING $flags, name
IF "$outpos"<>""
; stack the input buffer address for later on
STMFD sp!, {inptr}
ENDIF
; Do first stage - radix 4 or radix 8 depending on parity
IF "$radix"="4O"
FS_RAD8
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
FS_RAD4
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT t_$tablename
LDR cptr, =t_$tablename ; coefficient table
CMP count, #1
BEQ %FT10 ; exit for small case
12 ; General stage loop
GS_RAD4
CMP count, #2
BGT %BT12
IF "$radix"="4B"
; support odd parity as well
;BLT %FT10 ; less than 2 left (ie, finished)
;LS_RAD2 ; finish off with a radix 2 stage
ENDIF
10 ; we've finished the complex FFT
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
; convert to a real FFT
IF "$outpos"="I"
LDMFD sp!, {dout}
ELSE
MOV dout, dptr
ENDIF
; dinc = (N/2) >> datalog where N is the number of real points
IMPORT s_$tablename
LDR t0, = s_$tablename
LDR t0, [t0] ; max N handled by the table
MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle
CMP t0, t1
MOV cinc, #3<<$coeflog ; radix 4 table stage
MOVEQ cinc, #1<<$coeflog ; radix 4 table stage
LS_ZTOR
ENDIF
MEND
END

View File

@ -0,0 +1,236 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fs_rad8.h,v
; Revision: 1.5
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains first stage, radix-8 code
; It bit reverses (assuming a power of 2 FFT) and performs the first stage
;
MACRO
FS_RAD8
SETSHIFT postldshift, 3*norm
SETSHIFT postmulshift, 3*norm+qshift
SETSHIFT postldshift1, 3*norm-1
SETSHIFT postmulshift1, 3*norm+qshift-1
IF "$prescale"<>""
STMFD sp!, {dptr, N, r3}
ELSE
STMFD sp!, {dptr, N}
ENDIF
MOV bitrev, #0
MOV dinc, N, LSL #($datalog-2)
12 ; first (radix 8) stage loop
; do first two (radix 2) stages
FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev
FIRST_STAGE_RADIX8_EVEN dinc, bitrev
; third (radix 2) stage
LDMFD sp!, {x0r, x0i}
ADD $h0r, $h0r, x0r $postldshift ; standard add
ADD $h0i, $h0i, x0i $postldshift
SUB x0r, $h0r, x0r $postldshift1
SUB x0i, $h0i, x0i $postldshift1
STORE dptr, #1<<$datalog, $h0r, $h0i
LDMFD sp!, {x1r, x1i}
ADD $h1r, $h1r, x1r $postmulshift
ADD $h1i, $h1i, x1i $postmulshift
SUB x1r, $h1r, x1r $postmulshift1
SUB x1i, $h1i, x1i $postmulshift1
STORE dptr, #1<<$datalog, $h1r, $h1i
LDMFD sp!, {x2r, x2i}
SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were
ADDi $h2i, $h2i, x2i $postldshift ; swapped above
ADDi x2r, $h2r, x2r $postldshift1
SUBi x2i, $h2i, x2i $postldshift1
STORE dptr, #1<<$datalog, $h2r, $h2i
LDMFD sp!, {x3r, x3i}
ADD $h3r, $h3r, x3r $postmulshift
ADD $h3i, $h3i, x3i $postmulshift
SUB x3r, $h3r, x3r $postmulshift1
SUB x3i, $h3i, x3i $postmulshift1
STORE dptr, #1<<$datalog, $h3r, $h3i
STORE dptr, #1<<$datalog, x0r, x0i
STORE dptr, #1<<$datalog, x1r, x1i
STORE dptr, #1<<$datalog, x2r, x2i
STORE dptr, #1<<$datalog, x3r, x3i
IF reversed
SUBS dinc, dinc, #2<<$datalog
BGT %BT12
ELSE
; increment the count in a bit reverse manner
EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1
TST bitrev, dinc, LSR #($datalog-2+4)
BNE %BT12
; get here for 1/2 the loops - carry to next bit
EOR bitrev, bitrev, dinc, LSR #($datalog-2+5)
TST bitrev, dinc, LSR #($datalog-2+5)
BNE %BT12
; get here for 1/4 of the loops - stop unrolling
MOV t0, dinc, LSR #($datalog-2+6)
15 ; bit reverse increment loop
EOR bitrev, bitrev, t0
TST bitrev, t0
BNE %BT12
; get here for 1/8 of the loops (or when finished)
MOVS t0, t0, LSR #1 ; move down to next bit
BNE %BT15 ; carry on if we haven't run off the bottom
ENDIF
IF "$prescale"<>""
LDMFD sp!, {dptr, N, r3}
ELSE
LDMFD sp!, {dptr, N}
ENDIF
MOV count, N, LSR #3 ; start with N/8 blocks 8 each
MOV dinc, #8<<$datalog ; initial skip is 8 elements
MEND
MACRO
FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev
IF reversed
; load non bit reversed
ADD t0, inptr, #4<<$datalog
LOADDATAI t0, #1<<$datalog, x0r, x0i
LOADDATAI t0, #1<<$datalog, x1r, x1i
LOADDATAI t0, #1<<$datalog, x2r, x2i
LOADDATAI t0, #1<<$datalog, x3r, x3i
ELSE
; load data elements 1,3,5,7 into register order 1,5,3,7
ADD t0, inptr, $bitrev, LSL #$datalog
ADD t0, t0, $dinc_lsr1 ; load in odd terms first
LOADDATAI t0, $dinc, x0r, x0i
LOADDATAI t0, $dinc, x2r, x2i
LOADDATAI t0, $dinc, x1r, x1i
LOADDATAI t0, $dinc, x3r, x3i
ENDIF
IF "$prescale"="P"
LDR t0, [sp, #8]
MOV x0r, x0r, LSL t0
MOV x0i, x0i, LSL t0
MOV x1r, x1r, LSL t0
MOV x1i, x1i, LSL t0
MOV x2r, x2r, LSL t0
MOV x2i, x2i, LSL t0
MOV x3r, x3r, LSL t0
MOV x3i, x3i, LSL t0
ENDIF
SETREG h2, x3r, x3i
SETREG h3, t0, t1
; first stage (radix 2) butterflies
ADD x0r, x0r, x1r
ADD x0i, x0i, x1i
SUB x1r, x0r, x1r, LSL #1
SUB x1i, x0i, x1i, LSL #1
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
; second stage (radix 2) butterflies
SUB x2i, x0r, $h2r ; swap real and imag here
SUB x2r, x0i, $h2i ; for use later
ADD x0r, x0r, $h2r
ADD x0i, x0i, $h2i
ADDi x3r, x1r, $h3i
SUBi x3i, x1i, $h3r
SUBi x1r, x1r, $h3i
ADDi x1i, x1i, $h3r
; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage
LCLS tempname
tempname SETS "R_rad8"
IMPORT t_$qname$tempname
LDR t1, =t_$qname$tempname
; IMPORT t_$qname.R_rad8
; LDR t1, =t_$qname.R_rad8
LOADCOEFR t1, t1
STMFD sp!, {dinc} ;;; FIXME!!!
ADD t0, x1r, x1i ; real part when * (1-i)
SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2)
RSB t0, t0, x1i, LSL #1 ; imag part when * (1-i)
SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, x3i, x3r ; real part when * (-1-i)
SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, t0, x3i, LSL #1 ; imag part when * (-1-i)
SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2)
LDMFD sp!, {dinc} ;;; FIXME!!!
STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i}
MEND
MACRO
FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev
; load elements 0,2,4,6 into register order 0,4,2,6
SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1
SETREG g3, x0r, x0i
IF reversed
; load normally
LOADDATAI inptr, #1<<$datalog, $h0r, $h0i
LOADDATAI inptr, #1<<$datalog, $h1r, $h1i
LOADDATAI inptr, #1<<$datalog, $h2r, $h2i
LOADDATAI inptr, #1<<$datalog, $h3r, $h3i
ADD inptr, inptr, #4<<$datalog
ELSE
; load bit reversed
ADD x0r, inptr, $bitrev, LSL #$datalog
LOADDATAI x0r, $dinc, $h0r, $h0i
LOADDATAI x0r, $dinc, $h2r, $h2i
LOADDATAI x0r, $dinc, $h1r, $h1i
LOADDATAI x0r, $dinc, $h3r, $h3i
ENDIF
IF "$prescale"="P"
LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs!
MOV $h0r, $h0r, LSL x0r
MOV $h0i, $h0i, LSL x0r
MOV $h1r, $h1r, LSL x0r
MOV $h1i, $h1i, LSL x0r
MOV $h2r, $h2r, LSL x0r
MOV $h2i, $h2i, LSL x0r
MOV $h3r, $h3r, LSL x0r
MOV $h3i, $h3i, LSL x0r
ENDIF
SHIFTDATA $h0r, $h0i
; first stage (radix 2) butterflies
ADD $h0r, $h0r, $h1r $postldshift
ADD $h0i, $h0i, $h1i $postldshift
SUB $h1r, $h0r, $h1r $postldshift1
SUB $h1i, $h0i, $h1i $postldshift1
SUB $g3r, $h2r, $h3r
SUB $g3i, $h2i, $h3i
ADD $h2r, $h2r, $h3r
ADD $h2i, $h2i, $h3i
; second stage (radix 2) butterflies
ADD $h0r, $h0r, $h2r $postldshift
ADD $h0i, $h0i, $h2i $postldshift
SUB $h2r, $h0r, $h2r $postldshift1
SUB $h2i, $h0i, $h2i $postldshift1
ADDi $h3r, $h1r, $g3i $postldshift
SUBi $h3i, $h1i, $g3r $postldshift
SUBi $h1r, $h1r, $g3i $postldshift
ADDi $h1i, $h1i, $g3r $postldshift
MEND
END

View File

@ -0,0 +1,236 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fs_rad8.h,v
; Revision: 1.5
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains first stage, radix-8 code
; It bit reverses (assuming a power of 2 FFT) and performs the first stage
;
MACRO
FS_RAD8
SETSHIFT postldshift, 3*norm
SETSHIFT postmulshift, 3*norm+qshift
SETSHIFT postldshift1, 3*norm-1
SETSHIFT postmulshift1, 3*norm+qshift-1
IF "$prescale"<>""
STMFD sp!, {dptr, N, r3}
ELSE
STMFD sp!, {dptr, N}
ENDIF
MOV bitrev, #0
MOV dinc, N, LSL #($datalog-2)
12 ; first (radix 8) stage loop
; do first two (radix 2) stages
FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev
FIRST_STAGE_RADIX8_EVEN dinc, bitrev
; third (radix 2) stage
LDMFD sp!, {x0r, x0i}
ADD $h0r, $h0r, x0r $postldshift ; standard add
ADD $h0i, $h0i, x0i $postldshift
SUB x0r, $h0r, x0r $postldshift1
SUB x0i, $h0i, x0i $postldshift1
STORE dptr, #1<<$datalog, $h0r, $h0i
LDMFD sp!, {x1r, x1i}
ADD $h1r, $h1r, x1r $postmulshift
ADD $h1i, $h1i, x1i $postmulshift
SUB x1r, $h1r, x1r $postmulshift1
SUB x1i, $h1i, x1i $postmulshift1
STORE dptr, #1<<$datalog, $h1r, $h1i
LDMFD sp!, {x2r, x2i}
SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were
ADDi $h2i, $h2i, x2i $postldshift ; swapped above
ADDi x2r, $h2r, x2r $postldshift1
SUBi x2i, $h2i, x2i $postldshift1
STORE dptr, #1<<$datalog, $h2r, $h2i
LDMFD sp!, {x3r, x3i}
ADD $h3r, $h3r, x3r $postmulshift
ADD $h3i, $h3i, x3i $postmulshift
SUB x3r, $h3r, x3r $postmulshift1
SUB x3i, $h3i, x3i $postmulshift1
STORE dptr, #1<<$datalog, $h3r, $h3i
STORE dptr, #1<<$datalog, x0r, x0i
STORE dptr, #1<<$datalog, x1r, x1i
STORE dptr, #1<<$datalog, x2r, x2i
STORE dptr, #1<<$datalog, x3r, x3i
IF reversed
SUBS dinc, dinc, #2<<$datalog
BGT %BT12
ELSE
; increment the count in a bit reverse manner
EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1
TST bitrev, dinc, LSR #($datalog-2+4)
BNE %BT12
; get here for 1/2 the loops - carry to next bit
EOR bitrev, bitrev, dinc, LSR #($datalog-2+5)
TST bitrev, dinc, LSR #($datalog-2+5)
BNE %BT12
; get here for 1/4 of the loops - stop unrolling
MOV t0, dinc, LSR #($datalog-2+6)
15 ; bit reverse increment loop
EOR bitrev, bitrev, t0
TST bitrev, t0
BNE %BT12
; get here for 1/8 of the loops (or when finished)
MOVS t0, t0, LSR #1 ; move down to next bit
BNE %BT15 ; carry on if we haven't run off the bottom
ENDIF
IF "$prescale"<>""
LDMFD sp!, {dptr, N, r3}
ELSE
LDMFD sp!, {dptr, N}
ENDIF
MOV count, N, LSR #3 ; start with N/8 blocks 8 each
MOV dinc, #8<<$datalog ; initial skip is 8 elements
MEND
MACRO
FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev
IF reversed
; load non bit reversed
ADD t0, inptr, #4<<$datalog
LOADDATAI t0, #1<<$datalog, x0r, x0i
LOADDATAI t0, #1<<$datalog, x1r, x1i
LOADDATAI t0, #1<<$datalog, x2r, x2i
LOADDATAI t0, #1<<$datalog, x3r, x3i
ELSE
; load data elements 1,3,5,7 into register order 1,5,3,7
ADD t0, inptr, $bitrev, LSL #$datalog
ADD t0, t0, $dinc_lsr1 ; load in odd terms first
LOADDATAI t0, $dinc, x0r, x0i
LOADDATAI t0, $dinc, x2r, x2i
LOADDATAI t0, $dinc, x1r, x1i
LOADDATAI t0, $dinc, x3r, x3i
ENDIF
IF "$prescale"="P"
LDR t0, [sp, #8]
MOV x0r, x0r, LSL t0
MOV x0i, x0i, LSL t0
MOV x1r, x1r, LSL t0
MOV x1i, x1i, LSL t0
MOV x2r, x2r, LSL t0
MOV x2i, x2i, LSL t0
MOV x3r, x3r, LSL t0
MOV x3i, x3i, LSL t0
ENDIF
SETREG h2, x3r, x3i
SETREG h3, t0, t1
; first stage (radix 2) butterflies
ADD x0r, x0r, x1r
ADD x0i, x0i, x1i
SUB x1r, x0r, x1r, LSL #1
SUB x1i, x0i, x1i, LSL #1
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
; second stage (radix 2) butterflies
SUB x2i, x0r, $h2r ; swap real and imag here
SUB x2r, x0i, $h2i ; for use later
ADD x0r, x0r, $h2r
ADD x0i, x0i, $h2i
ADDi x3r, x1r, $h3i
SUBi x3i, x1i, $h3r
SUBi x1r, x1r, $h3i
ADDi x1i, x1i, $h3r
; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage
LCLS tempname
tempname SETS "R_rad8"
IMPORT t_$qname$tempname
LDR t1, =t_$qname$tempname
; IMPORT t_$qname.R_rad8
; LDR t1, =t_$qname.R_rad8
LOADCOEFR t1, t1
STMFD sp!, {dinc} ;;; FIXME!!!
SUB t0, x1r, x1i ; real part when * (1+i)
SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2)
ADD t0, t0, x1i, LSL #1 ; imag part when * (1+i)
SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, x3r, x3i ; imag part when * (-1+i)
SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, t0, x3r, LSL #1 ; real part when * (-1+i)
SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2)
LDMFD sp!, {dinc} ;;; FIXME!!!
STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i}
MEND
MACRO
FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev
; load elements 0,2,4,6 into register order 0,4,2,6
SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1
SETREG g3, x0r, x0i
IF reversed
; load normally
LOADDATAI inptr, #1<<$datalog, $h0r, $h0i
LOADDATAI inptr, #1<<$datalog, $h1r, $h1i
LOADDATAI inptr, #1<<$datalog, $h2r, $h2i
LOADDATAI inptr, #1<<$datalog, $h3r, $h3i
ADD inptr, inptr, #4<<$datalog
ELSE
; load bit reversed
ADD x0r, inptr, $bitrev, LSL #$datalog
LOADDATAI x0r, $dinc, $h0r, $h0i
LOADDATAI x0r, $dinc, $h2r, $h2i
LOADDATAI x0r, $dinc, $h1r, $h1i
LOADDATAI x0r, $dinc, $h3r, $h3i
ENDIF
IF "$prescale"="P"
LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs!
MOV $h0r, $h0r, LSL x0r
MOV $h0i, $h0i, LSL x0r
MOV $h1r, $h1r, LSL x0r
MOV $h1i, $h1i, LSL x0r
MOV $h2r, $h2r, LSL x0r
MOV $h2i, $h2i, LSL x0r
MOV $h3r, $h3r, LSL x0r
MOV $h3i, $h3i, LSL x0r
ENDIF
SHIFTDATA $h0r, $h0i
; first stage (radix 2) butterflies
ADD $h0r, $h0r, $h1r $postldshift
ADD $h0i, $h0i, $h1i $postldshift
SUB $h1r, $h0r, $h1r $postldshift1
SUB $h1i, $h0i, $h1i $postldshift1
SUB $g3r, $h2r, $h3r
SUB $g3i, $h2i, $h3i
ADD $h2r, $h2r, $h3r
ADD $h2i, $h2i, $h3i
; second stage (radix 2) butterflies
ADD $h0r, $h0r, $h2r $postldshift
ADD $h0i, $h0i, $h2i $postldshift
SUB $h2r, $h0r, $h2r $postldshift1
SUB $h2i, $h0i, $h2i $postldshift1
ADDi $h3r, $h1r, $g3i $postldshift
SUBi $h3i, $h1i, $g3r $postldshift
SUBi $h1r, $h1r, $g3i $postldshift
ADDi $h1i, $h1i, $g3r $postldshift
MEND
END

View File

@ -0,0 +1,111 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: gs_rad4.h,v
; Revision: 1.8
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains the general stage, radix 4 macro
MACRO
GS_RAD4
SETSHIFT postldshift, 2*norm
SETSHIFT postmulshift, 2*norm+qshift
; dinc contains the number of bytes between the values to read
; for the radix 4 bufferfly
; Thus:
; dinc*4 = number of bytes between the blocks at this level
; dinc>>datalog = number of elements in each block at this level
MOV count, count, LSR #2 ; a quarter the blocks per stage
STMFD sp!, {dptr, count}
ADD t0, dinc, dinc, LSL #1 ; 3*dinc
ADD dptr, dptr, t0 ; move to last of 4 butterflys
SUB count, count, #1<<16 ; prepare top half of counter
12 ; block loop
; set top half of counter to (elements/block - 1)
ADD count, count, dinc, LSL #(16-$datalog)
15 ; butterfly loop
IF (architecture>=5):LAND:(qshift<16)
; E extensions available (21 cycles)
; But needs a different table format
LDMIA cptr!, {x0i, x1i, x2i}
LDR x2r, [dptr], -dinc
LDR x1r, [dptr], -dinc
LDR x0r, [dptr], -dinc
TWIDDLE_E x3r, x3i, x2i, t0, x2r
TWIDDLE_E x2r, x2i, x1i, t0, x1r
TWIDDLE_E x1r, x1i, x0i, t0, x0r
ELSE
; load next three twiddle factors (66 @ 4 cycles/mul)
LOADCOEFS cptr, x1r, x1i, x2r, x2i, x3r, x3i
; load data in reversed order & perform twiddles
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x3r, x3i, t0, t1
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x2r, x2i, t0, t1
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x1r, x1i, t0, t1
ENDIF
LOADDATAZ dptr, x0r, x0i
SHIFTDATA x0r, x0i
; now calculate the h's
; h[0,k] = g[0,k] + g[2,k]
; h[1,k] = g[0,k] - g[2,k]
; h[2,k] = g[1,k] + g[3,k]
; h[3,k] = g[1,k] - g[3,k]
SETREGS h,t0,t1,x0r,x0i,x1r,x1i,x2r,x2i
ADD $h0r, x0r, x1r $postmulshift
ADD $h0i, x0i, x1i $postmulshift
SUB $h1r, x0r, x1r $postmulshift
SUB $h1i, x0i, x1i $postmulshift
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
; now calculate the y's and store results
; y[0*N/4+k] = h[0,k] + h[2,k]
; y[1*N/4+k] = h[1,k] + j*h[3,k]
; y[2*N/4+k] = h[0,k] - h[2,k]
; y[3*N/4+k] = h[1,k] - j*h[3,k]
SETREG y0,x3r,x3i
ADD $y0r, $h0r, $h2r $postmulshift
ADD $y0i, $h0i, $h2i $postmulshift
STORE dptr, dinc, $y0r, $y0i
SUBi $y0r, $h1r, $h3i $postmulshift
ADDi $y0i, $h1i, $h3r $postmulshift
STORE dptr, dinc, $y0r, $y0i
SUB $y0r, $h0r, $h2r $postmulshift
SUB $y0i, $h0i, $h2i $postmulshift
STORE dptr, dinc, $y0r, $y0i
ADDi $y0r, $h1r, $h3i $postmulshift
SUBi $y0i, $h1i, $h3r $postmulshift
STOREP dptr, $y0r, $y0i
; continue butterfly loop
SUBS count, count, #1<<16
BGE %BT15
; decrement counts for block loop
ADD t0, dinc, dinc, LSL #1 ; dinc * 3
ADD dptr, dptr, t0 ; move onto next block
SUB cptr, cptr, t0 $cdshift ; move back to coeficients start
SUB count, count, #1 ; done one more block
MOVS t1, count, LSL #16
BNE %BT12 ; still more blocks to do
; finished stage
ADD cptr, cptr, t0 $cdshift ; move onto next stage coeficients
LDMFD sp!, {dptr, count}
MOV dinc, dinc, LSL #2 ; four times the entries per block
MEND
END

View File

@ -0,0 +1,91 @@
# $Copyright:
# ----------------------------------------------------------------
# This confidential and proprietary software may be used only as
# authorised by a licensing agreement from ARM Limited
# (C) COPYRIGHT 2000,2002 ARM Limited
# ALL RIGHTS RESERVED
# The entire notice above must be reproduced on all authorised
# copies and copies may only be made to the extent permitted
# by a licensing agreement from ARM Limited.
# ----------------------------------------------------------------
# File: readme.txt,v
# Revision: 1.4
# ----------------------------------------------------------------
# $
!!! To fully understand the FFT/ARM9E/WIN_MOB implementation in SPLIB,
!!! you have to refer to the full set of files in RVDS' package:
!!! C:\Program Files\ARM\RVDS\Examples\3.0\79\windows\fft_v5te.
ARM Assembler FFT implementation
================================
Overview
========
This implementation has been restructured to allow FFT's of varying radix
rather than the fixed radix-2 or radix-4 versions allowed earlier. The
implementation of an optimised assembler FFT of a given size (N points)
consists of chaining together a sequence of stages 1,2,3,...,k such that the
j'th stage has radix Rj and:
N = R1*R2*R3*...*Rk
For the ARM implementations we keep the size of the Rj's decreasing with
increasing j, EXCEPT that if there are any non power of 2 factors (ie, odd
prime factors) then these come before all the power of 2 factors.
For example:
N=64 would be implemented as stages:
radix 4, radix 4, radix 4
N=128 would be implemented as stages:
radix 8, radix 4, radix 4
OR
radix 4, radix 4, radix 4, radix 2
N=192 would be implemented as stages:
radix 3, radix 4, radix 4, radix 4
The bitreversal is usally combined with the first stage where possible.
Structure
=========
The actual FFT routine is built out of a hierarchy of macros. All stage
macros and filenames are one of:
fs_rad<n> => the macro implements a radix <n> First Stage (usually
including the bit reversal)
gs_rad<n> => the macro implements a radix <n> General Stage (any
stage except the first - includes the twiddle operations)
ls_rad<n> => the macro implements a radix <n> Last Stage (this macro
is like the gs_rad<n> version but is optimised for
efficiency in the last stage)
ls_ztor => this macro converts the output of a complex FFT to
be the first half of the output of a real FFT of
double the number of input points.
Other files are:
fft_mac.h => Macro's and register definitions shared by all radix
implementations
fft_main.h => Main FFT macros drawing together the stage macros
to produce a complete FFT
Interfaces
==========
The register interfaces for the different type of stage macros are described
at the start of fft_mac.h

View File

@ -0,0 +1,695 @@
/*
* Copyright (C) ARM Limited 1998-2002. All rights reserved.
*
* t_01024_8.c
*
*/
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 };

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) ARM Limited 1998-2000. All rights reserved.
*
* t_rad.c
*
*/
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 };
*/

View File

@ -0,0 +1,92 @@
/*
* 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;
state_low_length = state_low_length;
filtered_low_length = filtered_low_length;
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;
}

View File

@ -0,0 +1,49 @@
/*
* 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;
}

View File

@ -0,0 +1,49 @@
/*
* 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_FilterMAFastQ12().
* The description header can be found in signal_processing_library.h
*
*/
#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)
{
WebRtc_Word32 o;
int 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;
for (j = 0; j < B_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
}
// 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);
*out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
}
return;
}

View File

@ -0,0 +1,41 @@
/*
* 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];
}
}

View File

@ -0,0 +1,44 @@
/*
* 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_GetScalingSquare().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int 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;
for (i = looptimes; i > 0; i--)
{
sabs = (*sptr > 0 ? *sptr++ : -*sptr++);
smax = (sabs > smax ? sabs : smax);
}
t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));
if (smax == 0)
{
return 0; // Since norm(0) returns 0
} else
{
return (t > nbits) ? 0 : nbits - t;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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_GetSizeInBits().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 value)
{
int bits = 0;
// Fast binary search to find the number of bits used
if ((0xFFFF0000 & value))
bits = 16;
if ((0x0000FF00 & (value >> bits)))
bits += 8;
if ((0x000000F0 & (value >> bits)))
bits += 4;
if ((0x0000000C & (value >> bits)))
bits += 2;
if ((0x00000002 & (value >> bits)))
bits += 1;
if ((0x00000001 & (value >> bits)))
bits += 1;
return bits;
}
#endif

View File

@ -0,0 +1,53 @@
/*
* 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 Hanning table with 256 entries.
*
*/
#include "signal_processing_library.h"
// Hanning table with 256 entries
WebRtc_Word16 WebRtcSpl_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,
383, 413, 446, 479, 513, 549, 586, 624,
663, 703, 744, 787, 830, 875, 920, 967,
1015, 1064, 1114, 1165, 1218, 1271, 1325, 1381,
1437, 1494, 1553, 1612, 1673, 1734, 1796, 1859,
1924, 1989, 2055, 2122, 2190, 2259, 2329, 2399,
2471, 2543, 2617, 2691, 2765, 2841, 2918, 2995,
3073, 3152, 3232, 3312, 3393, 3475, 3558, 3641,
3725, 3809, 3895, 3980, 4067, 4154, 4242, 4330,
4419, 4509, 4599, 4689, 4781, 4872, 4964, 5057,
5150, 5244, 5338, 5432, 5527, 5622, 5718, 5814,
5910, 6007, 6104, 6202, 6299, 6397, 6495, 6594,
6693, 6791, 6891, 6990, 7090, 7189, 7289, 7389,
7489, 7589, 7690, 7790, 7890, 7991, 8091, 8192,
8293, 8393, 8494, 8594, 8694, 8795, 8895, 8995,
9095, 9195, 9294, 9394, 9493, 9593, 9691, 9790,
9889, 9987, 10085, 10182, 10280, 10377, 10474, 10570,
10666, 10762, 10857, 10952, 11046, 11140, 11234, 11327,
11420, 11512, 11603, 11695, 11785, 11875, 11965, 12054,
12142, 12230, 12317, 12404, 12489, 12575, 12659, 12743,
12826, 12909, 12991, 13072, 13152, 13232, 13311, 13389,
13466, 13543, 13619, 13693, 13767, 13841, 13913, 13985,
14055, 14125, 14194, 14262, 14329, 14395, 14460, 14525,
14588, 14650, 14711, 14772, 14831, 14890, 14947, 15003,
15059, 15113, 15166, 15219, 15270, 15320, 15369, 15417,
15464, 15509, 15554, 15597, 15640, 15681, 15721, 15760,
15798, 15835, 15871, 15905, 15938, 15971, 16001, 16031,
16060, 16087, 16113, 16138, 16162, 16185, 16206, 16227,
16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345,
16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384
};

View File

@ -0,0 +1,120 @@
/*
* 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);
}
}

View File

@ -0,0 +1,259 @@
/*
* 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
}

View File

@ -0,0 +1,57 @@
/*
* 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_LpcToReflCoef().
* The description header can be found in signal_processing_library.h
*
*/
#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)
{
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;
k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(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]);
// (1 - k^2) in Q15
tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(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] = 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
}
tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);
k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15
}
return;
}

View File

@ -0,0 +1,305 @@
/*
* 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"
// Maximum absolute value of word16 vector.
WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(G_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;
#ifdef _ARM_OPT_
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
WebRtc_Word16 len4 = (length >> 2) << 2;
for (i = 0; i < len4; i = i + 4)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
for (i = len4; i < len; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
#else
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

View File

@ -0,0 +1,42 @@
/*
* 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_NormU32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
int WebRtcSpl_NormU32(WebRtc_UWord32 value)
{
int zeros = 0;
if (value == 0)
return 0;
if (!(0xFFFF0000 & value))
zeros = 16;
if (!(0xFF000000 & (value << zeros)))
zeros += 8;
if (!(0xF0000000 & (value << zeros)))
zeros += 4;
if (!(0xC0000000 & (value << zeros)))
zeros += 2;
if (!(0x80000000 & (value << zeros)))
zeros += 1;
return zeros;
}
#endif

View File

@ -0,0 +1,40 @@
/*
* 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_NormW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
int WebRtcSpl_NormW16(WebRtc_Word16 value)
{
int zeros = 0;
if (value <= 0)
value ^= 0xFFFF;
if ( !(0xFF80 & value))
zeros = 8;
if ( !(0xF800 & (value << zeros)))
zeros += 4;
if ( !(0xE000 & (value << zeros)))
zeros += 2;
if ( !(0xC000 & (value << zeros)))
zeros += 1;
return zeros;
}
#endif

View File

@ -0,0 +1,45 @@
/*
* 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_NormW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
int WebRtcSpl_NormW32(WebRtc_Word32 value)
{
int zeros = 0;
if (value <= 0)
value ^= 0xFFFFFFFF;
// Fast binary search to determine the number of left shifts required to 32-bit normalize
// the value
if (!(0xFFFF8000 & value))
zeros = 16;
if (!(0xFF800000 & (value << zeros)))
zeros += 8;
if (!(0xF8000000 & (value << zeros)))
zeros += 4;
if (!(0xE0000000 & (value << zeros)))
zeros += 2;
if (!(0xC0000000 & (value << zeros)))
zeros += 1;
return zeros;
}
#endif

View File

@ -0,0 +1,85 @@
/*
* 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.
*/
/*
* Table with 512 samples from a normal distribution with mean 1 and std 1
* The values are shifted up 13 steps (multiplied by 8192)
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_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,
6484, 2241, -8633, 792, 199, -3344, 6553, -10079,
-15040, 95, 11608, -12469, 14161, -4176, 2476, 6403,
13685, -16005, 6646, 2239, 10916, -3004, -602, -3141,
2142, 14144, -5829, 5305, 8209, 4713, 2697, -5112,
16092, -1210, -2891, -6631, -5360, -11878, -6781, -2739,
-6392, 536, 10923, 10872, 5059, -4748, -7770, 5477,
38, -1025, -2892, 1638, 6304, 14375, -11028, 1553,
-1565, 10762, -393, 4040, 5257, 12310, 6554, -4799,
4899, -6354, 1603, -1048, -2220, 8247, -186, -8944,
-12004, 2332, 4801, -4933, 6371, 131, 8614, -5927,
-8287, -22760, 4033, -15162, 3385, 3246, 3153, -5250,
3766, 784, 6494, -62, 3531, -1582, 15572, 662,
-3952, -330, -3196, 669, 7236, -2678, -6569, 23319,
-8645, -741, 14830, -15976, 4903, 315, -11342, 10311,
1858, -7777, 2145, 5436, 5677, -113, -10033, 826,
-1353, 17210, 7768, 986, -1471, 8291, -4982, 8207,
-14911, -6255, -2449, -11881, -7059, -11703, -4338, 8025,
7538, -2823, -12490, 9470, -1613, -2529, -10092, -7807,
9480, 6970, -12844, 5123, 3532, 4816, 4803, -8455,
-5045, 14032, -4378, -1643, 5756, -11041, -2732, -16618,
-6430, -18375, -3320, 6098, 5131, -4269, -8840, 2482,
-7048, 1547, -21890, -6505, -7414, -424, -11722, 7955,
1653, -17299, 1823, 473, -9232, 3337, 1111, 873,
4018, -8982, 9889, 3531, -11763, -3799, 7373, -4539,
3231, 7054, -8537, 7616, 6244, 16635, 447, -2915,
13967, 705, -2669, -1520, -1771, -16188, 5956, 5117,
6371, -9936, -1448, 2480, 5128, 7550, -8130, 5236,
8213, -6443, 7707, -1950, -13811, 7218, 7031, -3883,
67, 5731, -2874, 13480, -3743, 9298, -3280, 3552,
-4425, -18, -3785, -9988, -5357, 5477, -11794, 2117,
1416, -9935, 3376, 802, -5079, -8243, 12652, 66,
3653, -2368, 6781, -21895, -7227, 2487, 7839, -385,
6646, -7016, -4658, 5531, -1705, 834, 129, 3694,
-1343, 2238, -22640, -6417, -11139, 11301, -2945, -3494,
-5626, 185, -3615, -2041, -7972, -3106, -60, -23497,
-1566, 17064, 3519, 2518, 304, -6805, -10269, 2105,
1936, -426, -736, -8122, -1467, 4238, -6939, -13309,
360, 7402, -7970, 12576, 3287, 12194, -6289, -16006,
9171, 4042, -9193, 9123, -2512, 6388, -4734, -8739,
1028, -5406, -1696, 5889, -666, -4736, 4971, 3565,
9362, -6292, 3876, -3652, -19666, 7523, -4061, 391,
-11773, 7502, -3763, 4929, -9478, 13278, 2805, 4496,
7814, 16419, 12455, -14773, 2127, -2746, 3763, 4847,
3698, 6978, 4751, -6957, -3581, -45, 6252, 1513,
-4797, -7925, 11270, 16188, -2359, -5269, 9376, -10777,
7262, 20031, -6515, -2208, -5353, 8085, -1341, -1303,
7333, 5576, 3625, 5763, -7931, 9833, -3371, -10305,
6534, -13539, -9971, 997, 8464, -4064, -1495, 1857,
13624, 5458, 9490, -11086, -4524, 12022, -550, -198,
408, -8455, -7068, 10289, 9712, -3366, 9028, -7621,
-5243, 2362, 6909, 4672, -4933, -1799, 4709, -4563,
-62, -566, 1624, -7010, 14730, -17791, -3697, -2344,
-1741, 7099, -9509, -6855, -1989, 3495, -2289, 2031,
12784, 891, 14189, -3963, -5683, 421, -12575, 1724,
-12682, -5970, -8169, 3143, -1824, -5488, -5130, 8536,
12799, 794, 5738, 3459, -11689, -258, -3738, -3775,
-8742, 2333, 8312, -9383, 10331, 13119, 8398, 10644,
-19433, -6446, -16277, -11793, 16284, 9345, 15222, 15834,
2009, -7349, 130, -14547, 338, -5998, 3337, 21492,
2406, 7703, -951, 11196, -564, 3406, 2217, 4806,
2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492
};

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* 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;
}

View File

@ -0,0 +1,60 @@
/*
* 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_ReflCoefToLpc().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a)
{
WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
WebRtc_Word16 *aptr, *aptr2, *anyptr;
G_CONST WebRtc_Word16 *kptr;
int m, i;
kptr = k;
*a = 4096; // i.e., (Word16_MAX >> 3)+1.
*any = *a;
a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3);
for (m = 1; m < use_order; m++)
{
kptr++;
aptr = a;
aptr++;
aptr2 = &a[m];
anyptr = any;
anyptr++;
any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3);
for (i = 0; i < m; i++)
{
*anyptr = (*aptr)
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15);
anyptr++;
aptr++;
aptr2--;
}
aptr = a;
anyptr = any;
for (i = 0; i < (m + 2); i++)
{
*aptr = *anyptr;
aptr++;
anyptr++;
}
}
}

View File

@ -0,0 +1,505 @@
/*
* 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 resampling functions for 22 kHz.
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#include "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);
void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
const WebRtc_Word32 K);
// interpolation coefficients
static const WebRtc_Word16 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},
{-77, 457, -1677, 5958, 31175, -4136, 1405, -408, 71},
{ 98, -560, 1900, -5406, 29240, 9423, -2480, 663, -110}
};
//////////////////////
// 22 kHz -> 16 kHz //
//////////////////////
// number of subblocks; options: 1, 2, 4, 5, 10
#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)
{
int k;
// process two blocks of 10/SUB_BLOCKS_22_16 ms (to reduce temp buffer size)
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]
/////
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]
/////
// copy state to and from input array
tmpmem[8] = state->S_44_32[0];
tmpmem[9] = state->S_44_32[1];
tmpmem[10] = state->S_44_32[2];
tmpmem[11] = state->S_44_32[3];
tmpmem[12] = state->S_44_32[4];
tmpmem[13] = state->S_44_32[5];
tmpmem[14] = state->S_44_32[6];
tmpmem[15] = state->S_44_32[7];
state->S_44_32[0] = tmpmem[440 / SUB_BLOCKS_22_16 + 8];
state->S_44_32[1] = tmpmem[440 / SUB_BLOCKS_22_16 + 9];
state->S_44_32[2] = tmpmem[440 / SUB_BLOCKS_22_16 + 10];
state->S_44_32[3] = tmpmem[440 / SUB_BLOCKS_22_16 + 11];
state->S_44_32[4] = tmpmem[440 / SUB_BLOCKS_22_16 + 12];
state->S_44_32[5] = tmpmem[440 / SUB_BLOCKS_22_16 + 13];
state->S_44_32[6] = tmpmem[440 / SUB_BLOCKS_22_16 + 14];
state->S_44_32[7] = tmpmem[440 / SUB_BLOCKS_22_16 + 15];
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]
/////
WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16);
// move input/output pointers 10/SUB_BLOCKS_22_16 ms seconds ahead
in += 220 / SUB_BLOCKS_22_16;
out += 160 / SUB_BLOCKS_22_16;
}
}
// initialize state of 22 -> 16 resampler
void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state)
{
int k;
for (k = 0; k < 8; k++)
{
state->S_22_44[k] = 0;
state->S_44_32[k] = 0;
state->S_32_16[k] = 0;
}
}
//////////////////////
// 16 kHz -> 22 kHz //
//////////////////////
// number of subblocks; options: 1, 2, 4, 5, 10
#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)
{
int k;
// process two blocks of 10/SUB_BLOCKS_16_22 ms (to reduce temp buffer size)
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]
/////
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]
/////
// copy state to and from input array
tmpmem[0] = state->S_32_22[0];
tmpmem[1] = state->S_32_22[1];
tmpmem[2] = state->S_32_22[2];
tmpmem[3] = state->S_32_22[3];
tmpmem[4] = state->S_32_22[4];
tmpmem[5] = state->S_32_22[5];
tmpmem[6] = state->S_32_22[6];
tmpmem[7] = state->S_32_22[7];
state->S_32_22[0] = tmpmem[320 / SUB_BLOCKS_16_22];
state->S_32_22[1] = tmpmem[320 / SUB_BLOCKS_16_22 + 1];
state->S_32_22[2] = tmpmem[320 / SUB_BLOCKS_16_22 + 2];
state->S_32_22[3] = tmpmem[320 / SUB_BLOCKS_16_22 + 3];
state->S_32_22[4] = tmpmem[320 / SUB_BLOCKS_16_22 + 4];
state->S_32_22[5] = tmpmem[320 / SUB_BLOCKS_16_22 + 5];
state->S_32_22[6] = tmpmem[320 / SUB_BLOCKS_16_22 + 6];
state->S_32_22[7] = tmpmem[320 / SUB_BLOCKS_16_22 + 7];
WebRtcSpl_32khzTo22khzIntToShort(tmpmem, out, 20 / SUB_BLOCKS_16_22);
// move input/output pointers 10/SUB_BLOCKS_16_22 ms seconds ahead
in += 160 / SUB_BLOCKS_16_22;
out += 220 / SUB_BLOCKS_16_22;
}
}
// initialize state of 16 -> 22 resampler
void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state)
{
int k;
for (k = 0; k < 8; k++)
{
state->S_16_32[k] = 0;
state->S_32_22[k] = 0;
}
}
//////////////////////
// 22 kHz -> 8 kHz //
//////////////////////
// number of subblocks; options: 1, 2, 5, 10
#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)
{
int k;
// process two blocks of 10/SUB_BLOCKS_22_8 ms (to reduce temp buffer size)
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]
/////
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]
/////
// copy state to and from input array
tmpmem[8] = state->S_22_16[0];
tmpmem[9] = state->S_22_16[1];
tmpmem[10] = state->S_22_16[2];
tmpmem[11] = state->S_22_16[3];
tmpmem[12] = state->S_22_16[4];
tmpmem[13] = state->S_22_16[5];
tmpmem[14] = state->S_22_16[6];
tmpmem[15] = state->S_22_16[7];
state->S_22_16[0] = tmpmem[220 / SUB_BLOCKS_22_8 + 8];
state->S_22_16[1] = tmpmem[220 / SUB_BLOCKS_22_8 + 9];
state->S_22_16[2] = tmpmem[220 / SUB_BLOCKS_22_8 + 10];
state->S_22_16[3] = tmpmem[220 / SUB_BLOCKS_22_8 + 11];
state->S_22_16[4] = tmpmem[220 / SUB_BLOCKS_22_8 + 12];
state->S_22_16[5] = tmpmem[220 / SUB_BLOCKS_22_8 + 13];
state->S_22_16[6] = tmpmem[220 / SUB_BLOCKS_22_8 + 14];
state->S_22_16[7] = tmpmem[220 / SUB_BLOCKS_22_8 + 15];
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]
/////
WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8);
// move input/output pointers 10/SUB_BLOCKS_22_8 ms seconds ahead
in += 220 / SUB_BLOCKS_22_8;
out += 80 / SUB_BLOCKS_22_8;
}
}
// initialize state of 22 -> 8 resampler
void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state)
{
int k;
for (k = 0; k < 8; k++)
{
state->S_22_22[k] = 0;
state->S_22_22[k + 8] = 0;
state->S_22_16[k] = 0;
state->S_16_8[k] = 0;
}
}
//////////////////////
// 8 kHz -> 22 kHz //
//////////////////////
// number of subblocks; options: 1, 2, 5, 10
#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)
{
int k;
// process two blocks of 10/SUB_BLOCKS_8_22 ms (to reduce temp buffer size)
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]
/////
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]
/////
// copy state to and from input array
tmpmem[10] = state->S_16_11[0];
tmpmem[11] = state->S_16_11[1];
tmpmem[12] = state->S_16_11[2];
tmpmem[13] = state->S_16_11[3];
tmpmem[14] = state->S_16_11[4];
tmpmem[15] = state->S_16_11[5];
tmpmem[16] = state->S_16_11[6];
tmpmem[17] = state->S_16_11[7];
state->S_16_11[0] = tmpmem[160 / SUB_BLOCKS_8_22 + 10];
state->S_16_11[1] = tmpmem[160 / SUB_BLOCKS_8_22 + 11];
state->S_16_11[2] = tmpmem[160 / SUB_BLOCKS_8_22 + 12];
state->S_16_11[3] = tmpmem[160 / SUB_BLOCKS_8_22 + 13];
state->S_16_11[4] = tmpmem[160 / SUB_BLOCKS_8_22 + 14];
state->S_16_11[5] = tmpmem[160 / SUB_BLOCKS_8_22 + 15];
state->S_16_11[6] = tmpmem[160 / SUB_BLOCKS_8_22 + 16];
state->S_16_11[7] = tmpmem[160 / SUB_BLOCKS_8_22 + 17];
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]
/////
WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22);
// move input/output pointers 10/SUB_BLOCKS_8_22 ms seconds ahead
in += 80 / SUB_BLOCKS_8_22;
out += 220 / SUB_BLOCKS_8_22;
}
}
// initialize state of 8 -> 22 resampler
void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state)
{
int k;
for (k = 0; k < 8; k++)
{
state->S_8_16[k] = 0;
state->S_16_11[k] = 0;
state->S_11_22[k] = 0;
}
}
// 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)
{
WebRtc_Word32 tmp1 = 16384;
WebRtc_Word32 tmp2 = 16384;
WebRtc_Word16 coef;
coef = coef_ptr[0];
tmp1 += coef * in1[0];
tmp2 += coef * in2[-0];
coef = coef_ptr[1];
tmp1 += coef * in1[1];
tmp2 += coef * in2[-1];
coef = coef_ptr[2];
tmp1 += coef * in1[2];
tmp2 += coef * in2[-2];
coef = coef_ptr[3];
tmp1 += coef * in1[3];
tmp2 += coef * in2[-3];
coef = coef_ptr[4];
tmp1 += coef * in1[4];
tmp2 += coef * in2[-4];
coef = coef_ptr[5];
tmp1 += coef * in1[5];
tmp2 += coef * in2[-5];
coef = coef_ptr[6];
tmp1 += coef * in1[6];
tmp2 += coef * in2[-6];
coef = coef_ptr[7];
tmp1 += coef * in1[7];
tmp2 += coef * in2[-7];
coef = coef_ptr[8];
*out1 = tmp1 + coef * in1[8];
*out2 = tmp2 + coef * in2[-8];
}
// 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)
{
WebRtc_Word32 tmp1 = 16384;
WebRtc_Word32 tmp2 = 16384;
WebRtc_Word16 coef;
coef = coef_ptr[0];
tmp1 += coef * in1[0];
tmp2 += coef * in2[-0];
coef = coef_ptr[1];
tmp1 += coef * in1[1];
tmp2 += coef * in2[-1];
coef = coef_ptr[2];
tmp1 += coef * in1[2];
tmp2 += coef * in2[-2];
coef = coef_ptr[3];
tmp1 += coef * in1[3];
tmp2 += coef * in2[-3];
coef = coef_ptr[4];
tmp1 += coef * in1[4];
tmp2 += coef * in2[-4];
coef = coef_ptr[5];
tmp1 += coef * in1[5];
tmp2 += coef * in2[-5];
coef = coef_ptr[6];
tmp1 += coef * in1[6];
tmp2 += coef * in2[-6];
coef = coef_ptr[7];
tmp1 += coef * in1[7];
tmp2 += coef * in2[-7];
coef = coef_ptr[8];
tmp1 += coef * in1[8];
tmp2 += coef * in2[-8];
// scale down, round and saturate
tmp1 >>= 15;
if (tmp1 > (WebRtc_Word32)0x00007FFF)
tmp1 = 0x00007FFF;
if (tmp1 < (WebRtc_Word32)0xFFFF8000)
tmp1 = 0xFFFF8000;
tmp2 >>= 15;
if (tmp2 > (WebRtc_Word32)0x00007FFF)
tmp2 = 0x00007FFF;
if (tmp2 < (WebRtc_Word32)0xFFFF8000)
tmp2 = 0xFFFF8000;
*out1 = (WebRtc_Word16)tmp1;
*out2 = (WebRtc_Word16)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
// K: Number of blocks
void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In,
WebRtc_Word32* Out,
const WebRtc_Word32 K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (16 input samples -> 11 output samples);
// process in sub blocks of size 16 samples.
WebRtc_Word32 m;
for (m = 0; m < K; m++)
{
// first output sample
Out[0] = ((WebRtc_Word32)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]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToInt(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToInt(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToInt(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToInt(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]);
// update pointers
In += 16;
Out += 11;
}
}
// Resampling ratio: 11/16
// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K
// output: WebRtc_Word16 (saturated) :: size 11 * K
// K: Number of blocks
void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In,
WebRtc_Word16 *Out,
const WebRtc_Word32 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;
for (m = 0; m < K; m++)
{
// first output sample
tmp = In[3];
if (tmp > (WebRtc_Word32)0x00007FFF)
tmp = 0x00007FFF;
if (tmp < (WebRtc_Word32)0xFFFF8000)
tmp = 0xFFFF8000;
Out[0] = (WebRtc_Word16)tmp;
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToShort(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToShort(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToShort(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_DotProdIntToShort(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]);
// update pointers
In += 16;
Out += 11;
}
}

View File

@ -0,0 +1,186 @@
/*
* 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 resampling functions between 48 kHz and nb/wb.
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#include "signal_processing_library.h"
#include "resample_by_2_internal.h"
////////////////////////////
///// 48 kHz -> 16 kHz /////
////////////////////////////
// 48 -> 16 resampler
void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out,
WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem)
{
///// 48 --> 48(LP) /////
// WebRtc_Word16 in[480]
// WebRtc_Word32 out[480]
/////
WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48);
///// 48 --> 32 /////
// WebRtc_Word32 in[480]
// WebRtc_Word32 out[320]
/////
// copy state to and from input array
memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32));
memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32));
WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160);
///// 32 --> 16 /////
// WebRtc_Word32 in[320]
// WebRtc_Word16 out[160]
/////
WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16);
}
// initialize state of 48 -> 16 resampler
void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state)
{
memset(state->S_48_48, 0, 16 * sizeof(WebRtc_Word32));
memset(state->S_48_32, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_32_16, 0, 8 * sizeof(WebRtc_Word32));
}
////////////////////////////
///// 16 kHz -> 48 kHz /////
////////////////////////////
// 16 -> 48 resampler
void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,
WebRtcSpl_State16khzTo48khz* state, WebRtc_Word32* tmpmem)
{
///// 16 --> 32 /////
// WebRtc_Word16 in[160]
// WebRtc_Word32 out[320]
/////
WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32);
///// 32 --> 24 /////
// WebRtc_Word32 in[320]
// WebRtc_Word32 out[240]
// copy state to and from input array
/////
memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(WebRtc_Word32));
memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(WebRtc_Word32));
WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80);
///// 24 --> 48 /////
// WebRtc_Word32 in[240]
// WebRtc_Word16 out[480]
/////
WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
}
// initialize state of 16 -> 48 resampler
void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state)
{
memset(state->S_16_32, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_32_24, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32));
}
////////////////////////////
///// 48 kHz -> 8 kHz /////
////////////////////////////
// 48 -> 8 resampler
void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out,
WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem)
{
///// 48 --> 24 /////
// WebRtc_Word16 in[480]
// WebRtc_Word32 out[240]
/////
WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24);
///// 24 --> 24(LP) /////
// WebRtc_Word32 in[240]
// WebRtc_Word32 out[240]
/////
WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24);
///// 24 --> 16 /////
// WebRtc_Word32 in[240]
// WebRtc_Word32 out[160]
/////
// copy state to and from input array
memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32));
memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32));
WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80);
///// 16 --> 8 /////
// WebRtc_Word32 in[160]
// WebRtc_Word16 out[80]
/////
WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8);
}
// initialize state of 48 -> 8 resampler
void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state)
{
memset(state->S_48_24, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_24_24, 0, 16 * sizeof(WebRtc_Word32));
memset(state->S_24_16, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_16_8, 0, 8 * sizeof(WebRtc_Word32));
}
////////////////////////////
///// 8 kHz -> 48 kHz /////
////////////////////////////
// 8 -> 48 resampler
void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out,
WebRtcSpl_State8khzTo48khz* state, WebRtc_Word32* tmpmem)
{
///// 8 --> 16 /////
// WebRtc_Word16 in[80]
// WebRtc_Word32 out[160]
/////
WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16);
///// 16 --> 12 /////
// WebRtc_Word32 in[160]
// WebRtc_Word32 out[120]
/////
// copy state to and from input array
memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(WebRtc_Word32));
memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(WebRtc_Word32));
WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40);
///// 12 --> 24 /////
// WebRtc_Word32 in[120]
// WebRtc_Word16 out[240]
/////
WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24);
///// 24 --> 48 /////
// WebRtc_Word32 in[240]
// WebRtc_Word16 out[480]
/////
WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
}
// initialize state of 8 -> 48 resampler
void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state)
{
memset(state->S_8_16, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_16_12, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_12_24, 0, 8 * sizeof(WebRtc_Word32));
memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32));
}

View File

@ -0,0 +1,135 @@
/*
* 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 resampling by two functions.
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
// allpass filter coefficients.
static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528};
static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255};
// decimator
void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len,
WebRtc_Word16* out, WebRtc_Word32* filtState)
{
const WebRtc_Word16 *inptr;
WebRtc_Word16 *outptr;
WebRtc_Word32 *state;
WebRtc_Word32 tmp1, tmp2, diff, in32, out32;
WebRtc_Word16 i;
// local versions of pointers to input and output arrays
inptr = in; // input array
outptr = out; // output array (of length len/2)
state = filtState; // filter state array; length = 8
for (i = (len >> 1); i > 0; i--)
{
// lower allpass filter
in32 = (WebRtc_Word32)(*inptr++) << 10;
diff = in32 - state[1];
tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[0] );
state[0] = in32;
diff = tmp1 - state[2];
tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[1] );
state[1] = tmp1;
diff = tmp2 - state[3];
state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[2] );
state[2] = tmp2;
// upper allpass filter
in32 = (WebRtc_Word32)(*inptr++) << 10;
diff = in32 - state[5];
tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[4] );
state[4] = in32;
diff = tmp1 - state[6];
tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[5] );
state[5] = tmp1;
diff = tmp2 - state[7];
state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[6] );
state[6] = tmp2;
// add two allpass outputs, divide by two and round
out32 = (state[3] + state[7] + 1024) >> 11;
// limit amplitude to prevent wrap-around, and write to output array
if (out32 > 32767)
*outptr++ = 32767;
else if (out32 < -32768)
*outptr++ = -32768;
else
*outptr++ = (WebRtc_Word16)out32;
}
}
void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out,
WebRtc_Word32* filtState)
{
const WebRtc_Word16 *inptr;
WebRtc_Word16 *outptr;
WebRtc_Word32 *state;
WebRtc_Word32 tmp1, tmp2, diff, in32, out32;
WebRtc_Word16 i;
// local versions of pointers to input and output arrays
inptr = in; // input array
outptr = out; // output array (of length len*2)
state = filtState; // filter state array; length = 8
for (i = len; i > 0; i--)
{
// lower allpass filter
in32 = (WebRtc_Word32)(*inptr++) << 10;
diff = in32 - state[1];
tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[0] );
state[0] = in32;
diff = tmp1 - state[2];
tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[1] );
state[1] = tmp1;
diff = tmp2 - state[3];
state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[2] );
state[2] = tmp2;
// round; limit amplitude to prevent wrap-around; write to output array
out32 = (state[3] + 512) >> 10;
if (out32 > 32767)
*outptr++ = 32767;
else if (out32 < -32768)
*outptr++ = -32768;
else
*outptr++ = (WebRtc_Word16)out32;
// upper allpass filter
diff = in32 - state[5];
tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[4] );
state[4] = in32;
diff = tmp1 - state[6];
tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[5] );
state[5] = tmp1;
diff = tmp2 - state[7];
state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[6] );
state[6] = tmp2;
// round; limit amplitude to prevent wrap-around; write to output array
out32 = (state[7] + 512) >> 10;
if (out32 > 32767)
*outptr++ = 32767;
else if (out32 < -32768)
*outptr++ = -32768;
else
*outptr++ = (WebRtc_Word16)out32;
}
}

View File

@ -0,0 +1,679 @@
/*
* 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.
*
*/
#include "resample_by_2_internal.h"
// allpass filter coefficients.
static const WebRtc_Word16 kResampleAllpass[2][3] = {
{821, 6110, 12382},
{3050, 9368, 15063}
};
//
// decimator
// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
// output: WebRtc_Word16 (saturated) (of length len/2)
// state: filter state array; length = 8
void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
WebRtc_Word32 *state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
len >>= 1;
// lower allpass filter (operates on even input samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i << 1];
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// divide by two and store temporarily
in[i << 1] = (state[3] >> 1);
}
in++;
// upper allpass filter (operates on odd input samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i << 1];
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// divide by two and store temporarily
in[i << 1] = (state[7] >> 1);
}
in--;
// combine allpass outputs
for (i = 0; i < len; i += 2)
{
// divide by two, add both allpass outputs and round
tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
if (tmp0 > (WebRtc_Word32)0x00007FFF)
tmp0 = 0x00007FFF;
if (tmp0 < (WebRtc_Word32)0xFFFF8000)
tmp0 = 0xFFFF8000;
out[i] = (WebRtc_Word16)tmp0;
if (tmp1 > (WebRtc_Word32)0x00007FFF)
tmp1 = 0x00007FFF;
if (tmp1 < (WebRtc_Word32)0xFFFF8000)
tmp1 = 0xFFFF8000;
out[i + 1] = (WebRtc_Word16)tmp1;
}
}
//
// decimator
// input: WebRtc_Word16
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2)
// state: filter state array; length = 8
void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in,
WebRtc_Word32 len,
WebRtc_Word32 *out,
WebRtc_Word32 *state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
len >>= 1;
// lower allpass filter (operates on even input samples)
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// divide by two and store temporarily
out[i] = (state[3] >> 1);
}
in++;
// upper allpass filter (operates on odd input samples)
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// divide by two and store temporarily
out[i] += (state[7] >> 1);
}
in--;
}
//
// interpolator
// input: WebRtc_Word16
// output: WebRtc_Word32 (normalized, not saturated) (of length len*2)
// state: filter state array; length = 8
void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
WebRtc_Word32 *state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
// upper allpass filter (generates odd output samples)
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// scale down, round and store
out[i << 1] = state[7] >> 15;
}
out++;
// lower allpass filter (generates even output samples)
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// scale down, round and store
out[i << 1] = state[3] >> 15;
}
}
//
// interpolator
// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2)
// state: filter state array; length = 8
void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
WebRtc_Word32 *state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
// upper allpass filter (generates odd output samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i];
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// scale down, round and store
out[i << 1] = state[7];
}
out++;
// lower allpass filter (generates even output samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i];
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// scale down, round and store
out[i << 1] = state[3];
}
}
//
// interpolator
// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
// output: WebRtc_Word16 (saturated) (of length len*2)
// state: filter state array; length = 8
void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
WebRtc_Word32 *state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
// upper allpass filter (generates odd output samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i];
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// scale down, saturate and store
tmp1 = state[7] >> 15;
if (tmp1 > (WebRtc_Word32)0x00007FFF)
tmp1 = 0x00007FFF;
if (tmp1 < (WebRtc_Word32)0xFFFF8000)
tmp1 = 0xFFFF8000;
out[i << 1] = (WebRtc_Word16)tmp1;
}
out++;
// lower allpass filter (generates even output samples)
for (i = 0; i < len; i++)
{
tmp0 = in[i];
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// scale down, saturate and store
tmp1 = state[3] >> 15;
if (tmp1 > (WebRtc_Word32)0x00007FFF)
tmp1 = 0x00007FFF;
if (tmp1 < (WebRtc_Word32)0xFFFF8000)
tmp1 = 0xFFFF8000;
out[i << 1] = (WebRtc_Word16)tmp1;
}
}
// lowpass filter
// input: WebRtc_Word16
// output: WebRtc_Word32 (normalized, not saturated)
// state: filter state array; length = 8
void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out,
WebRtc_Word32* state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
len >>= 1;
// lower allpass filter: odd input -> even output samples
in++;
// initial state of polyphase delay element
tmp0 = state[12];
for (i = 0; i < len; i++)
{
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// scale down, round and store
out[i << 1] = state[3] >> 1;
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
}
in--;
// upper allpass filter: even input -> even output samples
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// average the two allpass outputs, scale down and store
out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
}
// switch to odd output samples
out++;
// lower allpass filter: even input -> odd output samples
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
diff = tmp0 - state[9];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[8] + diff * kResampleAllpass[1][0];
state[8] = tmp0;
diff = tmp1 - state[10];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[9] + diff * kResampleAllpass[1][1];
state[9] = tmp1;
diff = tmp0 - state[11];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[11] = state[10] + diff * kResampleAllpass[1][2];
state[10] = tmp0;
// scale down, round and store
out[i << 1] = state[11] >> 1;
}
// upper allpass filter: odd input -> odd output samples
in++;
for (i = 0; i < len; i++)
{
tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
diff = tmp0 - state[13];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[12] + diff * kResampleAllpass[0][0];
state[12] = tmp0;
diff = tmp1 - state[14];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[13] + diff * kResampleAllpass[0][1];
state[13] = tmp1;
diff = tmp0 - state[15];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[15] = state[14] + diff * kResampleAllpass[0][2];
state[14] = tmp0;
// average the two allpass outputs, scale down and store
out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
}
}
// lowpass filter
// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
// output: WebRtc_Word32 (normalized, not saturated)
// state: filter state array; length = 8
void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,
WebRtc_Word32* state)
{
WebRtc_Word32 tmp0, tmp1, diff;
WebRtc_Word32 i;
len >>= 1;
// lower allpass filter: odd input -> even output samples
in++;
// initial state of polyphase delay element
tmp0 = state[12];
for (i = 0; i < len; i++)
{
diff = tmp0 - state[1];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[0] + diff * kResampleAllpass[1][0];
state[0] = tmp0;
diff = tmp1 - state[2];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[1] + diff * kResampleAllpass[1][1];
state[1] = tmp1;
diff = tmp0 - state[3];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[3] = state[2] + diff * kResampleAllpass[1][2];
state[2] = tmp0;
// scale down, round and store
out[i << 1] = state[3] >> 1;
tmp0 = in[i << 1];
}
in--;
// upper allpass filter: even input -> even output samples
for (i = 0; i < len; i++)
{
tmp0 = in[i << 1];
diff = tmp0 - state[5];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[4] + diff * kResampleAllpass[0][0];
state[4] = tmp0;
diff = tmp1 - state[6];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[5] + diff * kResampleAllpass[0][1];
state[5] = tmp1;
diff = tmp0 - state[7];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[7] = state[6] + diff * kResampleAllpass[0][2];
state[6] = tmp0;
// average the two allpass outputs, scale down and store
out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
}
// switch to odd output samples
out++;
// lower allpass filter: even input -> odd output samples
for (i = 0; i < len; i++)
{
tmp0 = in[i << 1];
diff = tmp0 - state[9];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[8] + diff * kResampleAllpass[1][0];
state[8] = tmp0;
diff = tmp1 - state[10];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[9] + diff * kResampleAllpass[1][1];
state[9] = tmp1;
diff = tmp0 - state[11];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[11] = state[10] + diff * kResampleAllpass[1][2];
state[10] = tmp0;
// scale down, round and store
out[i << 1] = state[11] >> 1;
}
// upper allpass filter: odd input -> odd output samples
in++;
for (i = 0; i < len; i++)
{
tmp0 = in[i << 1];
diff = tmp0 - state[13];
// scale down and round
diff = (diff + (1 << 13)) >> 14;
tmp1 = state[12] + diff * kResampleAllpass[0][0];
state[12] = tmp0;
diff = tmp1 - state[14];
// scale down and round
diff = diff >> 14;
if (diff < 0)
diff += 1;
tmp0 = state[13] + diff * kResampleAllpass[0][1];
state[13] = tmp1;
diff = tmp0 - state[15];
// scale down and truncate
diff = diff >> 14;
if (diff < 0)
diff += 1;
state[15] = state[14] + diff * kResampleAllpass[0][2];
state[14] = tmp0;
// average the two allpass outputs, scale down and store
out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This header file contains some internal resampling functions.
*
*/
#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_
#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_
#include "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_

View File

@ -0,0 +1,242 @@
/*
* 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 resampling functions between 48, 44, 32 and 24 kHz.
* The description headers can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
// interpolation coefficients
static const WebRtc_Word16 kCoefficients48To32[2][8] = {
{778, -2050, 1087, 23285, 12903, -3783, 441, 222},
{222, 441, -3783, 12903, 23285, 1087, -2050, 778}
};
static const WebRtc_Word16 kCoefficients32To24[3][8] = {
{767, -2362, 2434, 24406, 10620, -3838, 721, 90},
{386, -381, -2646, 19062, 19062, -2646, -381, 386},
{90, 721, -3838, 10620, 24406, 2434, -2362, 767}
};
static const WebRtc_Word16 kCoefficients44To32[4][9] = {
{117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},
{-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},
{50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},
{-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}
};
// Resampling ratio: 2/3
// input: WebRtc_Word32 (normalized, not saturated) :: size 3 * K
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K
// K: number of blocks
void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
const WebRtc_Word32 K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (3 input samples -> 2 output samples);
// process in sub blocks of size 3 samples.
WebRtc_Word32 tmp;
WebRtc_Word32 m;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
tmp += kCoefficients48To32[0][0] * In[0];
tmp += kCoefficients48To32[0][1] * In[1];
tmp += kCoefficients48To32[0][2] * In[2];
tmp += kCoefficients48To32[0][3] * In[3];
tmp += kCoefficients48To32[0][4] * In[4];
tmp += kCoefficients48To32[0][5] * In[5];
tmp += kCoefficients48To32[0][6] * In[6];
tmp += kCoefficients48To32[0][7] * In[7];
Out[0] = tmp;
tmp = 1 << 14;
tmp += kCoefficients48To32[1][0] * In[1];
tmp += kCoefficients48To32[1][1] * In[2];
tmp += kCoefficients48To32[1][2] * In[3];
tmp += kCoefficients48To32[1][3] * In[4];
tmp += kCoefficients48To32[1][4] * In[5];
tmp += kCoefficients48To32[1][5] * In[6];
tmp += kCoefficients48To32[1][6] * In[7];
tmp += kCoefficients48To32[1][7] * In[8];
Out[1] = tmp;
// update pointers
In += 3;
Out += 2;
}
}
// Resampling ratio: 3/4
// input: WebRtc_Word32 (normalized, not saturated) :: size 4 * K
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K
// K: number of blocks
void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
const WebRtc_Word32 K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (4 input samples -> 3 output samples);
// process in sub blocks of size 4 samples.
WebRtc_Word32 m;
WebRtc_Word32 tmp;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
tmp += kCoefficients32To24[0][0] * In[0];
tmp += kCoefficients32To24[0][1] * In[1];
tmp += kCoefficients32To24[0][2] * In[2];
tmp += kCoefficients32To24[0][3] * In[3];
tmp += kCoefficients32To24[0][4] * In[4];
tmp += kCoefficients32To24[0][5] * In[5];
tmp += kCoefficients32To24[0][6] * In[6];
tmp += kCoefficients32To24[0][7] * In[7];
Out[0] = tmp;
tmp = 1 << 14;
tmp += kCoefficients32To24[1][0] * In[1];
tmp += kCoefficients32To24[1][1] * In[2];
tmp += kCoefficients32To24[1][2] * In[3];
tmp += kCoefficients32To24[1][3] * In[4];
tmp += kCoefficients32To24[1][4] * In[5];
tmp += kCoefficients32To24[1][5] * In[6];
tmp += kCoefficients32To24[1][6] * In[7];
tmp += kCoefficients32To24[1][7] * In[8];
Out[1] = tmp;
tmp = 1 << 14;
tmp += kCoefficients32To24[2][0] * In[2];
tmp += kCoefficients32To24[2][1] * In[3];
tmp += kCoefficients32To24[2][2] * In[4];
tmp += kCoefficients32To24[2][3] * In[5];
tmp += kCoefficients32To24[2][4] * In[6];
tmp += kCoefficients32To24[2][5] * In[7];
tmp += kCoefficients32To24[2][6] * In[8];
tmp += kCoefficients32To24[2][7] * In[9];
Out[2] = tmp;
// update pointers
In += 4;
Out += 3;
}
}
//
// fractional resampling filters
// Fout = 11/16 * Fin
// Fout = 8/11 * Fin
//
// compute two inner-products and store them to output array
static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2,
const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1,
WebRtc_Word32 *out2)
{
WebRtc_Word32 tmp1 = 16384;
WebRtc_Word32 tmp2 = 16384;
WebRtc_Word16 coef;
coef = coef_ptr[0];
tmp1 += coef * in1[0];
tmp2 += coef * in2[-0];
coef = coef_ptr[1];
tmp1 += coef * in1[1];
tmp2 += coef * in2[-1];
coef = coef_ptr[2];
tmp1 += coef * in1[2];
tmp2 += coef * in2[-2];
coef = coef_ptr[3];
tmp1 += coef * in1[3];
tmp2 += coef * in2[-3];
coef = coef_ptr[4];
tmp1 += coef * in1[4];
tmp2 += coef * in2[-4];
coef = coef_ptr[5];
tmp1 += coef * in1[5];
tmp2 += coef * in2[-5];
coef = coef_ptr[6];
tmp1 += coef * in1[6];
tmp2 += coef * in2[-6];
coef = coef_ptr[7];
tmp1 += coef * in1[7];
tmp2 += coef * in2[-7];
coef = coef_ptr[8];
*out1 = tmp1 + coef * in1[8];
*out2 = tmp2 + coef * in2[-8];
}
// Resampling ratio: 8/11
// input: WebRtc_Word32 (normalized, not saturated) :: size 11 * K
// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 8 * K
// K: number of blocks
void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out,
const WebRtc_Word32 K)
{
/////////////////////////////////////////////////////////////
// Filter operation:
//
// Perform resampling (11 input samples -> 8 output samples);
// process in sub blocks of size 11 samples.
WebRtc_Word32 tmp;
WebRtc_Word32 m;
for (m = 0; m < K; m++)
{
tmp = 1 << 14;
// first output sample
Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp;
// sum and accumulate filter coefficients and input samples
tmp += kCoefficients44To32[3][0] * In[5];
tmp += kCoefficients44To32[3][1] * In[6];
tmp += kCoefficients44To32[3][2] * In[7];
tmp += kCoefficients44To32[3][3] * In[8];
tmp += kCoefficients44To32[3][4] * In[9];
tmp += kCoefficients44To32[3][5] * In[10];
tmp += kCoefficients44To32[3][6] * In[11];
tmp += kCoefficients44To32[3][7] * In[12];
tmp += kCoefficients44To32[3][8] * In[13];
Out[4] = tmp;
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
// sum and accumulate filter coefficients and input samples
WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
// update pointers
In += 11;
Out += 8;
}
}

View File

@ -0,0 +1,60 @@
/*
* 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
};

View File

@ -0,0 +1,150 @@
/*
* 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,
};

View File

@ -0,0 +1,83 @@
# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
{
'includes': [
'../../../../common_settings.gypi', # Common settings
],
'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',
'add_sat_w16.c',
'add_sat_w32.c',
'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',
'get_size_in_bits.c',
'hanning_table.c',
'ilbc_specific_functions.c',
'levinson_durbin.c',
'lpc_to_refl_coef.c',
'min_max_operations.c',
'norm_u32.c',
'norm_w16.c',
'norm_w32.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_version.c',
'splitting_filter.c',
'sqrt_of_one_minus_x_squared.c',
'sub_sat_w16.c',
'sub_sat_w32.c',
'vector_scaling_operations.c',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,38 @@
/*
* 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_Sqrt().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#define iter1(N) \
try1 = root + (1 << (N)); \
if (value >= try1 << (N)) \
{ \
value -= try1 << (N); \
root |= 2 << (N); \
}
// (out) Square root of input parameter
WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value) {
// new routine for performance, 4 cycles/bit in ARM
// output precision is 16 bits
WebRtc_Word32 root = 0, try1;
iter1 (15); iter1 (14); iter1 (13); iter1 (12);
iter1 (11); iter1 (10); iter1 ( 9); iter1 ( 8);
iter1 ( 7); iter1 ( 6); iter1 ( 5); iter1 ( 4);
iter1 ( 3); iter1 ( 2); iter1 ( 1); iter1 ( 0);
return root >> 1;
}

View File

@ -0,0 +1,93 @@
@
@ 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.
@ sqrt() routine. 3 cycles/bit, total 51 cycles.
@ IN : r0 32 bit unsigned integer
@ OUT: r0 = INT (SQRT (r0)), precision is 16 bits
@ TMP: r1, r2
.global WebRtcSpl_Sqrt
.align 2
.section .text.WebRtcSpl_Sqrt:
WebRtcSpl_Sqrt:
.fnstart
MOV r1, #3 << 30
MOV r2, #1 << 30
@ unroll for i = 0 .. 15
CMP r0, r2, ROR #2 * 0
SUBHS r0, r0, r2, ROR #2 * 0
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 1
SUBHS r0, r0, r2, ROR #2 * 1
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 2
SUBHS r0, r0, r2, ROR #2 * 2
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 3
SUBHS r0, r0, r2, ROR #2 * 3
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 4
SUBHS r0, r0, r2, ROR #2 * 4
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 5
SUBHS r0, r0, r2, ROR #2 * 5
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 6
SUBHS r0, r0, r2, ROR #2 * 6
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 7
SUBHS r0, r0, r2, ROR #2 * 7
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 8
SUBHS r0, r0, r2, ROR #2 * 8
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 9
SUBHS r0, r0, r2, ROR #2 * 9
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 10
SUBHS r0, r0, r2, ROR #2 * 10
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 11
SUBHS r0, r0, r2, ROR #2 * 11
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 12
SUBHS r0, r0, r2, ROR #2 * 12
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 13
SUBHS r0, r0, r2, ROR #2 * 13
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 14
SUBHS r0, r0, r2, ROR #2 * 14
ADC r2, r1, r2, LSL #1
CMP r0, r2, ROR #2 * 15
SUBHS r0, r0, r2, ROR #2 * 15
ADC r2, r1, r2, LSL #1
BIC r0, r2, #3 << 30 @ for rounding add: CMP r0, r2 ADC r2, #1
.fnend

View File

@ -0,0 +1,25 @@
/*
* 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;
}

View File

@ -0,0 +1,200 @@
/*
* 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 splitting filter functions.
*
*/
#include "signal_processing_library.h"
// Number of samples in a low/high-band frame.
enum
{
kBandFrameLength = 160
};
// QMF filter coefficients in Q16.
static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261};
static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010};
///////////////////////////////////////////////////////////////////////////////////////////////
// WebRtcSpl_AllPassQMF(...)
//
// Allpass filter used by the analysis and synthesis parts of the QMF filter.
//
// Input:
// - in_data : Input data sequence (Q10)
// - data_length : Length of data sequence (>2)
// - filter_coefficients : Filter coefficients (length 3, Q16)
//
// Input & Output:
// - filter_state : Filter state (length 6, Q10).
//
// Output:
// - out_data : Output data sequence (Q10), length equal to
// |data_length|
//
void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length,
WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients,
WebRtc_Word32* filter_state)
{
// The procedure is to filter the input with three first order all pass filters
// (cascade operations).
//
// a_3 + q^-1 a_2 + q^-1 a_1 + q^-1
// y[n] = ----------- ----------- ----------- x[n]
// 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1
//
// The input vector |filter_coefficients| includes these three filter coefficients.
// The filter state contains the in_data state, in_data[-1], followed by
// the out_data state, out_data[-1]. This is repeated for each cascade.
// The first cascade filter will filter the |in_data| and store the output in
// |out_data|. The second will the take the |out_data| as input and make an
// intermediate storage in |in_data|, to save memory. The third, and final, cascade
// filter operation takes the |in_data| (which is the output from the previous cascade
// filter) and store the output in |out_data|.
// Note that the input vector values are changed during the process.
WebRtc_Word16 k;
WebRtc_Word32 diff;
// First all-pass cascade; filter from in_data to out_data.
// Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at
// vector position n. Then the final output will be y[n] = y_3[n]
// First loop, use the states stored in memory.
// "diff" should be safe from wrap around since max values are 2^25
diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1])
// y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1])
out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]);
// For the remaining loops, use previous values.
for (k = 1; k < data_length; k++)
{
diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1])
// y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1])
out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]);
}
// Update states.
filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time
filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
// Second all-pass cascade; filter from out_data to in_data.
diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1])
// y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1])
in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]);
for (k = 1; k < data_length; k++)
{
diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1])
// y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1])
in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]);
}
filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
// Third all-pass cascade; filter from in_data to out_data.
diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1])
// y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1])
out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]);
for (k = 1; k < data_length; k++)
{
diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1])
// y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1])
out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]);
}
filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time
}
void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band,
WebRtc_Word16* high_band, WebRtc_Word32* filter_state1,
WebRtc_Word32* filter_state2)
{
WebRtc_Word16 i;
WebRtc_Word16 k;
WebRtc_Word32 tmp;
WebRtc_Word32 half_in1[kBandFrameLength];
WebRtc_Word32 half_in2[kBandFrameLength];
WebRtc_Word32 filter1[kBandFrameLength];
WebRtc_Word32 filter2[kBandFrameLength];
// Split even and odd samples. Also shift them to Q10.
for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2)
{
half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10);
half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10);
}
// All pass filter even and odd samples, independently.
WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1,
filter_state1);
WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2,
filter_state2);
// Take the sum and difference of filtered version of odd and even
// branches to get upper & lower band.
for (i = 0; i < kBandFrameLength; i++)
{
tmp = filter1[i] + filter2[i] + 1024;
tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
low_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX,
tmp, WEBRTC_SPL_WORD16_MIN);
tmp = filter1[i] - filter2[i] + 1024;
tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
high_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX,
tmp, WEBRTC_SPL_WORD16_MIN);
}
}
void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band,
WebRtc_Word16* out_data, WebRtc_Word32* filter_state1,
WebRtc_Word32* filter_state2)
{
WebRtc_Word32 tmp;
WebRtc_Word32 half_in1[kBandFrameLength];
WebRtc_Word32 half_in2[kBandFrameLength];
WebRtc_Word32 filter1[kBandFrameLength];
WebRtc_Word32 filter2[kBandFrameLength];
WebRtc_Word16 i;
WebRtc_Word16 k;
// Obtain the sum and difference channels out of upper and lower-band channels.
// Also shift to Q10 domain.
for (i = 0; i < kBandFrameLength; i++)
{
tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i];
half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);
tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i];
half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10);
}
// all-pass filter the sum and difference channels
WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2,
filter_state1);
WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1,
filter_state2);
// The filtered signals are even and odd samples of the output. Combine
// them. The signals are Q10 should shift them back to Q0 and take care of
// saturation.
for (i = 0, k = 0; i < kBandFrameLength; i++)
{
tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10);
out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768);
tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10);
out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768);
}
}

View File

@ -0,0 +1,35 @@
/*
* 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_SqrtOfOneMinusXSquared().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16 *xQ15, int vector_length,
WebRtc_Word16 *yQ15)
{
WebRtc_Word32 sq;
int m;
WebRtc_Word16 tmp;
for (m = 0; m < vector_length; m++)
{
tmp = xQ15[m];
sq = WEBRTC_SPL_MUL_16_16(tmp, tmp); // x^2 in Q30
sq = 1073741823 - sq; // 1-x^2, where 1 ~= 0.99999999906 is 1073741823 in Q30
sq = WebRtcSpl_Sqrt(sq); // sqrt(1-x^2) in Q15
yQ15[m] = (WebRtc_Word16)sq;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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_SubSatW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2)
{
WebRtc_Word32 l_diff;
WebRtc_Word16 s_diff;
// perform subtraction
l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2;
// default setting
s_diff = (WebRtc_Word16)l_diff;
// check for overflow
if (l_diff > (WebRtc_Word32)32767)
s_diff = (WebRtc_Word16)32767;
// check for underflow
if (l_diff < (WebRtc_Word32)-32768)
s_diff = (WebRtc_Word16)-32768;
return s_diff;
}
#else
#pragma message(">> WebRtcSpl_SubSatW16.c is excluded from this build")
#endif // XSCALE_OPT
#endif // SPL_NO_DOUBLE_IMPLEMENTATIONS

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the function WebRtcSpl_SubSatW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2)
{
WebRtc_Word32 l_diff;
// perform subtraction
l_diff = var1 - var2;
// check for underflow
if ((var1 < 0) && (var2 > 0) && (l_diff > 0))
l_diff = (WebRtc_Word32)0x80000000;
// check for overflow
if ((var1 > 0) && (var2 < 0) && (l_diff < 0))
l_diff = (WebRtc_Word32)0x7FFFFFFF;
return l_diff;
}
#endif

View File

@ -0,0 +1,151 @@
/*
* 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++) = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768);
}
}
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);
}
}

View File

@ -0,0 +1,227 @@
.globl FFT_4OFQ14
FFT_4OFQ14:
stmdb sp!, {r4 - r11, lr}
ldr lr, =s_Q14S_8
ldr lr, [lr]
cmp r2, lr
movgt r0, #1
ldmgtia sp!, {r4 - r11, pc}
stmdb sp!, {r1, r2}
mov r3, #0
mov r2, r2
LBL1:
add r12, r0, r3, lsl #2
add r12, r12, r2, lsr #1
ldrsh r5, [r12, #2]
ldrsh r4, [r12], +r2
ldrsh r9, [r12, #2]
ldrsh r8, [r12], +r2
ldrsh r7, [r12, #2]
ldrsh r6, [r12], +r2
ldrsh r11, [r12, #2]
ldrsh r10, [r12], +r2
add r4, r4, r6
add r5, r5, r7
sub r6, r4, r6, lsl #1
sub r7, r5, r7, lsl #1
sub r12, r8, r10
sub lr, r9, r11
add r10, r8, r10
add r11, r9, r11
sub r9, r4, r10
sub r8, r5, r11
add r4, r4, r10
add r5, r5, r11
sub r10, r6, lr
add r11, r7, r12
add r6, r6, lr
sub r7, r7, r12
ldr lr, =t_Q14R_rad8
ldrsh lr, [lr]
stmdb sp!, {r2}
add r12, r6, r7
mul r6, r12, lr
rsb r12, r12, r7, lsl #1
mul r7, r12, lr
sub r12, r11, r10
mul r10, r12, lr
sub r12, r12, r11, lsl #1
mul r11, r12, lr
ldmia sp!, {r2}
stmdb sp!, {r4 - r11}
add r4, r0, r3, lsl #2
ldrsh r7, [r4, #2]
ldrsh r6, [r4], +r2
ldrsh r11, [r4, #2]
ldrsh r10, [r4], +r2
ldrsh r9, [r4, #2]
ldrsh r8, [r4], +r2
ldrsh lr, [r4, #2]
ldrsh r12, [r4], +r2
mov r7, r7, asr #3
mov r6, r6, asr #3
add r6, r6, r8, asr #3
add r7, r7, r9, asr #3
sub r8, r6, r8, asr #2
sub r9, r7, r9, asr #2
sub r4, r10, r12
sub r5, r11, lr
add r10, r10, r12
add r11, r11, lr
add r6, r6, r10, asr #3
add r7, r7, r11, asr #3
sub r10, r6, r10, asr #2
sub r11, r7, r11, asr #2
sub r12, r8, r5, asr #3
add lr, r9, r4, asr #3
add r8, r8, r5, asr #3
sub r9, r9, r4, asr #3
ldmia sp!, {r4, r5}
add r6, r6, r4, asr #3
add r7, r7, r5, asr #3
sub r4, r6, r4, asr #2
sub r5, r7, r5, asr #2
strh r7, [r1, #2]
strh r6, [r1], #4
ldmia sp!, {r6, r7}
add r8, r8, r6, asr #17
add r9, r9, r7, asr #17
sub r6, r8, r6, asr #16
sub r7, r9, r7, asr #16
strh r9, [r1, #2]
strh r8, [r1], #4
ldmia sp!, {r8, r9}
add r10, r10, r8, asr #3
sub r11, r11, r9, asr #3
sub r8, r10, r8, asr #2
add r9, r11, r9, asr #2
strh r11, [r1, #2]
strh r10, [r1], #4
ldmia sp!, {r10, r11}
add r12, r12, r10, asr #17
add lr, lr, r11, asr #17
sub r10, r12, r10, asr #16
sub r11, lr, r11, asr #16
strh lr, [r1, #2]
strh r12, [r1], #4
strh r5, [r1, #2]
strh r4, [r1], #4
strh r7, [r1, #2]
strh r6, [r1], #4
strh r9, [r1, #2]
strh r8, [r1], #4
strh r11, [r1, #2]
strh r10, [r1], #4
eor r3, r3, r2, lsr #4
tst r3, r2, lsr #4
bne LBL1
eor r3, r3, r2, lsr #5
tst r3, r2, lsr #5
bne LBL1
mov r12, r2, lsr #6
LBL2:
eor r3, r3, r12
tst r3, r12
bne LBL1
movs r12, r12, lsr #1
bne LBL2
ldmia sp!, {r1, r2}
mov r3, r2, lsr #3
mov r2, #0x20
ldr r0, =t_Q14S_8
cmp r3, #1
beq LBL3
LBL6:
mov r3, r3, lsr #2
stmdb sp!, {r1, r3}
add r12, r2, r2, lsl #1
add r1, r1, r12
sub r3, r3, #1, 16
LBL5:
add r3, r3, r2, lsl #14
LBL4:
ldrsh r6, [r0], #2
ldrsh r7, [r0], #2
ldrsh r8, [r0], #2
ldrsh r9, [r0], #2
ldrsh r10, [r0], #2
ldrsh r11, [r0], #2
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r5, r4
mul r12, lr, r11
add lr, r10, r11, lsl #1
mla r11, r5, r10, r12
mla r10, r4, lr, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r5, r4
mul r12, lr, r9
add lr, r8, r9, lsl #1
mla r9, r5, r8, r12
mla r8, r4, lr, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r5, r4
mul r12, lr, r7
add lr, r6, r7, lsl #1
mla r7, r5, r6, r12
mla r6, r4, lr, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1]
mov r5, r5, asr #2
mov r4, r4, asr #2
add r12, r4, r6, asr #16
add lr, r5, r7, asr #16
sub r4, r4, r6, asr #16
sub r5, r5, r7, asr #16
add r6, r8, r10
add r7, r9, r11
sub r8, r8, r10
sub r9, r9, r11
add r10, r12, r6, asr #16
add r11, lr, r7, asr #16
strh r11, [r1, #2]
strh r10, [r1], +r2
add r10, r4, r9, asr #16
sub r11, r5, r8, asr #16
strh r11, [r1, #2]
strh r10, [r1], +r2
sub r10, r12, r6, asr #16
sub r11, lr, r7, asr #16
strh r11, [r1, #2]
strh r10, [r1], +r2
sub r10, r4, r9, asr #16
add r11, r5, r8, asr #16
strh r11, [r1, #2]
strh r10, [r1], #4
subs r3, r3, #1, 16
bge LBL4
add r12, r2, r2, lsl #1
add r1, r1, r12
sub r0, r0, r12
sub r3, r3, #1
movs lr, r3, lsl #16
bne LBL5
add r0, r0, r12
ldmia sp!, {r1, r3}
mov r2, r2, lsl #2
cmp r3, #2
bgt LBL6
LBL3:
mov r0, #0
ldmia sp!, {r4 - r11, pc}
andeq r3, r1, r0, lsr #32
andeq r10, r1, r12, ror #31
andeq r3, r1, r8, lsr #32

View File

@ -0,0 +1,221 @@
.globl FFT_4OIQ14
FFT_4OIQ14:
stmdb sp!, {r4 - r11, lr}
ldr lr, =s_Q14S_8
ldr lr, [lr]
cmp r2, lr
movgt r0, #1
ldmgtia sp!, {r4 - r11, pc}
stmdb sp!, {r1, r2}
mov r3, #0
mov r2, r2
LBL1:
add r12, r0, r3, lsl #2
add r12, r12, r2, lsr #1
ldrsh r5, [r12, #2]
ldrsh r4, [r12], +r2
ldrsh r9, [r12, #2]
ldrsh r8, [r12], +r2
ldrsh r7, [r12, #2]
ldrsh r6, [r12], +r2
ldrsh r11, [r12, #2]
ldrsh r10, [r12], +r2
add r4, r4, r6
add r5, r5, r7
sub r6, r4, r6, lsl #1
sub r7, r5, r7, lsl #1
sub r12, r8, r10
sub lr, r9, r11
add r10, r8, r10
add r11, r9, r11
sub r9, r4, r10
sub r8, r5, r11
add r4, r4, r10
add r5, r5, r11
add r10, r6, lr
sub r11, r7, r12
sub r6, r6, lr
add r7, r7, r12
ldr lr, =t_Q14R_rad8
ldrsh lr, [lr]
stmdb sp!, {r2}
sub r12, r6, r7
mul r6, r12, lr
add r12, r12, r7, lsl #1
mul r7, r12, lr
sub r12, r10, r11
mul r11, r12, lr
sub r12, r12, r10, lsl #1
mul r10, r12, lr
ldmia sp!, {r2}
stmdb sp!, {r4 - r11}
add r4, r0, r3, lsl #2
ldrsh r7, [r4, #2]
ldrsh r6, [r4], +r2
ldrsh r11, [r4, #2]
ldrsh r10, [r4], +r2
ldrsh r9, [r4, #2]
ldrsh r8, [r4], +r2
ldrsh lr, [r4, #2]
ldrsh r12, [r4], +r2
add r6, r6, r8
add r7, r7, r9
sub r8, r6, r8, lsl #1
sub r9, r7, r9, lsl #1
sub r4, r10, r12
sub r5, r11, lr
add r10, r10, r12
add r11, r11, lr
add r6, r6, r10
add r7, r7, r11
sub r10, r6, r10, lsl #1
sub r11, r7, r11, lsl #1
add r12, r8, r5
sub lr, r9, r4
sub r8, r8, r5
add r9, r9, r4
ldmia sp!, {r4, r5}
add r6, r6, r4
add r7, r7, r5
sub r4, r6, r4, lsl #1
sub r5, r7, r5, lsl #1
strh r7, [r1, #2]
strh r6, [r1], #4
ldmia sp!, {r6, r7}
add r8, r8, r6, asr #14
add r9, r9, r7, asr #14
sub r6, r8, r6, asr #13
sub r7, r9, r7, asr #13
strh r9, [r1, #2]
strh r8, [r1], #4
ldmia sp!, {r8, r9}
sub r10, r10, r8
add r11, r11, r9
add r8, r10, r8, lsl #1
sub r9, r11, r9, lsl #1
strh r11, [r1, #2]
strh r10, [r1], #4
ldmia sp!, {r10, r11}
add r12, r12, r10, asr #14
add lr, lr, r11, asr #14
sub r10, r12, r10, asr #13
sub r11, lr, r11, asr #13
strh lr, [r1, #2]
strh r12, [r1], #4
strh r5, [r1, #2]
strh r4, [r1], #4
strh r7, [r1, #2]
strh r6, [r1], #4
strh r9, [r1, #2]
strh r8, [r1], #4
strh r11, [r1, #2]
strh r10, [r1], #4
eor r3, r3, r2, lsr #4
tst r3, r2, lsr #4
bne LBL1
eor r3, r3, r2, lsr #5
tst r3, r2, lsr #5
bne LBL1
mov r12, r2, lsr #6
LBL2:
eor r3, r3, r12
tst r3, r12
bne LBL1
movs r12, r12, lsr #1
bne LBL2
ldmia sp!, {r1, r2}
mov r3, r2, lsr #3
mov r2, #0x20
ldr r0, =t_Q14S_8
cmp r3, #1
beq LBL3
LBL6:
mov r3, r3, lsr #2
stmdb sp!, {r1, r3}
add r12, r2, r2, lsl #1
add r1, r1, r12
sub r3, r3, #1, 16
LBL5:
add r3, r3, r2, lsl #14
LBL4:
ldrsh r6, [r0], #2
ldrsh r7, [r0], #2
ldrsh r8, [r0], #2
ldrsh r9, [r0], #2
ldrsh r10, [r0], #2
ldrsh r11, [r0], #2
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r4, r5
mul r12, lr, r11
add r11, r10, r11, lsl #1
mla r10, r4, r10, r12
mla r11, r5, r11, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r4, r5
mul r12, lr, r9
add r9, r8, r9, lsl #1
mla r8, r4, r8, r12
mla r9, r5, r9, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1], -r2
sub lr, r4, r5
mul r12, lr, r7
add r7, r6, r7, lsl #1
mla r6, r4, r6, r12
mla r7, r5, r7, r12
ldrsh r5, [r1, #2]
ldrsh r4, [r1]
add r12, r4, r6, asr #14
add lr, r5, r7, asr #14
sub r4, r4, r6, asr #14
sub r5, r5, r7, asr #14
add r6, r8, r10
add r7, r9, r11
sub r8, r8, r10
sub r9, r9, r11
add r10, r12, r6, asr #14
add r11, lr, r7, asr #14
strh r11, [r1, #2]
strh r10, [r1], +r2
sub r10, r4, r9, asr #14
add r11, r5, r8, asr #14
strh r11, [r1, #2]
strh r10, [r1], +r2
sub r10, r12, r6, asr #14
sub r11, lr, r7, asr #14
strh r11, [r1, #2]
strh r10, [r1], +r2
add r10, r4, r9, asr #14
sub r11, r5, r8, asr #14
strh r11, [r1, #2]
strh r10, [r1], #4
subs r3, r3, #1, 16
bge LBL4
add r12, r2, r2, lsl #1
add r1, r1, r12
sub r0, r0, r12
sub r3, r3, #1
movs lr, r3, lsl #16
bne LBL5
add r0, r0, r12
ldmia sp!, {r1, r3}
mov r2, r2, lsl #2
cmp r3, #2
bgt LBL6
LBL3:
mov r0, #0
ldmia sp!, {r4 - r11, pc}
andeq r3, r1, r0, lsr #32
andeq r10, r1, r12, ror #31
andeq r3, r1, r8, lsr #32

View File

@ -0,0 +1,704 @@
/*
* 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 };

View File

@ -0,0 +1,27 @@
/*
* 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 };

View File

@ -0,0 +1,478 @@
/*
* 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 = (char*) malloc(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(-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) {
int B[] = {4, 12, 133, 1100};
int Bs[] = {2, 6, 66, 550};
WebRtc_UWord8* b8 = (WebRtc_UWord8*) malloc(4);
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* b32 = (WebRtc_Word32*) malloc(4);
WebRtc_UWord8* bTmp8 = (WebRtc_UWord8*) malloc(4);
WebRtc_Word16* bTmp16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* bTmp32 = (WebRtc_Word32*) malloc(4);
WebRtcSpl_MemSetW16(b16, 3, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(3, b16[kk]);
}
EXPECT_EQ(4, WebRtcSpl_ZerosArrayW16(b16, 4));
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(0, b16[kk]);
}
EXPECT_EQ(4, WebRtcSpl_OnesArrayW16(b16, 4));
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(1, b16[kk]);
}
WebRtcSpl_MemSetW32(b32, 3, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(3, b32[kk]);
}
EXPECT_EQ(4, WebRtcSpl_ZerosArrayW32(b32, 4));
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(0, b32[kk]);
}
EXPECT_EQ(4, WebRtcSpl_OnesArrayW32(b32, 4));
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(1, b32[kk]);
}
for (int kk = 0; kk < 4; ++kk) {
bTmp8[kk] = (WebRtc_Word8)kk;
bTmp16[kk] = (WebRtc_Word16)kk;
bTmp32[kk] = (WebRtc_Word32)kk;
}
WEBRTC_SPL_MEMCPY_W8(b8, bTmp8, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(b8[kk], bTmp8[kk]);
}
WEBRTC_SPL_MEMCPY_W16(b16, bTmp16, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(b16[kk], bTmp16[kk]);
}
// WEBRTC_SPL_MEMCPY_W32(b32, bTmp32, 4);
// for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(b32[kk], bTmp32[kk]);
// }
EXPECT_EQ(2, WebRtcSpl_CopyFromEndW16(b16, 4, 2, bTmp16));
for (int kk = 0; kk < 2; ++kk) {
EXPECT_EQ(kk+2, bTmp16[kk]);
}
for (int kk = 0; kk < 4; ++kk) {
b32[kk] = B[kk];
b16[kk] = (WebRtc_Word16)B[kk];
}
WebRtcSpl_VectorBitShiftW32ToW16(bTmp16, 4, b32, 1);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
}
WebRtcSpl_VectorBitShiftW16(bTmp16, 4, b16, 1);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((B[kk]>>1), bTmp16[kk]);
}
WebRtcSpl_VectorBitShiftW32(bTmp32, 4, b32, 1);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((B[kk]>>1), bTmp32[kk]);
}
WebRtcSpl_MemCpyReversedOrder(&bTmp16[3], b16, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(b16[3-kk], bTmp16[kk]);
}
}
TEST_F(SplTest, MinMaxOperationsTest) {
int B[] = {4, 12, 133, -1100};
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* b32 = (WebRtc_Word32*) malloc(4);
for (int kk = 0; kk < 4; ++kk) {
b16[kk] = B[kk];
b32[kk] = B[kk];
}
EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW16(b16, 4));
EXPECT_EQ(1100, WebRtcSpl_MaxAbsValueW32(b32, 4));
EXPECT_EQ(133, WebRtcSpl_MaxValueW16(b16, 4));
EXPECT_EQ(133, WebRtcSpl_MaxValueW32(b32, 4));
EXPECT_EQ(3, WebRtcSpl_MaxAbsIndexW16(b16, 4));
EXPECT_EQ(2, WebRtcSpl_MaxIndexW16(b16, 4));
EXPECT_EQ(2, WebRtcSpl_MaxIndexW32(b32, 4));
EXPECT_EQ(-1100, WebRtcSpl_MinValueW16(b16, 4));
EXPECT_EQ(-1100, WebRtcSpl_MinValueW32(b32, 4));
EXPECT_EQ(3, WebRtcSpl_MinIndexW16(b16, 4));
EXPECT_EQ(3, WebRtcSpl_MinIndexW32(b32, 4));
EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, 4, 1));
}
TEST_F(SplTest, VectorOperationsTest) {
int B[] = {4, 12, 133, 1100};
WebRtc_Word16* a16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* b32 = (WebRtc_Word32*) malloc(4);
WebRtc_Word16* bTmp16 = (WebRtc_Word16*) malloc(4);
for (int kk = 0; kk < 4; ++kk) {
a16[kk] = B[kk];
b16[kk] = B[kk];
}
WebRtcSpl_AffineTransformVector(bTmp16, b16, 3, 7, 2, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((B[kk]*3+7)>>2, bTmp16[kk]);
}
WebRtcSpl_ScaleAndAddVectorsWithRound(b16, 3, b16, 2, 2, bTmp16, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((B[kk]*3+B[kk]*2+2)>>2, bTmp16[kk]);
}
WebRtcSpl_AddAffineVectorToVector(bTmp16, b16, 3, 7, 2, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
}
WebRtcSpl_CrossCorrelation(b32, b16, bTmp16, 4, 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, 4, 2));
WebRtcSpl_ScaleVector(b16, bTmp16, 13, 4, 2);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
}
WebRtcSpl_ScaleVectorWithSat(b16, bTmp16, 13, 4, 2);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
}
WebRtcSpl_ScaleAndAddVectors(a16, 13, 2, b16, 7, 2, bTmp16, 4);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(((a16[kk]*13)>>2)+((b16[kk]*7)>>2), bTmp16[kk]);
}
WebRtcSpl_AddVectorsAndShift(bTmp16, a16, b16, 4, 2);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(B[kk] >> 1, bTmp16[kk]);
}
WebRtcSpl_ReverseOrderMultArrayElements(bTmp16, a16, &b16[3], 4, 2);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((a16[kk]*b16[3-kk])>>2, bTmp16[kk]);
}
WebRtcSpl_ElementwiseVectorMult(bTmp16, a16, b16, 4, 6);
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ((a16[kk]*b16[kk])>>6, bTmp16[kk]);
}
WebRtcSpl_SqrtOfOneMinusXSquared(b16, 4, bTmp16);
for (int kk = 0; kk < 3; ++kk) {
EXPECT_EQ(32767, bTmp16[kk]);
}
EXPECT_EQ(32749, bTmp16[3]);
}
TEST_F(SplTest, EstimatorsTest) {
int B[] = {4, 12, 133, 1100};
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* b32 = (WebRtc_Word32*) malloc(4);
WebRtc_Word16* bTmp16 = (WebRtc_Word16*) malloc(4);
for (int kk = 0; kk < 4; ++kk) {
b16[kk] = B[kk];
b32[kk] = B[kk];
}
EXPECT_EQ(0, WebRtcSpl_LevinsonDurbin(b32, b16, bTmp16, 2));
}
TEST_F(SplTest, FilterTest) {
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 = (WebRtc_Word16*) malloc(4);
WebRtc_Word16* bTmp16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word16* bTmp16Low = (WebRtc_Word16*) malloc(4);
WebRtc_Word16* bState = (WebRtc_Word16*) malloc(4);
WebRtc_Word16* bStateLow = (WebRtc_Word16*) malloc(4);
WebRtcSpl_ZerosArrayW16(bState, 4);
WebRtcSpl_ZerosArrayW16(bStateLow, 4);
for (int kk = 0; kk < 4; ++kk) {
b16[kk] = A[kk];
}
// MA filters
WebRtcSpl_FilterMAFastQ12(b16, bTmp16, B, 4, 4);
for (int kk = 0; kk < 4; ++kk) {
//EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
}
// AR filters
WebRtcSpl_FilterARFastQ12(b16, bTmp16, A, 4, 4);
for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
}
EXPECT_EQ(4, WebRtcSpl_FilterAR(A5, 5, b16, 4, bState, 4, bStateLow, 4, bTmp16, bTmp16Low, 4));
}
TEST_F(SplTest, RandTest) {
WebRtc_Word16 BU[] = {3653, 12446, 8525, 30691};
WebRtc_Word16 BN[] = {3459, -11689, -258, -3738};
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_UWord32* bSeed = (WebRtc_UWord32*) malloc(1);
bSeed[0] = 100000;
EXPECT_EQ(464449057, WebRtcSpl_IncreaseSeed(bSeed));
EXPECT_EQ(31565, WebRtcSpl_RandU(bSeed));
EXPECT_EQ(-9786, WebRtcSpl_RandN(bSeed));
EXPECT_EQ(4, WebRtcSpl_RandUArray(b16, 4, bSeed));
for (int kk = 0; kk < 4; ++kk) {
EXPECT_EQ(BU[kk], b16[kk]);
}
}
TEST_F(SplTest, SignalProcessingTest) {
int A[] = {1, 2, 33, 100};
WebRtc_Word16* b16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* b32 = (WebRtc_Word32*) malloc(4);
WebRtc_Word16* bTmp16 = (WebRtc_Word16*) malloc(4);
WebRtc_Word32* bTmp32 = (WebRtc_Word32*) malloc(4);
int bScale = 0;
for (int kk = 0; kk < 4; ++kk) {
b16[kk] = A[kk];
b32[kk] = A[kk];
}
EXPECT_EQ(2, WebRtcSpl_AutoCorrelation(b16, 4, 1, bTmp32, &bScale));
WebRtcSpl_ReflCoefToLpc(b16, 4, bTmp16);
// for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
// }
WebRtcSpl_LpcToReflCoef(bTmp16, 4, b16);
// for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(a16[kk], b16[kk]);
// }
WebRtcSpl_AutoCorrToReflCoef(b32, 4, bTmp16);
// for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
// }
WebRtcSpl_GetHanningWindow(bTmp16, 4);
// for (int kk = 0; kk < 4; ++kk) {
// EXPECT_EQ(aTmp16[kk], bTmp16[kk]);
// }
for (int kk = 0; kk < 4; ++kk) {
b16[kk] = A[kk];
}
EXPECT_EQ(11094 , WebRtcSpl_Energy(b16, 4, &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();
}

View File

@ -0,0 +1,30 @@
/*
* 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_

View File

@ -0,0 +1,2 @@
bjornv@google.com
jks@google.com

View File

@ -0,0 +1,159 @@
/*
* 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_

View File

@ -0,0 +1,61 @@
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libwebrtc_vad
LOCAL_MODULE_TAGS := optional
LOCAL_GENERATED_SOURCES :=
LOCAL_SRC_FILES := webrtc_vad.c \
vad_const.c \
vad_core.c \
vad_filterbank.c \
vad_gmm.c \
vad_sp.c
# Flags passed to both C and C++ files.
MY_CFLAGS :=
MY_CFLAGS_C :=
MY_DEFS := '-DNO_TCMALLOC' \
'-DNO_HEAPCHECKER' \
'-DWEBRTC_TARGET_PC' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DANDROID'
LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../interface \
$(LOCAL_PATH)/../../../signal_processing_library/main/interface
# Flags passed to only C++ (and not C) files.
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := libdl \
libstlport
LOCAL_ADDITIONAL_DEPENDENCIES :=
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl -lpthread
endif
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
endif
include external/stlport/libstlport.mk
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,51 @@
# 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.
{
'includes': [
'../../../../common_settings.gypi', # Common settings
],
'targets': [
{
'target_name': 'vad',
'type': '<(library)',
'dependencies': [
'../../../signal_processing_library/main/source/spl.gyp:spl',
],
'include_dirs': [
'../interface',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
],
},
'sources': [
'../interface/webrtc_vad.h',
'webrtc_vad.c',
'vad_const.c',
'vad_const.h',
'vad_defines.h',
'vad_core.c',
'vad_core.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:

View File

@ -0,0 +1,80 @@
/*
* 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 constant values used internally in VAD.
*/
#include "vad_const.h"
// Spectrum Weighting
const WebRtc_Word16 kSpectrumWeight[6] = {6, 8, 10, 12, 14, 16};
const WebRtc_Word16 kCompVar = 22005;
// Constant 160*log10(2) in Q9
const WebRtc_Word16 kLogConst = 24660;
// Constant log2(exp(1)) in Q12
const WebRtc_Word16 kLog10Const = 5909;
// Q15
const WebRtc_Word16 kNoiseUpdateConst = 655;
const WebRtc_Word16 kSpeechUpdateConst = 6554;
// Q8
const WebRtc_Word16 kBackEta = 154;
// Coefficients used by WebRtcVad_HpOutput, Q14
const WebRtc_Word16 kHpZeroCoefs[3] = {6631, -13262, 6631};
const WebRtc_Word16 kHpPoleCoefs[3] = {16384, -7756, 5620};
// Allpass filter coefficients, upper and lower, in Q15
// Upper: 0.64, Lower: 0.17
const WebRtc_Word16 kAllPassCoefsQ15[2] = {20972, 5571};
const WebRtc_Word16 kAllPassCoefsQ13[2] = {5243, 1392}; // Q13
// Minimum difference between the two models, Q5
const WebRtc_Word16 kMinimumDifference[6] = {544, 544, 576, 576, 576, 576};
// Upper limit of mean value for speech model, Q7
const WebRtc_Word16 kMaximumSpeech[6] = {11392, 11392, 11520, 11520, 11520, 11520};
// Minimum value for mean value
const WebRtc_Word16 kMinimumMean[2] = {640, 768};
// Upper limit of mean value for noise model, Q7
const WebRtc_Word16 kMaximumNoise[6] = {9216, 9088, 8960, 8832, 8704, 8576};
// Adjustment for division with two in WebRtcVad_SplitFilter
const WebRtc_Word16 kOffsetVector[6] = {368, 368, 272, 176, 176, 176};
// Start values for the Gaussian models, Q7
// Weights for the two Gaussians for the six channels (noise)
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)
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)
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)
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)
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)
const WebRtc_Word16 kSpeechDataStds[12] = {555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540,
1079, 850};

View File

@ -0,0 +1,59 @@
/*
* 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 declarations of the internally used constants.
*/
#ifndef WEBRTC_VAD_CONST_H_
#define WEBRTC_VAD_CONST_H_
#include "typedefs.h"
// TODO(ajm): give these internal-linkage by moving to the appropriate file
// where possible, and otherwise tag with WebRtcVad_.
// Spectrum Weighting
extern const WebRtc_Word16 kSpectrumWeight[];
extern const WebRtc_Word16 kCompVar;
// Logarithm constant
extern const WebRtc_Word16 kLogConst;
extern const WebRtc_Word16 kLog10Const;
// Q15
extern const WebRtc_Word16 kNoiseUpdateConst;
extern const WebRtc_Word16 kSpeechUpdateConst;
// Q8
extern const WebRtc_Word16 kBackEta;
// Coefficients used by WebRtcVad_HpOutput, Q14
extern const WebRtc_Word16 kHpZeroCoefs[];
extern const WebRtc_Word16 kHpPoleCoefs[];
// Allpass filter coefficients, upper and lower, in Q15 resp. Q13
extern const WebRtc_Word16 kAllPassCoefsQ15[];
extern const WebRtc_Word16 kAllPassCoefsQ13[];
// Minimum difference between the two models, Q5
extern const WebRtc_Word16 kMinimumDifference[];
// Maximum value when updating the speech model, Q7
extern const WebRtc_Word16 kMaximumSpeech[];
// Minimum value for mean value
extern const WebRtc_Word16 kMinimumMean[];
// Upper limit of mean value for noise model, Q7
extern const WebRtc_Word16 kMaximumNoise[];
// Adjustment for division with two in WebRtcVad_SplitFilter
extern const WebRtc_Word16 kOffsetVector[];
// Start values for the Gaussian models, Q7
extern const WebRtc_Word16 kNoiseDataWeights[];
extern const WebRtc_Word16 kSpeechDataWeights[];
extern const WebRtc_Word16 kNoiseDataMeans[];
extern const WebRtc_Word16 kSpeechDataMeans[];
extern const WebRtc_Word16 kNoiseDataStds[];
extern const WebRtc_Word16 kSpeechDataStds[];
#endif // WEBRTC_VAD_CONST_H_

View File

@ -0,0 +1,685 @@
/*
* 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 "vad_const.h"
#include "vad_defines.h"
#include "vad_filterbank.h"
#include "vad_gmm.h"
#include "vad_sp.h"
#include "signal_processing_library.h"
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;
}

View File

@ -0,0 +1,132 @@
/*
* 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_

View File

@ -0,0 +1,95 @@
/*
* 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 macros used in VAD.
*/
#ifndef WEBRTC_VAD_DEFINES_H_
#define WEBRTC_VAD_DEFINES_H_
#define NUM_CHANNELS 6 // Eight frequency bands
#define NUM_MODELS 2 // Number of Gaussian models
#define NUM_TABLE_VALUES NUM_CHANNELS * NUM_MODELS
#define MIN_ENERGY 10
#define ALPHA1 6553 // 0.2 in Q15
#define ALPHA2 32439 // 0.99 in Q15
#define NSP_MAX 6 // Maximum number of VAD=1 frames in a row counted
#define MIN_STD 384 // Minimum standard deviation
// Mode 0, Quality thresholds - Different thresholds for the different frame lengths
#define INDIVIDUAL_10MS_Q 24
#define INDIVIDUAL_20MS_Q 21 // (log10(2)*66)<<2 ~=16
#define INDIVIDUAL_30MS_Q 24
#define TOTAL_10MS_Q 57
#define TOTAL_20MS_Q 48
#define TOTAL_30MS_Q 57
#define OHMAX1_10MS_Q 8 // Max Overhang 1
#define OHMAX2_10MS_Q 14 // Max Overhang 2
#define OHMAX1_20MS_Q 4 // Max Overhang 1
#define OHMAX2_20MS_Q 7 // Max Overhang 2
#define OHMAX1_30MS_Q 3
#define OHMAX2_30MS_Q 5
// Mode 1, Low bitrate thresholds - Different thresholds for the different frame lengths
#define INDIVIDUAL_10MS_LBR 37
#define INDIVIDUAL_20MS_LBR 32
#define INDIVIDUAL_30MS_LBR 37
#define TOTAL_10MS_LBR 100
#define TOTAL_20MS_LBR 80
#define TOTAL_30MS_LBR 100
#define OHMAX1_10MS_LBR 8 // Max Overhang 1
#define OHMAX2_10MS_LBR 14 // Max Overhang 2
#define OHMAX1_20MS_LBR 4
#define OHMAX2_20MS_LBR 7
#define OHMAX1_30MS_LBR 3
#define OHMAX2_30MS_LBR 5
// Mode 2, Very aggressive thresholds - Different thresholds for the different frame lengths
#define INDIVIDUAL_10MS_AGG 82
#define INDIVIDUAL_20MS_AGG 78
#define INDIVIDUAL_30MS_AGG 82
#define TOTAL_10MS_AGG 285 //580
#define TOTAL_20MS_AGG 260
#define TOTAL_30MS_AGG 285
#define OHMAX1_10MS_AGG 6 // Max Overhang 1
#define OHMAX2_10MS_AGG 9 // Max Overhang 2
#define OHMAX1_20MS_AGG 3
#define OHMAX2_20MS_AGG 5
#define OHMAX1_30MS_AGG 2
#define OHMAX2_30MS_AGG 3
// Mode 3, Super aggressive thresholds - Different thresholds for the different frame lengths
#define INDIVIDUAL_10MS_VAG 94
#define INDIVIDUAL_20MS_VAG 94
#define INDIVIDUAL_30MS_VAG 94
#define TOTAL_10MS_VAG 1100 //1700
#define TOTAL_20MS_VAG 1050
#define TOTAL_30MS_VAG 1100
#define OHMAX1_10MS_VAG 6 // Max Overhang 1
#define OHMAX2_10MS_VAG 9 // Max Overhang 2
#define OHMAX1_20MS_VAG 3
#define OHMAX2_20MS_VAG 5
#define OHMAX1_30MS_VAG 2
#define OHMAX2_30MS_VAG 3
#endif // WEBRTC_VAD_DEFINES_H_

View File

@ -0,0 +1,267 @@
/*
* 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 "vad_defines.h"
#include "vad_const.h"
#include "signal_processing_library.h"
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);
}
}
}

View File

@ -0,0 +1,143 @@
/*
* 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_

View File

@ -0,0 +1,70 @@
/*
* 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 "vad_const.h"
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
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This header file 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_

View File

@ -0,0 +1,231 @@
/*
* 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 "vad_defines.h"
#include "vad_const.h"
#include "signal_processing_library.h"
// 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];
}

View File

@ -0,0 +1,60 @@
/*
* 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_

View File

@ -0,0 +1,197 @@
/*
* 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;
}
}

View File

@ -0,0 +1,123 @@
/*
* 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();
}

View File

@ -0,0 +1,28 @@
/*
* 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_

21
src/common_settings.gypi Normal file
View File

@ -0,0 +1,21 @@
# 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.
# Placeholder until all gyp files point to build/common.gypi instead.
{
'includes': [
'build/common.gypi',
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

Some files were not shown because too many files have changed in this diff Show More