git-svn-id: http://webrtc.googlecode.com/svn/trunk@156 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f0a476bf76
commit
470e71d364
13
src/README.chromium
Normal file
13
src/README.chromium
Normal 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
74
src/build/common.gypi
Normal 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:
|
97
src/build/common_standalone.gypi
Normal file
97
src/build/common_standalone.gypi
Normal 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:
|
50
src/build/external_code.gypi
Normal file
50
src/build/external_code.gypi
Normal 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
91
src/build/gyp_webrtc
Executable 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
1
src/common_audio/OWNERS
Normal file
@ -0,0 +1 @@
|
||||
bjornv@google.com
|
3
src/common_audio/resampler/OWNERS
Normal file
3
src/common_audio/resampler/OWNERS
Normal file
@ -0,0 +1,3 @@
|
||||
bjornv@google.com
|
||||
tlegrand@google.com
|
||||
jks@google.com
|
110
src/common_audio/resampler/main/interface/resampler.h
Normal file
110
src/common_audio/resampler/main/interface/resampler.h
Normal 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_
|
58
src/common_audio/resampler/main/source/Android.mk
Normal file
58
src/common_audio/resampler/main/source/Android.mk
Normal 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)
|
981
src/common_audio/resampler/main/source/resampler.cc
Normal file
981
src/common_audio/resampler/main/source/resampler.cc
Normal 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
|
40
src/common_audio/resampler/main/source/resampler.gyp
Normal file
40
src/common_audio/resampler/main/source/resampler.gyp
Normal 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:
|
3
src/common_audio/signal_processing_library/OWNERS
Normal file
3
src/common_audio/signal_processing_library/OWNERS
Normal file
@ -0,0 +1,3 @@
|
||||
bjornv@google.com
|
||||
tlegrand@google.com
|
||||
jks@google.com
|
File diff suppressed because it is too large
Load Diff
@ -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_
|
@ -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)
|
@ -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
|
@ -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
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
};
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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 };
|
@ -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 };
|
||||
*/
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
||||
};
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
};
|
@ -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;
|
||||
}
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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_
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
};
|
@ -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,
|
||||
};
|
@ -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:
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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 };
|
@ -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 };
|
@ -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();
|
||||
}
|
@ -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_
|
2
src/common_audio/vad/OWNERS
Normal file
2
src/common_audio/vad/OWNERS
Normal file
@ -0,0 +1,2 @@
|
||||
bjornv@google.com
|
||||
jks@google.com
|
159
src/common_audio/vad/main/interface/webrtc_vad.h
Normal file
159
src/common_audio/vad/main/interface/webrtc_vad.h
Normal 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_
|
61
src/common_audio/vad/main/source/Android.mk
Normal file
61
src/common_audio/vad/main/source/Android.mk
Normal 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)
|
51
src/common_audio/vad/main/source/vad.gyp
Normal file
51
src/common_audio/vad/main/source/vad.gyp
Normal 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:
|
80
src/common_audio/vad/main/source/vad_const.c
Normal file
80
src/common_audio/vad/main/source/vad_const.c
Normal 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};
|
59
src/common_audio/vad/main/source/vad_const.h
Normal file
59
src/common_audio/vad/main/source/vad_const.h
Normal 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_
|
685
src/common_audio/vad/main/source/vad_core.c
Normal file
685
src/common_audio/vad/main/source/vad_core.c
Normal 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;
|
||||
}
|
132
src/common_audio/vad/main/source/vad_core.h
Normal file
132
src/common_audio/vad/main/source/vad_core.h
Normal 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_
|
95
src/common_audio/vad/main/source/vad_defines.h
Normal file
95
src/common_audio/vad/main/source/vad_defines.h
Normal 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_
|
267
src/common_audio/vad/main/source/vad_filterbank.c
Normal file
267
src/common_audio/vad/main/source/vad_filterbank.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
143
src/common_audio/vad/main/source/vad_filterbank.h
Normal file
143
src/common_audio/vad/main/source/vad_filterbank.h
Normal 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_
|
70
src/common_audio/vad/main/source/vad_gmm.c
Normal file
70
src/common_audio/vad/main/source/vad_gmm.c
Normal 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
|
||||
}
|
47
src/common_audio/vad/main/source/vad_gmm.h
Normal file
47
src/common_audio/vad/main/source/vad_gmm.h
Normal 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_
|
231
src/common_audio/vad/main/source/vad_sp.c
Normal file
231
src/common_audio/vad/main/source/vad_sp.c
Normal 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];
|
||||
}
|
60
src/common_audio/vad/main/source/vad_sp.h
Normal file
60
src/common_audio/vad/main/source/vad_sp.h
Normal 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_
|
197
src/common_audio/vad/main/source/webrtc_vad.c
Normal file
197
src/common_audio/vad/main/source/webrtc_vad.c
Normal 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;
|
||||
}
|
||||
}
|
123
src/common_audio/vad/main/test/unit_test/unit_test.cc
Normal file
123
src/common_audio/vad/main/test/unit_test/unit_test.cc
Normal 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();
|
||||
}
|
28
src/common_audio/vad/main/test/unit_test/unit_test.h
Normal file
28
src/common_audio/vad/main/test/unit_test/unit_test.h
Normal 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
21
src/common_settings.gypi
Normal 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
Loading…
Reference in New Issue
Block a user