mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-07-22 11:53:16 +00:00
update speex to 1.2rc1
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11979 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
d885488f15
commit
4ee40ddc34
@ -1,10 +1,11 @@
|
||||
Copyright 2002-2006
|
||||
Xiph.org Foundation
|
||||
Jean-Marc Valin
|
||||
David Rowe
|
||||
EpicGames
|
||||
Analog Devices
|
||||
Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
||||
Copyright 2002-2008 Xiph.org Foundation
|
||||
Copyright 2002-2008 Jean-Marc Valin
|
||||
Copyright 2005-2007 Analog Devices Inc.
|
||||
Copyright 2005-2008 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO)
|
||||
Copyright 1993, 2002, 2006 David Rowe
|
||||
Copyright 2003 EpicGames
|
||||
Copyright 1992-1994 Jutta Degener, Carsten Bormann
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
@ -2,18 +2,18 @@
|
||||
|
||||
# To disable automatic dependency tracking if using other tools than
|
||||
# gcc and gmake, add the option 'no-dependencies'
|
||||
AUTOMAKE_OPTIONS = 1.7
|
||||
AUTOMAKE_OPTIONS = 1.8
|
||||
|
||||
m4datadir = $(datadir)/aclocal
|
||||
m4data_DATA = speex.m4
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = speex.pc
|
||||
pkgconfig_DATA = speex.pc speexdsp.pc
|
||||
|
||||
EXTRA_DIST = Speex.spec Speex.spec.in Speex.kdevelop speex.m4 speex.pc.in README.blackfin README.symbian README.TI-DSP
|
||||
|
||||
#Fools KDevelop into including all files
|
||||
SUBDIRS = libspeex include doc win32 symbian ti
|
||||
SUBDIRS = libspeex include @src@ doc win32 symbian ti
|
||||
|
||||
DIST_SUBDIRS = libspeex include src doc win32 symbian ti
|
||||
|
||||
|
@ -11,11 +11,14 @@
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description/>
|
||||
<secondaryLanguages/>
|
||||
<versioncontrol>kdevsubversion</versioncontrol>
|
||||
<defaultencoding/>
|
||||
<projectname>Speex</projectname>
|
||||
</general>
|
||||
<kdevautoproject>
|
||||
<general>
|
||||
<activetarget>libspeex/libspeex.la</activetarget>
|
||||
<useconfiguration>default</useconfiguration>
|
||||
<useconfiguration>float</useconfiguration>
|
||||
</general>
|
||||
<run>
|
||||
<mainprogram>src/Speex</mainprogram>
|
||||
@ -25,23 +28,47 @@
|
||||
<terminal>false</terminal>
|
||||
<autocompile>true</autocompile>
|
||||
<envvars/>
|
||||
<autoinstall>false</autoinstall>
|
||||
<autokdesu>false</autokdesu>
|
||||
</run>
|
||||
<configurations>
|
||||
<optimized>
|
||||
<builddir>optimized</builddir>
|
||||
<ccompiler>GccOptions</ccompiler>
|
||||
<cxxcompiler>GppOptions</cxxcompiler>
|
||||
<f77compiler>G77Options</f77compiler>
|
||||
<cflags>-O2 -g0</cflags>
|
||||
</optimized>
|
||||
<debug>
|
||||
<configargs>--enable-debug=full</configargs>
|
||||
<builddir>debug</builddir>
|
||||
<ccompiler>GccOptions</ccompiler>
|
||||
<cxxcompiler>GppOptions</cxxcompiler>
|
||||
<f77compiler>G77Options</f77compiler>
|
||||
<cflags>-O0 -g3</cflags>
|
||||
</debug>
|
||||
<float>
|
||||
<builddir>float</builddir>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevpgf77options</f77compiler>
|
||||
<cflags>-O2 -g -Wall</cflags>
|
||||
<envvars/>
|
||||
<configargs>--disable-shared</configargs>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompilerbinary/>
|
||||
<cxxcompilerbinary/>
|
||||
<f77compilerbinary/>
|
||||
<cxxflags/>
|
||||
<f77flags/>
|
||||
</float>
|
||||
<fixed>
|
||||
<configargs>--enable-fixed-point --disable-shared</configargs>
|
||||
<builddir>fixed</builddir>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevpgf77options</f77compiler>
|
||||
<cflags>-O2 -g -Wall</cflags>
|
||||
<envvars/>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompilerbinary/>
|
||||
<cxxcompilerbinary/>
|
||||
<f77compilerbinary/>
|
||||
<cxxflags/>
|
||||
<f77flags/>
|
||||
</fixed>
|
||||
<default>
|
||||
<envvars/>
|
||||
</default>
|
||||
</configurations>
|
||||
<make>
|
||||
<envvars>
|
||||
@ -49,9 +76,11 @@
|
||||
<envvar value="1" name="WANT_AUTOMAKE_1_6" />
|
||||
</envvars>
|
||||
<abortonerror>false</abortonerror>
|
||||
<numberofjobs>1</numberofjobs>
|
||||
<numberofjobs>4</numberofjobs>
|
||||
<dontact>false</dontact>
|
||||
<makebin/>
|
||||
<runmultiplejobs>true</runmultiplejobs>
|
||||
<prio>0</prio>
|
||||
</make>
|
||||
</kdevautoproject>
|
||||
<kdevdebugger>
|
||||
@ -69,6 +98,7 @@
|
||||
<display>
|
||||
<staticmembers>false</staticmembers>
|
||||
<demanglenames>true</demanglenames>
|
||||
<outputradix>10</outputradix>
|
||||
</display>
|
||||
</kdevdebugger>
|
||||
<kdevfilecreate>
|
||||
@ -88,10 +118,50 @@
|
||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||
<codeCompletionDelay>250</codeCompletionDelay>
|
||||
<codeCompletionDelay>350</codeCompletionDelay>
|
||||
<argumentsHintDelay>400</argumentsHintDelay>
|
||||
<headerCompletionDelay>250</headerCompletionDelay>
|
||||
<showOnlyAccessibleItems>false</showOnlyAccessibleItems>
|
||||
<completionBoxItemOrder>0</completionBoxItemOrder>
|
||||
<howEvaluationContextMenu>true</howEvaluationContextMenu>
|
||||
<showCommentWithArgumentHint>true</showCommentWithArgumentHint>
|
||||
<statusBarTypeEvaluation>false</statusBarTypeEvaluation>
|
||||
<namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
|
||||
<processPrimaryTypes>true</processPrimaryTypes>
|
||||
<processFunctionArguments>true</processFunctionArguments>
|
||||
<preProcessAllHeaders>false</preProcessAllHeaders>
|
||||
<parseMissingHeaders>false</parseMissingHeaders>
|
||||
<resolveIncludePaths>true</resolveIncludePaths>
|
||||
<alwaysParseInBackground>true</alwaysParseInBackground>
|
||||
<usePermanentCaching>true</usePermanentCaching>
|
||||
<alwaysIncludeNamespaces>true</alwaysIncludeNamespaces>
|
||||
<includePaths>.;</includePaths>
|
||||
<parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
|
||||
<resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
|
||||
</codecompletion>
|
||||
<qt>
|
||||
<used>false</used>
|
||||
<version>3</version>
|
||||
<root>/usr/share/qt3</root>
|
||||
<includestyle>3</includestyle>
|
||||
<designerintegration>EmbeddedKDevDesigner</designerintegration>
|
||||
<qmake>/usr/share/qt3/bin/qmake</qmake>
|
||||
<designer>/usr/bin/designer-qt3</designer>
|
||||
<designerpluginpaths/>
|
||||
</qt>
|
||||
<creategettersetter>
|
||||
<prefixGet/>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
<inlineGet>true</inlineGet>
|
||||
<inlineSet>true</inlineSet>
|
||||
</creategettersetter>
|
||||
<splitheadersource>
|
||||
<enabled>true</enabled>
|
||||
<synchronize>true</synchronize>
|
||||
<orientation>Horizontal</orientation>
|
||||
</splitheadersource>
|
||||
</kdevcppsupport>
|
||||
<kdevfileview>
|
||||
<groups>
|
||||
@ -101,6 +171,7 @@
|
||||
<tree>
|
||||
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
||||
<hidenonprojectfiles>true</hidenonprojectfiles>
|
||||
<showvcsfields>false</showvcsfields>
|
||||
</tree>
|
||||
</kdevfileview>
|
||||
<kdevdoctreeview>
|
||||
@ -120,4 +191,11 @@
|
||||
<implementationsuffix>.cpp</implementationsuffix>
|
||||
</filetemplates>
|
||||
</cppsupportpart>
|
||||
<kdevdocumentation>
|
||||
<projectdoc>
|
||||
<docsystem/>
|
||||
<docurl/>
|
||||
<usermanualurl/>
|
||||
</projectdoc>
|
||||
</kdevdocumentation>
|
||||
</kdevelop>
|
||||
|
@ -1,5 +1,5 @@
|
||||
%define name speex
|
||||
%define ver 1.2beta1
|
||||
%define ver 1.2rc1
|
||||
%define rel 1
|
||||
|
||||
Summary: An open-source, patent-free speech codec
|
||||
@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install
|
||||
%{_includedir}/speex/speex*.h
|
||||
/usr/share/aclocal/speex.m4
|
||||
%{_libdir}/pkgconfig/speex.pc
|
||||
%{_libdir}/pkgconfig/speexdsp.pc
|
||||
%{_libdir}/libspeex*.a
|
||||
|
@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install
|
||||
%{_includedir}/speex/speex*.h
|
||||
/usr/share/aclocal/speex.m4
|
||||
%{_libdir}/pkgconfig/speex.pc
|
||||
%{_libdir}/pkgconfig/speexdsp.pc
|
||||
%{_libdir}/libspeex*.a
|
||||
|
@ -1,29 +1,43 @@
|
||||
Better saturation handling in mdf?
|
||||
get rid of crap that shouldn't be exposed in speex.h
|
||||
For 1.2:
|
||||
Major points:
|
||||
- Make documentation match the actual code (especially jitter buffer, AEC and preprocessor)
|
||||
- Get AGC to work in fixed-point even if not totally converted
|
||||
- Stabilise all APIs (need feedback)
|
||||
- Short-term estimate in jitter buffer
|
||||
- Control delay in new AEC API.
|
||||
- NaN checks?
|
||||
- Better error reporting
|
||||
- Make kiss-fft 32-bit safe
|
||||
|
||||
Minor issues:
|
||||
- Fix last frame of speexenc
|
||||
|
||||
|
||||
Post 1.2:
|
||||
improve float<->int conversion
|
||||
split encoder and decoder?
|
||||
Merge TriMedia stuff
|
||||
packet dump
|
||||
Do VAD properly
|
||||
--enable-{aec,preprocessor,jitter,resampler}
|
||||
|
||||
Optimisations
|
||||
- Add restrict in a few places?
|
||||
- enable 4x4 version of pitch_xcorr() at least on some archs?
|
||||
- use __builtin_expect() (likely()/unlikely())
|
||||
|
||||
Would be nice:
|
||||
Implement wideband split as IIR instead of QMF?
|
||||
|
||||
Allocator override (speex_lib_ctl)
|
||||
Better error handling
|
||||
Allocator override (speex_lib_ctl?)
|
||||
Fixed-point:
|
||||
- Wideband
|
||||
- Initialization
|
||||
- VBR
|
||||
- Jitter buffer
|
||||
- AGC
|
||||
Denoiser:
|
||||
- Smooth gain (remove musical noise)
|
||||
- Better noise adaptation
|
||||
- Do some tuning
|
||||
AGC:
|
||||
- Use median filtering instead of "non-linear mean"
|
||||
|
||||
|
||||
|
||||
Features
|
||||
-Add maximum/minimum bit-rate control for VBR
|
||||
-Improve error handling (with perror-like call?)
|
||||
|
||||
Long-term quality improvements
|
||||
-Improve perceptual enhancement (including wideband)
|
||||
- Use median filtering instead of "non-linear mean"?
|
||||
|
||||
Standards
|
||||
-Complete Speex RTP profile
|
||||
@ -32,4 +46,3 @@ Standards
|
||||
ideas:
|
||||
Peelable stream (double codebook, higher bands, stereo)
|
||||
LPC from spectral domain
|
||||
Better psycho-acoustic model. Masking curve from Vorbis?
|
||||
|
@ -19,7 +19,7 @@ AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE" ; then
|
||||
OGG_LIBS=""
|
||||
OGG_LIBS="-L$prefix/lib"
|
||||
fi
|
||||
|
||||
OGG_LIBS="$OGG_LIBS -logg"
|
||||
|
@ -9,14 +9,17 @@
|
||||
/* Make use of Blackfin assembly optimizations */
|
||||
#undef BFIN_ASM
|
||||
|
||||
/* Disable wideband codec */
|
||||
#undef DISABLE_WIDEBAND
|
||||
/* Disable all parts of the API that are using floats */
|
||||
#undef DISABLE_FLOAT_API
|
||||
|
||||
/* Disable VBR and VAD from the codec */
|
||||
#undef DISABLE_VBR
|
||||
|
||||
/* Enable valgrind extra checks */
|
||||
#undef ENABLE_VALGRIND
|
||||
|
||||
/* Enable support for Epic 4.8 kbps mode */
|
||||
#undef EPIC_48K
|
||||
/* Symbol visibility prefix */
|
||||
#undef EXPORT
|
||||
|
||||
/* Debug fixed-point implementation */
|
||||
#undef FIXED_DEBUG
|
||||
@ -24,9 +27,18 @@
|
||||
/* Compile as fixed-point */
|
||||
#undef FIXED_POINT
|
||||
|
||||
/* Compile as floating-point */
|
||||
#undef FLOATING_POINT
|
||||
|
||||
/* Define to 1 if you have the <alloca.h> header file. */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
@ -84,16 +96,13 @@
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Reduce precision to 16 bits (EXPERIMENTAL) */
|
||||
#undef PRECISION16
|
||||
|
||||
/* The size of a `int', as computed by sizeof. */
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of a `long', as computed by sizeof. */
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG
|
||||
|
||||
/* The size of a `short', as computed by sizeof. */
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
/* Version extra */
|
||||
@ -120,12 +129,21 @@
|
||||
/* Make use of alloca */
|
||||
#undef USE_ALLOCA
|
||||
|
||||
/* Use FFTW3 for FFT */
|
||||
#undef USE_GPL_FFTW3
|
||||
|
||||
/* Use Intel Math Kernel Library for FFT */
|
||||
#undef USE_INTEL_MKL
|
||||
|
||||
/* Use KISS Fast Fourier Transform */
|
||||
#undef USE_KISS_FFT
|
||||
|
||||
/* Use FFT from OggVorbis */
|
||||
#undef USE_SMALLFT
|
||||
|
||||
/* Use C99 variable-size arrays */
|
||||
#undef VAR_ARRAYS
|
||||
|
||||
/* Enable Vorbis-style psychoacoustics (EXPERIMENTAL) */
|
||||
#undef VORBIS_PSYCHO
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
@ -6,15 +6,15 @@ AM_CONFIG_HEADER([config.h])
|
||||
|
||||
SPEEX_MAJOR_VERSION=1
|
||||
SPEEX_MINOR_VERSION=1
|
||||
SPEEX_MICRO_VERSION=13
|
||||
SPEEX_MICRO_VERSION=16
|
||||
SPEEX_EXTRA_VERSION=
|
||||
#SPEEX_VERSION=
|
||||
SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION
|
||||
SPEEX_VERSION="1.2beta1"
|
||||
#SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION
|
||||
SPEEX_VERSION="1.2rc1"
|
||||
|
||||
SPEEX_LT_CURRENT=5
|
||||
SPEEX_LT_CURRENT=6
|
||||
SPEEX_LT_REVISION=0
|
||||
SPEEX_LT_AGE=4
|
||||
SPEEX_LT_AGE=5
|
||||
|
||||
AC_SUBST(SPEEX_LT_CURRENT)
|
||||
AC_SUBST(SPEEX_LT_REVISION)
|
||||
@ -30,6 +30,7 @@ AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
@ -40,7 +41,8 @@ AC_C_RESTRICT
|
||||
|
||||
AC_MSG_CHECKING(for C99 variable-size arrays)
|
||||
AC_TRY_COMPILE( , [
|
||||
int foo=10;
|
||||
int foo;
|
||||
foo = 10;
|
||||
int array[foo];
|
||||
],
|
||||
[has_var_arrays=yes;AC_DEFINE([VAR_ARRAYS], [], [Use C99 variable-size arrays])
|
||||
@ -49,8 +51,14 @@ has_var_arrays=no
|
||||
)
|
||||
AC_MSG_RESULT($has_var_arrays)
|
||||
|
||||
AC_CHECK_HEADERS([alloca.h getopt.h])
|
||||
AC_MSG_CHECKING(for alloca)
|
||||
AC_TRY_COMPILE( [#include <alloca.h>], [
|
||||
AC_TRY_COMPILE( [
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
], [
|
||||
int foo=10;
|
||||
int *array = alloca(foo);
|
||||
],
|
||||
@ -64,9 +72,49 @@ has_alloca=no
|
||||
)
|
||||
AC_MSG_RESULT($has_alloca)
|
||||
|
||||
AC_MSG_CHECKING(for SSE in current arch/CFLAGS)
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <xmmintrin.h>
|
||||
__m128 testfunc(float *a, float *b) {
|
||||
return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b));
|
||||
}
|
||||
]])],
|
||||
[
|
||||
has_sse=yes
|
||||
],
|
||||
[
|
||||
has_sse=no
|
||||
]
|
||||
)
|
||||
AC_MSG_RESULT($has_sse)
|
||||
|
||||
SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden"
|
||||
AC_MSG_CHECKING(for ELF visibility)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#pragma GCC visibility push(hidden)
|
||||
__attribute__((visibility("default")))
|
||||
int var=10;
|
||||
]])],
|
||||
[
|
||||
has_visibility=yes
|
||||
AC_DEFINE([EXPORT], [__attribute__((visibility("default")))], [Symbol visibility prefix])
|
||||
],
|
||||
[
|
||||
has_visibility=no
|
||||
AC_DEFINE([EXPORT], [], [Symbol visibility prefix])
|
||||
CFLAGS="$SAVE_CFLAGS"
|
||||
]
|
||||
)
|
||||
AC_MSG_RESULT($has_visibility)
|
||||
|
||||
AC_CHECK_HEADERS(sys/soundcard.h sys/audioio.h)
|
||||
|
||||
XIPH_PATH_OGG([src="src"], [src=""])
|
||||
AC_SUBST(src)
|
||||
|
||||
AC_CHECK_LIB(m, sin)
|
||||
|
||||
# Check for getopt_long; if not found, use included source.
|
||||
@ -86,30 +134,45 @@ AC_DEFINE_UNQUOTED(SPEEX_MINOR_VERSION, ${SPEEX_MINOR_VERSION}, [Version minor])
|
||||
AC_DEFINE_UNQUOTED(SPEEX_MICRO_VERSION, ${SPEEX_MICRO_VERSION}, [Version micro])
|
||||
AC_DEFINE_UNQUOTED(SPEEX_EXTRA_VERSION, "${SPEEX_EXTRA_VERSION}", [Version extra])
|
||||
|
||||
AC_ARG_ENABLE(wideband, [ --disable-wideband Disable wideband codec],
|
||||
[if test "$enableval" = no; then
|
||||
AC_DEFINE([DISABLE_WIDEBAND], , [Disable wideband codec])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(vorbis-psy, [ --enable-vorbis-psy Enable Vorbis-style psychoacoustics (EXPERIMENTAL)],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_DEFINE([VORBIS_PSYCHO], , [Enable Vorbis-style psychoacoustics (EXPERIMENTAL)])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(valgrind, [ --enable-valgrind Enable valgrind extra checks],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_DEFINE([ENABLE_VALGRIND], , [Enable valgrind extra checks])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [if test "$enableval" = yes; then
|
||||
AC_DEFINE([_USE_SSE], , [Enable SSE support])
|
||||
AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [
|
||||
if test "x$enableval" != xno; then
|
||||
has_sse=yes
|
||||
CFLAGS="$CFLAGS -O3 -msse"
|
||||
else
|
||||
has_sse=no
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
FFT=smallft
|
||||
|
||||
AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point],
|
||||
[if test "$enableval" = yes; then
|
||||
FFT=kiss
|
||||
has_sse=no
|
||||
AC_DEFINE([FIXED_POINT], , [Compile as fixed-point])
|
||||
else
|
||||
AC_DEFINE([FLOATING_POINT], , [Compile as floating-point])
|
||||
fi],
|
||||
AC_DEFINE([FLOATING_POINT], , [Compile as floating-point]))
|
||||
|
||||
if test "$has_sse" = yes; then
|
||||
AC_DEFINE([_USE_SSE], , [Enable SSE support])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(float-api, [ --disable-float-api Disable the floating-point API],
|
||||
[if test "$enableval" = no; then
|
||||
AC_DEFINE([DISABLE_FLOAT_API], , [Disable all parts of the API that are using floats])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(vbr, [ --disable-vbr Disable VBR and VAD from the codec],
|
||||
[if test "$enableval" = no; then
|
||||
AC_DEFINE([DISABLE_VBR], , [Disable VBR and VAD from the codec])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(arm4-asm, [ --enable-arm4-asm Make use of ARM4 assembly optimizations],
|
||||
@ -122,7 +185,7 @@ AC_ARG_ENABLE(arm5e-asm, [ --enable-arm5e-asm Make use of ARM5E assembly o
|
||||
AC_DEFINE([ARM5E_ASM], , [Make use of ARM5E assembly optimizations])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(blackfin-asm, [ --enable-blackfin-asm Make use of Blackfin assembly optimizations],
|
||||
AC_ARG_ENABLE(blackfin-asm, [ --enable-blackfin-asm Make use of Blackfin assembly optimizations],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_DEFINE([BFIN_ASM], , [Make use of Blackfin assembly optimizations])
|
||||
LDFLAGS="-Wl,-elf2flt=-s100000"
|
||||
@ -133,21 +196,49 @@ AC_ARG_ENABLE(fixed-point-debug, [ --enable-fixed-point-debug Debug fixed-poin
|
||||
AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(epic-48k, [ --enable-epic-48k Enable support for Epic 4.8 kbps mode],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_DEFINE([EPIC_48K], , [Enable support for Epic 4.8 kbps mode])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(ti-c55x, [ --enable-ti-c55x Enable support for TI C55X DSP],
|
||||
[if test "$enableval" = yes; then
|
||||
has_char16=yes;
|
||||
AC_DEFINE([TI_C55X], , [Enable support for TI C55X DSP])
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(16bit-precision, [ --enable-16bit-precision Reduce precision to 16 bits (EXPERIMENTAL)],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_DEFINE([PRECISION16], , [Reduce precision to 16 bits (EXPERIMENTAL)])
|
||||
fi])
|
||||
AC_ARG_WITH([fft], [AS_HELP_STRING([--with-fft=choice],[use an alternate FFT implementation. The available choices are
|
||||
kiss (default fixed point), smallft (default floating point), gpl-fftw3 and proprietary-intel-mkl])],
|
||||
[FFT=$withval]
|
||||
)
|
||||
|
||||
FFT_PKGCONFIG=
|
||||
AS_CASE([$FFT],
|
||||
[kiss], [
|
||||
AC_DEFINE([USE_KISS_FFT], [], [Use KISS Fast Fourier Transform])
|
||||
],
|
||||
[smallft], [
|
||||
AC_DEFINE([USE_SMALLFT], [], [Use FFT from OggVorbis])
|
||||
],
|
||||
[gpl-fftw3], [
|
||||
AC_DEFINE([USE_GPL_FFTW3], [], [Use FFTW3 for FFT])
|
||||
PKG_CHECK_MODULES(FFT, fftw3f)
|
||||
],
|
||||
[proprietary-intel-mkl], [
|
||||
AC_DEFINE([USE_INTEL_MKL], [], [Use Intel Math Kernel Library for FFT])
|
||||
AC_MSG_CHECKING(for valid MKL)
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <mkl.h>
|
||||
void func() {
|
||||
DFTI_DESCRIPTOR_HANDLE h;
|
||||
MKL_LONG result=DftiCreateDescriptor(&h, DFTI_SINGLE, DFTI_REAL, 0);
|
||||
}]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_FAILURE([Failed to compile MKL test program. Make sure you set CFLAGS to include the include directory and set LDFLAGS to include the library directory and all necesarry libraries.])]
|
||||
)
|
||||
],
|
||||
[AC_MSG_FAILURE([Unknown FFT $FFT specified for --with-fft])]
|
||||
)
|
||||
AM_CONDITIONAL(BUILD_KISS_FFT, [test "$FFT" = "kiss"])
|
||||
AM_CONDITIONAL(BUILD_SMALLFT, [test "$FFT" = "smallft"])
|
||||
AC_SUBST(FFT_PKGCONFIG)
|
||||
|
||||
|
||||
AC_CHECK_SIZEOF(short)
|
||||
AC_CHECK_SIZEOF(int)
|
||||
@ -182,47 +273,28 @@ fi
|
||||
AC_SUBST(SIZE16)
|
||||
AC_SUBST(SIZE32)
|
||||
|
||||
|
||||
AC_DEFUN([AX_COMPILER_VENDOR],
|
||||
[
|
||||
AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
|
||||
[ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
|
||||
# note: don't check for gcc first since some other compilers define __GNUC__
|
||||
for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
|
||||
vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
|
||||
#if !($vencpp)
|
||||
thisisanerror;
|
||||
#endif
|
||||
])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
|
||||
done
|
||||
])
|
||||
])
|
||||
|
||||
AX_COMPILER_VENDOR
|
||||
|
||||
# Enable 64 bit build
|
||||
AC_ARG_ENABLE(64,
|
||||
[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="no"])
|
||||
|
||||
if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
|
||||
if test "${enable_64}" = "yes"; then
|
||||
CFLAGS="$CFLAGS -m64"
|
||||
CXXFLAGS="$CXXFLAGS -m64"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_OUTPUT([Makefile libspeex/Makefile src/Makefile doc/Makefile Speex.spec
|
||||
include/Makefile include/speex/Makefile speex.pc
|
||||
include/Makefile include/speex/Makefile speex.pc speexdsp.pc
|
||||
win32/Makefile win32/libspeex/Makefile win32/speexenc/Makefile
|
||||
win32/speexdec/Makefile symbian/Makefile
|
||||
win32/VS2003/Makefile win32/VS2005/Makefile
|
||||
win32/VS2003/Makefile
|
||||
win32/VS2003/tests/Makefile
|
||||
win32/VS2003/libspeex/Makefile
|
||||
win32/VS2003/libspeexdsp/Makefile
|
||||
win32/VS2003/speexdec/Makefile
|
||||
win32/VS2003/speexenc/Makefile
|
||||
win32/VS2005/Makefile
|
||||
win32/VS2005/libspeex/Makefile
|
||||
win32/VS2005/speexdec/Makefile
|
||||
win32/VS2005/speexenc/Makefile
|
||||
win32/VS2005/libspeexdsp/Makefile
|
||||
win32/VS2005/tests/Makefile
|
||||
win32/VS2008/libspeexdsp/Makefile
|
||||
win32/VS2008/Makefile
|
||||
win32/VS2008/speexdec/Makefile
|
||||
win32/VS2008/tests/Makefile
|
||||
win32/VS2008/libspeex/Makefile
|
||||
win32/VS2008/speexenc/Makefile
|
||||
include/speex/speex_config_types.h ti/Makefile
|
||||
ti/speex_C54_test/Makefile ti/speex_C55_test/Makefile
|
||||
ti/speex_C64_test/Makefile ])
|
||||
|
@ -1,5 +1,3 @@
|
||||
docdir=$(prefix)/share/doc/@PACKAGE@-@VERSION@
|
||||
|
||||
doc_DATA = manual.pdf
|
||||
|
||||
EXTRA_DIST = $(doc_DATA)
|
||||
|
Binary file not shown.
@ -3,13 +3,7 @@
|
||||
|
||||
nodist_pkginclude_HEADERS = speex_config_types.h
|
||||
|
||||
pkginclude_HEADERS = speex.h \
|
||||
speex_types.h \
|
||||
speex_bits.h \
|
||||
speex_header.h \
|
||||
speex_callbacks.h \
|
||||
speex_stereo.h \
|
||||
speex_preprocess.h \
|
||||
speex_jitter.h \
|
||||
speex_echo.h
|
||||
pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \
|
||||
speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \
|
||||
speex_stereo.h speex_types.h
|
||||
|
||||
|
@ -35,6 +35,10 @@
|
||||
|
||||
#ifndef SPEEX_H
|
||||
#define SPEEX_H
|
||||
/** @defgroup Codec Speex encoder and decoder
|
||||
* This is the Speex codec itself.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_bits.h"
|
||||
#include "speex/speex_types.h"
|
||||
@ -151,19 +155,9 @@ extern "C" {
|
||||
/** Get status of input/output high-pass filtering */
|
||||
#define SPEEX_GET_HIGHPASS 45
|
||||
|
||||
/* Used internally, NOT TO BE USED in applications */
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_PI_GAIN 100
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_EXC 101
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_INNOV 102
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_DTX_STATUS 103
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_INNOVATION_SAVE 104
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_WIDEBAND 105
|
||||
/** Get "activity level" of the last decoded frame, i.e.
|
||||
how much damage we cause if we remove the frame */
|
||||
#define SPEEX_GET_ACTIVITY 47
|
||||
|
||||
|
||||
/* Preserving compatibility:*/
|
||||
@ -218,11 +212,6 @@ extern "C" {
|
||||
/** modeID for the defined ultra-wideband mode */
|
||||
#define SPEEX_MODEID_UWB 2
|
||||
|
||||
#ifdef EPIC_48K
|
||||
/** modeID for the Epic 48K mode */
|
||||
#define SPEEX_MODEID_NB_48K 1000
|
||||
#endif
|
||||
|
||||
struct SpeexMode;
|
||||
|
||||
|
||||
@ -307,7 +296,7 @@ typedef struct SpeexMode {
|
||||
* encode, you need one state per channel.
|
||||
*
|
||||
* @param mode The mode to use (either speex_nb_mode or speex_wb.mode)
|
||||
* @return A newly created encoder
|
||||
* @return A newly created encoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_encoder_init(const SpeexMode *mode);
|
||||
|
||||
@ -318,7 +307,9 @@ void speex_encoder_destroy(void *state);
|
||||
/** Uses an existing encoder state to encode one frame of speech pointed to by
|
||||
"in". The encoded bit-stream is saved in "bits".
|
||||
@param state Encoder state
|
||||
@param in Frame that will be encoded with a +-2^15 range
|
||||
@param in Frame that will be encoded with a +-2^15 range. This data MAY be
|
||||
overwritten by the encoder and should be considered uninitialised
|
||||
after the call.
|
||||
@param bits Bit-stream where the data will be written
|
||||
@return 0 if frame needs not be transmitted (DTX only), 1 otherwise
|
||||
*/
|
||||
@ -338,7 +329,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);
|
||||
* @param state Encoder state
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_encoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
@ -349,7 +340,7 @@ int speex_encoder_ctl(void *state, int request, void *ptr);
|
||||
* decode, you need one state per channel.
|
||||
*
|
||||
* @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
|
||||
* @return A newly created decoder state
|
||||
* @return A newly created decoder state or NULL if state allocation fails
|
||||
*/
|
||||
void *speex_decoder_init(const SpeexMode *mode);
|
||||
|
||||
@ -384,7 +375,7 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);
|
||||
* @param state Decoder state
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_decoder_ctl(void *state, int request, void *ptr);
|
||||
|
||||
@ -394,12 +385,14 @@ int speex_decoder_ctl(void *state, int request, void *ptr);
|
||||
* @param mode Speex mode
|
||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
|
||||
|
||||
/** Functions for controlling the behavior of libspeex
|
||||
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown, -2 for invalid parameter
|
||||
*/
|
||||
int speex_lib_ctl(int request, void *ptr);
|
||||
|
||||
@ -412,20 +405,20 @@ extern const SpeexMode speex_wb_mode;
|
||||
/** Default "ultra-wideband" mode */
|
||||
extern const SpeexMode speex_uwb_mode;
|
||||
|
||||
#ifdef EPIC_48K
|
||||
/** 4.8 kbps narrowband mode */
|
||||
extern const SpeexMode speex_nb_48k_mode;
|
||||
#endif
|
||||
|
||||
/** List of all modes available */
|
||||
extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
|
||||
|
||||
/** Obtain one of the modes available */
|
||||
const SpeexMode * speex_lib_get_mode (int mode);
|
||||
|
||||
#ifndef WIN32
|
||||
/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */
|
||||
#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @}*/
|
||||
#endif
|
||||
|
@ -35,6 +35,11 @@
|
||||
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations
|
||||
* This is the structure that holds the bit-stream when encoding or decoding
|
||||
* with Speex. It allows some manipulations as well.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -59,6 +64,9 @@ void speex_bits_init(SpeexBits *bits);
|
||||
/** Initializes SpeexBits struct using a pre-allocated buffer*/
|
||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
|
||||
|
||||
/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */
|
||||
void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size);
|
||||
|
||||
/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
|
||||
void speex_bits_destroy(SpeexBits *bits);
|
||||
|
||||
@ -72,13 +80,20 @@ void speex_bits_rewind(SpeexBits *bits);
|
||||
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len);
|
||||
|
||||
/** Append bytes to the bit-stream
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param bytes pointer to the bytes what will be appended
|
||||
* @param len Number of bytes of append
|
||||
*/
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);
|
||||
|
||||
/** Write the content of a bit-stream to an area of memory */
|
||||
/** Write the content of a bit-stream to an area of memory
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param bytes Memory location where to write the bits
|
||||
* @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer)
|
||||
* @return Number of bytes written to the "bytes" buffer
|
||||
*/
|
||||
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len);
|
||||
|
||||
/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */
|
||||
@ -114,13 +129,19 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
|
||||
*/
|
||||
int speex_bits_nbytes(SpeexBits *bits);
|
||||
|
||||
/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */
|
||||
/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @param nbBits Number of bits to look for
|
||||
* @return Value of the bits peeked, interpreted as unsigned
|
||||
*/
|
||||
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);
|
||||
|
||||
/** Get the value of the next bit in the stream, without modifying the
|
||||
* "cursor" position
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @return Value of the bit peeked (one bit only)
|
||||
*/
|
||||
int speex_bits_peek(SpeexBits *bits);
|
||||
|
||||
@ -134,6 +155,7 @@ void speex_bits_advance(SpeexBits *bits, int n);
|
||||
/** Returns the number of bits remaining to be read in a stream
|
||||
*
|
||||
* @param bits Bit-stream to operate on
|
||||
* @return Number of bits that can still be read from the stream
|
||||
*/
|
||||
int speex_bits_remaining(SpeexBits *bits);
|
||||
|
||||
@ -148,4 +170,5 @@ void speex_bits_insert_terminator(SpeexBits *bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
#endif
|
||||
|
68
libs/speex/include/speex/speex_buffer.h
Normal file
68
libs/speex/include/speex/speex_buffer.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: speex_buffer.h
|
||||
This is a very simple ring buffer implementation. It is not thread-safe
|
||||
so you need to do your own locking.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SPEEX_BUFFER_H
|
||||
#define SPEEX_BUFFER_H
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct SpeexBuffer_;
|
||||
typedef struct SpeexBuffer_ SpeexBuffer;
|
||||
|
||||
SpeexBuffer *speex_buffer_init(int size);
|
||||
|
||||
void speex_buffer_destroy(SpeexBuffer *st);
|
||||
|
||||
int speex_buffer_write(SpeexBuffer *st, void *data, int len);
|
||||
|
||||
int speex_buffer_writezeros(SpeexBuffer *st, int len);
|
||||
|
||||
int speex_buffer_read(SpeexBuffer *st, void *data, int len);
|
||||
|
||||
int speex_buffer_get_available(SpeexBuffer *st);
|
||||
|
||||
int speex_buffer_resize(SpeexBuffer *st, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -35,6 +35,9 @@
|
||||
|
||||
#ifndef SPEEX_CALLBACKS_H
|
||||
#define SPEEX_CALLBACKS_H
|
||||
/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex.h"
|
||||
|
||||
@ -110,13 +113,16 @@ int speex_default_user_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
|
||||
|
||||
|
||||
/** Standard handler for low mode request (change low mode, no questions asked) */
|
||||
int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for VBR request (Set VBR, no questions asked) */
|
||||
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */
|
||||
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */
|
||||
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
|
||||
|
||||
@ -124,5 +130,5 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
|
@ -33,7 +33,10 @@
|
||||
|
||||
#ifndef SPEEX_ECHO_H
|
||||
#define SPEEX_ECHO_H
|
||||
|
||||
/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller
|
||||
* This is the acoustic echo canceller module.
|
||||
* @{
|
||||
*/
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -48,41 +51,120 @@ extern "C" {
|
||||
/** Get sampling rate */
|
||||
#define SPEEX_ECHO_GET_SAMPLING_RATE 25
|
||||
|
||||
/* Can't set window sizes */
|
||||
/** Get size of impulse response (int32) */
|
||||
#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27
|
||||
|
||||
/*struct drft_lookup;*/
|
||||
/* Can't set window content */
|
||||
/** Get impulse response (int32[]) */
|
||||
#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29
|
||||
|
||||
/** Internal echo canceller state. Should never be accessed directly. */
|
||||
struct SpeexEchoState_;
|
||||
|
||||
/** @class SpeexEchoState
|
||||
* This holds the state of the echo canceller. You need one per channel.
|
||||
*/
|
||||
|
||||
/** Internal echo canceller state. Should never be accessed directly. */
|
||||
typedef struct SpeexEchoState_ SpeexEchoState;
|
||||
|
||||
/** Creates a new echo canceller state */
|
||||
/** Creates a new echo canceller state
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
|
||||
* @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
|
||||
* @return Newly-created echo canceller state
|
||||
*/
|
||||
SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
|
||||
|
||||
/** Destroys an echo canceller state */
|
||||
/** Creates a new multi-channel echo canceller state
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms)
|
||||
* @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms)
|
||||
* @param nb_mic Number of microphone channels
|
||||
* @param nb_speakers Number of speaker channels
|
||||
* @return Newly-created echo canceller state
|
||||
*/
|
||||
SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers);
|
||||
|
||||
/** Destroys an echo canceller state
|
||||
* @param st Echo canceller state
|
||||
*/
|
||||
void speex_echo_state_destroy(SpeexEchoState *st);
|
||||
|
||||
/** Performs echo cancellation a frame */
|
||||
/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added
|
||||
* to playback in this form)
|
||||
*
|
||||
* @param st Echo canceller state
|
||||
* @param rec Signal from the microphone (near end + far end echo)
|
||||
* @param play Signal played to the speaker (received from far end)
|
||||
* @param out Returns near-end signal with echo removed
|
||||
*/
|
||||
void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
|
||||
|
||||
/** Performs echo cancellation a frame (deprecated) */
|
||||
void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
|
||||
|
||||
/** Perform echo cancellation using internal playback buffer */
|
||||
void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out, spx_int32_t *Yout);
|
||||
/** Perform echo cancellation using internal playback buffer, which is delayed by two frames
|
||||
* to account for the delay introduced by most soundcards (but it could be off!)
|
||||
* @param st Echo canceller state
|
||||
* @param rec Signal from the microphone (near end + far end echo)
|
||||
* @param out Returns near-end signal with echo removed
|
||||
*/
|
||||
void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
|
||||
|
||||
/** Let the echo canceller know that a frame was just played */
|
||||
/** Let the echo canceller know that a frame was just queued to the soundcard
|
||||
* @param st Echo canceller state
|
||||
* @param play Signal played to the speaker (received from far end)
|
||||
*/
|
||||
void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play);
|
||||
|
||||
/** Reset the echo canceller state */
|
||||
/** Reset the echo canceller to its original state
|
||||
* @param st Echo canceller state
|
||||
*/
|
||||
void speex_echo_state_reset(SpeexEchoState *st);
|
||||
|
||||
/** Used like the ioctl function to control the echo canceller parameters
|
||||
*
|
||||
* @param state Encoder state
|
||||
* @param st Echo canceller state
|
||||
* @param request ioctl-type request (one of the SPEEX_ECHO_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr);
|
||||
|
||||
|
||||
|
||||
struct SpeexDecorrState_;
|
||||
|
||||
typedef struct SpeexDecorrState_ SpeexDecorrState;
|
||||
|
||||
|
||||
/** Create a state for the channel decorrelation algorithm
|
||||
This is useful for multi-channel echo cancellation only
|
||||
* @param rate Sampling rate
|
||||
* @param channels Number of channels (it's a bit pointless if you don't have at least 2)
|
||||
* @param frame_size Size of the frame to process at ones (counting samples *per* channel)
|
||||
*/
|
||||
SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size);
|
||||
|
||||
/** Remove correlation between the channels by modifying the phase and possibly
|
||||
adding noise in a way that is not (or little) perceptible.
|
||||
* @param st Decorrelator state
|
||||
* @param in Input audio in interleaved format
|
||||
* @param out Result of the decorrelation (out *may* alias in)
|
||||
* @param strength How much alteration of the audio to apply from 0 to 100.
|
||||
*/
|
||||
void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength);
|
||||
|
||||
/** Destroy a Decorrelation state
|
||||
* @param st State to destroy
|
||||
*/
|
||||
void speex_decorrelate_destroy(SpeexDecorrState *st);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @}*/
|
||||
#endif
|
||||
|
@ -36,6 +36,10 @@
|
||||
|
||||
#ifndef SPEEX_HEADER_H
|
||||
#define SPEEX_HEADER_H
|
||||
/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header
|
||||
* This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
@ -45,6 +49,7 @@ extern "C" {
|
||||
|
||||
struct SpeexMode;
|
||||
|
||||
/** Length of the Speex header identifier */
|
||||
#define SPEEX_HEADER_STRING_LENGTH 8
|
||||
|
||||
/** Maximum number of characters for encoding the Speex version number in the header */
|
||||
@ -78,9 +83,12 @@ char *speex_header_to_packet(SpeexHeader *header, int *size);
|
||||
/** Creates a SpeexHeader from a packet */
|
||||
SpeexHeader *speex_packet_to_header(char *packet, int size);
|
||||
|
||||
/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */
|
||||
void speex_header_free(void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
|
@ -35,83 +35,163 @@
|
||||
|
||||
#ifndef SPEEX_JITTER_H
|
||||
#define SPEEX_JITTER_H
|
||||
/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer
|
||||
* This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size
|
||||
* to maintain good quality and low latency.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex.h"
|
||||
#include "speex_bits.h"
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Generic adaptive jitter buffer state */
|
||||
struct JitterBuffer_;
|
||||
|
||||
/** Generic adaptive jitter buffer state */
|
||||
typedef struct JitterBuffer_ JitterBuffer;
|
||||
|
||||
/** Definition of an incoming packet */
|
||||
typedef struct _JitterBufferPacket JitterBufferPacket;
|
||||
|
||||
/** Definition of an incoming packet */
|
||||
struct _JitterBufferPacket {
|
||||
char *data;
|
||||
spx_uint32_t len;
|
||||
spx_uint32_t timestamp;
|
||||
spx_uint32_t span;
|
||||
char *data; /**< Data bytes contained in the packet */
|
||||
spx_uint32_t len; /**< Length of the packet in bytes */
|
||||
spx_uint32_t timestamp; /**< Timestamp for the packet */
|
||||
spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */
|
||||
spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */
|
||||
spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */
|
||||
};
|
||||
|
||||
|
||||
/** Packet has been retrieved */
|
||||
#define JITTER_BUFFER_OK 0
|
||||
/** Packet is lost or is late */
|
||||
#define JITTER_BUFFER_MISSING 1
|
||||
#define JITTER_BUFFER_INCOMPLETE 2
|
||||
/** A "fake" packet is meant to be inserted here to increase buffering */
|
||||
#define JITTER_BUFFER_INSERTION 2
|
||||
/** There was an error in the jitter buffer */
|
||||
#define JITTER_BUFFER_INTERNAL_ERROR -1
|
||||
/** Invalid argument */
|
||||
#define JITTER_BUFFER_BAD_ARGUMENT -2
|
||||
|
||||
/** Initialise jitter buffer */
|
||||
JitterBuffer *jitter_buffer_init(int tick);
|
||||
|
||||
/** Reset jitter buffer */
|
||||
/** Set minimum amount of extra buffering required (margin) */
|
||||
#define JITTER_BUFFER_SET_MARGIN 0
|
||||
/** Get minimum amount of extra buffering required (margin) */
|
||||
#define JITTER_BUFFER_GET_MARGIN 1
|
||||
/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */
|
||||
|
||||
/** Get the amount of available packets currently buffered */
|
||||
#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3
|
||||
/** Included because of an early misspelling (will remove in next release) */
|
||||
#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3
|
||||
|
||||
/** Assign a function to destroy unused packet. When setting that, the jitter
|
||||
buffer no longer copies packet data. */
|
||||
#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4
|
||||
/** */
|
||||
#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5
|
||||
|
||||
/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */
|
||||
#define JITTER_BUFFER_SET_DELAY_STEP 6
|
||||
/** */
|
||||
#define JITTER_BUFFER_GET_DELAY_STEP 7
|
||||
|
||||
/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */
|
||||
#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8
|
||||
#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9
|
||||
|
||||
/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss
|
||||
should be half of that or less. */
|
||||
#define JITTER_BUFFER_SET_MAX_LATE_RATE 10
|
||||
#define JITTER_BUFFER_GET_MAX_LATE_RATE 11
|
||||
|
||||
/** Equivalent cost of one percent late packet in timestamp units */
|
||||
#define JITTER_BUFFER_SET_LATE_COST 12
|
||||
#define JITTER_BUFFER_GET_LATE_COST 13
|
||||
|
||||
|
||||
/** Initialises jitter buffer
|
||||
*
|
||||
* @param step_size Starting value for the size of concleanment packets and delay
|
||||
adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP
|
||||
and JITTER_BUFFER_GET_CONCEALMENT_SIZE.
|
||||
* @return Newly created jitter buffer state
|
||||
*/
|
||||
JitterBuffer *jitter_buffer_init(int step_size);
|
||||
|
||||
/** Restores jitter buffer to its original state
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_reset(JitterBuffer *jitter);
|
||||
|
||||
/** Destroy jitter buffer */
|
||||
/** Destroys jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_destroy(JitterBuffer *jitter);
|
||||
|
||||
/** Put one packet into the jitter buffer */
|
||||
/** Put one packet into the jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Incoming packet
|
||||
*/
|
||||
void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);
|
||||
|
||||
/** Get one packet from the jitter buffer */
|
||||
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *current_timestamp);
|
||||
/** Get one packet from the jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Returned packet
|
||||
* @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee)
|
||||
* @param current_timestamp Timestamp for the returned packet
|
||||
*/
|
||||
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset);
|
||||
|
||||
/** Get pointer timestamp of jitter buffer */
|
||||
/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp.
|
||||
* This is mainly useful for media where a single "frame" can be split into several packets.
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param packet Returned packet
|
||||
*/
|
||||
int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet);
|
||||
|
||||
/** Get pointer timestamp of jitter buffer
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);
|
||||
|
||||
/** Advance by one tick */
|
||||
/** Advance by one tick
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
*/
|
||||
void jitter_buffer_tick(JitterBuffer *jitter);
|
||||
|
||||
/** Telling the jitter buffer about the remaining data in the application buffer
|
||||
* @param jitter Jitter buffer state
|
||||
* @param rem Amount of data buffered by the application (timestamp units)
|
||||
*/
|
||||
void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem);
|
||||
|
||||
/** Speex jitter-buffer state. */
|
||||
typedef struct SpeexJitter {
|
||||
SpeexBits current_packet; /**< Current Speex packet */
|
||||
int valid_bits; /**< True if Speex bits are valid */
|
||||
JitterBuffer *packets;
|
||||
void *dec; /**< Pointer to Speex decoder */
|
||||
spx_int32_t frame_size; /**< Frame size of Speex decoder */
|
||||
} SpeexJitter;
|
||||
/** Used like the ioctl function to control the jitter buffer parameters
|
||||
*
|
||||
* @param jitter Jitter buffer state
|
||||
* @param request ioctl-type request (one of the JITTER_BUFFER_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);
|
||||
|
||||
/** Initialise jitter buffer */
|
||||
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate);
|
||||
int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
|
||||
|
||||
/** Destroy jitter buffer */
|
||||
void speex_jitter_destroy(SpeexJitter *jitter);
|
||||
|
||||
/** Put one packet into the jitter buffer */
|
||||
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp);
|
||||
|
||||
/** Get one packet from the jitter buffer */
|
||||
void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset);
|
||||
|
||||
/** Get pointer timestamp of jitter buffer */
|
||||
int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,10 @@
|
||||
/* Copyright (C) 2003 Epic Games
|
||||
Written by Jean-Marc Valin */
|
||||
/**
|
||||
@file speex_preprocess.h
|
||||
@brief Speex preprocessor
|
||||
* @file speex_preprocess.h
|
||||
* @brief Speex preprocessor. The preprocess can do noise suppression,
|
||||
* residual echo suppression (after using the echo canceller), automatic
|
||||
* gain control (AGC) and voice activity detection (VAD).
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -34,91 +36,61 @@
|
||||
|
||||
#ifndef SPEEX_PREPROCESS_H
|
||||
#define SPEEX_PREPROCESS_H
|
||||
/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor
|
||||
* This is the Speex preprocessor. The preprocess can do noise suppression,
|
||||
* residual echo suppression (after using the echo canceller), automatic
|
||||
* gain control (AGC) and voice activity detection (VAD).
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct drft_lookup;
|
||||
|
||||
/** Speex pre-processor state. */
|
||||
typedef struct SpeexPreprocessState {
|
||||
int frame_size; /**< Number of samples processed each time */
|
||||
int ps_size; /**< Number of points in the power spectrum */
|
||||
int sampling_rate; /**< Sampling rate of the input/output */
|
||||
|
||||
/* parameters */
|
||||
int denoise_enabled;
|
||||
int agc_enabled;
|
||||
float agc_level;
|
||||
int vad_enabled;
|
||||
int dereverb_enabled;
|
||||
float reverb_decay;
|
||||
float reverb_level;
|
||||
float speech_prob_start;
|
||||
float speech_prob_continue;
|
||||
|
||||
float *frame; /**< Processing frame (2*ps_size) */
|
||||
float *ps; /**< Current power spectrum */
|
||||
float *gain2; /**< Adjusted gains */
|
||||
float *window; /**< Analysis/Synthesis window */
|
||||
float *noise; /**< Noise estimate */
|
||||
float *reverb_estimate; /**< Estimate of reverb energy */
|
||||
float *old_ps; /**< Power spectrum for last frame */
|
||||
float *gain; /**< Ephraim Malah gain */
|
||||
float *prior; /**< A-priori SNR */
|
||||
float *post; /**< A-posteriori SNR */
|
||||
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||
struct SpeexPreprocessState_;
|
||||
|
||||
float *S; /**< Smoothed power spectrum */
|
||||
float *Smin; /**< See Cohen paper */
|
||||
float *Stmp; /**< See Cohen paper */
|
||||
float *update_prob; /**< Propability of speech presence for noise update */
|
||||
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||
typedef struct SpeexPreprocessState_ SpeexPreprocessState;
|
||||
|
||||
float *zeta; /**< Smoothed a priori SNR */
|
||||
float Zpeak;
|
||||
float Zlast;
|
||||
|
||||
float *loudness_weight; /**< Perceptual loudness curve */
|
||||
|
||||
float *echo_noise;
|
||||
|
||||
float *noise_bands;
|
||||
float *noise_bands2;
|
||||
int noise_bandsN;
|
||||
float *speech_bands;
|
||||
float *speech_bands2;
|
||||
int speech_bandsN;
|
||||
|
||||
float *inbuf; /**< Input buffer (overlapped analysis) */
|
||||
float *outbuf; /**< Output buffer (for overlap and add) */
|
||||
|
||||
float speech_prob;
|
||||
int last_speech;
|
||||
float loudness; /**< loudness estimate */
|
||||
float loudness2; /**< loudness estimate */
|
||||
int nb_adapt; /**< Number of frames used for adaptation so far */
|
||||
int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */
|
||||
int consec_noise; /**< Number of consecutive noise frames */
|
||||
int nb_preprocess; /**< Number of frames processed so far */
|
||||
struct drft_lookup *fft_lookup; /**< Lookup table for the FFT */
|
||||
|
||||
} SpeexPreprocessState;
|
||||
|
||||
/** Creates a new preprocessing state */
|
||||
/** Creates a new preprocessing state. You MUST create one state per channel processed.
|
||||
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be
|
||||
* the same value as that used for the echo canceller for residual echo cancellation to work.
|
||||
* @param sampling_rate Sampling rate used for the input.
|
||||
* @return Newly created preprocessor state
|
||||
*/
|
||||
SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);
|
||||
|
||||
/** Destroys a denoising state */
|
||||
/** Destroys a preprocessor state
|
||||
* @param st Preprocessor state to destroy
|
||||
*/
|
||||
void speex_preprocess_state_destroy(SpeexPreprocessState *st);
|
||||
|
||||
/** Preprocess a frame */
|
||||
/** Preprocess a frame
|
||||
* @param st Preprocessor state
|
||||
* @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init().
|
||||
* @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on.
|
||||
*/
|
||||
int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x);
|
||||
|
||||
/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/
|
||||
int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
|
||||
|
||||
/** Preprocess a frame */
|
||||
void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
|
||||
/** Update preprocessor state, but do not compute the output
|
||||
* @param st Preprocessor state
|
||||
* @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init().
|
||||
*/
|
||||
void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x);
|
||||
|
||||
/** Used like the ioctl function to control the preprocessor parameters */
|
||||
/** Used like the ioctl function to control the preprocessor parameters
|
||||
* @param st Preprocessor state
|
||||
* @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros)
|
||||
* @param ptr Data exchanged to-from function
|
||||
* @return 0 if no error, -1 if request in unknown
|
||||
*/
|
||||
int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
|
||||
|
||||
|
||||
@ -138,9 +110,9 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
|
||||
/** Get preprocessor Voice Activity Detection state */
|
||||
#define SPEEX_PREPROCESS_GET_VAD 5
|
||||
|
||||
/** Set preprocessor Automatic Gain Control level */
|
||||
/** Set preprocessor Automatic Gain Control level (float) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6
|
||||
/** Get preprocessor Automatic Gain Control level */
|
||||
/** Get preprocessor Automatic Gain Control level (float) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7
|
||||
|
||||
/** Set preprocessor dereverb state */
|
||||
@ -158,14 +130,90 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
|
||||
/** Get preprocessor dereverb decay */
|
||||
#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13
|
||||
|
||||
/** Set probability required for the VAD to go from silence to voice */
|
||||
#define SPEEX_PREPROCESS_SET_PROB_START 14
|
||||
/** Get probability required for the VAD to go from silence to voice */
|
||||
#define SPEEX_PREPROCESS_GET_PROB_START 15
|
||||
|
||||
/** Set probability required for the VAD to stay in the voice state (integer percent) */
|
||||
#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16
|
||||
/** Get probability required for the VAD to stay in the voice state (integer percent) */
|
||||
#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17
|
||||
|
||||
/** Set maximum attenuation of the noise in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18
|
||||
/** Get maximum attenuation of the noise in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19
|
||||
|
||||
/** Set maximum attenuation of the residual echo in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20
|
||||
/** Get maximum attenuation of the residual echo in dB (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21
|
||||
|
||||
/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22
|
||||
/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23
|
||||
|
||||
/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */
|
||||
#define SPEEX_PREPROCESS_SET_ECHO_STATE 24
|
||||
/** Get the corresponding echo canceller state */
|
||||
#define SPEEX_PREPROCESS_GET_ECHO_STATE 25
|
||||
|
||||
/** Set maximal gain increase in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26
|
||||
|
||||
/** Get maximal gain increase in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27
|
||||
|
||||
/** Set maximal gain decrease in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28
|
||||
|
||||
/** Get maximal gain decrease in dB/second (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29
|
||||
|
||||
/** Set maximal gain in dB (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30
|
||||
|
||||
/** Get maximal gain in dB (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31
|
||||
|
||||
/* Can't set loudness */
|
||||
/** Get loudness */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33
|
||||
|
||||
/* Can't set gain */
|
||||
/** Get current gain (int32 percent) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_GAIN 35
|
||||
|
||||
/* Can't set spectrum size */
|
||||
/** Get spectrum size for power spectrum (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_PSD_SIZE 37
|
||||
|
||||
/* Can't set power spectrum */
|
||||
/** Get power spectrum (int32[] of squared values) */
|
||||
#define SPEEX_PREPROCESS_GET_PSD 39
|
||||
|
||||
/* Can't set noise size */
|
||||
/** Get spectrum size for noise estimate (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41
|
||||
|
||||
/* Can't set noise estimate */
|
||||
/** Get noise estimate (int32[] of squared values) */
|
||||
#define SPEEX_PREPROCESS_GET_NOISE_PSD 43
|
||||
|
||||
/* Can't set speech probability */
|
||||
/** Get speech probability in last frame (int32). */
|
||||
#define SPEEX_PREPROCESS_GET_PROB 45
|
||||
|
||||
/** Set preprocessor Automatic Gain Control level (int32) */
|
||||
#define SPEEX_PREPROCESS_SET_AGC_TARGET 46
|
||||
/** Get preprocessor Automatic Gain Control level (int32) */
|
||||
#define SPEEX_PREPROCESS_GET_AGC_TARGET 47
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
#endif
|
||||
|
340
libs/speex/include/speex/speex_resampler.h
Normal file
340
libs/speex/include/speex/speex_resampler.h
Normal file
@ -0,0 +1,340 @@
|
||||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: speex_resampler.h
|
||||
Resampling code
|
||||
|
||||
The design goals of this code are:
|
||||
- Very fast algorithm
|
||||
- Low memory requirement
|
||||
- Good *perceptual* quality (and not best SNR)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SPEEX_RESAMPLER_H
|
||||
#define SPEEX_RESAMPLER_H
|
||||
|
||||
#ifdef OUTSIDE_SPEEX
|
||||
|
||||
/********* WARNING: MENTAL SANITY ENDS HERE *************/
|
||||
|
||||
/* If the resampler is defined outside of Speex, we change the symbol names so that
|
||||
there won't be any clash if linking with Speex later on. */
|
||||
|
||||
/* #define RANDOM_PREFIX your software name here */
|
||||
#ifndef RANDOM_PREFIX
|
||||
#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
|
||||
#endif
|
||||
|
||||
#define CAT_PREFIX2(a,b) a ## b
|
||||
#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
|
||||
|
||||
#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
|
||||
#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
|
||||
#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
|
||||
#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
|
||||
#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
|
||||
#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
|
||||
#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
|
||||
#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
|
||||
#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
|
||||
#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
|
||||
#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
|
||||
#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
|
||||
#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
|
||||
#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
|
||||
#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
|
||||
#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
|
||||
#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
|
||||
#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
|
||||
#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
|
||||
#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
|
||||
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
|
||||
#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
|
||||
|
||||
#define spx_int16_t short
|
||||
#define spx_int32_t int
|
||||
#define spx_uint16_t unsigned short
|
||||
#define spx_uint32_t unsigned int
|
||||
|
||||
#else /* OUTSIDE_SPEEX */
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
#endif /* OUTSIDE_SPEEX */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPEEX_RESAMPLER_QUALITY_MAX 10
|
||||
#define SPEEX_RESAMPLER_QUALITY_MIN 0
|
||||
#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
|
||||
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
|
||||
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
|
||||
|
||||
enum {
|
||||
RESAMPLER_ERR_SUCCESS = 0,
|
||||
RESAMPLER_ERR_ALLOC_FAILED = 1,
|
||||
RESAMPLER_ERR_BAD_STATE = 2,
|
||||
RESAMPLER_ERR_INVALID_ARG = 3,
|
||||
RESAMPLER_ERR_PTR_OVERLAP = 4,
|
||||
|
||||
RESAMPLER_ERR_MAX_ERROR
|
||||
};
|
||||
|
||||
struct SpeexResamplerState_;
|
||||
typedef struct SpeexResamplerState_ SpeexResamplerState;
|
||||
|
||||
/** Create a new resampler with integer input and output rates.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Create a new resampler with fractional input/output rates. The sampling
|
||||
* rate ratio is an arbitrary rational number with both the numerator and
|
||||
* denominator being 32-bit integers.
|
||||
* @param nb_channels Number of channels to be processed
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
|
||||
* and 10 has very high quality.
|
||||
* @return Newly created resampler state
|
||||
* @retval NULL Error: not enough memory
|
||||
*/
|
||||
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate,
|
||||
int quality,
|
||||
int *err);
|
||||
|
||||
/** Destroy a resampler state.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
void speex_resampler_destroy(SpeexResamplerState *st);
|
||||
|
||||
/** Resample a float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the
|
||||
* number of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_float(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param channel_index Index of the channel to process for the multi-channel
|
||||
* base (0 otherwise)
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written
|
||||
*/
|
||||
int speex_resampler_process_int(SpeexResamplerState *st,
|
||||
spx_uint32_t channel_index,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
|
||||
const float *in,
|
||||
spx_uint32_t *in_len,
|
||||
float *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
|
||||
* @param st Resampler state
|
||||
* @param in Input buffer
|
||||
* @param in_len Number of input samples in the input buffer. Returns the number
|
||||
* of samples processed. This is all per-channel.
|
||||
* @param out Output buffer
|
||||
* @param out_len Size of the output buffer. Returns the number of samples written.
|
||||
* This is all per-channel.
|
||||
*/
|
||||
int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
|
||||
const spx_int16_t *in,
|
||||
spx_uint32_t *in_len,
|
||||
spx_int16_t *out,
|
||||
spx_uint32_t *out_len);
|
||||
|
||||
/** Set (change) the input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz).
|
||||
* @param out_rate Output sampling rate (integer number of Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current input/output sampling rates (integer value).
|
||||
* @param st Resampler state
|
||||
* @param in_rate Input sampling rate (integer number of Hz) copied.
|
||||
* @param out_rate Output sampling rate (integer number of Hz) copied.
|
||||
*/
|
||||
void speex_resampler_get_rate(SpeexResamplerState *st,
|
||||
spx_uint32_t *in_rate,
|
||||
spx_uint32_t *out_rate);
|
||||
|
||||
/** Set (change) the input/output sampling rates and resampling ratio
|
||||
* (fractional values in Hz supported).
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio
|
||||
* @param ratio_den Denominator of the sampling rate ratio
|
||||
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
|
||||
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
|
||||
*/
|
||||
int speex_resampler_set_rate_frac(SpeexResamplerState *st,
|
||||
spx_uint32_t ratio_num,
|
||||
spx_uint32_t ratio_den,
|
||||
spx_uint32_t in_rate,
|
||||
spx_uint32_t out_rate);
|
||||
|
||||
/** Get the current resampling ratio. This will be reduced to the least
|
||||
* common denominator.
|
||||
* @param st Resampler state
|
||||
* @param ratio_num Numerator of the sampling rate ratio copied
|
||||
* @param ratio_den Denominator of the sampling rate ratio copied
|
||||
*/
|
||||
void speex_resampler_get_ratio(SpeexResamplerState *st,
|
||||
spx_uint32_t *ratio_num,
|
||||
spx_uint32_t *ratio_den);
|
||||
|
||||
/** Set (change) the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
int speex_resampler_set_quality(SpeexResamplerState *st,
|
||||
int quality);
|
||||
|
||||
/** Get the conversion quality.
|
||||
* @param st Resampler state
|
||||
* @param quality Resampling quality between 0 and 10, where 0 has poor
|
||||
* quality and 10 has very high quality.
|
||||
*/
|
||||
void speex_resampler_get_quality(SpeexResamplerState *st,
|
||||
int *quality);
|
||||
|
||||
/** Set (change) the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride
|
||||
*/
|
||||
void speex_resampler_set_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the input stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Input stride copied
|
||||
*/
|
||||
void speex_resampler_get_input_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Set (change) the output stride.
|
||||
* @param st Resampler state
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_set_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t stride);
|
||||
|
||||
/** Get the output stride.
|
||||
* @param st Resampler state copied
|
||||
* @param stride Output stride
|
||||
*/
|
||||
void speex_resampler_get_output_stride(SpeexResamplerState *st,
|
||||
spx_uint32_t *stride);
|
||||
|
||||
/** Get the latency in input samples introduced by the resampler.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_input_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Get the latency in output samples introduced by the resampler.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_get_output_latency(SpeexResamplerState *st);
|
||||
|
||||
/** Make sure that the first samples to go out of the resamplers don't have
|
||||
* leading zeros. This is only useful before starting to use a newly created
|
||||
* resampler. It is recommended to use that when resampling an audio file, as
|
||||
* it will generate a file with the same length. For real-time processing,
|
||||
* it is probably easier not to use this call (so that the output duration
|
||||
* is the same for the first frame).
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_skip_zeros(SpeexResamplerState *st);
|
||||
|
||||
/** Reset a resampler so a new (unrelated) stream can be processed.
|
||||
* @param st Resampler state
|
||||
*/
|
||||
int speex_resampler_reset_mem(SpeexResamplerState *st);
|
||||
|
||||
/** Returns the English meaning for an error code
|
||||
* @param err Error code
|
||||
* @return English string
|
||||
*/
|
||||
const char *speex_resampler_strerror(int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -34,6 +34,10 @@
|
||||
|
||||
#ifndef STEREO_H
|
||||
#define STEREO_H
|
||||
/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files
|
||||
* This describes the Speex intensity stereo encoding/decoding
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "speex/speex_types.h"
|
||||
#include "speex/speex_bits.h"
|
||||
@ -42,7 +46,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** State used for decoding (intensity) stereo information */
|
||||
/** If you access any of these fields directly, I'll personally come and bite you */
|
||||
typedef struct SpeexStereoState {
|
||||
float balance; /**< Left/right balance info */
|
||||
float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
|
||||
@ -52,9 +56,18 @@ typedef struct SpeexStereoState {
|
||||
float reserved2; /**< Reserved for future use */
|
||||
} SpeexStereoState;
|
||||
|
||||
/** Initialization value for a stereo state */
|
||||
/** Deprecated. Use speex_stereo_state_init() instead. */
|
||||
#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}
|
||||
|
||||
/** Initialise/create a stereo stereo state */
|
||||
SpeexStereoState *speex_stereo_state_init();
|
||||
|
||||
/** Reset/re-initialise an already allocated stereo state */
|
||||
void speex_stereo_state_reset(SpeexStereoState *stereo);
|
||||
|
||||
/** Destroy a stereo stereo state */
|
||||
void speex_stereo_state_destroy(SpeexStereoState *stereo);
|
||||
|
||||
/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
|
||||
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
|
||||
|
||||
@ -74,5 +87,5 @@ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
|
@ -31,10 +31,10 @@
|
||||
typedef _G_int16_t spx_int16_t;
|
||||
typedef _G_uint16_t spx_uint16_t;
|
||||
# elif defined(__MINGW32__)
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
typedef short spx_int16_t;
|
||||
typedef unsigned short spx_uint16_t;
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef int spx_int32_t;
|
||||
typedef unsigned int spx_uint32_t;
|
||||
@ -56,7 +56,7 @@
|
||||
typedef SInt32 spx_int32_t;
|
||||
typedef UInt32 spx_uint32_t;
|
||||
|
||||
#elif defined(__MACOSX__) /* MacOS X Framework build */
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef int16_t spx_int16_t;
|
||||
|
@ -2,41 +2,54 @@
|
||||
#AUTOMAKE_OPTIONS = no-dependencies
|
||||
|
||||
|
||||
EXTRA_DIST=testenc.c testenc_wb.c testenc_uwb.c testdenoise.c testecho.c
|
||||
EXTRA_DIST=echo_diagnostic.m
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir)
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@ @FFT_CFLAGS@
|
||||
|
||||
lib_LTLIBRARIES = libspeex.la
|
||||
lib_LTLIBRARIES = libspeex.la libspeexdsp.la
|
||||
|
||||
# Sources for compilation in the library
|
||||
libspeex_la_SOURCES = nb_celp.c sb_celp.c lpc.c ltp.c lsp.c quant_lsp.c \
|
||||
lsp_tables_nb.c gain_table.c gain_table_lbr.c cb_search.c filters.c bits.c \
|
||||
modes.c speex.c vq.c high_lsp_tables.c vbr.c hexc_table.c \
|
||||
exc_5_256_table.c exc_5_64_table.c exc_8_128_table.c exc_10_32_table.c \
|
||||
exc_10_16_table.c exc_20_32_table.c hexc_10_32_table.c misc.c speex_header.c \
|
||||
speex_callbacks.c math_approx.c stereo.c preprocess.c smallft.c lbr_48k_tables.c \
|
||||
jitter.c mdf.c vorbis_psy.c fftwrap.c kiss_fft.c _kiss_fft_guts.h kiss_fft.h \
|
||||
kiss_fftr.c kiss_fftr.h window.c
|
||||
libspeex_la_SOURCES = cb_search.c exc_10_32_table.c exc_8_128_table.c \
|
||||
filters.c gain_table.c hexc_table.c high_lsp_tables.c lsp.c \
|
||||
ltp.c speex.c stereo.c vbr.c vq.c bits.c exc_10_16_table.c \
|
||||
exc_20_32_table.c exc_5_256_table.c exc_5_64_table.c gain_table_lbr.c hexc_10_32_table.c \
|
||||
lpc.c lsp_tables_nb.c modes.c modes_wb.c nb_celp.c quant_lsp.c sb_celp.c \
|
||||
speex_callbacks.c speex_header.c window.c
|
||||
|
||||
noinst_HEADERS = lsp.h nb_celp.h lpc.h lpc_bfin.h ltp.h quant_lsp.h \
|
||||
cb_search.h filters.h stack_alloc.h vq.h vq_sse.h vq_arm4.h vq_bfin.h \
|
||||
modes.h sb_celp.h vbr.h misc.h misc_bfin.h ltp_sse.h ltp_arm4.h \
|
||||
ltp_bfin.h filters_sse.h filters_arm4.h filters_bfin.h math_approx.h \
|
||||
smallft.h arch.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h \
|
||||
fixed_generic.h cb_search_sse.h cb_search_arm4.h cb_search_bfin.h vorbis_psy.h \
|
||||
fftwrap.h pseudofloat.h lsp_bfin.h quant_lsp_bfin.h
|
||||
if BUILD_KISS_FFT
|
||||
FFTSRC=kiss_fft.c _kiss_fft_guts.h kiss_fft.h kiss_fftr.c kiss_fftr.h
|
||||
else
|
||||
if BUILD_SMALLFT
|
||||
FFTSRC=smallft.c
|
||||
else
|
||||
FFTSRC=
|
||||
endif
|
||||
endif
|
||||
|
||||
libspeexdsp_la_SOURCES = preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c buffer.c scal.c $(FFTSRC)
|
||||
|
||||
noinst_HEADERS = arch.h cb_search_arm4.h cb_search_bfin.h cb_search_sse.h \
|
||||
filters.h filters_arm4.h filters_bfin.h filters_sse.h fixed_arm4.h \
|
||||
fixed_arm5e.h fixed_bfin.h fixed_debug.h lpc.h lpc_bfin.h ltp.h ltp_arm4.h \
|
||||
ltp_sse.h math_approx.h misc_bfin.h nb_celp.h quant_lsp.h sb_celp.h \
|
||||
stack_alloc.h vbr.h vq.h vq_arm4.h vq_bfin.h vq_sse.h cb_search.h fftwrap.h \
|
||||
filterbank.h fixed_generic.h lsp.h lsp_bfin.h ltp_bfin.h modes.h os_support.h \
|
||||
pseudofloat.h quant_lsp_bfin.h smallft.h vorbis_psy.h resample_sse.h
|
||||
|
||||
|
||||
libspeex_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@
|
||||
libspeexdsp_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@
|
||||
|
||||
noinst_PROGRAMS = testenc testenc_wb testenc_uwb testdenoise testecho
|
||||
noinst_PROGRAMS = testenc testenc_wb testenc_uwb testdenoise testecho testjitter
|
||||
testenc_SOURCES = testenc.c
|
||||
testenc_LDADD = $(top_builddir)/libspeex/libspeex.la
|
||||
testenc_LDADD = libspeex.la
|
||||
testenc_wb_SOURCES = testenc_wb.c
|
||||
testenc_wb_LDADD = $(top_builddir)/libspeex/libspeex.la
|
||||
testenc_wb_LDADD = libspeex.la
|
||||
testenc_uwb_SOURCES = testenc_uwb.c
|
||||
testenc_uwb_LDADD = $(top_builddir)/libspeex/libspeex.la
|
||||
testenc_uwb_LDADD = libspeex.la
|
||||
testdenoise_SOURCES = testdenoise.c
|
||||
testdenoise_LDADD = $(top_builddir)/libspeex/libspeex.la
|
||||
testdenoise_LDADD = libspeexdsp.la @FFT_LIBS@
|
||||
testecho_SOURCES = testecho.c
|
||||
testecho_LDADD = $(top_builddir)/libspeex/libspeex.la
|
||||
testecho_LDADD = libspeexdsp.la @FFT_LIBS@
|
||||
testjitter_SOURCES = testjitter.c
|
||||
testjitter_LDADD = libspeexdsp.la @FFT_LIBS@
|
||||
|
@ -20,6 +20,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
and defines
|
||||
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
|
||||
#include "kiss_fft.h"
|
||||
#include "math_approx.h"
|
||||
|
||||
#define MAXFACTORS 32
|
||||
/* e.g. an fft of length 128 has 4 factors
|
||||
@ -44,7 +45,7 @@ struct kiss_fft_state{
|
||||
C_ADDTO( res , a) : res += a
|
||||
* */
|
||||
#ifdef FIXED_POINT
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
# define FRACBITS 15
|
||||
# define SAMPPROD spx_int32_t
|
||||
#define SAMP_MAX 32767
|
||||
@ -67,6 +68,10 @@ struct kiss_fft_state{
|
||||
do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
|
||||
(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
|
||||
|
||||
# define C_MUL4(m,a,b) \
|
||||
do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \
|
||||
(m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0)
|
||||
|
||||
# define DIVSCALAR(x,k) \
|
||||
(x) = sround( smul( x, SAMP_MAX/k ) )
|
||||
|
||||
@ -84,6 +89,9 @@ struct kiss_fft_state{
|
||||
#define C_MUL(m,a,b) \
|
||||
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
|
||||
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
|
||||
|
||||
#define C_MUL4(m,a,b) C_MUL(m,a,b)
|
||||
|
||||
# define C_FIXDIV(c,div) /* NOOP */
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r *= (s);\
|
||||
@ -140,6 +148,11 @@ struct kiss_fft_state{
|
||||
(x)->r = KISS_FFT_COS(phase);\
|
||||
(x)->i = KISS_FFT_SIN(phase);\
|
||||
}while(0)
|
||||
#define kf_cexp2(x,phase) \
|
||||
do{ \
|
||||
(x)->r = spx_cos_norm((phase));\
|
||||
(x)->i = spx_cos_norm((phase)-32768);\
|
||||
}while(0)
|
||||
|
||||
|
||||
/* a debugging function */
|
||||
|
@ -35,12 +35,55 @@
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
#ifndef SPEEX_VERSION
|
||||
#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
|
||||
#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
|
||||
#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */
|
||||
#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
|
||||
#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */
|
||||
#endif
|
||||
|
||||
/* A couple test to catch stupid option combinations */
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
#error You cannot compile as floating point and fixed point at the same time
|
||||
#endif
|
||||
#ifdef _USE_SSE
|
||||
#error SSE is only for floating-point
|
||||
#endif
|
||||
#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
|
||||
#error Make up your mind. What CPU do you have?
|
||||
#endif
|
||||
#ifdef VORBIS_PSYCHO
|
||||
#error Vorbis-psy model currently not implemented in fixed-point
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef FLOATING_POINT
|
||||
#error You now need to define either FIXED_POINT or FLOATING_POINT
|
||||
#endif
|
||||
#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
|
||||
#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
|
||||
#endif
|
||||
#ifdef FIXED_POINT_DEBUG
|
||||
#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OUTSIDE_SPEEX
|
||||
#include "speex/speex_types.h"
|
||||
#endif
|
||||
|
||||
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
|
||||
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
|
||||
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
|
||||
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
@ -64,10 +107,12 @@ typedef spx_word32_t spx_sig_t;
|
||||
#define LPC_SHIFT 13
|
||||
#define LSP_SHIFT 13
|
||||
#define SIG_SHIFT 14
|
||||
#define GAIN_SHIFT 6
|
||||
|
||||
#define VERY_SMALL 0
|
||||
#define VERY_LARGE32 ((spx_word32_t)2147483647)
|
||||
#define VERY_LARGE16 ((spx_word16_t)32767)
|
||||
#define Q15_ONE ((spx_word16_t)32767)
|
||||
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
@ -80,8 +125,6 @@ typedef spx_word32_t spx_sig_t;
|
||||
#include "fixed_arm5e.h"
|
||||
#elif defined (ARM4_ASM)
|
||||
#include "fixed_arm4.h"
|
||||
#elif defined (ARM5E_ASM)
|
||||
#include "fixed_arm5e.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#include "fixed_bfin.h"
|
||||
#endif
|
||||
@ -106,13 +149,11 @@ typedef float spx_word32_t;
|
||||
#define GAIN_SCALING 1.f
|
||||
#define GAIN_SCALING_1 1.f
|
||||
|
||||
#define LPC_SHIFT 0
|
||||
#define LSP_SHIFT 0
|
||||
#define SIG_SHIFT 0
|
||||
|
||||
#define VERY_SMALL 1e-15f
|
||||
#define VERY_LARGE32 1e15f
|
||||
#define VERY_LARGE16 1e15f
|
||||
#define Q15_ONE ((spx_word16_t)1.f)
|
||||
|
||||
#define QCONST16(x,bits) (x)
|
||||
#define QCONST32(x,bits) (x)
|
||||
@ -127,6 +168,7 @@ typedef float spx_word32_t;
|
||||
#define SHL32(a,shift) (a)
|
||||
#define PSHR16(a,shift) (a)
|
||||
#define PSHR32(a,shift) (a)
|
||||
#define VSHR32(a,shift) (a)
|
||||
#define SATURATE16(x,a) (x)
|
||||
#define SATURATE32(x,a) (x)
|
||||
|
||||
@ -147,6 +189,7 @@ typedef float spx_word32_t;
|
||||
#define MULT16_32_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_32_P15(a,b) ((a)*(b))
|
||||
|
||||
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||
@ -186,4 +229,11 @@ typedef float spx_word32_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
extern long long spx_mips;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -37,14 +37,15 @@
|
||||
#endif
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/* Maximum size of the bit-stream (for fixed-size allocation) */
|
||||
#ifndef MAX_CHARS_PER_FRAME
|
||||
#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
|
||||
#endif
|
||||
|
||||
void speex_bits_init(SpeexBits *bits)
|
||||
EXPORT void speex_bits_init(SpeexBits *bits)
|
||||
{
|
||||
bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
|
||||
if (!bits->chars)
|
||||
@ -57,7 +58,7 @@ void speex_bits_init(SpeexBits *bits)
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
bits->chars = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
@ -67,15 +68,30 @@ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
speex_bits_reset(bits);
|
||||
}
|
||||
|
||||
void speex_bits_destroy(SpeexBits *bits)
|
||||
EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
bits->chars = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
|
||||
bits->owner=0;
|
||||
|
||||
bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
|
||||
}
|
||||
|
||||
EXPORT void speex_bits_destroy(SpeexBits *bits)
|
||||
{
|
||||
if (bits->owner)
|
||||
speex_free(bits->chars);
|
||||
/* Will do something once the allocation is dynamic */
|
||||
}
|
||||
|
||||
void speex_bits_reset(SpeexBits *bits)
|
||||
EXPORT void speex_bits_reset(SpeexBits *bits)
|
||||
{
|
||||
/* We only need to clear the first byte now */
|
||||
bits->chars[0]=0;
|
||||
bits->nbBits=0;
|
||||
bits->charPtr=0;
|
||||
@ -83,20 +99,20 @@ void speex_bits_reset(SpeexBits *bits)
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_rewind(SpeexBits *bits)
|
||||
EXPORT void speex_bits_rewind(SpeexBits *bits)
|
||||
{
|
||||
bits->charPtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
|
||||
EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
|
||||
{
|
||||
int i;
|
||||
int nchars = len / BYTES_PER_CHAR;
|
||||
if (nchars > bits->buf_size)
|
||||
{
|
||||
speex_warning_int("Packet is larger than allocated buffer: ", len);
|
||||
speex_notify("Packet is larger than allocated buffer");
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->chars, nchars);
|
||||
@ -109,7 +125,7 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating input");
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
@ -130,18 +146,14 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
|
||||
|
||||
static void speex_bits_flush(SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
if (bits->charPtr>0)
|
||||
{
|
||||
for (i=bits->charPtr;i<nchars; i++)
|
||||
bits->chars[i-bits->charPtr]=bits->chars[i];
|
||||
}
|
||||
SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
|
||||
bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
|
||||
bits->charPtr=0;
|
||||
}
|
||||
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
|
||||
EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
|
||||
{
|
||||
int i,pos;
|
||||
int nchars = nbytes/BYTES_PER_CHAR;
|
||||
@ -158,10 +170,10 @@ void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
speex_warning("Could not resize input buffer: truncating oversize input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating input");
|
||||
speex_warning("Do not own input buffer: truncating oversize input");
|
||||
nchars=bits->buf_size;
|
||||
}
|
||||
}
|
||||
@ -173,7 +185,7 @@ void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
|
||||
bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
|
||||
}
|
||||
|
||||
int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
{
|
||||
int i;
|
||||
int max_nchars = max_nbytes/BYTES_PER_CHAR;
|
||||
@ -196,7 +208,7 @@ int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
return max_nchars*BYTES_PER_CHAR;
|
||||
}
|
||||
|
||||
int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
EXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
{
|
||||
int max_nchars = max_nbytes/BYTES_PER_CHAR;
|
||||
int i;
|
||||
@ -209,27 +221,24 @@ int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
|
||||
bits->chars[0]=bits->chars[max_nchars];
|
||||
else
|
||||
bits->chars[0]=0;
|
||||
for (i=1;i<((bits->nbBits)>>LOG2_BITS_PER_CHAR)+1;i++)
|
||||
bits->chars[i]=0;
|
||||
bits->charPtr=0;
|
||||
bits->nbBits &= (BITS_PER_CHAR-1);
|
||||
return max_nchars*BYTES_PER_CHAR;
|
||||
}
|
||||
|
||||
void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
{
|
||||
unsigned int d=data;
|
||||
|
||||
if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
|
||||
{
|
||||
speex_warning("Buffer too small to pack bits");
|
||||
speex_notify("Buffer too small to pack bits");
|
||||
if (bits->owner)
|
||||
{
|
||||
int new_nchars = ((bits->buf_size+5)*3)>>1;
|
||||
int new_nchars = ((bits->buf_size+5)*3)>>1;
|
||||
char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
|
||||
if (tmp)
|
||||
{
|
||||
speex_memset_bytes(tmp, 0, new_nchars);
|
||||
bits->buf_size=new_nchars;
|
||||
bits->chars=tmp;
|
||||
} else {
|
||||
@ -260,7 +269,7 @@ void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
}
|
||||
}
|
||||
|
||||
int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
||||
EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
|
||||
/* If number is negative */
|
||||
@ -271,7 +280,7 @@ int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
@ -293,7 +302,7 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
int bitPtr, charPtr;
|
||||
@ -322,7 +331,7 @@ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
return d;
|
||||
}
|
||||
|
||||
int speex_bits_peek(SpeexBits *bits)
|
||||
EXPORT int speex_bits_peek(SpeexBits *bits)
|
||||
{
|
||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
@ -331,7 +340,7 @@ int speex_bits_peek(SpeexBits *bits)
|
||||
return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
|
||||
}
|
||||
|
||||
void speex_bits_advance(SpeexBits *bits, int n)
|
||||
EXPORT void speex_bits_advance(SpeexBits *bits, int n)
|
||||
{
|
||||
if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
|
||||
bits->overflow=1;
|
||||
@ -341,7 +350,7 @@ void speex_bits_advance(SpeexBits *bits, int n)
|
||||
bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */
|
||||
}
|
||||
|
||||
int speex_bits_remaining(SpeexBits *bits)
|
||||
EXPORT int speex_bits_remaining(SpeexBits *bits)
|
||||
{
|
||||
if (bits->overflow)
|
||||
return -1;
|
||||
@ -349,12 +358,12 @@ int speex_bits_remaining(SpeexBits *bits)
|
||||
return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
|
||||
}
|
||||
|
||||
int speex_bits_nbytes(SpeexBits *bits)
|
||||
EXPORT int speex_bits_nbytes(SpeexBits *bits)
|
||||
{
|
||||
return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||
}
|
||||
|
||||
void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
EXPORT void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
{
|
||||
if (bits->bitPtr)
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
|
176
libs/speex/libspeex/buffer.c
Normal file
176
libs/speex/libspeex/buffer.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: buffer.c
|
||||
This is a very simple ring buffer implementation. It is not thread-safe
|
||||
so you need to do your own locking.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "os_support.h"
|
||||
#include "arch.h"
|
||||
#include <speex/speex_buffer.h>
|
||||
|
||||
struct SpeexBuffer_ {
|
||||
char *data;
|
||||
int size;
|
||||
int read_ptr;
|
||||
int write_ptr;
|
||||
int available;
|
||||
};
|
||||
|
||||
EXPORT SpeexBuffer *speex_buffer_init(int size)
|
||||
{
|
||||
SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer));
|
||||
st->data = speex_alloc(size);
|
||||
st->size = size;
|
||||
st->read_ptr = 0;
|
||||
st->write_ptr = 0;
|
||||
st->available = 0;
|
||||
return st;
|
||||
}
|
||||
|
||||
EXPORT void speex_buffer_destroy(SpeexBuffer *st)
|
||||
{
|
||||
speex_free(st->data);
|
||||
speex_free(st);
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len)
|
||||
{
|
||||
int end;
|
||||
int end1;
|
||||
char *data = _data;
|
||||
if (len > st->size)
|
||||
{
|
||||
data += len-st->size;
|
||||
len = st->size;
|
||||
}
|
||||
end = st->write_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr);
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_COPY(st->data, data+end1 - st->write_ptr, end);
|
||||
}
|
||||
st->available += len;
|
||||
if (st->available > st->size)
|
||||
{
|
||||
st->available = st->size;
|
||||
st->read_ptr = st->write_ptr;
|
||||
}
|
||||
st->write_ptr += len;
|
||||
if (st->write_ptr > st->size)
|
||||
st->write_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len)
|
||||
{
|
||||
/* This is almost the same as for speex_buffer_write() but using
|
||||
SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */
|
||||
int end;
|
||||
int end1;
|
||||
if (len > st->size)
|
||||
{
|
||||
len = st->size;
|
||||
}
|
||||
end = st->write_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr);
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_MEMSET(st->data, 0, end);
|
||||
}
|
||||
st->available += len;
|
||||
if (st->available > st->size)
|
||||
{
|
||||
st->available = st->size;
|
||||
st->read_ptr = st->write_ptr;
|
||||
}
|
||||
st->write_ptr += len;
|
||||
if (st->write_ptr > st->size)
|
||||
st->write_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len)
|
||||
{
|
||||
int end, end1;
|
||||
char *data = _data;
|
||||
if (len > st->available)
|
||||
{
|
||||
SPEEX_MEMSET(data+st->available, 0, st->size-st->available);
|
||||
len = st->available;
|
||||
}
|
||||
end = st->read_ptr + len;
|
||||
end1 = end;
|
||||
if (end1 > st->size)
|
||||
end1 = st->size;
|
||||
SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr);
|
||||
|
||||
if (end > st->size)
|
||||
{
|
||||
end -= st->size;
|
||||
SPEEX_COPY(data+end1 - st->read_ptr, st->data, end);
|
||||
}
|
||||
st->available -= len;
|
||||
st->read_ptr += len;
|
||||
if (st->read_ptr > st->size)
|
||||
st->read_ptr -= st->size;
|
||||
return len;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_get_available(SpeexBuffer *st)
|
||||
{
|
||||
return st->available;
|
||||
}
|
||||
|
||||
EXPORT int speex_buffer_resize(SpeexBuffer *st, int len)
|
||||
{
|
||||
int old_len = st->size;
|
||||
if (len > old_len)
|
||||
{
|
||||
st->data = speex_realloc(st->data, len);
|
||||
/* FIXME: move data/pointers properly for growing the buffer */
|
||||
} else {
|
||||
/* FIXME: move data/pointers properly for shrinking the buffer */
|
||||
st->data = speex_realloc(st->data, len);
|
||||
}
|
||||
return len;
|
||||
}
|
@ -37,7 +37,9 @@
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "vq.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "cb_search_sse.h"
|
||||
@ -146,8 +148,7 @@ int update_target
|
||||
ALLOC(e, nsf, spx_sig_t);
|
||||
|
||||
/* FIXME: Do we still need to copy the target? */
|
||||
for (i=0;i<nsf;i++)
|
||||
t[i]=target[i];
|
||||
SPEEX_COPY(t, target, nsf);
|
||||
|
||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
||||
|
||||
@ -181,7 +182,7 @@ int update_target
|
||||
t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
if (sign)
|
||||
if (sign==1)
|
||||
{
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
|
||||
@ -226,11 +227,13 @@ int update_target
|
||||
/* Update target: only update target if necessary */
|
||||
if (update_target)
|
||||
{
|
||||
VARDECL(spx_sig_t *r2);
|
||||
ALLOC(r2, nsf, spx_sig_t);
|
||||
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
VARDECL(spx_word16_t *r2);
|
||||
ALLOC(r2, nsf, spx_word16_t);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],EXTRACT16(PSHR32(r2[j],8)));
|
||||
r2[j] = EXTRACT16(PSHR32(e[j] ,6));
|
||||
syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],PSHR16(r2[j],2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +266,6 @@ int update_target
|
||||
#endif
|
||||
VARDECL(spx_word16_t *t);
|
||||
VARDECL(spx_sig_t *e);
|
||||
VARDECL(spx_sig_t *r2);
|
||||
VARDECL(spx_word16_t *tmp);
|
||||
VARDECL(spx_word32_t *ndist);
|
||||
VARDECL(spx_word32_t *odist);
|
||||
@ -316,7 +318,6 @@ int update_target
|
||||
#endif
|
||||
ALLOC(t, nsf, spx_word16_t);
|
||||
ALLOC(e, nsf, spx_sig_t);
|
||||
ALLOC(r2, nsf, spx_sig_t);
|
||||
ALLOC(ind, nb_subvect, int);
|
||||
|
||||
ALLOC(tmp, 2*N*nsf, spx_word16_t);
|
||||
@ -341,11 +342,10 @@ int update_target
|
||||
oind[i]=itmp+(2*i+1)*nb_subvect;
|
||||
}
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
t[i]=target[i];
|
||||
SPEEX_COPY(t, target, nsf);
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
speex_move(&ot[j][0], t, nsf*sizeof(spx_word16_t));
|
||||
SPEEX_COPY(&ot[j][0], t, nsf);
|
||||
|
||||
/* Pre-compute codewords response and energy */
|
||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
||||
@ -359,7 +359,11 @@ int update_target
|
||||
/*"erase" nbest list*/
|
||||
for (j=0;j<N;j++)
|
||||
ndist[j]=VERY_LARGE32;
|
||||
|
||||
/* This is not strictly necessary, but it provides an additonal safety
|
||||
to prevent crashes in case something goes wrong in the previous
|
||||
steps (e.g. NaNs) */
|
||||
for (j=0;j<N;j++)
|
||||
best_nind[j] = best_ntarget[j] = 0;
|
||||
/*For all n-bests of previous subvector*/
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
@ -397,6 +401,7 @@ int update_target
|
||||
best_nind[n] = best_nind[n-1];
|
||||
best_ntarget[n] = best_ntarget[n-1];
|
||||
}
|
||||
/* n is equal to m here, so they're interchangeable */
|
||||
ndist[m] = err;
|
||||
best_nind[n] = best_index[k];
|
||||
best_ntarget[n] = j;
|
||||
@ -495,9 +500,13 @@ int update_target
|
||||
/* Update target: only update target if necessary */
|
||||
if (update_target)
|
||||
{
|
||||
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
VARDECL(spx_word16_t *r2);
|
||||
ALLOC(r2, nsf, spx_word16_t);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],EXTRACT16(PSHR32(r2[j],8)));
|
||||
r2[j] = EXTRACT16(PSHR32(e[j] ,6));
|
||||
syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]=SUB16(target[j],PSHR16(r2[j],2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,16 +586,13 @@ int update_target
|
||||
)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_sig_t *tmp);
|
||||
ALLOC(tmp, nsf, spx_sig_t);
|
||||
for (i=0;i<nsf;i++)
|
||||
tmp[i]=PSHR32(EXTEND32(target[i]),SIG_SHIFT);
|
||||
residue_percep_zero(tmp, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||
VARDECL(spx_word16_t *tmp);
|
||||
ALLOC(tmp, nsf, spx_word16_t);
|
||||
residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]+=tmp[i];
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=0;
|
||||
exc[i]+=SHL32(EXTEND32(tmp[i]),8);
|
||||
SPEEX_MEMSET(target, 0, nsf);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#define CB_SEARCH_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** Split codebook parameters. */
|
||||
typedef struct split_cb_params {
|
||||
|
@ -73,7 +73,10 @@ void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *
|
||||
:
|
||||
: "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E)
|
||||
: "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0",
|
||||
"L1", "A0", "A1", "memory", "LC0", "LC1"
|
||||
"L1", "A0", "A1", "memory"
|
||||
#if !(__GNUC__ == 3)
|
||||
, "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */
|
||||
#endif
|
||||
);
|
||||
shape_cb += subvect_size;
|
||||
resp += subvect_size;
|
||||
|
72
libs/speex/libspeex/echo_diagnostic.m
Normal file
72
libs/speex/libspeex/echo_diagnostic.m
Normal file
@ -0,0 +1,72 @@
|
||||
% Attempts to diagnose AEC problems from recorded samples
|
||||
%
|
||||
% out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
|
||||
%
|
||||
% Computes the full matrix inversion to cancel echo from the
|
||||
% recording 'rec_file' using the far end signal 'play_file' using
|
||||
% a filter length of 'tail_length'. The output is saved to 'out_file'.
|
||||
function out = echo_diagnostic(rec_file, play_file, out_file, tail_length)
|
||||
|
||||
F=fopen(rec_file,'rb');
|
||||
rec=fread(F,Inf,'short');
|
||||
fclose (F);
|
||||
F=fopen(play_file,'rb');
|
||||
play=fread(F,Inf,'short');
|
||||
fclose (F);
|
||||
|
||||
rec = [rec; zeros(1024,1)];
|
||||
play = [play; zeros(1024,1)];
|
||||
|
||||
N = length(rec);
|
||||
corr = real(ifft(fft(rec).*conj(fft(play))));
|
||||
acorr = real(ifft(fft(play).*conj(fft(play))));
|
||||
|
||||
[a,b] = max(corr);
|
||||
|
||||
if b > N/2
|
||||
b = b-N;
|
||||
end
|
||||
printf ("Far end to near end delay is %d samples\n", b);
|
||||
if (b > .3*tail_length)
|
||||
printf ('This is too much delay, try delaying the far-end signal a bit\n');
|
||||
else if (b < 0)
|
||||
printf ('You have a negative delay, the echo canceller has no chance to cancel anything!\n');
|
||||
else
|
||||
printf ('Delay looks OK.\n');
|
||||
end
|
||||
end
|
||||
end
|
||||
N2 = round(N/2);
|
||||
corr1 = real(ifft(fft(rec(1:N2)).*conj(fft(play(1:N2)))));
|
||||
corr2 = real(ifft(fft(rec(N2+1:end)).*conj(fft(play(N2+1:end)))));
|
||||
|
||||
[a,b1] = max(corr1);
|
||||
if b1 > N2/2
|
||||
b1 = b1-N2;
|
||||
end
|
||||
[a,b2] = max(corr2);
|
||||
if b2 > N2/2
|
||||
b2 = b2-N2;
|
||||
end
|
||||
drift = (b1-b2)/N2;
|
||||
printf ('Drift estimate is %f%% (%d samples)\n', 100*drift, b1-b2);
|
||||
if abs(b1-b2) < 10
|
||||
printf ('A drift of a few (+-10) samples is normal.\n');
|
||||
else
|
||||
if abs(b1-b2) < 30
|
||||
printf ('There may be (not sure) excessive clock drift. Is the capture and playback done on the same soundcard?\n');
|
||||
else
|
||||
printf ('Your clock is drifting! No way the AEC will be able to do anything with that. Most likely, you''re doing capture and playback from two different cards.\n');
|
||||
end
|
||||
end
|
||||
end
|
||||
acorr(1) = .001+1.00001*acorr(1);
|
||||
AtA = toeplitz(acorr(1:tail_length));
|
||||
bb = corr(1:tail_length);
|
||||
h = AtA\bb;
|
||||
|
||||
out = (rec - filter(h, 1, play));
|
||||
|
||||
F=fopen(out_file,'w');
|
||||
fwrite(F,out,'short');
|
||||
fclose (F);
|
@ -36,11 +36,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/*#define USE_SMALLFT*/
|
||||
#define USE_KISS_FFT
|
||||
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#define MAX_FFT_SIZE 2048
|
||||
|
||||
@ -64,7 +61,7 @@ static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t boun
|
||||
}
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
out[i] = in[i] << shift;
|
||||
out[i] = SHL16(in[i], shift);
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
@ -74,7 +71,7 @@ static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
out[i] = (in[i] + (1<<(shift-1))) >> shift;
|
||||
out[i] = PSHR16(in[i], shift);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -103,8 +100,8 @@ void spx_fft(void *table, float *in, float *out)
|
||||
if (in==out)
|
||||
{
|
||||
int i;
|
||||
speex_warning("FFT should not be done in-place");
|
||||
float scale = 1./((struct drft_lookup *)table)->n;
|
||||
speex_warning("FFT should not be done in-place");
|
||||
for (i=0;i<((struct drft_lookup *)table)->n;i++)
|
||||
out[i] = scale*in[i];
|
||||
} else {
|
||||
@ -120,7 +117,6 @@ void spx_ifft(void *table, float *in, float *out)
|
||||
{
|
||||
if (in==out)
|
||||
{
|
||||
int i;
|
||||
speex_warning("FFT should not be done in-place");
|
||||
} else {
|
||||
int i;
|
||||
@ -130,6 +126,119 @@ void spx_ifft(void *table, float *in, float *out)
|
||||
spx_drft_backward((struct drft_lookup *)table, out);
|
||||
}
|
||||
|
||||
#elif defined(USE_INTEL_MKL)
|
||||
#include <mkl.h>
|
||||
|
||||
struct mkl_config {
|
||||
DFTI_DESCRIPTOR_HANDLE desc;
|
||||
int N;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config));
|
||||
table->N = size;
|
||||
DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size);
|
||||
DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT);
|
||||
DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
|
||||
DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size);
|
||||
DftiCommitDescriptor(table->desc);
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiFreeDescriptor(t->desc);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiComputeForward(t->desc, in, out);
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
struct mkl_config *t = (struct mkl_config *) table;
|
||||
DftiComputeBackward(t->desc, in, out);
|
||||
}
|
||||
|
||||
#elif defined(USE_GPL_FFTW3)
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
struct fftw_config {
|
||||
float *in;
|
||||
float *out;
|
||||
fftwf_plan fft;
|
||||
fftwf_plan ifft;
|
||||
int N;
|
||||
};
|
||||
|
||||
void *spx_fft_init(int size)
|
||||
{
|
||||
struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config));
|
||||
table->in = fftwf_malloc(sizeof(float) * (size+2));
|
||||
table->out = fftwf_malloc(sizeof(float) * (size+2));
|
||||
|
||||
table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT);
|
||||
table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT);
|
||||
|
||||
table->N = size;
|
||||
return table;
|
||||
}
|
||||
|
||||
void spx_fft_destroy(void *table)
|
||||
{
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
fftwf_destroy_plan(t->fft);
|
||||
fftwf_destroy_plan(t->ifft);
|
||||
fftwf_free(t->in);
|
||||
fftwf_free(t->out);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
const int N = t->N;
|
||||
float *iptr = t->in;
|
||||
float *optr = t->out;
|
||||
const float m = 1.0 / N;
|
||||
for(i=0;i<N;++i)
|
||||
iptr[i]=in[i] * m;
|
||||
|
||||
fftwf_execute(t->fft);
|
||||
|
||||
out[0] = optr[0];
|
||||
for(i=1;i<N;++i)
|
||||
out[i] = optr[i+1];
|
||||
}
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
struct fftw_config *t = (struct fftw_config *) table;
|
||||
const int N = t->N;
|
||||
float *iptr = t->in;
|
||||
float *optr = t->out;
|
||||
|
||||
iptr[0] = in[0];
|
||||
iptr[1] = 0.0f;
|
||||
for(i=1;i<N;++i)
|
||||
iptr[i+1] = in[i];
|
||||
iptr[N+1] = 0.0f;
|
||||
|
||||
fftwf_execute(t->ifft);
|
||||
|
||||
for(i=0;i<N;++i)
|
||||
out[i] = optr[i];
|
||||
}
|
||||
|
||||
#elif defined(USE_KISS_FFT)
|
||||
|
||||
#include "kiss_fftr.h"
|
||||
@ -138,7 +247,6 @@ void spx_ifft(void *table, float *in, float *out)
|
||||
struct kiss_config {
|
||||
kiss_fftr_cfg forward;
|
||||
kiss_fftr_cfg backward;
|
||||
kiss_fft_cpx *freq_data;
|
||||
int N;
|
||||
};
|
||||
|
||||
@ -146,7 +254,6 @@ void *spx_fft_init(int size)
|
||||
{
|
||||
struct kiss_config *table;
|
||||
table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));
|
||||
table->freq_data = (kiss_fft_cpx*)speex_alloc(sizeof(kiss_fft_cpx)*((size>>1)+1));
|
||||
table->forward = kiss_fftr_alloc(size,0,NULL,NULL);
|
||||
table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
|
||||
table->N = size;
|
||||
@ -158,7 +265,6 @@ void spx_fft_destroy(void *table)
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
kiss_fftr_free(t->forward);
|
||||
kiss_fftr_free(t->backward);
|
||||
speex_free(t->freq_data);
|
||||
speex_free(table);
|
||||
}
|
||||
|
||||
@ -166,18 +272,10 @@ void spx_fft_destroy(void *table)
|
||||
|
||||
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
int shift;
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
shift = maximize_range(in, in, 32000, t->N);
|
||||
kiss_fftr(t->forward, in, t->freq_data);
|
||||
out[0] = t->freq_data[0].r;
|
||||
for (i=1;i<t->N>>1;i++)
|
||||
{
|
||||
out[(i<<1)-1] = t->freq_data[i].r;
|
||||
out[(i<<1)] = t->freq_data[i].i;
|
||||
}
|
||||
out[(i<<1)-1] = t->freq_data[i].r;
|
||||
kiss_fftr2(t->forward, in, out);
|
||||
renorm_range(in, in, shift, t->N);
|
||||
renorm_range(out, out, shift, t->N);
|
||||
}
|
||||
@ -190,32 +288,16 @@ void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
float scale;
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
scale = 1./t->N;
|
||||
kiss_fftr(t->forward, in, t->freq_data);
|
||||
out[0] = scale*t->freq_data[0].r;
|
||||
for (i=1;i<t->N>>1;i++)
|
||||
{
|
||||
out[(i<<1)-1] = scale*t->freq_data[i].r;
|
||||
out[(i<<1)] = scale*t->freq_data[i].i;
|
||||
}
|
||||
out[(i<<1)-1] = scale*t->freq_data[i].r;
|
||||
kiss_fftr2(t->forward, in, out);
|
||||
for (i=0;i<t->N;i++)
|
||||
out[i] *= scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||
{
|
||||
int i;
|
||||
struct kiss_config *t = (struct kiss_config *)table;
|
||||
t->freq_data[0].r = in[0];
|
||||
t->freq_data[0].i = 0;
|
||||
for (i=1;i<t->N>>1;i++)
|
||||
{
|
||||
t->freq_data[i].r = in[(i<<1)-1];
|
||||
t->freq_data[i].i = in[(i<<1)];
|
||||
}
|
||||
t->freq_data[i].r = in[(i<<1)-1];
|
||||
t->freq_data[i].i = 0;
|
||||
|
||||
kiss_fftri(t->backward, t->freq_data, out);
|
||||
kiss_fftri2(t->backward, in, out);
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#ifndef FFTWRAP_H
|
||||
#define FFTWRAP_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** Compute tables for an FFT */
|
||||
void *spx_fft_init(int size);
|
||||
|
227
libs/speex/libspeex/filterbank.c
Normal file
227
libs/speex/libspeex/filterbank.c
Normal file
@ -0,0 +1,227 @@
|
||||
/* Copyright (C) 2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file filterbank.c
|
||||
@brief Converting between psd and filterbank
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "filterbank.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))
|
||||
|
||||
#else
|
||||
#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
|
||||
#endif
|
||||
|
||||
#define toMEL(n) (2595.f*log10(1.f+(n)/700.f))
|
||||
|
||||
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
|
||||
{
|
||||
FilterBank *bank;
|
||||
spx_word32_t df;
|
||||
spx_word32_t max_mel, mel_interval;
|
||||
int i;
|
||||
int id1;
|
||||
int id2;
|
||||
df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
|
||||
max_mel = toBARK(EXTRACT16(sampling/2));
|
||||
mel_interval = PDIV32(max_mel,banks-1);
|
||||
|
||||
bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
|
||||
bank->nb_banks = banks;
|
||||
bank->len = len;
|
||||
bank->bank_left = (int*)speex_alloc(len*sizeof(int));
|
||||
bank->bank_right = (int*)speex_alloc(len*sizeof(int));
|
||||
bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
|
||||
bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
|
||||
/* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
bank->scaling = (float*)speex_alloc(banks*sizeof(float));
|
||||
#endif
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
spx_word16_t curr_freq;
|
||||
spx_word32_t mel;
|
||||
spx_word16_t val;
|
||||
curr_freq = EXTRACT16(MULT16_32_P15(i,df));
|
||||
mel = toBARK(curr_freq);
|
||||
if (mel > max_mel)
|
||||
break;
|
||||
#ifdef FIXED_POINT
|
||||
id1 = DIV32(mel,mel_interval);
|
||||
#else
|
||||
id1 = (int)(floor(mel/mel_interval));
|
||||
#endif
|
||||
if (id1>banks-2)
|
||||
{
|
||||
id1 = banks-2;
|
||||
val = Q15_ONE;
|
||||
} else {
|
||||
val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
|
||||
}
|
||||
id2 = id1+1;
|
||||
bank->bank_left[i] = id1;
|
||||
bank->filter_left[i] = SUB16(Q15_ONE,val);
|
||||
bank->bank_right[i] = id2;
|
||||
bank->filter_right[i] = val;
|
||||
}
|
||||
|
||||
/* Think I can safely disable normalisation for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
bank->scaling[i] = 0;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
bank->scaling[id] += bank->filter_left[i];
|
||||
id = bank->bank_right[i];
|
||||
bank->scaling[id] += bank->filter_right[i];
|
||||
}
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
|
||||
#endif
|
||||
return bank;
|
||||
}
|
||||
|
||||
void filterbank_destroy(FilterBank *bank)
|
||||
{
|
||||
speex_free(bank->bank_left);
|
||||
speex_free(bank->bank_right);
|
||||
speex_free(bank->filter_left);
|
||||
speex_free(bank->filter_right);
|
||||
#ifndef FIXED_POINT
|
||||
speex_free(bank->scaling);
|
||||
#endif
|
||||
speex_free(bank);
|
||||
}
|
||||
|
||||
void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = 0;
|
||||
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id;
|
||||
id = bank->bank_left[i];
|
||||
mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
|
||||
id = bank->bank_right[i];
|
||||
mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
|
||||
}
|
||||
/* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
|
||||
#ifndef FIXED_POINT
|
||||
/*for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
spx_word32_t tmp;
|
||||
int id1, id2;
|
||||
id1 = bank->bank_left[i];
|
||||
id2 = bank->bank_right[i];
|
||||
tmp = MULT16_16(mel[id1],bank->filter_left[i]);
|
||||
tmp += MULT16_16(mel[id2],bank->filter_right[i]);
|
||||
ps[i] = EXTRACT16(PSHR32(tmp,15));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] = 0;
|
||||
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
mel[id] += bank->filter_left[i]*ps[i];
|
||||
id = bank->bank_right[i];
|
||||
mel[id] += bank->filter_right[i]*ps[i];
|
||||
}
|
||||
for (i=0;i<bank->nb_banks;i++)
|
||||
mel[i] *= bank->scaling[i];
|
||||
}
|
||||
|
||||
void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bank->len;i++)
|
||||
{
|
||||
int id = bank->bank_left[i];
|
||||
ps[i] = mel[id]*bank->filter_left[i];
|
||||
id = bank->bank_right[i];
|
||||
ps[i] += mel[id]*bank->filter_right[i];
|
||||
}
|
||||
}
|
||||
|
||||
void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
|
||||
{
|
||||
/* Low freq slope: 14 dB/Bark*/
|
||||
/* High freq slope: 9 dB/Bark*/
|
||||
/* Noise vs tone: 5 dB difference */
|
||||
/* FIXME: Temporary kludge */
|
||||
float bark[100];
|
||||
int i;
|
||||
/* Assumes 1/3 Bark resolution */
|
||||
float decay_low = 0.34145f;
|
||||
float decay_high = 0.50119f;
|
||||
filterbank_compute_bank(bank, ps, bark);
|
||||
for (i=1;i<bank->nb_banks;i++)
|
||||
{
|
||||
/*float decay_high = 13-1.6*log10(bark[i-1]);
|
||||
decay_high = pow(10,(-decay_high/30.f));*/
|
||||
bark[i] = bark[i] + decay_high*bark[i-1];
|
||||
}
|
||||
for (i=bank->nb_banks-2;i>=0;i--)
|
||||
{
|
||||
bark[i] = bark[i] + decay_low*bark[i+1];
|
||||
}
|
||||
filterbank_compute_psd(bank, bark, mask);
|
||||
}
|
||||
|
||||
#endif
|
66
libs/speex/libspeex/filterbank.h
Normal file
66
libs/speex/libspeex/filterbank.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 2006 Jean-Marc Valin */
|
||||
/**
|
||||
@file filterbank.h
|
||||
@brief Converting between psd and filterbank
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FILTERBANK_H
|
||||
#define FILTERBANK_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct {
|
||||
int *bank_left;
|
||||
int *bank_right;
|
||||
spx_word16_t *filter_left;
|
||||
spx_word16_t *filter_right;
|
||||
#ifndef FIXED_POINT
|
||||
float *scaling;
|
||||
#endif
|
||||
int nb_banks;
|
||||
int len;
|
||||
} FilterBank;
|
||||
|
||||
|
||||
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type);
|
||||
|
||||
void filterbank_destroy(FilterBank *bank);
|
||||
|
||||
void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel);
|
||||
|
||||
void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd);
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);
|
||||
void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "ltp.h"
|
||||
#include <math.h>
|
||||
@ -62,6 +62,24 @@ void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, i
|
||||
}
|
||||
}
|
||||
|
||||
void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
/* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */
|
||||
if (!(vec[i]>=min_val && vec[i] <= max_val))
|
||||
{
|
||||
if (vec[i] < min_val)
|
||||
vec[i] = min_val;
|
||||
else if (vec[i] > max_val)
|
||||
vec[i] = max_val;
|
||||
else /* Has to be NaN */
|
||||
vec[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
|
||||
{
|
||||
int i;
|
||||
@ -83,8 +101,8 @@ void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_m
|
||||
spx_word16_t yi;
|
||||
spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);
|
||||
yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767));
|
||||
mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), MULT16_32_Q14(-den[1],vout));
|
||||
mem[1] = ADD32(MULT16_16(num[2],x[i]), MULT16_32_Q14(-den[2],vout));
|
||||
mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1));
|
||||
mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1));
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
@ -218,10 +236,10 @@ spx_word16_t compute_rms16(const spx_word16_t *x, int len)
|
||||
for (i=0;i<len;i+=4)
|
||||
{
|
||||
spx_word32_t sum2=0;
|
||||
sum2 = MAC16_16(sum2,PSHR16(x[i],1),PSHR16(x[i],1));
|
||||
sum2 = MAC16_16(sum2,PSHR16(x[i+1],1),PSHR16(x[i+1],1));
|
||||
sum2 = MAC16_16(sum2,PSHR16(x[i+2],1),PSHR16(x[i+2],1));
|
||||
sum2 = MAC16_16(sum2,PSHR16(x[i+3],1),PSHR16(x[i+3],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1));
|
||||
sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1));
|
||||
sum = ADD32(sum,SHR32(sum2,6));
|
||||
}
|
||||
return SHL16(spx_sqrt(DIV32(sum,len)),4);
|
||||
@ -297,53 +315,6 @@ spx_word16_t compute_rms16(const spx_word16_t *x, int len)
|
||||
|
||||
|
||||
|
||||
#ifndef OVERRIDE_FILTER_MEM2
|
||||
#ifdef PRECISION16
|
||||
void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t xi,yi,nyi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi= EXTRACT16(PSHR32(SATURATE(x[i],536870911),SIG_SHIFT));
|
||||
yi = EXTRACT16(PSHR32(SATURATE(ADD32(x[i], SHL32(mem[0],1)),536870911),SIG_SHIFT));
|
||||
nyi = NEG16(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi));
|
||||
y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_sig_t xi,yi,nyi;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHR32(mem[i],1);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=SATURATE(x[i],805306368);
|
||||
yi = SATURATE(ADD32(xi, SHL32(mem[0],2)),805306368);
|
||||
nyi = NEG32(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_32_Q15(MAC16_32_Q15(mem[j+1], num[j],xi), den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = SUB32(MULT16_32_Q15(num[ord-1],xi), MULT16_32_Q15(den[ord-1],yi));
|
||||
y[i] = yi;
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHL32(mem[i],1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#ifndef OVERRIDE_FILTER_MEM16
|
||||
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
@ -363,60 +334,7 @@ void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
filter_mem2(x, num, den, y, N, ord, mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_IIR_MEM2
|
||||
#ifdef PRECISION16
|
||||
void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t yi,nyi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
yi = EXTRACT16(PSHR32(SATURATE(x[i] + SHL32(mem[0],1),536870911),SIG_SHIFT));
|
||||
nyi = NEG16(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(mem[j+1],den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = MULT16_16(den[ord-1],nyi);
|
||||
y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word32_t xi,yi,nyi;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHR32(mem[i],1);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=SATURATE(x[i],805306368);
|
||||
yi = SATURATE(xi + SHL32(mem[0],2),805306368);
|
||||
nyi = NEG32(yi);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_32_Q15(mem[j+1],den[j],nyi);
|
||||
}
|
||||
mem[ord-1] = MULT16_32_Q15(den[ord-1],nyi);
|
||||
y[i] = yi;
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHL32(mem[i],1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#ifndef OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
@ -436,59 +354,7 @@ void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, in
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
iir_mem2(x, den, y, N, ord, mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_FIR_MEM2
|
||||
#ifdef PRECISION16
|
||||
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word16_t xi,yi;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi= EXTRACT16(PSHR32(SATURATE(x[i],536870911),SIG_SHIFT));
|
||||
yi = EXTRACT16(PSHR32(SATURATE(x[i] + SHL32(mem[0],1),536870911),SIG_SHIFT));
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_16(mem[j+1], num[j],xi);
|
||||
}
|
||||
mem[ord-1] = MULT16_16(num[ord-1],xi);
|
||||
y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_word32_t xi,yi;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHR32(mem[i],1);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=SATURATE(x[i],805306368);
|
||||
yi = xi + SHL32(mem[0],2);
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = MAC16_32_Q15(mem[j+1], num[j],xi);
|
||||
}
|
||||
mem[ord-1] = MULT16_32_Q15(num[ord-1],xi);
|
||||
y[i] = SATURATE(yi,805306368);
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHL32(mem[i],1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#ifndef OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
@ -508,43 +374,33 @@ void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, in
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
fir_mem2(x, num, y, N, ord, mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void syn_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
iir_mem2(xx, ak, y, N, ord, mem);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(y, awk1, awk2, y, N, ord, mem);
|
||||
}
|
||||
|
||||
void residue_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack)
|
||||
void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(xx, ak, awk1, y, N, ord, mem);
|
||||
iir_mem16(xx, ak, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
fir_mem2(y, awk2, y, N, ord, mem);
|
||||
mem[i]=0;
|
||||
filter_mem16(y, awk1, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_mem_t *mem);
|
||||
ALLOC(mem, ord, spx_mem_t);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem16(xx, ak, awk1, y, N, ord, mem, stack);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
fir_mem16(y, awk2, y, N, ord, mem, stack);
|
||||
}
|
||||
|
||||
|
||||
#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
|
||||
@ -581,7 +437,8 @@ void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, cons
|
||||
}
|
||||
#endif
|
||||
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *y1, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack)
|
||||
/* Decomposes a signal into low-band and high-band using a QMF */
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack)
|
||||
{
|
||||
int i,j,k,M2;
|
||||
VARDECL(spx_word16_t *a);
|
||||
@ -594,105 +451,139 @@ void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *y1, s
|
||||
M2=M>>1;
|
||||
for (i=0;i<M;i++)
|
||||
a[M-i-1]= aa[i];
|
||||
|
||||
for (i=0;i<M-1;i++)
|
||||
x[i]=mem[M-i-2];
|
||||
for (i=0;i<N;i++)
|
||||
x[i+M-1]=SATURATE(PSHR(xx[i],1),16383);
|
||||
x[i+M-1]=SHR16(xx[i],1);
|
||||
for (i=0;i<M-1;i++)
|
||||
mem[i]=SHR16(xx[N-i-1],1);
|
||||
for (i=0,k=0;i<N;i+=2,k++)
|
||||
{
|
||||
y1[k]=0;
|
||||
y2[k]=0;
|
||||
spx_word32_t y1k=0, y2k=0;
|
||||
for (j=0;j<M2;j++)
|
||||
{
|
||||
y1[k]=ADD32(y1[k],MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2[k]=SUB32(y2[k],MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
j++;
|
||||
y1[k]=ADD32(y1[k],MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2[k]=ADD32(y2[k],MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
||||
y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||
}
|
||||
y1[k] = SHR32(y1[k],1);
|
||||
y2[k] = SHR32(y2[k],1);
|
||||
y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767));
|
||||
y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767));
|
||||
}
|
||||
for (i=0;i<M-1;i++)
|
||||
mem[i]=SATURATE(PSHR(xx[N-i-1],1),16383);
|
||||
}
|
||||
|
||||
|
||||
/* By segher */
|
||||
void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N, int M, spx_word32_t *mem, char *stack)
|
||||
/* Re-synthesised a signal from the QMF low-band and high-band signals */
|
||||
void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack)
|
||||
/* assumptions:
|
||||
all odd x[i] are zero -- well, actually they are left out of the array now
|
||||
N and M are multiples of 4 */
|
||||
{
|
||||
int i, j;
|
||||
VARDECL(spx_word16_t *xx);
|
||||
int M2, N2;
|
||||
VARDECL(spx_word16_t *xx1);
|
||||
VARDECL(spx_word16_t *xx2);
|
||||
|
||||
ALLOC(xx, M+N-1, spx_word16_t);
|
||||
M2 = M>>1;
|
||||
N2 = N>>1;
|
||||
ALLOC(xx1, M2+N2, spx_word16_t);
|
||||
ALLOC(xx2, M2+N2, spx_word16_t);
|
||||
|
||||
for (i = 0; i < N/2; i++)
|
||||
xx[2*i] = PSHR32(x[N/2-1-i],SIG_SHIFT);
|
||||
for (i = 0; i < M - 1; i += 2)
|
||||
xx[N+i] = mem[i+1];
|
||||
for (i = 0; i < N2; i++)
|
||||
xx1[i] = x1[N2-1-i];
|
||||
for (i = 0; i < M2; i++)
|
||||
xx1[N2+i] = mem1[2*i+1];
|
||||
for (i = 0; i < N2; i++)
|
||||
xx2[i] = x2[N2-1-i];
|
||||
for (i = 0; i < M2; i++)
|
||||
xx2[N2+i] = mem2[2*i+1];
|
||||
|
||||
for (i = 0; i < N; i += 4) {
|
||||
for (i = 0; i < N2; i += 2) {
|
||||
spx_sig_t y0, y1, y2, y3;
|
||||
spx_word16_t x0;
|
||||
spx_word16_t x10, x20;
|
||||
|
||||
y0 = y1 = y2 = y3 = 0;
|
||||
x0 = xx[N-4-i];
|
||||
x10 = xx1[N2-2-i];
|
||||
x20 = xx2[N2-2-i];
|
||||
|
||||
for (j = 0; j < M; j += 4) {
|
||||
spx_word16_t x1;
|
||||
for (j = 0; j < M2; j += 2) {
|
||||
spx_word16_t x11, x21;
|
||||
spx_word16_t a0, a1;
|
||||
|
||||
a0 = a[j];
|
||||
a1 = a[j+1];
|
||||
x1 = xx[N-2+j-i];
|
||||
a0 = a[2*j];
|
||||
a1 = a[2*j+1];
|
||||
x11 = xx1[N2-1+j-i];
|
||||
x21 = xx2[N2-1+j-i];
|
||||
|
||||
y0 = ADD32(y0,SHR(MULT16_16(a0, x1),2));
|
||||
y1 = ADD32(y1,SHR(MULT16_16(a1, x1),2));
|
||||
y2 = ADD32(y2,SHR(MULT16_16(a0, x0),2));
|
||||
y3 = ADD32(y3,SHR(MULT16_16(a1, x0),2));
|
||||
#ifdef FIXED_POINT
|
||||
/* We multiply twice by the same coef to avoid overflows */
|
||||
y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);
|
||||
y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21);
|
||||
y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20);
|
||||
y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20);
|
||||
#else
|
||||
y0 = ADD32(y0,MULT16_16(a0, x11-x21));
|
||||
y1 = ADD32(y1,MULT16_16(a1, x11+x21));
|
||||
y2 = ADD32(y2,MULT16_16(a0, x10-x20));
|
||||
y3 = ADD32(y3,MULT16_16(a1, x10+x20));
|
||||
#endif
|
||||
a0 = a[2*j+2];
|
||||
a1 = a[2*j+3];
|
||||
x10 = xx1[N2+j-i];
|
||||
x20 = xx2[N2+j-i];
|
||||
|
||||
a0 = a[j+2];
|
||||
a1 = a[j+3];
|
||||
x0 = xx[N+j-i];
|
||||
|
||||
y0 = ADD32(y0,SHR(MULT16_16(a0, x0),2));
|
||||
y1 = ADD32(y1,SHR(MULT16_16(a1, x0),2));
|
||||
y2 = ADD32(y2,SHR(MULT16_16(a0, x1),2));
|
||||
y3 = ADD32(y3,SHR(MULT16_16(a1, x1),2));
|
||||
#ifdef FIXED_POINT
|
||||
/* We multiply twice by the same coef to avoid overflows */
|
||||
y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);
|
||||
y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);
|
||||
y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);
|
||||
y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);
|
||||
#else
|
||||
y0 = ADD32(y0,MULT16_16(a0, x10-x20));
|
||||
y1 = ADD32(y1,MULT16_16(a1, x10+x20));
|
||||
y2 = ADD32(y2,MULT16_16(a0, x11-x21));
|
||||
y3 = ADD32(y3,MULT16_16(a1, x11+x21));
|
||||
#endif
|
||||
}
|
||||
y[i] = y0;
|
||||
y[i+1] = y1;
|
||||
y[i+2] = y2;
|
||||
y[i+3] = y3;
|
||||
#ifdef FIXED_POINT
|
||||
y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));
|
||||
y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));
|
||||
y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767));
|
||||
y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767));
|
||||
#else
|
||||
/* Normalize up explicitly if we're in float */
|
||||
y[2*i] = 2.f*y0;
|
||||
y[2*i+1] = 2.f*y1;
|
||||
y[2*i+2] = 2.f*y2;
|
||||
y[2*i+3] = 2.f*y3;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < M - 1; i += 2)
|
||||
mem[i+1] = xx[i];
|
||||
for (i = 0; i < M2; i++)
|
||||
mem1[2*i+1] = xx1[i];
|
||||
for (i = 0; i < M2; i++)
|
||||
mem2[2*i+1] = xx2[i];
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#if 0
|
||||
spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043},
|
||||
const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043},
|
||||
{-98, 1133, -4425, 29179, 8895, -2328, 444},
|
||||
{444, -2328, 8895, 29179, -4425, 1133, -98}};
|
||||
#else
|
||||
spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540},
|
||||
const spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540},
|
||||
{-1064, 2817, -6694, 31589, 6837, -990, -209},
|
||||
{-209, -990, 6837, 31589, -6694, 2817, -1064}};
|
||||
#endif
|
||||
#else
|
||||
#if 0
|
||||
float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},
|
||||
const float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},
|
||||
{-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403},
|
||||
{0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}};
|
||||
#else
|
||||
float shift_filt[3][7] = {{-0.011915, 0.046995, -0.152373, 0.614108, 0.614108, -0.152373, 0.046995},
|
||||
{-0.0324855, 0.0859768, -0.2042986, 0.9640297, 0.2086420, -0.0302054, -0.0063646},
|
||||
{-0.0063646, -0.0302054, 0.2086420, 0.9640297, -0.2042986, 0.0859768, -0.0324855}};
|
||||
const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f},
|
||||
{-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f},
|
||||
{-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -784,7 +675,9 @@ char *stack
|
||||
spx_word16_t g1, g2;
|
||||
spx_word16_t ngain;
|
||||
spx_word16_t gg1, gg2;
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
int scaledown=0;
|
||||
#endif
|
||||
#if 0 /* Set to 1 to enable full pitch search */
|
||||
int nol_pitch[6];
|
||||
spx_word16_t nol_pitch_coef[6];
|
||||
@ -819,6 +712,23 @@ char *stack
|
||||
else
|
||||
interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(exc[i])>16383)
|
||||
{
|
||||
scaledown = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i] = SHR16(exc[i],1);
|
||||
for (i=0;i<2*nsf;i++)
|
||||
iexc[i] = SHR16(iexc[i],1);
|
||||
}
|
||||
#endif
|
||||
/*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/
|
||||
|
||||
/*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
|
||||
@ -898,5 +808,14 @@ char *stack
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]);
|
||||
#ifdef FIXED_POINT
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i] = SHL16(exc[i],1);
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#ifndef FILTERS_H
|
||||
#define FILTERS_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
spx_word16_t compute_rms(const spx_sig_t *x, int len);
|
||||
spx_word16_t compute_rms16(const spx_word16_t *x, int len);
|
||||
@ -58,13 +58,8 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int le
|
||||
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem);
|
||||
|
||||
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack);
|
||||
void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N, int M, spx_word32_t *mem, char *stack);
|
||||
|
||||
|
||||
void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
|
||||
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
|
||||
void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
|
||||
void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack);
|
||||
void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack);
|
||||
|
||||
void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
|
||||
void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack);
|
||||
@ -72,12 +67,11 @@ void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, in
|
||||
|
||||
/* Apply bandwidth expansion on LPC coef */
|
||||
void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);
|
||||
void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len);
|
||||
|
||||
|
||||
|
||||
void syn_percep_zero(const spx_sig_t *x, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack);
|
||||
|
||||
void residue_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack);
|
||||
void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
|
||||
void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
|
||||
|
||||
|
@ -33,9 +33,8 @@
|
||||
*/
|
||||
|
||||
#define OVERRIDE_NORMALIZE16
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
|
||||
int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
|
||||
{
|
||||
int i;
|
||||
spx_sig_t max_val=1;
|
||||
int sig_shift;
|
||||
int dead1, dead2, dead3, dead4, dead5, dead6;
|
||||
@ -87,7 +86,7 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
|
||||
"\tmov %5, %5, asr %3 \n"
|
||||
"\tstrh %5, [%1], #2 \n"
|
||||
|
||||
"\tbge .normalize16loop%=\n"
|
||||
"\tbgt .normalize16loop%=\n"
|
||||
: "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift)
|
||||
@ -95,295 +94,3 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
|
||||
return sig_shift;
|
||||
}
|
||||
|
||||
#define OVERRIDE_FILTER_MEM2
|
||||
void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_sig_t xi,yi,nyi;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHR32(mem[i],1);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
int deadm, deadn, deadd, deadidx, x1, y1, dead1, dead2, dead3, dead4, dead5, dead6;
|
||||
xi=SATURATE(x[i],805306368);
|
||||
yi = SATURATE(ADD32(xi, SHL(mem[0],2)),805306368);
|
||||
nyi = -yi;
|
||||
y[i] = yi;
|
||||
__asm__ __volatile__ (
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
#ifdef SHORTCUTS
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
|
||||
#else
|
||||
".filterloop%=: \n"
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tldr %10, [%0, #4]\n"
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tsmull %7, %11, %5, %6\n"
|
||||
"\tadd %8, %8, %9, lsl #17\n"
|
||||
"\tldrsh %6, [%1], #2\n"
|
||||
"\tadd %10, %10, %8\n"
|
||||
"\tsmull %8, %9, %4, %6\n"
|
||||
"\tadd %10, %10, %7, lsr #15\n"
|
||||
"\tsubs %3, %3, #1\n"
|
||||
"\tadd %10, %10, %11, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
"\t bne .filterloop%=\n"
|
||||
#endif
|
||||
"\tmov %8, %8, lsr #15\n"
|
||||
"\tadd %10, %8, %9, lsl #17\n"
|
||||
"\tldrsh %6, [%2], #2\n"
|
||||
"\tsmull %8, %9, %5, %6\n"
|
||||
"\tadd %10, %10, %8, lsr #15\n"
|
||||
"\tadd %10, %10, %9, lsl #17\n"
|
||||
"\tstr %10, [%0], #4 \n"
|
||||
|
||||
: "=r" (deadm), "=r" (deadn), "=r" (deadd), "=r" (deadidx),
|
||||
"=r" (xi), "=r" (nyi), "=r" (dead1), "=r" (dead2),
|
||||
"=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6)
|
||||
: "0" (mem), "1" (num), "2" (den), "3" (ord-1), "4" (xi), "5" (nyi)
|
||||
: "cc", "memory");
|
||||
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHL32(mem[i],1);
|
||||
}
|
||||
|
||||
#define OVERRIDE_IIR_MEM2
|
||||
void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i,j;
|
||||
spx_sig_t xi,yi,nyi;
|
||||
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHR32(mem[i],1);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
int deadm, deadd, deadidx, dead1, dead2, dead3, dead4, dead5, dead6;
|
||||
xi=SATURATE(x[i],805306368);
|
||||
yi = SATURATE(ADD32(xi, SHL(mem[0],2)),805306368);
|
||||
nyi = -yi;
|
||||
y[i] = yi;
|
||||
__asm__ __volatile__ (
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
|
||||
#ifdef SHORTCUTS
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %9, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %9, %9, %8\n"
|
||||
"\tstr %9, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %9, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %9, %9, %8\n"
|
||||
"\tstr %9, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %9, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %9, %9, %8\n"
|
||||
"\tstr %9, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %9, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %9, %9, %8\n"
|
||||
"\tstr %9, [%0], #4 \n"
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
|
||||
|
||||
#else
|
||||
".iirloop%=: \n"
|
||||
"\tldr %7, [%0, #4]\n"
|
||||
|
||||
"\tldrsh %4, [%1], #2\n"
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tadd %8, %5, %6, lsl #17\n"
|
||||
"\tsmull %5, %6, %3, %4\n"
|
||||
"\tadd %7, %7, %8\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
"\tsubs %2, %2, #1\n"
|
||||
"\t bne .iirloop%=\n"
|
||||
|
||||
#endif
|
||||
"\tmov %5, %5, lsr #15\n"
|
||||
"\tadd %7, %5, %6, lsl #17\n"
|
||||
"\tstr %7, [%0], #4 \n"
|
||||
|
||||
: "=r" (deadm), "=r" (deadd), "=r" (deadidx), "=r" (nyi),
|
||||
"=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
||||
"=r" (dead5), "=r" (dead6)
|
||||
: "0" (mem), "1" (den), "2" (ord-1), "3" (nyi)
|
||||
: "cc", "memory");
|
||||
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i] = SHL32(mem[i],1);
|
||||
|
||||
}
|
||||
|
@ -79,143 +79,6 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int le
|
||||
return sig_shift;
|
||||
}
|
||||
|
||||
#define OVERRIDE_FILTER_MEM2
|
||||
void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
spx_word32_t xy2[N+1];
|
||||
spx_word32_t *xy = xy2+1;
|
||||
spx_word32_t numden_a[2*ord+2];
|
||||
spx_word16_t *numden = (spx_word16_t*) numden_a;
|
||||
int i;
|
||||
for (i=0;i<ord;i++)
|
||||
{
|
||||
numden[2*i] = num[i];
|
||||
numden[2*i+1] = den[i];
|
||||
}
|
||||
__asm__ __volatile__
|
||||
(
|
||||
/* Register setup */
|
||||
"R0 = %5;\n\t" /*ord */
|
||||
|
||||
"P0 = %3;\n\t"
|
||||
"I0 = P0;\n\t"
|
||||
"B0 = P0;\n\t" /* numden */
|
||||
"L0 = 0;\n\t"
|
||||
|
||||
"P2 = %0;\n\t" /* Fused xy */
|
||||
"I2 = P2;\n\t"
|
||||
"L2 = 0;\n\t"
|
||||
|
||||
"P4 = %6;\n\t" /* mem */
|
||||
"P0 = %1;\n\t" /* _x */
|
||||
"P1 = %2;\n\t" /* _y */
|
||||
|
||||
/* First sample */
|
||||
"R1 = [P4++];\n\t"
|
||||
"R1 <<= 1;\n\t" /* shift mem */
|
||||
"R2 = [P0++];\n\t" /* load x[0] */
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"[P1++] = R1;\n\t" /* store y[0] */
|
||||
"R1 <<= 2;\n\t"
|
||||
"R2 <<= 2;\n\t"
|
||||
"R2 = PACK(R1.H, R2.H);\n\t" /* pack x16 and y16 */
|
||||
"[P2] = R2;\n\t"
|
||||
|
||||
/* Samples 1 to ord-1 (using memory) */
|
||||
"R0 += -1;\n\t"
|
||||
"R3 = 0;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"LOOP filter_start%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_start%=;\n\t"
|
||||
"R3 += 1;\n\t"
|
||||
"LC1 = R3;\n\t"
|
||||
|
||||
"R1 = [P4++];\n\t"
|
||||
"A1 = R1;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"I0 = B0;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"P2 += 4;\n\t"
|
||||
"R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP filter_start_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_start_inner%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END filter_start_inner%=;\n\t"
|
||||
"A0 += A1;\n\t"
|
||||
"R4 = A0;\n\t"
|
||||
"R4 <<= 1;\n\t" /* shift mem */
|
||||
"R2 = [P0++];\n\t" /* load x */
|
||||
"R4 = R4 + R2;\n\t"
|
||||
"[P1++] = R4;\n\t" /* store y */
|
||||
"R4 <<= 2;\n\t"
|
||||
"R2 <<= 2;\n\t"
|
||||
"R2 = PACK(R4.H, R2.H);\n\t" /* pack x16 and y16 */
|
||||
"[P2] = R2;\n\t"
|
||||
|
||||
"LOOP_END filter_start%=;\n\t"
|
||||
|
||||
/* Samples ord to N*/
|
||||
"R0 = %5;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"I0 = B0;\n\t" /* numden */
|
||||
"R0 <<= 1;\n\t"
|
||||
"L0 = R0;\n\t"
|
||||
|
||||
"R0 = %5;\n\t" /* org */
|
||||
"R2 = %4;\n\t" /* N */
|
||||
"R2 = R2 - R0;\n\t"
|
||||
"R4 = [I0++];\n\t" /* numden */
|
||||
"LC0 = R2;\n\t"
|
||||
"P3 = R0;\n\t"
|
||||
"R0 <<= 2;\n\t"
|
||||
"R0 += 8;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"M0 = R0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"R5 = [I2--];\n\t" /* load xy */
|
||||
"LOOP filter_mid%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_mid%=;\n\t"
|
||||
"LOOP filter_mid_inner%= LC1=P3;\n\t"
|
||||
"LOOP_BEGIN filter_mid_inner%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END filter_mid_inner%=;\n\t"
|
||||
"R0 = (A0 += A1) || I2 += M0;\n\t"
|
||||
"R0 = R0 << 1 || R5 = [P0++];\n\t" /* load x */
|
||||
"R0 = R0 + R5;\n\t"
|
||||
"R0 = R0 << 2 || [P1++] = R0;\n\t" /* shift y | store y */
|
||||
"R5 = R5 << 2;\n\t"
|
||||
"R5 = PACK(R0.H, R5.H);\n\t"
|
||||
"A1 = A0 = 0 || [I2--] = R5\n\t"
|
||||
"LOOP_END filter_mid%=;\n\t"
|
||||
"I2 += 4;\n\t"
|
||||
"P2 = I2;\n\t"
|
||||
/* Update memory */
|
||||
"P4 = %6;\n\t"
|
||||
"R0 = %5;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"P0 = B0;\n\t"
|
||||
"A1 = A0 = 0;\n\t"
|
||||
"LOOP mem_update%= LC0;\n\t"
|
||||
"LOOP_BEGIN mem_update%=;\n\t"
|
||||
"I2 = P2;\n\t"
|
||||
"I0 = P0;\n\t"
|
||||
"P0 += 4;\n\t"
|
||||
"R0 = LC0;\n\t"
|
||||
"LC1 = R0;\n\t"
|
||||
"R5 = [I2--] || R4 = [I0++];\n\t"
|
||||
"LOOP mem_accum%= LC1;\n\t"
|
||||
"LOOP_BEGIN mem_accum%=;\n\t"
|
||||
"A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t"
|
||||
"LOOP_END mem_accum%=;\n\t"
|
||||
"R0 = (A0 += A1);\n\t"
|
||||
"A1 = A0 = 0 || [P4++] = R0;\n\t"
|
||||
"LOOP_END mem_update%=;\n\t"
|
||||
"L0 = 0;\n\t"
|
||||
: : "m" (xy), "m" (_x), "m" (_y), "m" (numden), "m" (N), "m" (ord), "m" (mem)
|
||||
: "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B0", "I0", "I2", "L0", "L2", "M0", "memory"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_FILTER_MEM16
|
||||
@ -363,130 +226,6 @@ void filter_mem16(const spx_word16_t *_x, const spx_coef_t *num, const spx_coef_
|
||||
|
||||
|
||||
|
||||
|
||||
#define OVERRIDE_IIR_MEM2
|
||||
void iir_mem2(const spx_sig_t *_x, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
spx_word16_t y[N+2];
|
||||
spx_word16_t *yy;
|
||||
yy = y+2;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
/* Register setup */
|
||||
"R0 = %5;\n\t" /*ord */
|
||||
|
||||
"P1 = %3;\n\t"
|
||||
"I1 = P1;\n\t"
|
||||
"B1 = P1;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
|
||||
"P3 = %0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"L3 = 0;\n\t"
|
||||
|
||||
"P4 = %6;\n\t"
|
||||
"P0 = %1;\n\t"
|
||||
"P1 = %2;\n\t"
|
||||
|
||||
/* First sample */
|
||||
"R1 = [P4++];\n\t"
|
||||
"R1 <<= 1;\n\t"
|
||||
"R2 = [P0++];\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"[P1++] = R1;\n\t"
|
||||
"R1 <<= 2;\n\t"
|
||||
"W[P3] = R1.H;\n\t"
|
||||
"R2 <<= 2;\n\t"
|
||||
|
||||
/* Samples 1 to ord-1 (using memory) */
|
||||
"R0 += -1;\n\t"
|
||||
"R3 = 0;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"LOOP filter_start%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_start%=;\n\t"
|
||||
"R3 += 1;\n\t"
|
||||
"LC1 = R3;\n\t"
|
||||
|
||||
"R1 = [P4++];\n\t"
|
||||
"A1 = R1;\n\t"
|
||||
"I1 = B1;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"P3 += 2;\n\t"
|
||||
"LOOP filter_start_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_start_inner%=;\n\t"
|
||||
"R4.L = W[I1++];\n\t"
|
||||
"R5.L = W[I3--];\n\t"
|
||||
"A1 -= R4.L*R5.L (IS);\n\t"
|
||||
"LOOP_END filter_start_inner%=;\n\t"
|
||||
|
||||
"R1 = A1;\n\t"
|
||||
"R1 <<= 1;\n\t"
|
||||
"R2 = [P0++];\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"[P1++] = R1;\n\t"
|
||||
"R1 <<= 2;\n\t"
|
||||
"W[P3] = R1.H;\n\t"
|
||||
"R2 <<= 2;\n\t"
|
||||
"LOOP_END filter_start%=;\n\t"
|
||||
|
||||
/* Samples ord to N*/
|
||||
"R0 = %5;\n\t"
|
||||
"R0 <<= 1;\n\t"
|
||||
"I1 = B1;\n\t"
|
||||
"L1 = R0;\n\t"
|
||||
|
||||
"R0 = %5;\n\t"
|
||||
"R2 = %4;\n\t"
|
||||
"R2 = R2 - R0;\n\t"
|
||||
"R4.L = W[I1++];\n\t"
|
||||
"LC0 = R2;\n\t"
|
||||
"LOOP filter_mid%= LC0;\n\t"
|
||||
"LOOP_BEGIN filter_mid%=;\n\t"
|
||||
"LC1 = R0;\n\t"
|
||||
"A1 = 0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"P3 += 2;\n\t"
|
||||
"R5.L = W[I3--];\n\t"
|
||||
"LOOP filter_mid_inner%= LC1;\n\t"
|
||||
"LOOP_BEGIN filter_mid_inner%=;\n\t"
|
||||
"A1 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
|
||||
"LOOP_END filter_mid_inner%=;\n\t"
|
||||
"R1 = A1;\n\t"
|
||||
"R1 = R1 << 1 || R2 = [P0++];\n\t"
|
||||
"R1 = R1 + R2;\n\t"
|
||||
"R1 = R1 << 2 || [P1++] = R1;\n\t"
|
||||
"W[P3] = R1.H;\n\t"
|
||||
"LOOP_END filter_mid%=;\n\t"
|
||||
|
||||
/* Update memory */
|
||||
"P4 = %6;\n\t"
|
||||
"R0 = %5;\n\t"
|
||||
"LC0 = R0;\n\t"
|
||||
"P1 = B1;\n\t"
|
||||
"LOOP mem_update%= LC0;\n\t"
|
||||
"LOOP_BEGIN mem_update%=;\n\t"
|
||||
"A0 = 0;\n\t"
|
||||
"I3 = P3;\n\t"
|
||||
"I1 = P1;\n\t"
|
||||
"P1 += 2;\n\t"
|
||||
"R0 = LC0;\n\t"
|
||||
"LC1=R0;\n\t"
|
||||
"R5.L = W[I3--] || R4.L = W[I1++];\n\t"
|
||||
"LOOP mem_accum%= LC1;\n\t"
|
||||
"LOOP_BEGIN mem_accum%=;\n\t"
|
||||
"A0 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t"
|
||||
"LOOP_END mem_accum%=;\n\t"
|
||||
"R0 = A0;\n\t"
|
||||
"[P4++] = R0;\n\t"
|
||||
"LOOP_END mem_update%=;\n\t"
|
||||
"L1 = 0;\n\t"
|
||||
: : "m" (yy), "m" (_x), "m" (_y), "m" (den), "m" (N), "m" (ord), "m" (mem)
|
||||
: "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B1", "I1", "I3", "L1", "L3", "memory"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const spx_word16_t *_x, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
@ -612,18 +351,6 @@ void iir_mem16(const spx_word16_t *_x, const spx_coef_t *den, spx_word16_t *_y,
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_FIR_MEM2
|
||||
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
|
||||
{
|
||||
int i;
|
||||
spx_coef_t den2[12];
|
||||
spx_coef_t *den;
|
||||
den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc);
|
||||
for (i=0;i<10;i++)
|
||||
den[i] = 0;
|
||||
filter_mem2(x, num, den, y, N, ord, mem);
|
||||
}
|
||||
|
||||
#define OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
void filter_mem2_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[3], den[3], mem[3];
|
||||
|
||||
@ -87,7 +87,7 @@ void filter_mem2_10(const float *x, const float *_num, const float *_den, float
|
||||
_mm_store_ss(_mem+9, mem[2]);
|
||||
}
|
||||
|
||||
void filter_mem2_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
void filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[2], den[2], mem[2];
|
||||
|
||||
@ -130,18 +130,18 @@ void filter_mem2_8(const float *x, const float *_num, const float *_den, float *
|
||||
}
|
||||
|
||||
|
||||
#define OVERRIDE_FILTER_MEM2
|
||||
void filter_mem2(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
#define OVERRIDE_FILTER_MEM16
|
||||
void filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
filter_mem2_10(x, _num, _den, y, N, ord, _mem);
|
||||
filter_mem16_10(x, _num, _den, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
filter_mem2_8(x, _num, _den, y, N, ord, _mem);
|
||||
filter_mem16_8(x, _num, _den, y, N, ord, _mem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iir_mem2_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
void iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 den[3], mem[3];
|
||||
|
||||
@ -190,7 +190,7 @@ void iir_mem2_10(const float *x, const float *_den, float *y, int N, int ord, fl
|
||||
}
|
||||
|
||||
|
||||
void iir_mem2_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
void iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 den[2], mem[2];
|
||||
|
||||
@ -229,17 +229,17 @@ void iir_mem2_8(const float *x, const float *_den, float *y, int N, int ord, flo
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
}
|
||||
|
||||
#define OVERRIDE_IIR_MEM2
|
||||
void iir_mem2(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
||||
#define OVERRIDE_IIR_MEM16
|
||||
void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
iir_mem2_10(x, _den, y, N, ord, _mem);
|
||||
iir_mem16_10(x, _den, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
iir_mem2_8(x, _den, y, N, ord, _mem);
|
||||
iir_mem16_8(x, _den, y, N, ord, _mem);
|
||||
}
|
||||
|
||||
|
||||
void fir_mem2_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
void fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[3], mem[3];
|
||||
|
||||
@ -287,7 +287,7 @@ void fir_mem2_10(const float *x, const float *_num, float *y, int N, int ord, fl
|
||||
_mm_store_ss(_mem+9, mem[2]);
|
||||
}
|
||||
|
||||
void fir_mem2_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
void fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
__m128 num[2], mem[2];
|
||||
|
||||
@ -326,11 +326,11 @@ void fir_mem2_8(const float *x, const float *_num, float *y, int N, int ord, flo
|
||||
_mm_storeu_ps(_mem+4, mem[1]);
|
||||
}
|
||||
|
||||
#define OVERRIDE_FIR_MEM2
|
||||
void fir_mem2(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
||||
#define OVERRIDE_FIR_MEM16
|
||||
void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack)
|
||||
{
|
||||
if(ord==10)
|
||||
fir_mem2_10(x, _num, y, N, ord, _mem);
|
||||
fir_mem16_10(x, _num, y, N, ord, _mem);
|
||||
else if (ord==8)
|
||||
fir_mem2_8(x, _num, y, N, ord, _mem);
|
||||
fir_mem16_8(x, _num, y, N, ord, _mem);
|
||||
}
|
||||
|
@ -74,53 +74,57 @@ static inline int NEG32(long long x)
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline short EXTRACT16(int x)
|
||||
#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
|
||||
static inline short _EXTRACT16(int x, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "EXTRACT16: input is not short: %d\n", x);
|
||||
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
|
||||
}
|
||||
res = x;
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int EXTEND32(int x)
|
||||
#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
|
||||
static inline int _EXTEND32(int x, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "EXTRACT16: input is not short: %d\n", x);
|
||||
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
|
||||
}
|
||||
res = x;
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline short SHR16(int a, int shift)
|
||||
#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
|
||||
static inline short _SHR16(int a, int shift, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift);
|
||||
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SHR16: output is not short: %d\n", res);
|
||||
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
static inline short SHL16(int a, int shift)
|
||||
#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
|
||||
static inline short _SHL16(int a, int shift, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift);
|
||||
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SHR16: output is not short: %d\n", res);
|
||||
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
@ -134,7 +138,9 @@ static inline int SHR32(long long a, int shift)
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
@ -143,62 +149,71 @@ static inline int SHL32(long long a, int shift)
|
||||
long long res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
|
||||
fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
||||
{
|
||||
fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
|
||||
#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
|
||||
#define PSHR16(a,shift) (SHR16(ADD16(a,(1<<((shift)-1))),shift))
|
||||
#define PSHR32(a,shift) (SHR32(ADD32(a,(1<<((shift)-1))),shift))
|
||||
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
#define SHR(a,shift) ((a) >> (shift))
|
||||
#define SHL(a,shift) ((a) << (shift))
|
||||
//#define SHR(a,shift) ((a) >> (shift))
|
||||
//#define SHL(a,shift) ((a) << (shift))
|
||||
|
||||
static inline short ADD16(int a, int b)
|
||||
#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
|
||||
static inline short _ADD16(int a, int b, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "ADD16: inputs are not short: %d %d\n", a, b);
|
||||
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "ADD16: output is not short: %d+%d=%d\n", a,b,res);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
static inline short SUB16(int a, int b)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "SUB16: inputs are not short: %d %d\n", a, b);
|
||||
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SUB16: output is not short: %d\n", res);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int ADD32(long long a, long long b)
|
||||
#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
|
||||
static inline short _SUB16(int a, int b, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
|
||||
static inline int _ADD32(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "ADD32: inputs are not int: %d %d\n", (int)a, (int)b);
|
||||
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "ADD32: output is not int: %d\n", (int)res);
|
||||
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
}
|
||||
spx_mips++;
|
||||
return res;
|
||||
@ -220,8 +235,6 @@ static inline int SUB32(long long a, long long b)
|
||||
|
||||
#define ADD64(a,b) (MIPS_INC(a)+(b))
|
||||
|
||||
#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
|
||||
|
||||
/* result fits in 16 bits */
|
||||
static inline short MULT16_16_16(int a, int b)
|
||||
{
|
||||
@ -237,36 +250,56 @@ static inline short MULT16_16_16(int a, int b)
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int MULT16_16(int a, int b)
|
||||
#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
|
||||
static inline int _MULT16_16(int a, int b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16: inputs are not short: %d %d\n", a, b);
|
||||
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
}
|
||||
res = ((long long)a)*b;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_16: output is not int: %d\n", (int)res);
|
||||
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
spx_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
|
||||
#define MAC16_16_Q11(c,a,b) (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))
|
||||
#define MAC16_16_Q13(c,a,b) (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))
|
||||
#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
|
||||
#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
|
||||
#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
|
||||
#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
|
||||
|
||||
|
||||
static inline int MULT16_32_QX(int a, long long b, int Q)
|
||||
#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
|
||||
static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
|
||||
fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
|
||||
}
|
||||
if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
|
||||
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
|
||||
res = (((long long)a)*(long long)b) >> Q;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
|
||||
fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
|
||||
spx_mips+=5;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int MULT16_32_PX(int a, long long b, int Q)
|
||||
{
|
||||
long long res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
|
||||
}
|
||||
if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
|
||||
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);
|
||||
res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
|
||||
spx_mips+=5;
|
||||
return res;
|
||||
}
|
||||
@ -278,6 +311,7 @@ static inline int MULT16_32_QX(int a, long long b, int Q)
|
||||
#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
|
||||
#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
|
||||
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
|
||||
#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
|
||||
#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
|
||||
|
||||
static inline int SATURATE(int a, int b)
|
||||
@ -341,7 +375,9 @@ static inline short MULT16_16_Q15(int a, int b)
|
||||
res = ((long long)a)*b;
|
||||
res >>= 15;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
|
||||
}
|
||||
spx_mips+=3;
|
||||
return res;
|
||||
}
|
||||
@ -398,23 +434,24 @@ static inline short MULT16_16_P15(int a, int b)
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
|
||||
|
||||
static inline int DIV32_16(long long a, long long b)
|
||||
static inline int _DIV32_16(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32_16: divide by zero: %d/%d\n", (int)a, (int)b);
|
||||
fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
return 0;
|
||||
}
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d\n", (int)a, (int)b);
|
||||
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
}
|
||||
res = a/b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d\n", (int)a,(int)b,(int)res);
|
||||
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
|
||||
if (res>32767)
|
||||
res = 32767;
|
||||
if (res<-32768)
|
||||
@ -423,22 +460,24 @@ static inline int DIV32_16(long long a, long long b)
|
||||
spx_mips+=20;
|
||||
return res;
|
||||
}
|
||||
static inline int DIV32(long long a, long long b)
|
||||
|
||||
#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
|
||||
static inline int _DIV32(long long a, long long b, char *file, int line)
|
||||
{
|
||||
long long res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32: divide by zero: %d/%d\n", (int)a, (int)b);
|
||||
fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "DIV32: inputs are not int/short: %d %d\n", (int)a, (int)b);
|
||||
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
}
|
||||
res = a/b;
|
||||
if (!VERIFY_INT(res))
|
||||
fprintf (stderr, "DIV32: output is not int: %d\n", (int)res);
|
||||
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
spx_mips+=36;
|
||||
return res;
|
||||
}
|
||||
|
@ -46,14 +46,15 @@
|
||||
#define SHL16(a,shift) ((a) << (shift))
|
||||
#define SHR32(a,shift) ((a) >> (shift))
|
||||
#define SHL32(a,shift) ((a) << (shift))
|
||||
#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift))
|
||||
#define PSHR32(a,shift) (SHR32((a)+(1<<((shift)-1)),shift))
|
||||
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
|
||||
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
#define SHR(a,shift) ((a) >> (shift))
|
||||
#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
|
||||
#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
|
||||
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
|
||||
@ -77,6 +78,7 @@
|
||||
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
|
||||
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
|
||||
|
||||
#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
Copyright (c) 2005-2007, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@ -18,127 +19,149 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#endif
|
||||
|
||||
#include "_kiss_fft_guts.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/* The guts header contains all the multiplication and addition macros that are defined for
|
||||
fixed or floating point complex numbers. It also delares the kf_ internal functions.
|
||||
*/
|
||||
|
||||
static kiss_fft_cpx *scratchbuf=NULL;
|
||||
static size_t nscratchbuf=0;
|
||||
static kiss_fft_cpx *tmpbuf=NULL;
|
||||
static size_t ntmpbuf=0;
|
||||
|
||||
#define CHECKBUF(buf,nbuf,n) \
|
||||
do { \
|
||||
if ( nbuf < (size_t)(n) ) {\
|
||||
speex_free(buf); \
|
||||
buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(sizeof(kiss_fft_cpx)*(n)); \
|
||||
nbuf = (size_t)(n); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
static void kf_bfly2(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx * Fout2;
|
||||
kiss_fft_cpx * tw1 = st->twiddles;
|
||||
kiss_fft_cpx * tw1;
|
||||
kiss_fft_cpx t;
|
||||
Fout2 = Fout + m;
|
||||
if (!st->inverse) {
|
||||
int i;
|
||||
kiss_fft_cpx *x=Fout;
|
||||
for (i=0;i<2*m;i++)
|
||||
int i,j;
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
x[i].r = SHR(x[i].r,1);
|
||||
x[i].i = SHR(x[i].i,1);
|
||||
Fout = Fout_beg + i*mm;
|
||||
Fout2 = Fout + m;
|
||||
tw1 = st->twiddles;
|
||||
for(j=0;j<m;j++)
|
||||
{
|
||||
/* Almost the same as the code path below, except that we divide the input by two
|
||||
(while keeping the best accuracy possible) */
|
||||
spx_word32_t tr, ti;
|
||||
tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1);
|
||||
ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1);
|
||||
tw1 += fstride;
|
||||
Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
|
||||
Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
|
||||
Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15);
|
||||
Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15);
|
||||
++Fout2;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i,j;
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
Fout2 = Fout + m;
|
||||
tw1 = st->twiddles;
|
||||
for(j=0;j<m;j++)
|
||||
{
|
||||
C_MUL (t, *Fout2 , *tw1);
|
||||
tw1 += fstride;
|
||||
C_SUB( *Fout2 , *Fout , t );
|
||||
C_ADDTO( *Fout , t );
|
||||
++Fout2;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do{
|
||||
C_MUL (t, *Fout2 , *tw1);
|
||||
tw1 += fstride;
|
||||
C_SUB( *Fout2 , *Fout , t );
|
||||
C_ADDTO( *Fout , t );
|
||||
++Fout2;
|
||||
++Fout;
|
||||
}while (--m);
|
||||
}
|
||||
|
||||
static void kf_bfly4(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
const size_t m
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *tw1,*tw2,*tw3;
|
||||
kiss_fft_cpx scratch[6];
|
||||
size_t k=m;
|
||||
const size_t m2=2*m;
|
||||
const size_t m3=3*m;
|
||||
int i, j;
|
||||
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
|
||||
if (!st->inverse) {
|
||||
int i;
|
||||
kiss_fft_cpx *x=Fout;
|
||||
for (i=0;i<4*m;i++)
|
||||
{
|
||||
x[i].r = PSHR16(x[i].r,2);
|
||||
x[i].i = PSHR16(x[i].i,2);
|
||||
}
|
||||
}
|
||||
if (st->inverse)
|
||||
{
|
||||
do {
|
||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
Fout[m].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m].i = scratch[5].i + scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i - scratch[4].r;
|
||||
++Fout;
|
||||
} while(--k);
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
for (j=0;j<m;j++)
|
||||
{
|
||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
Fout[m].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m].i = scratch[5].i + scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i - scratch[4].r;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
do {
|
||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
Fout[m].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m].i = scratch[5].i - scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i + scratch[4].r;
|
||||
++Fout;
|
||||
}while(--k);
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
for (j=0;j<m;j++)
|
||||
{
|
||||
C_MUL4(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL4(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL4(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
Fout->r = PSHR16(Fout->r, 2);
|
||||
Fout->i = PSHR16(Fout->i, 2);
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
Fout[m2].r = PSHR16(Fout[m2].r, 2);
|
||||
Fout[m2].i = PSHR16(Fout[m2].i, 2);
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
Fout[m].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m].i = scratch[5].i - scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i + scratch[4].r;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,10 +286,13 @@ static void kf_bfly_generic(
|
||||
int u,k,q1,q;
|
||||
kiss_fft_cpx * twiddles = st->twiddles;
|
||||
kiss_fft_cpx t;
|
||||
kiss_fft_cpx scratchbuf[17];
|
||||
int Norig = st->nfft;
|
||||
|
||||
CHECKBUF(scratchbuf,nscratchbuf,p);
|
||||
|
||||
/*CHECKBUF(scratchbuf,nscratchbuf,p);*/
|
||||
if (p>17)
|
||||
speex_fatal("KissFFT: max radix supported is 17");
|
||||
|
||||
for ( u=0; u<m; ++u ) {
|
||||
k=u;
|
||||
for ( q1=0 ; q1<p ; ++q1 ) {
|
||||
@ -291,6 +317,39 @@ static void kf_bfly_generic(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void kf_shuffle(
|
||||
kiss_fft_cpx * Fout,
|
||||
const kiss_fft_cpx * f,
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
int * factors,
|
||||
const kiss_fft_cfg st
|
||||
)
|
||||
{
|
||||
const int p=*factors++; /* the radix */
|
||||
const int m=*factors++; /* stage's fft length/p */
|
||||
|
||||
/*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
|
||||
if (m==1)
|
||||
{
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
Fout[j] = *f;
|
||||
f += fstride*in_stride;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
kf_shuffle( Fout , f, fstride*p, in_stride, factors,st);
|
||||
f += fstride*in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void kf_work(
|
||||
@ -299,24 +358,34 @@ void kf_work(
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
int * factors,
|
||||
const kiss_fft_cfg st
|
||||
const kiss_fft_cfg st,
|
||||
int N,
|
||||
int s2,
|
||||
int m2
|
||||
)
|
||||
{
|
||||
int i;
|
||||
kiss_fft_cpx * Fout_beg=Fout;
|
||||
const int p=*factors++; /* the radix */
|
||||
const int m=*factors++; /* stage's fft length/p */
|
||||
const kiss_fft_cpx * Fout_end = Fout + p*m;
|
||||
|
||||
if (m==1) {
|
||||
do{
|
||||
*Fout = *f;
|
||||
f += fstride*in_stride;
|
||||
}while(++Fout != Fout_end );
|
||||
}else{
|
||||
do{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st);
|
||||
f += fstride*in_stride;
|
||||
}while( (Fout += m) != Fout_end );
|
||||
#if 0
|
||||
/*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
|
||||
if (m==1)
|
||||
{
|
||||
/* int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
Fout[j] = *f;
|
||||
f += fstride*in_stride;
|
||||
}*/
|
||||
} else {
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
|
||||
f += fstride*in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
|
||||
Fout=Fout_beg;
|
||||
@ -328,6 +397,36 @@ void kf_work(
|
||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
||||
}
|
||||
#else
|
||||
/*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/
|
||||
if (m==1)
|
||||
{
|
||||
/*for (i=0;i<N;i++)
|
||||
{
|
||||
int j;
|
||||
Fout = Fout_beg+i*m2;
|
||||
const kiss_fft_cpx * f2 = f+i*s2;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
*Fout++ = *f2;
|
||||
f2 += fstride*in_stride;
|
||||
}
|
||||
}*/
|
||||
}else{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch (p) {
|
||||
case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break;
|
||||
case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break;
|
||||
case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break;
|
||||
case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break;
|
||||
default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||
@ -338,8 +437,6 @@ static
|
||||
void kf_factor(int n,int * facbuf)
|
||||
{
|
||||
int p=4;
|
||||
double floor_sqrt;
|
||||
floor_sqrt = floor( sqrt((double)n) );
|
||||
|
||||
/*factor out powers of 4, powers of 2, then any remaining primes */
|
||||
do {
|
||||
@ -349,7 +446,7 @@ void kf_factor(int n,int * facbuf)
|
||||
case 2: p = 3; break;
|
||||
default: p += 2; break;
|
||||
}
|
||||
if (p > floor_sqrt)
|
||||
if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n)
|
||||
p = n; /* no more factors, skip to end */
|
||||
}
|
||||
n /= p;
|
||||
@ -357,7 +454,6 @@ void kf_factor(int n,int * facbuf)
|
||||
*facbuf++ = n;
|
||||
} while (n > 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* User-callable function to allocate all necessary storage space for the fft.
|
||||
@ -382,15 +478,22 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem
|
||||
int i;
|
||||
st->nfft=nfft;
|
||||
st->inverse = inverse_fft;
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nfft;++i) {
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
double phase = ( -2*pi /nfft ) * i;
|
||||
if (st->inverse)
|
||||
phase *= -1;
|
||||
kf_cexp(st->twiddles+i, phase );
|
||||
spx_word32_t phase = i;
|
||||
if (!st->inverse)
|
||||
phase = -phase;
|
||||
kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft));
|
||||
}
|
||||
|
||||
#else
|
||||
for (i=0;i<nfft;++i) {
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
double phase = ( -2*pi /nfft ) * i;
|
||||
if (st->inverse)
|
||||
phase *= -1;
|
||||
kf_cexp(st->twiddles+i, phase );
|
||||
}
|
||||
#endif
|
||||
kf_factor(nfft,st->factors);
|
||||
}
|
||||
return st;
|
||||
@ -401,12 +504,15 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem
|
||||
|
||||
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
|
||||
{
|
||||
if (fin == fout) {
|
||||
CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
|
||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||
speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
|
||||
}else{
|
||||
kf_work( fout, fin, 1,in_stride, st->factors,st );
|
||||
if (fin == fout)
|
||||
{
|
||||
speex_fatal("In-place FFT not supported");
|
||||
/*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
|
||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||
SPEEX_MOVE(fout,tmpbuf,st->nfft);*/
|
||||
} else {
|
||||
kf_shuffle( fout, fin, 1,in_stride, st->factors,st);
|
||||
kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,16 +521,3 @@ void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
|
||||
kiss_fft_stride(cfg,fin,fout,1);
|
||||
}
|
||||
|
||||
|
||||
/* not really necessary to call, but if someone is doing in-place ffts, they may want to free the
|
||||
buffers from CHECKBUF
|
||||
*/
|
||||
void kiss_fft_cleanup(void)
|
||||
{
|
||||
speex_free(scratchbuf);
|
||||
scratchbuf = NULL;
|
||||
nscratchbuf=0;
|
||||
speex_free(tmpbuf);
|
||||
tmpbuf=NULL;
|
||||
ntmpbuf=0;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -32,7 +32,7 @@ extern "C" {
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
# define kiss_fft_scalar spx_int16_t
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
|
@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "os_support.h"
|
||||
#include "kiss_fftr.h"
|
||||
#include "_kiss_fft_guts.h"
|
||||
|
||||
@ -58,13 +59,22 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme
|
||||
st->super_twiddles = st->tmpbuf + nfft;
|
||||
kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
|
||||
|
||||
for (i = 0; i < nfft; ++i) {
|
||||
double phase =
|
||||
-3.14159265358979323846264338327 * ((double) i / nfft + .5);
|
||||
if (inverse_fft)
|
||||
phase *= -1;
|
||||
kf_cexp (st->super_twiddles+i,phase);
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<nfft;++i) {
|
||||
spx_word32_t phase = i+(nfft>>1);
|
||||
if (!inverse_fft)
|
||||
phase = -phase;
|
||||
kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft));
|
||||
}
|
||||
#else
|
||||
for (i=0;i<nfft;++i) {
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
double phase = pi*(((double)i) /nfft + .5);
|
||||
if (!inverse_fft)
|
||||
phase = -phase;
|
||||
kf_cexp(st->super_twiddles+i, phase );
|
||||
}
|
||||
#endif
|
||||
return st;
|
||||
}
|
||||
|
||||
@ -75,8 +85,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
|
||||
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
|
||||
|
||||
if ( st->substate->inverse) {
|
||||
speex_warning("kiss fft usage error: improper alloc\n");
|
||||
exit(1);
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
@ -124,14 +133,13 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
|
||||
void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k, ncfft;
|
||||
|
||||
if (st->substate->inverse == 0) {
|
||||
speex_warning ("kiss fft usage error: improper alloc\n");
|
||||
exit (1);
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
@ -161,3 +169,129 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t
|
||||
}
|
||||
kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
|
||||
}
|
||||
|
||||
void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k,ncfft;
|
||||
kiss_fft_cpx f2k,tdc;
|
||||
spx_word32_t f1kr, f1ki, twr, twi;
|
||||
|
||||
if ( st->substate->inverse) {
|
||||
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
/*perform the parallel fft of two real signals packed in real,imag*/
|
||||
kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
|
||||
/* The real part of the DC element of the frequency spectrum in st->tmpbuf
|
||||
* contains the sum of the even-numbered elements of the input time sequence
|
||||
* The imag part is the sum of the odd-numbered elements
|
||||
*
|
||||
* The sum of tdc.r and tdc.i is the sum of the input time sequence.
|
||||
* yielding DC of input time sequence
|
||||
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
|
||||
* yielding Nyquist bin of input time sequence
|
||||
*/
|
||||
|
||||
tdc.r = st->tmpbuf[0].r;
|
||||
tdc.i = st->tmpbuf[0].i;
|
||||
C_FIXDIV(tdc,2);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
|
||||
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
|
||||
freqdata[0] = tdc.r + tdc.i;
|
||||
freqdata[2*ncfft-1] = tdc.r - tdc.i;
|
||||
|
||||
for ( k=1;k <= ncfft/2 ; ++k )
|
||||
{
|
||||
/*fpk = st->tmpbuf[k];
|
||||
fpnk.r = st->tmpbuf[ncfft-k].r;
|
||||
fpnk.i = - st->tmpbuf[ncfft-k].i;
|
||||
C_FIXDIV(fpk,2);
|
||||
C_FIXDIV(fpnk,2);
|
||||
|
||||
C_ADD( f1k, fpk , fpnk );
|
||||
C_SUB( f2k, fpk , fpnk );
|
||||
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
|
||||
freqdata[2*k] = HALF_OF(f1k.i + tw.i);
|
||||
freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
|
||||
freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
|
||||
*/
|
||||
|
||||
/*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
freqdata[2*k-1] = HALF_OF(f1k.r + tw.r);
|
||||
freqdata[2*k] = HALF_OF(f1k.i + tw.i);
|
||||
freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r);
|
||||
freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i);
|
||||
*/
|
||||
f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1);
|
||||
f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1);
|
||||
|
||||
f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13);
|
||||
f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13);
|
||||
|
||||
twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1);
|
||||
twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
freqdata[2*k-1] = PSHR32(f1kr + twr, 15);
|
||||
freqdata[2*k] = PSHR32(f1ki + twi, 15);
|
||||
freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15);
|
||||
freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15);
|
||||
#else
|
||||
freqdata[2*k-1] = .5f*(f1kr + twr);
|
||||
freqdata[2*k] = .5f*(f1ki + twi);
|
||||
freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr);
|
||||
freqdata[2*(ncfft-k)] = .5f*(twi - f1ki);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k, ncfft;
|
||||
|
||||
if (st->substate->inverse == 0) {
|
||||
speex_fatal ("kiss fft usage error: improper alloc\n");
|
||||
}
|
||||
|
||||
ncfft = st->substate->nfft;
|
||||
|
||||
st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1];
|
||||
st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1];
|
||||
/*C_FIXDIV(st->tmpbuf[0],2);*/
|
||||
|
||||
for (k = 1; k <= ncfft / 2; ++k) {
|
||||
kiss_fft_cpx fk, fnkc, fek, fok, tmp;
|
||||
fk.r = freqdata[2*k-1];
|
||||
fk.i = freqdata[2*k];
|
||||
fnkc.r = freqdata[2*(ncfft - k)-1];
|
||||
fnkc.i = -freqdata[2*(ncfft - k)];
|
||||
/*C_FIXDIV( fk , 2 );
|
||||
C_FIXDIV( fnkc , 2 );*/
|
||||
|
||||
C_ADD (fek, fk, fnkc);
|
||||
C_SUB (tmp, fk, fnkc);
|
||||
C_MUL (fok, tmp, st->super_twiddles[k]);
|
||||
C_ADD (st->tmpbuf[k], fek, fok);
|
||||
C_SUB (st->tmpbuf[ncfft - k], fek, fok);
|
||||
#ifdef USE_SIMD
|
||||
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
|
||||
#else
|
||||
st->tmpbuf[ncfft - k].i *= -1;
|
||||
#endif
|
||||
}
|
||||
kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
|
||||
}
|
||||
|
@ -32,7 +32,12 @@ void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *f
|
||||
output freqdata has nfft/2+1 complex points
|
||||
*/
|
||||
|
||||
void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata);
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
|
||||
void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata);
|
||||
|
||||
/*
|
||||
input freqdata has nfft/2+1 complex points
|
||||
output timedata has nfft scalar points
|
||||
|
@ -35,7 +35,7 @@
|
||||
#ifndef LPC_H
|
||||
#define LPC_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
void _spx_autocorr(
|
||||
const spx_word16_t * x, /* in: [0...n-1] samples x */
|
||||
|
@ -509,7 +509,7 @@ void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
|
||||
|
||||
/* hard limit ak's to +/- 32767 */
|
||||
|
||||
if (a < -32767) a = 32767;
|
||||
if (a < -32767) a = -32767;
|
||||
if (a > 32767) a = 32767;
|
||||
ak[j-1] = (short)a;
|
||||
|
||||
|
@ -51,7 +51,7 @@ Modified by Jean-Marc Valin
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
|
||||
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "filters.h"
|
||||
#include <speex/speex_bits.h>
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
@ -176,20 +177,56 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
||||
VARDECL(spx_word32_t *best_ener);
|
||||
spx_word32_t e0;
|
||||
VARDECL(spx_word32_t *corr);
|
||||
#ifdef FIXED_POINT
|
||||
/* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
|
||||
arrays for (normalized) 16-bit values */
|
||||
VARDECL(spx_word16_t *corr16);
|
||||
VARDECL(spx_word16_t *ener16);
|
||||
spx_word32_t *energy;
|
||||
int cshift=0, eshift=0;
|
||||
int scaledown = 0;
|
||||
ALLOC(corr16, end-start+1, spx_word16_t);
|
||||
ALLOC(ener16, end-start+1, spx_word16_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
energy = corr;
|
||||
#else
|
||||
/* In floating-point, we need to float arrays and no normalized copies */
|
||||
VARDECL(spx_word32_t *energy);
|
||||
|
||||
spx_word16_t *corr16;
|
||||
spx_word16_t *ener16;
|
||||
ALLOC(energy, end-start+2, spx_word32_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
corr16 = corr;
|
||||
ener16 = energy;
|
||||
#endif
|
||||
|
||||
ALLOC(best_score, N, spx_word32_t);
|
||||
ALLOC(best_ener, N, spx_word32_t);
|
||||
ALLOC(corr, end-start+1, spx_word32_t);
|
||||
ALLOC(energy, end-start+2, spx_word32_t);
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
best_score[i]=-1;
|
||||
best_ener[i]=0;
|
||||
pitch[i]=start;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
if (ABS16(sw[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If the weighted input is close to saturation, then we scale it down */
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
sw[i]=SHR16(sw[i],1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
energy[0]=inner_prod(sw-start, sw-start, len);
|
||||
e0=inner_prod(sw, sw, len);
|
||||
for (i=start;i<end;i++)
|
||||
@ -199,59 +236,42 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
||||
if (energy[i-start+1] < 0)
|
||||
energy[i-start+1] = 0;
|
||||
}
|
||||
|
||||
pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
|
||||
|
||||
/* FIXME: Fixed-point and floating-point code should be merged */
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
eshift = normalize16(energy, ener16, 32766, end-start+1);
|
||||
#endif
|
||||
|
||||
/* In fixed-point, this actually overrites the energy array (aliased to corr) */
|
||||
pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* Normalize to 180 so we can square it and it still fits in 16 bits */
|
||||
cshift = normalize16(corr, corr16, 180, end-start+1);
|
||||
/* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
|
||||
if (scaledown)
|
||||
{
|
||||
VARDECL(spx_word16_t *corr16);
|
||||
VARDECL(spx_word16_t *ener16);
|
||||
ALLOC(corr16, end-start+1, spx_word16_t);
|
||||
ALLOC(ener16, end-start+1, spx_word16_t);
|
||||
/* Normalize to 180 so we can square it and it still fits in 16 bits */
|
||||
normalize16(corr, corr16, 180, end-start+1);
|
||||
normalize16(energy, ener16, 180, end-start+1);
|
||||
|
||||
for (i=start;i<=end;i++)
|
||||
for (i=-end;i<len;i++)
|
||||
{
|
||||
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
||||
/* Instead of dividing the tmp by the energy, we multiply on the other side */
|
||||
if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
/* We can safely put it last and then check */
|
||||
best_score[N-1]=tmp;
|
||||
best_ener[N-1]=ener16[i-start]+1;
|
||||
pitch[N-1]=i;
|
||||
/* Check if it comes in front of others */
|
||||
for (j=0;j<N-1;j++)
|
||||
{
|
||||
if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
for (k=N-1;k>j;k--)
|
||||
{
|
||||
best_score[k]=best_score[k-1];
|
||||
best_ener[k]=best_ener[k-1];
|
||||
pitch[k]=pitch[k-1];
|
||||
}
|
||||
best_score[j]=tmp;
|
||||
best_ener[j]=ener16[i-start]+1;
|
||||
pitch[j]=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sw[i]=SHL16(sw[i],1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Search for the best pitch prediction gain */
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
float tmp = corr[i-start]*corr[i-start];
|
||||
if (tmp*best_ener[N-1]>best_score[N-1]*(1+energy[i-start]))
|
||||
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
||||
/* Instead of dividing the tmp by the energy, we multiply on the other side */
|
||||
if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
/* We can safely put it last and then check */
|
||||
best_score[N-1]=tmp;
|
||||
best_ener[N-1]=ener16[i-start]+1;
|
||||
pitch[N-1]=i;
|
||||
/* Check if it comes in front of others */
|
||||
for (j=0;j<N-1;j++)
|
||||
{
|
||||
if (tmp*best_ener[j]>best_score[j]*(1+energy[i-start]))
|
||||
if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
|
||||
{
|
||||
for (k=N-1;k>j;k--)
|
||||
{
|
||||
@ -260,29 +280,30 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
||||
pitch[k]=pitch[k-1];
|
||||
}
|
||||
best_score[j]=tmp;
|
||||
best_ener[j]=energy[i-start]+1;
|
||||
best_ener[j]=ener16[i-start]+1;
|
||||
pitch[j]=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute open-loop gain */
|
||||
|
||||
/* Compute open-loop gain if necessary */
|
||||
if (gain)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
i=pitch[j];
|
||||
g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
|
||||
/* FIXME: g = max(g,corr/energy) */
|
||||
if (g<0)
|
||||
g = 0;
|
||||
gain[j]=g;
|
||||
}
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
spx_word16_t g;
|
||||
i=pitch[j];
|
||||
g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6));
|
||||
/* FIXME: g = max(g,corr/energy) */
|
||||
if (g<0)
|
||||
g = 0;
|
||||
gain[j]=g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -342,7 +363,8 @@ const spx_word16_t *r,
|
||||
spx_word16_t *new_target,
|
||||
int *cdbk_index,
|
||||
int plc_tuning,
|
||||
spx_word32_t cumul_gain
|
||||
spx_word32_t cumul_gain,
|
||||
int scaledown
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
@ -366,6 +388,9 @@ spx_word32_t cumul_gain
|
||||
x[1]=tmp1+nsf;
|
||||
x[2]=tmp1+2*nsf;
|
||||
|
||||
for (j=0;j<nsf;j++)
|
||||
new_target[j] = target[j];
|
||||
|
||||
{
|
||||
VARDECL(spx_mem_t *mm);
|
||||
int pp=pitch-1;
|
||||
@ -379,6 +404,16 @@ spx_word32_t cumul_gain
|
||||
else
|
||||
e[j]=0;
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale target and excitation down if needed (avoiding overflow) */
|
||||
if (scaledown)
|
||||
{
|
||||
for (j=0;j<nsf;j++)
|
||||
e[j] = SHR16(e[j],1);
|
||||
for (j=0;j<nsf;j++)
|
||||
new_target[j] = SHR16(new_target[j],1);
|
||||
}
|
||||
#endif
|
||||
for (j=0;j<p;j++)
|
||||
mm[j] = 0;
|
||||
iir_mem16(e, ak, e, nsf, p, mm, stack);
|
||||
@ -391,13 +426,18 @@ spx_word32_t cumul_gain
|
||||
for (i=1;i>=0;i--)
|
||||
{
|
||||
spx_word16_t e0=exc2[-pitch-1+i];
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale excitation down if needed (avoiding overflow) */
|
||||
if (scaledown)
|
||||
e0 = SHR16(e0,1);
|
||||
#endif
|
||||
x[i][0]=MULT16_16_Q14(r[0], e0);
|
||||
for (j=0;j<nsf-1;j++)
|
||||
x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
|
||||
}
|
||||
|
||||
for (i=0;i<3;i++)
|
||||
corr[i]=inner_prod(x[i],target,nsf);
|
||||
corr[i]=inner_prod(x[i],new_target,nsf);
|
||||
for (i=0;i<3;i++)
|
||||
for (j=0;j<=i;j++)
|
||||
A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
|
||||
@ -456,8 +496,7 @@ spx_word32_t cumul_gain
|
||||
*cdbk_index=best_cdbk;
|
||||
}
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=0;
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
int j;
|
||||
@ -478,7 +517,7 @@ spx_word32_t cumul_gain
|
||||
{
|
||||
spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
|
||||
MULT16_16(gain[2],x[0][i]));
|
||||
new_target[i] = SUB16(target[i], EXTRACT16(PSHR32(tmp,6)));
|
||||
new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
|
||||
}
|
||||
err = inner_prod(new_target, new_target, nsf);
|
||||
|
||||
@ -509,7 +548,7 @@ int plc_tuning,
|
||||
spx_word32_t *cumul_gain
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
int i;
|
||||
int cdbk_index, pitch=0, best_gain_index=0;
|
||||
VARDECL(spx_sig_t *best_exc);
|
||||
VARDECL(spx_word16_t *new_target);
|
||||
@ -520,7 +559,8 @@ spx_word32_t *cumul_gain
|
||||
const ltp_params *params;
|
||||
const signed char *gain_cdbk;
|
||||
int gain_cdbk_size;
|
||||
|
||||
int scaledown=0;
|
||||
|
||||
VARDECL(int *nbest);
|
||||
|
||||
params = (const ltp_params*) par;
|
||||
@ -540,11 +580,29 @@ spx_word32_t *cumul_gain
|
||||
{
|
||||
speex_bits_pack(bits, 0, params->pitch_bits);
|
||||
speex_bits_pack(bits, 0, params->gain_bits);
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=0;
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
return start;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* Check if we need to scale everything down in the pitch search to avoid overflows */
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(target[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i=-end;i<nsf;i++)
|
||||
{
|
||||
if (ABS16(exc2[i])>16383)
|
||||
{
|
||||
scaledown=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (N>end-start+1)
|
||||
N=end-start+1;
|
||||
if (end != start)
|
||||
@ -559,16 +617,13 @@ spx_word32_t *cumul_gain
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
pitch=nbest[i];
|
||||
for (j=0;j<nsf;j++)
|
||||
exc[j]=0;
|
||||
SPEEX_MEMSET(exc, 0, nsf);
|
||||
err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
|
||||
bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain);
|
||||
bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
|
||||
if (err<best_err || best_err<0)
|
||||
{
|
||||
for (j=0;j<nsf;j++)
|
||||
best_exc[j]=exc[j];
|
||||
for (j=0;j<nsf;j++)
|
||||
best_target[j]=new_target[j];
|
||||
SPEEX_COPY(best_exc, exc, nsf);
|
||||
SPEEX_COPY(best_target, new_target, nsf);
|
||||
best_err=err;
|
||||
best_pitch=pitch;
|
||||
best_gain_index=cdbk_index;
|
||||
@ -584,11 +639,16 @@ spx_word32_t *cumul_gain
|
||||
#endif
|
||||
/*printf ("%f\n", cumul_gain);*/
|
||||
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=best_exc[i];
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=best_target[i];
|
||||
|
||||
SPEEX_COPY(exc, best_exc, nsf);
|
||||
SPEEX_COPY(target, best_target, nsf);
|
||||
#ifdef FIXED_POINT
|
||||
/* Scale target back up if needed */
|
||||
if (scaledown)
|
||||
{
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=SHL16(target[i],1);
|
||||
}
|
||||
#endif
|
||||
return pitch;
|
||||
}
|
||||
|
||||
@ -669,8 +729,7 @@ int cdbk_offset
|
||||
gain[0] = SHL16(gain[0],7);
|
||||
gain[1] = SHL16(gain[1],7);
|
||||
gain[2] = SHL16(gain[2],7);
|
||||
for (i=0;i<nsf;i++)
|
||||
exc_out[i]=0;
|
||||
SPEEX_MEMSET(exc_out, 0, nsf);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
int j;
|
||||
@ -717,8 +776,8 @@ spx_word32_t *cumul_gain
|
||||
)
|
||||
{
|
||||
int i;
|
||||
VARDECL(spx_sig_t *res);
|
||||
ALLOC(res, nsf, spx_sig_t);
|
||||
VARDECL(spx_word16_t *res);
|
||||
ALLOC(res, nsf, spx_word16_t);
|
||||
#ifdef FIXED_POINT
|
||||
if (pitch_coef>63)
|
||||
pitch_coef=63;
|
||||
@ -734,9 +793,11 @@ spx_word32_t *cumul_gain
|
||||
{
|
||||
exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
|
||||
}
|
||||
syn_percep_zero(exc, ak, awk1, awk2, res, nsf, p, stack);
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),PSHR32(res[i],SIG_SHIFT-1)),32700));
|
||||
res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
|
||||
syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
|
||||
return start;
|
||||
}
|
||||
|
||||
@ -770,7 +831,7 @@ int cdbk_offset
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
|
||||
exc[i] = PSHR(exc_out[i],13);
|
||||
exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
|
||||
}
|
||||
*pitch_val = start;
|
||||
gain_val[0]=gain_val[2]=0;
|
||||
|
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** LTP parameters. */
|
||||
typedef struct {
|
||||
|
@ -75,9 +75,10 @@ spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
|
||||
"\tadd %2, %2, %7, asr #5\n"
|
||||
"\tadd %3, %3, %10, asr #5\n"
|
||||
"\tbne .inner_prod_loop%=\n"
|
||||
: "=r" (deadx), "=r" (deady), "=r" (sum1), "=r" (sum2), "=r" (deadlen),
|
||||
"=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "1" (y), "2" (sum1), "3" (sum2), "4" (len>>3)
|
||||
: "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2),
|
||||
"=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3),
|
||||
"=r" (dead4), "=r" (dead5), "=r" (dead6)
|
||||
: "0" (x), "1" (y), "4" (len>>3)
|
||||
: "cc"
|
||||
);
|
||||
return (sum1+sum2)>>1;
|
||||
@ -169,13 +170,11 @@ void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *c
|
||||
"\tstr %6, %13 \n"
|
||||
"\tstr %7, %14 \n"
|
||||
|
||||
: "=r" (y0), "=r" (y1), "=r" (y2), "=r" (y3),
|
||||
: "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3),
|
||||
"=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
|
||||
"=r" (x), "=r" (y), "=r" (x0),
|
||||
"=m" (sum1), "=m" (sum2), "=m" (sum3), "=m" (sum4), "=r" (dead1)
|
||||
: "0" (y0), "1" (y1), "2" (y2), "3" (y3),
|
||||
"8" (x), "9" (y),
|
||||
"11" (sum1), "12" (sum2), "13" (sum3), "14" (sum4)
|
||||
"+r" (x), "+r" (y), "=r" (x0), "+m" (sum1),
|
||||
"+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1)
|
||||
:
|
||||
: "cc", "memory"
|
||||
);
|
||||
}
|
||||
|
@ -330,7 +330,6 @@ static int pitch_gain_search_3tap_vq(
|
||||
" %0 = 0;\n\t" /* %0: best_sum */
|
||||
" %1 = 0;\n\t" /* %1: best_cbdk */
|
||||
" P1 = 0;\n\t" /* P1: loop counter */
|
||||
" R5 = 64;\n\t" /* R5: pitch_control */
|
||||
|
||||
" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
|
||||
"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */
|
||||
@ -339,6 +338,7 @@ static int pitch_gain_search_3tap_vq(
|
||||
" R2 += 32;\n\t"
|
||||
" R3 += 32;\n\t"
|
||||
" R4 += 32;\n\t"
|
||||
" R4.H = 64;\n\t" /* R4.H: pitch_control */
|
||||
|
||||
" R0 = B [P0++] (X);\n\t"
|
||||
" B0 = R0;\n\t" /* BO: gain_sum */
|
||||
@ -349,13 +349,13 @@ static int pitch_gain_search_3tap_vq(
|
||||
" A0 = 0;\n\t"
|
||||
|
||||
" R0.L = W[I1++];\n\t"
|
||||
" R1.L = R2.L*R5.L (IS);\n\t"
|
||||
" R1.L = R2.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R3.L*R5.L (IS);\n\t"
|
||||
" R1.L = R3.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R4.L*R5.L (IS);\n\t"
|
||||
" R1.L = R4.L*R4.H (IS);\n\t"
|
||||
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||
|
||||
" R1.L = R2.L*R3.L (IS);\n\t"
|
||||
@ -406,7 +406,7 @@ static int pitch_gain_search_3tap_vq(
|
||||
: "=&d" (best_sum), "=&d" (best_cdbk)
|
||||
: "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
|
||||
"b" (-VERY_LARGE32)
|
||||
: "R0", "R1", "R2", "R3", "R4", "R5", "P0",
|
||||
: "R0", "R1", "R2", "R3", "R4", "P0",
|
||||
"P1", "I1", "L1", "A0", "B0"
|
||||
#if (__GNUC__ == 4)
|
||||
, "LC1"
|
||||
|
@ -35,16 +35,298 @@
|
||||
#ifndef MATH_APPROX_H
|
||||
#define MATH_APPROX_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
spx_word16_t spx_cos(spx_word16_t x);
|
||||
#ifndef FIXED_POINT
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
spx_word16_t spx_sqrt(spx_word32_t x);
|
||||
spx_word16_t spx_acos(spx_word16_t x);
|
||||
#else
|
||||
#define spx_sqrt sqrt
|
||||
#define spx_acos acos
|
||||
#endif
|
||||
#define spx_exp exp
|
||||
#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
|
||||
#define spx_atan atan
|
||||
|
||||
/** Generate a pseudo-random number */
|
||||
static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
|
||||
{
|
||||
const unsigned int jflone = 0x3f800000;
|
||||
const unsigned int jflmsk = 0x007fffff;
|
||||
union {int i; float f;} ran;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
ran.i = jflone | (jflmsk & *seed);
|
||||
ran.f -= 1.5;
|
||||
return 3.4642*std*ran.f;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static inline spx_int16_t spx_ilog2(spx_uint32_t x)
|
||||
{
|
||||
int r=0;
|
||||
if (x>=(spx_int32_t)65536)
|
||||
{
|
||||
x >>= 16;
|
||||
r += 16;
|
||||
}
|
||||
if (x>=256)
|
||||
{
|
||||
x >>= 8;
|
||||
r += 8;
|
||||
}
|
||||
if (x>=16)
|
||||
{
|
||||
x >>= 4;
|
||||
r += 4;
|
||||
}
|
||||
if (x>=4)
|
||||
{
|
||||
x >>= 2;
|
||||
r += 2;
|
||||
}
|
||||
if (x>=2)
|
||||
{
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_int16_t spx_ilog4(spx_uint32_t x)
|
||||
{
|
||||
int r=0;
|
||||
if (x>=(spx_int32_t)65536)
|
||||
{
|
||||
x >>= 16;
|
||||
r += 8;
|
||||
}
|
||||
if (x>=256)
|
||||
{
|
||||
x >>= 8;
|
||||
r += 4;
|
||||
}
|
||||
if (x>=16)
|
||||
{
|
||||
x >>= 4;
|
||||
r += 2;
|
||||
}
|
||||
if (x>=4)
|
||||
{
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/** Generate a pseudo-random number */
|
||||
static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
|
||||
{
|
||||
spx_word32_t res;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
|
||||
return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
|
||||
}
|
||||
|
||||
/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
|
||||
/*#define C0 3634
|
||||
#define C1 21173
|
||||
#define C2 -12627
|
||||
#define C3 4215*/
|
||||
|
||||
/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
|
||||
#define C0 3634
|
||||
#define C1 21173
|
||||
#define C2 -12627
|
||||
#define C3 4204
|
||||
|
||||
static inline spx_word16_t spx_sqrt(spx_word32_t x)
|
||||
{
|
||||
int k;
|
||||
spx_word32_t rt;
|
||||
k = spx_ilog4(x)-6;
|
||||
x = VSHR32(x, (k<<1));
|
||||
rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
|
||||
rt = VSHR32(rt,7-k);
|
||||
return rt;
|
||||
}
|
||||
|
||||
/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
|
||||
|
||||
|
||||
#define A1 16469
|
||||
#define A2 2242
|
||||
#define A3 1486
|
||||
|
||||
static inline spx_word16_t spx_acos(spx_word16_t x)
|
||||
{
|
||||
int s=0;
|
||||
spx_word16_t ret;
|
||||
spx_word16_t sq;
|
||||
if (x<0)
|
||||
{
|
||||
s=1;
|
||||
x = NEG16(x);
|
||||
}
|
||||
x = SUB16(16384,x);
|
||||
|
||||
x = x >> 1;
|
||||
sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
|
||||
ret = spx_sqrt(SHL32(EXTEND32(sq),13));
|
||||
|
||||
/*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
|
||||
if (s)
|
||||
ret = SUB16(25736,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define K1 8192
|
||||
#define K2 -4096
|
||||
#define K3 340
|
||||
#define K4 -10
|
||||
|
||||
static inline spx_word16_t spx_cos(spx_word16_t x)
|
||||
{
|
||||
spx_word16_t x2;
|
||||
|
||||
if (x<12868)
|
||||
{
|
||||
x2 = MULT16_16_P13(x,x);
|
||||
return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
|
||||
} else {
|
||||
x = SUB16(25736,x);
|
||||
x2 = MULT16_16_P13(x,x);
|
||||
return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
|
||||
}
|
||||
}
|
||||
|
||||
#define L1 32767
|
||||
#define L2 -7651
|
||||
#define L3 8277
|
||||
#define L4 -626
|
||||
|
||||
static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
|
||||
{
|
||||
spx_word16_t x2;
|
||||
|
||||
x2 = MULT16_16_P15(x,x);
|
||||
return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
|
||||
}
|
||||
|
||||
static inline spx_word16_t spx_cos_norm(spx_word32_t x)
|
||||
{
|
||||
x = x&0x0001ffff;
|
||||
if (x>SHL32(EXTEND32(1), 16))
|
||||
x = SUB32(SHL32(EXTEND32(1), 17),x);
|
||||
if (x&0x00007fff)
|
||||
{
|
||||
if (x<SHL32(EXTEND32(1), 15))
|
||||
{
|
||||
return _spx_cos_pi_2(EXTRACT16(x));
|
||||
} else {
|
||||
return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
|
||||
}
|
||||
} else {
|
||||
if (x&0x0000ffff)
|
||||
return 0;
|
||||
else if (x&0x0001ffff)
|
||||
return -32767;
|
||||
else
|
||||
return 32767;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
K0 = 1
|
||||
K1 = log(2)
|
||||
K2 = 3-4*log(2)
|
||||
K3 = 3*log(2) - 2
|
||||
*/
|
||||
#define D0 16384
|
||||
#define D1 11356
|
||||
#define D2 3726
|
||||
#define D3 1301
|
||||
/* Input in Q11 format, output in Q16 */
|
||||
static inline spx_word32_t spx_exp2(spx_word16_t x)
|
||||
{
|
||||
int integer;
|
||||
spx_word16_t frac;
|
||||
integer = SHR16(x,11);
|
||||
if (integer>14)
|
||||
return 0x7fffffff;
|
||||
else if (integer < -15)
|
||||
return 0;
|
||||
frac = SHL16(x-SHL16(integer,11),3);
|
||||
frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
|
||||
return VSHR32(EXTEND32(frac), -integer-2);
|
||||
}
|
||||
|
||||
/* Input in Q11 format, output in Q16 */
|
||||
static inline spx_word32_t spx_exp(spx_word16_t x)
|
||||
{
|
||||
if (x>21290)
|
||||
return 0x7fffffff;
|
||||
else if (x<-21290)
|
||||
return 0;
|
||||
else
|
||||
return spx_exp2(MULT16_16_P14(23637,x));
|
||||
}
|
||||
#define M1 32767
|
||||
#define M2 -21
|
||||
#define M3 -11943
|
||||
#define M4 4936
|
||||
|
||||
static inline spx_word16_t spx_atan01(spx_word16_t x)
|
||||
{
|
||||
return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
|
||||
}
|
||||
|
||||
#undef M1
|
||||
#undef M2
|
||||
#undef M3
|
||||
#undef M4
|
||||
|
||||
/* Input in Q15, output in Q14 */
|
||||
static inline spx_word16_t spx_atan(spx_word32_t x)
|
||||
{
|
||||
if (x <= 32767)
|
||||
{
|
||||
return SHR16(spx_atan01(x),1);
|
||||
} else {
|
||||
int e = spx_ilog2(x);
|
||||
if (e>=29)
|
||||
return 25736;
|
||||
x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
|
||||
return SUB16(25736, SHR16(spx_atan01(x),1));
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
|
||||
#define C1 0.9999932946f
|
||||
#define C2 -0.4999124376f
|
||||
#define C3 0.0414877472f
|
||||
#define C4 -0.0012712095f
|
||||
|
||||
|
||||
#define SPX_PI_2 1.5707963268
|
||||
static inline spx_word16_t spx_cos(spx_word16_t x)
|
||||
{
|
||||
if (x<SPX_PI_2)
|
||||
{
|
||||
x *= x;
|
||||
return C1 + x*(C2+x*(C3+C4*x));
|
||||
} else {
|
||||
x = M_PI-x;
|
||||
x *= x;
|
||||
return NEG16(C1 + x*(C2+x*(C3+C4*x)));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,28 +43,23 @@
|
||||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define MAX_IN_SAMPLES 640
|
||||
|
||||
const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
|
||||
|
||||
/* Extern declarations for all codebooks we use here */
|
||||
extern const signed char gain_cdbk_nb[];
|
||||
extern const signed char gain_cdbk_lbr[];
|
||||
extern const signed char hexc_table[];
|
||||
extern const signed char exc_5_256_table[];
|
||||
extern const signed char exc_5_64_table[];
|
||||
extern const signed char exc_8_128_table[];
|
||||
extern const signed char exc_10_32_table[];
|
||||
extern const signed char exc_10_16_table[];
|
||||
extern const signed char exc_20_32_table[];
|
||||
extern const signed char hexc_10_32_table[];
|
||||
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
@ -150,28 +145,7 @@ static const split_cb_params split_cb_sb = {
|
||||
0,
|
||||
};
|
||||
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high = {
|
||||
8, /*subvect_size*/
|
||||
5, /*nb_subvect*/
|
||||
hexc_table, /*shape_cb*/
|
||||
7, /*shape_bits*/
|
||||
1,
|
||||
};
|
||||
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
hexc_10_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* 2150 bps "vocoder-like" mode for comfort noise */
|
||||
static const SpeexSubmode nb_submode1 = {
|
||||
@ -354,11 +328,7 @@ static const SpeexNBMode nb_mode = {
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
.012, /*lag_factor*/
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
#ifdef EPIC_48K
|
||||
0,
|
||||
#endif
|
||||
{NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
|
||||
&nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
5,
|
||||
@ -367,7 +337,7 @@ static const SpeexNBMode nb_mode = {
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
const SpeexMode speex_nb_mode = {
|
||||
EXPORT const SpeexMode speex_nb_mode = {
|
||||
&nb_mode,
|
||||
nb_mode_query,
|
||||
"narrowband",
|
||||
@ -384,290 +354,13 @@ const SpeexMode speex_nb_mode = {
|
||||
};
|
||||
|
||||
|
||||
/* Wideband part */
|
||||
|
||||
static const SpeexSubmode wb_submode1 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*No innovation quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
36
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode2 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high_lbr,
|
||||
#endif
|
||||
-1,
|
||||
112
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode3 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
192
|
||||
};
|
||||
|
||||
static const SpeexSubmode wb_submode4 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
352
|
||||
};
|
||||
|
||||
|
||||
/* Split-band wideband CELP mode*/
|
||||
static const SpeexSBMode sb_wb_mode = {
|
||||
&speex_nb_mode,
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
640, /*bufSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
.012, /*lag_factor*/
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
0.9,
|
||||
{NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
|
||||
3,
|
||||
{1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
|
||||
{1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
|
||||
vbr_hb_thresh,
|
||||
5
|
||||
};
|
||||
|
||||
|
||||
const SpeexMode speex_wb_mode = {
|
||||
&sb_wb_mode,
|
||||
wb_mode_query,
|
||||
"wideband (sub-band CELP)",
|
||||
1,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* "Ultra-wideband" mode stuff */
|
||||
|
||||
|
||||
|
||||
/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
|
||||
static const SpeexSBMode sb_uwb_mode = {
|
||||
&speex_wb_mode,
|
||||
320, /*frameSize*/
|
||||
80, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
1280, /*bufSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
.012, /*lag_factor*/
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
0.7,
|
||||
{NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
1,
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
vbr_uhb_thresh,
|
||||
2
|
||||
};
|
||||
|
||||
|
||||
const SpeexMode speex_uwb_mode = {
|
||||
&sb_uwb_mode,
|
||||
wb_mode_query,
|
||||
"ultra-wideband (sub-band CELP)",
|
||||
2,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef EPIC_48K
|
||||
|
||||
extern const signed char gain_cdbk_ulbr[];
|
||||
extern const signed char exc_12_32_table[];
|
||||
|
||||
/* Parameters for Long-Term Prediction (LTP)*/
|
||||
static const ltp_params ltp_params_48k = {
|
||||
gain_cdbk_ulbr,
|
||||
3,
|
||||
0
|
||||
};
|
||||
|
||||
static const split_cb_params split_cb_nb_48k = {
|
||||
12, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
exc_12_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
/* 4.8 kbps very low bit-rate mode */
|
||||
static const SpeexSubmode nb_48k_submode = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_48k,
|
||||
lsp_unquant_48k,
|
||||
/*No pitch quantization*/
|
||||
pitch_search_3tap,
|
||||
pitch_unquant_3tap,
|
||||
<p_params_48k,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
&split_cb_nb_48k,
|
||||
#ifdef FIXED_POINT
|
||||
22938, 16384, 11796, 18022,
|
||||
#else
|
||||
0.7, 0.5, .36, .55,
|
||||
#endif
|
||||
144
|
||||
};
|
||||
|
||||
|
||||
/* Special, non-standard 4.8 kbps mode */
|
||||
static const SpeexNBMode nb_48k_mode = {
|
||||
240, /*frameSize*/
|
||||
48, /*subframeSize*/
|
||||
10, /*lpcSize*/
|
||||
640, /*bufSize*/
|
||||
17, /*pitchStart*/
|
||||
144, /*pitchEnd*/
|
||||
0.9, /*gamma1*/
|
||||
0.6, /*gamma2*/
|
||||
.01, /*lag_factor*/
|
||||
QCONST16(.0003,15), /*lpc_floor*/
|
||||
1,
|
||||
{NULL, NULL, &nb_48k_submode, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
2,
|
||||
{2,2,2,2,2,2,2,2,2,2,2}
|
||||
};
|
||||
|
||||
|
||||
/* Default mode for narrowband */
|
||||
const SpeexMode speex_nb_48k_mode = {
|
||||
&nb_48k_mode,
|
||||
nb_mode_query,
|
||||
"narrowband 4.8 kbps",
|
||||
1000,
|
||||
4,
|
||||
&nb_encoder_init,
|
||||
&nb_encoder_destroy,
|
||||
&nb_encode,
|
||||
&nb_decoder_init,
|
||||
&nb_decoder_destroy,
|
||||
&nb_decode,
|
||||
&nb_encoder_ctl,
|
||||
&nb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
|
||||
EXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
|
||||
{
|
||||
return mode->query(mode->mode, request, ptr);
|
||||
}
|
||||
|
||||
const SpeexMode * speex_lib_get_mode (int mode)
|
||||
{
|
||||
#ifdef EPIC_48K
|
||||
if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode;
|
||||
#ifdef FIXED_DEBUG
|
||||
long long spx_mips=0;
|
||||
#endif
|
||||
|
||||
if (mode < 0 || mode > SPEEX_NB_MODES) return NULL;
|
||||
|
||||
return speex_mode_list[mode];
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
#include <speex/speex.h>
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define NB_SUBMODES 16
|
||||
#define NB_SUBMODE_BITS 4
|
||||
@ -46,6 +46,23 @@
|
||||
#define SB_SUBMODES 8
|
||||
#define SB_SUBMODE_BITS 3
|
||||
|
||||
/* Used internally, NOT TO BE USED in applications */
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_PI_GAIN 100
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_EXC 101
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_INNOV 102
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_DTX_STATUS 103
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_INNOVATION_SAVE 104
|
||||
/** Used internally*/
|
||||
#define SPEEX_SET_WIDEBAND 105
|
||||
|
||||
/** Used internally*/
|
||||
#define SPEEX_GET_STACK 106
|
||||
|
||||
|
||||
/** Quantizes LSPs */
|
||||
typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
|
||||
@ -81,7 +98,7 @@ typedef struct SpeexSubmode {
|
||||
lsp_quant_func lsp_quant; /**< LSP quantization function */
|
||||
lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
|
||||
|
||||
/*Lont-term predictor functions*/
|
||||
/*Long-term predictor functions*/
|
||||
ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
|
||||
ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
|
||||
const void *ltp_params; /**< Pitch parameters (options) */
|
||||
@ -106,13 +123,8 @@ typedef struct SpeexNBMode {
|
||||
|
||||
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
||||
spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
|
||||
float lag_factor; /**< Lag-windowing parameter */
|
||||
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
|
||||
|
||||
#ifdef EPIC_48K
|
||||
int lbr48k; /**< 1 for the special 4.8 kbps mode */
|
||||
#endif
|
||||
|
||||
const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||
int quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
@ -125,18 +137,18 @@ typedef struct SpeexSBMode {
|
||||
int frameSize; /**< Size of frames used for encoding */
|
||||
int subframeSize; /**< Size of sub-frames used for encoding */
|
||||
int lpcSize; /**< Order of LPC filter */
|
||||
int bufSize; /**< Signal buffer size in encoder */
|
||||
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
||||
spx_word16_t gamma2; /**< Perceptual filter parameter #1 */
|
||||
float lag_factor; /**< Lag-windowing parameter */
|
||||
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
|
||||
float folding_gain;
|
||||
spx_word16_t folding_gain;
|
||||
|
||||
const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
int quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||
#ifndef DISABLE_VBR
|
||||
const float (*vbr_thresh)[11];
|
||||
#endif
|
||||
int nb_modes;
|
||||
} SpeexSBMode;
|
||||
|
||||
|
300
libs/speex/libspeex/modes_wb.c
Normal file
300
libs/speex/libspeex/modes_wb.c
Normal file
@ -0,0 +1,300 @@
|
||||
/* Copyright (C) 2002-2007 Jean-Marc Valin
|
||||
File: modes.c
|
||||
|
||||
Describes the wideband modes of the codec
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "modes.h"
|
||||
#include "ltp.h"
|
||||
#include "quant_lsp.h"
|
||||
#include "cb_search.h"
|
||||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
EXPORT const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
|
||||
|
||||
extern const signed char hexc_table[];
|
||||
extern const signed char hexc_10_32_table[];
|
||||
|
||||
#ifndef DISABLE_WIDEBAND
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high = {
|
||||
8, /*subvect_size*/
|
||||
5, /*nb_subvect*/
|
||||
hexc_table, /*shape_cb*/
|
||||
7, /*shape_bits*/
|
||||
1,
|
||||
};
|
||||
|
||||
|
||||
/* Split-VQ innovation for high-band wideband */
|
||||
static const split_cb_params split_cb_high_lbr = {
|
||||
10, /*subvect_size*/
|
||||
4, /*nb_subvect*/
|
||||
hexc_10_32_table, /*shape_cb*/
|
||||
5, /*shape_bits*/
|
||||
0,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode1 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*No innovation quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
36
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode2 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high_lbr,
|
||||
#endif
|
||||
-1,
|
||||
112
|
||||
};
|
||||
|
||||
|
||||
static const SpeexSubmode wb_submode3 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
192
|
||||
};
|
||||
|
||||
static const SpeexSubmode wb_submode4 = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
/*LSP quantization*/
|
||||
lsp_quant_high,
|
||||
lsp_unquant_high,
|
||||
/*Pitch quantization*/
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*Innovation quantization*/
|
||||
split_cb_search_shape_sign,
|
||||
split_cb_shape_sign_unquant,
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
NULL,
|
||||
#else
|
||||
&split_cb_high,
|
||||
#endif
|
||||
-1,
|
||||
352
|
||||
};
|
||||
|
||||
|
||||
/* Split-band wideband CELP mode*/
|
||||
static const SpeexSBMode sb_wb_mode = {
|
||||
&speex_nb_mode,
|
||||
160, /*frameSize*/
|
||||
40, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
QCONST16(0.9f,15),
|
||||
{NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
|
||||
3,
|
||||
{1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
|
||||
{1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
|
||||
#ifndef DISABLE_VBR
|
||||
vbr_hb_thresh,
|
||||
#endif
|
||||
5
|
||||
};
|
||||
|
||||
|
||||
EXPORT const SpeexMode speex_wb_mode = {
|
||||
&sb_wb_mode,
|
||||
wb_mode_query,
|
||||
"wideband (sub-band CELP)",
|
||||
1,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* "Ultra-wideband" mode stuff */
|
||||
|
||||
|
||||
|
||||
/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
|
||||
static const SpeexSBMode sb_uwb_mode = {
|
||||
&speex_wb_mode,
|
||||
320, /*frameSize*/
|
||||
80, /*subframeSize*/
|
||||
8, /*lpcSize*/
|
||||
#ifdef FIXED_POINT
|
||||
29491, 19661, /* gamma1, gamma2 */
|
||||
#else
|
||||
0.9, 0.6, /* gamma1, gamma2 */
|
||||
#endif
|
||||
QCONST16(.0002,15), /*lpc_floor*/
|
||||
QCONST16(0.7f,15),
|
||||
{NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
1,
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
#ifndef DISABLE_VBR
|
||||
vbr_uhb_thresh,
|
||||
#endif
|
||||
2
|
||||
};
|
||||
|
||||
int wb_mode_query(const void *mode, int request, void *ptr)
|
||||
{
|
||||
const SpeexSBMode *m = (const SpeexSBMode*)mode;
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case SPEEX_MODE_FRAME_SIZE:
|
||||
*((int*)ptr)=2*m->frameSize;
|
||||
break;
|
||||
case SPEEX_SUBMODE_BITS_PER_FRAME:
|
||||
if (*((int*)ptr)==0)
|
||||
*((int*)ptr) = SB_SUBMODE_BITS+1;
|
||||
else if (m->submodes[*((int*)ptr)]==NULL)
|
||||
*((int*)ptr) = -1;
|
||||
else
|
||||
*((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
|
||||
break;
|
||||
default:
|
||||
speex_warning_int("Unknown wb_mode_query request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
EXPORT const SpeexMode speex_uwb_mode = {
|
||||
&sb_uwb_mode,
|
||||
wb_mode_query,
|
||||
"ultra-wideband (sub-band CELP)",
|
||||
2,
|
||||
4,
|
||||
&sb_encoder_init,
|
||||
&sb_encoder_destroy,
|
||||
&sb_encode,
|
||||
&sb_decoder_init,
|
||||
&sb_decoder_destroy,
|
||||
&sb_decode,
|
||||
&sb_encoder_ctl,
|
||||
&sb_decoder_ctl,
|
||||
};
|
||||
|
||||
/* We have defined speex_lib_get_mode() as a macro in speex.h */
|
||||
#undef speex_lib_get_mode
|
||||
|
||||
EXPORT const SpeexMode * speex_lib_get_mode (int mode)
|
||||
{
|
||||
if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
|
||||
|
||||
return speex_mode_list[mode];
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,10 +64,6 @@ typedef struct EncState {
|
||||
int ol_voiced; /**< Open-loop voiced/non-voiced decision */
|
||||
int *pitch;
|
||||
|
||||
#ifdef EPIC_48K
|
||||
int lbr_48k;
|
||||
#endif
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
VorbisPsy *psy;
|
||||
float *psy_window;
|
||||
@ -77,7 +73,6 @@ typedef struct EncState {
|
||||
|
||||
spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
|
||||
spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */
|
||||
float lag_factor; /**< Lag windowing Gaussian width */
|
||||
spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
spx_word16_t *winBuf; /**< Input buffer (original signal) */
|
||||
@ -86,7 +81,7 @@ typedef struct EncState {
|
||||
spx_word16_t *swBuf; /**< Weighted signal buffer */
|
||||
spx_word16_t *sw; /**< Start of weighted signal frame */
|
||||
const spx_word16_t *window; /**< Temporary (Hanning) window */
|
||||
spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
|
||||
const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */
|
||||
spx_lsp_t *old_lsp; /**< LSPs for previous frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||
spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */
|
||||
@ -96,8 +91,9 @@ typedef struct EncState {
|
||||
spx_mem_t *mem_exc2; /**< Filter memory for excitation (whole frame) */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
spx_sig_t *innov_save; /**< If non-NULL, innovation is copied here */
|
||||
|
||||
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
VBRState *vbr; /**< State of the VBR data */
|
||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||
float relative_quality; /**< Relative quality that will be needed by VBR */
|
||||
@ -110,6 +106,8 @@ typedef struct EncState {
|
||||
float abr_drift;
|
||||
float abr_drift2;
|
||||
float abr_count;
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
|
||||
spx_int32_t sampling_rate;
|
||||
int plc_tuning;
|
||||
@ -134,10 +132,6 @@ typedef struct DecState {
|
||||
int max_pitch; /**< Maximum pitch value allowed */
|
||||
spx_int32_t sampling_rate;
|
||||
|
||||
#ifdef EPIC_48K
|
||||
int lbr_48k;
|
||||
#endif
|
||||
|
||||
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
|
||||
|
||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||
@ -148,7 +142,11 @@ typedef struct DecState {
|
||||
spx_mem_t *mem_sp; /**< Filter memory for synthesis signal */
|
||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
||||
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
|
||||
spx_sig_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
|
||||
spx_word16_t level;
|
||||
spx_word16_t max_level;
|
||||
spx_word16_t min_level;
|
||||
|
||||
/* This is used in packet loss concealment */
|
||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||
@ -168,7 +166,7 @@ typedef struct DecState {
|
||||
/*Vocoder data*/
|
||||
spx_word16_t voc_m1;
|
||||
spx_word32_t voc_m2;
|
||||
float voc_mean;
|
||||
spx_word16_t voc_mean;
|
||||
int voc_offset;
|
||||
|
||||
int dtx_enabled;
|
||||
|
169
libs/speex/libspeex/os_support.h
Normal file
169
libs/speex/libspeex/os_support.h
Normal file
@ -0,0 +1,169 @@
|
||||
/* Copyright (C) 2007 Jean-Marc Valin
|
||||
|
||||
File: os_support.h
|
||||
This is the (tiny) OS abstraction layer. Aside from math.h, this is the
|
||||
only place where system headers are allowed.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef OS_SUPPORT_H
|
||||
#define OS_SUPPORT_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#ifdef OS_SUPPORT_CUSTOM
|
||||
#include "os_support_custom.h"
|
||||
#endif
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free
|
||||
NOTE: speex_alloc needs to CLEAR THE MEMORY */
|
||||
#ifndef OVERRIDE_SPEEX_ALLOC
|
||||
static inline void *speex_alloc (int size)
|
||||
{
|
||||
/* WARNING: this is not equivalent to malloc(). If you want to use malloc()
|
||||
or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise
|
||||
you will experience strange bugs */
|
||||
return calloc(size,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
|
||||
#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
|
||||
static inline void *speex_alloc_scratch (int size)
|
||||
{
|
||||
/* Scratch space doesn't need to be cleared */
|
||||
return calloc(size,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
|
||||
#ifndef OVERRIDE_SPEEX_REALLOC
|
||||
static inline void *speex_realloc (void *ptr, int size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
|
||||
#ifndef OVERRIDE_SPEEX_FREE
|
||||
static inline void speex_free (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
|
||||
#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
|
||||
static inline void speex_free_scratch (void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */
|
||||
#ifndef OVERRIDE_SPEEX_COPY
|
||||
#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
|
||||
#endif
|
||||
|
||||
/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term
|
||||
provides compile-time type checking */
|
||||
#ifndef OVERRIDE_SPEEX_MOVE
|
||||
#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
|
||||
#endif
|
||||
|
||||
/** Set n bytes of memory to value of c, starting at address s */
|
||||
#ifndef OVERRIDE_SPEEX_MEMSET
|
||||
#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst))))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_FATAL
|
||||
static inline void _speex_fatal(const char *str, const char *file, int line)
|
||||
{
|
||||
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_WARNING
|
||||
static inline void speex_warning(const char *str)
|
||||
{
|
||||
#ifndef DISABLE_WARNINGS
|
||||
fprintf (stderr, "warning: %s\n", str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_WARNING_INT
|
||||
static inline void speex_warning_int(const char *str, int val)
|
||||
{
|
||||
#ifndef DISABLE_WARNINGS
|
||||
fprintf (stderr, "warning: %s %d\n", str, val);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_NOTIFY
|
||||
static inline void speex_notify(const char *str)
|
||||
{
|
||||
#ifndef DISABLE_NOTIFICATIONS
|
||||
fprintf (stderr, "notification: %s\n", str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_SPEEX_PUTC
|
||||
/** Speex wrapper for putc */
|
||||
static inline void _speex_putc(int ch, void *file)
|
||||
{
|
||||
FILE *f = (FILE *)file;
|
||||
fprintf(f, "%c", ch);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
|
||||
#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
|
||||
|
||||
#ifndef RELEASE
|
||||
static inline void print_vec(float *vec, int len, char *name)
|
||||
{
|
||||
int i;
|
||||
printf ("%s ", name);
|
||||
for (i=0;i<len;i++)
|
||||
printf (" %f", vec[i]);
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,15 @@
|
||||
/**
|
||||
@file pseudofloat.h
|
||||
@brief Pseudo-floating point
|
||||
* This header file provides a lightweight floating point type for
|
||||
* use on fixed-point platforms when a large dynamic range is
|
||||
* required. The new type is not compatible with the 32-bit IEEE format,
|
||||
* it is not even remotely as accurate as 32-bit floats, and is not
|
||||
* even guaranteed to produce even remotely correct results for code
|
||||
* other than Speex. It makes all kinds of shortcuts that are acceptable
|
||||
* for Speex, but may not be acceptable for your application. You're
|
||||
* quite welcome to reuse this code and improve it, but don't assume
|
||||
* it works out of the box. Most likely, it doesn't.
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -35,7 +44,8 @@
|
||||
#ifndef PSEUDOFLOAT_H
|
||||
#define PSEUDOFLOAT_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
#include "math_approx.h"
|
||||
#include <math.h>
|
||||
|
||||
@ -65,18 +75,8 @@ static inline spx_float_t PSEUDOFLOAT(spx_int32_t x)
|
||||
spx_float_t r = {0,0};
|
||||
return r;
|
||||
}
|
||||
while (x>32767)
|
||||
{
|
||||
x >>= 1;
|
||||
/*x *= .5;*/
|
||||
e++;
|
||||
}
|
||||
while (x<16383)
|
||||
{
|
||||
x <<= 1;
|
||||
/*x *= 2;*/
|
||||
e--;
|
||||
}
|
||||
e = spx_ilog2(ABS32(x))-14;
|
||||
x = VSHR32(x, e);
|
||||
if (sign)
|
||||
{
|
||||
spx_float_t r;
|
||||
@ -205,6 +205,14 @@ static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b)
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
spx_float_t r;
|
||||
r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
|
||||
r.e = (a).e+(b).e+15;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static inline spx_float_t FLOAT_SHL(spx_float_t a, int b)
|
||||
{
|
||||
@ -232,61 +240,38 @@ static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a)
|
||||
|
||||
static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b)
|
||||
{
|
||||
if (a.e<-15)
|
||||
return SHR32(MULT16_32_Q15(a.m, b),-a.e-15);
|
||||
else
|
||||
return SHL32(MULT16_32_Q15(a.m, b),15+a.e);
|
||||
return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15);
|
||||
}
|
||||
|
||||
static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b)
|
||||
{
|
||||
int e=0;
|
||||
int e1, e2;
|
||||
spx_float_t r;
|
||||
/* FIXME: Handle the sign */
|
||||
if (a==0)
|
||||
if (a==0 || b==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
while (a>32767)
|
||||
{
|
||||
a >>= 1;
|
||||
e++;
|
||||
}
|
||||
while (a<16384)
|
||||
{
|
||||
a <<= 1;
|
||||
e--;
|
||||
}
|
||||
while (b>32767)
|
||||
{
|
||||
b >>= 1;
|
||||
e++;
|
||||
}
|
||||
while (b<16384)
|
||||
{
|
||||
b <<= 1;
|
||||
e--;
|
||||
}
|
||||
e1 = spx_ilog2(ABS32(a));
|
||||
a = VSHR32(a, e1-14);
|
||||
e2 = spx_ilog2(ABS32(b));
|
||||
b = VSHR32(b, e2-14);
|
||||
r.m = MULT16_16_Q15(a,b);
|
||||
r.e = e+15;
|
||||
r.e = e1+e2-13;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)
|
||||
{
|
||||
int e=0;
|
||||
spx_float_t r;
|
||||
/* FIXME: Handle the sign */
|
||||
if (a==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
while (a<SHL32(EXTEND32(b.m),14))
|
||||
{
|
||||
a <<= 1;
|
||||
e--;
|
||||
}
|
||||
while (a>=SHL32(EXTEND32(b.m-1),15))
|
||||
e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15;
|
||||
a = VSHR32(a, e);
|
||||
if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15))
|
||||
{
|
||||
a >>= 1;
|
||||
e++;
|
||||
@ -297,41 +282,47 @@ static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)
|
||||
}
|
||||
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b)
|
||||
{
|
||||
int e=0;
|
||||
int e0=0,e=0;
|
||||
spx_float_t r;
|
||||
/* FIXME: Handle the sign */
|
||||
if (a==0)
|
||||
{
|
||||
return FLOAT_ZERO;
|
||||
}
|
||||
while (b>32767)
|
||||
if (b>32767)
|
||||
{
|
||||
b >>= 1;
|
||||
e--;
|
||||
e0 = spx_ilog2(b)-14;
|
||||
b = VSHR32(b, e0);
|
||||
e0 = -e0;
|
||||
}
|
||||
while (a<SHL32(b,14))
|
||||
{
|
||||
a <<= 1;
|
||||
e--;
|
||||
}
|
||||
while (a>=SHL32(b-1,15))
|
||||
e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15;
|
||||
a = VSHR32(a, e);
|
||||
if (ABS32(a)>=SHL32(EXTEND32(b-1),15))
|
||||
{
|
||||
a >>= 1;
|
||||
e++;
|
||||
}
|
||||
e += e0;
|
||||
r.m = DIV32_16(a,b);
|
||||
r.e = e;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Do NOT attempt to divide by a negative number */
|
||||
static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b)
|
||||
{
|
||||
int e=0;
|
||||
spx_int32_t num;
|
||||
spx_float_t r;
|
||||
if (b.m<=0)
|
||||
{
|
||||
speex_warning_int("Attempted to divide by", b.m);
|
||||
return FLOAT_ONE;
|
||||
}
|
||||
num = a.m;
|
||||
a.m = ABS16(a.m);
|
||||
while (a.m >= b.m)
|
||||
{
|
||||
e++;
|
||||
@ -347,7 +338,7 @@ static inline spx_float_t FLOAT_SQRT(spx_float_t a)
|
||||
{
|
||||
spx_float_t r;
|
||||
spx_int32_t m;
|
||||
m = a.m << 14;
|
||||
m = SHL32(EXTEND32(a.m), 14);
|
||||
r.e = a.e - 14;
|
||||
if (r.e & 1)
|
||||
{
|
||||
@ -367,6 +358,7 @@ static inline spx_float_t FLOAT_SQRT(spx_float_t a)
|
||||
#define FLOAT_HALF 0.5f
|
||||
#define PSEUDOFLOAT(x) (x)
|
||||
#define FLOAT_MULT(a,b) ((a)*(b))
|
||||
#define FLOAT_AMULT(a,b) ((a)*(b))
|
||||
#define FLOAT_MUL32(a,b) ((a)*(b))
|
||||
#define FLOAT_DIV32(a,b) ((a)/(b))
|
||||
#define FLOAT_EXTRACT16(a) (a)
|
||||
|
@ -35,12 +35,13 @@
|
||||
#endif
|
||||
|
||||
#include "quant_lsp.h"
|
||||
#include "os_support.h"
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef BFIN_ASM
|
||||
#include "quant_lsp_bfin.h"
|
||||
@ -304,11 +305,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
#ifdef DISABLE_WIDEBAND
|
||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
speex_error("Wideband and Ultra-wideband are disabled");
|
||||
speex_fatal("Wideband and Ultra-wideband are disabled");
|
||||
}
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
speex_error("Wideband and Ultra-wideband are disabled");
|
||||
speex_fatal("Wideband and Ultra-wideband are disabled");
|
||||
}
|
||||
#else
|
||||
extern const signed char high_lsp_cdbk[];
|
||||
@ -382,66 +383,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EPIC_48K
|
||||
|
||||
extern const signed char cdbk_lsp_vlbr[5120];
|
||||
extern const signed char cdbk_lsp2_vlbr[160];
|
||||
|
||||
void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
spx_word16_t quant_weight[10];
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i];
|
||||
|
||||
compute_quant_weights(qlsp, quant_weight, order);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=SUB16(qlsp[i],LSP_SCALING*(.25*i+.3125));
|
||||
#ifndef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i] = qlsp[i]*LSP_SCALE;
|
||||
#endif
|
||||
|
||||
id = lsp_quant(qlsp, cdbk_lsp_vlbr, 512, order);
|
||||
speex_bits_pack(bits, id, 9);
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]*=4;
|
||||
|
||||
id = lsp_weight_quant(qlsp, quant_weight, cdbk_lsp2_vlbr, 16, 10);
|
||||
speex_bits_pack(bits, id, 4);
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=PSHR(qlsp[i],2);
|
||||
#else
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=qlsp[i]*0.00097655;
|
||||
#endif
|
||||
|
||||
for (i=0;i<order;i++)
|
||||
qlsp[i]=lsp[i]-qlsp[i];
|
||||
}
|
||||
|
||||
void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
||||
{
|
||||
int i, id;
|
||||
for (i=0;i<order;i++)
|
||||
lsp[i]=LSP_SCALING*(.25*i+.3125);
|
||||
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 9);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] += LSP_SCALING*0.0039062*cdbk_lsp_vlbr[id*10+i];
|
||||
|
||||
id=speex_bits_unpack_unsigned(bits, 4);
|
||||
for (i=0;i<10;i++)
|
||||
lsp[i] += LSP_SCALING*0.00097655*cdbk_lsp2_vlbr[id*10+i];
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@
|
||||
#define QUANT_LSP_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define MAX_LSP_SIZE 20
|
||||
|
||||
@ -71,13 +71,4 @@ void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
||||
/* Decodes high-band LSPs */
|
||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
|
||||
#ifdef EPIC_48K
|
||||
/* Quantizes narrowband LSPs with 14 bits */
|
||||
void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
|
||||
|
||||
/* Decodes quantized narrowband LSPs (14 bits) */
|
||||
void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -68,19 +68,19 @@ static int lsp_quant(
|
||||
" B0 = %2;\n\t"
|
||||
|
||||
" R2.L = W [I0++];\n\t"
|
||||
" LSETUP (lq1, lq2) LC0 = %4;\n\t"
|
||||
"lq1: R3 = 0;\n\t" /* R3: dist */
|
||||
" LSETUP (lq3, lq4) LC1 = %5;\n\t"
|
||||
"lq3: R1 = B [P2++] (X);\n\t"
|
||||
" LSETUP (1f, 2f) LC0 = %4;\n\t"
|
||||
"1: R3 = 0;\n\t" /* R3: dist */
|
||||
" LSETUP (3f, 4f) LC1 = %5;\n\t"
|
||||
"3: R1 = B [P2++] (X);\n\t"
|
||||
" R1 <<= 5;\n\t"
|
||||
" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
|
||||
" R0 = R0.L*R0.L;\n\t"
|
||||
"lq4: R3 = R3 + R0;\n\t"
|
||||
"4: R3 = R3 + R0;\n\t"
|
||||
|
||||
" cc =R3<%0;\n\t"
|
||||
" if cc %0=R3;\n\t"
|
||||
" if cc %1=R5;\n\t"
|
||||
"lq2: R5 += 1;\n\t"
|
||||
"2: R5 += 1;\n\t"
|
||||
" L0 = 0;\n\t"
|
||||
: "=&d" (best_dist), "=&d" (best_id)
|
||||
: "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
|
||||
@ -132,10 +132,10 @@ static int lsp_weight_quant(
|
||||
" B0 = %2;\n\t"
|
||||
" B1 = %3;\n\t"
|
||||
|
||||
" LSETUP (lwq1, lwq2) LC0 = %5;\n\t"
|
||||
"lwq1: R3 = 0 (X);\n\t" /* R3: dist */
|
||||
" LSETUP (lwq3, lwq4) LC1 = %6;\n\t"
|
||||
"lwq3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
|
||||
" LSETUP (1f, 2f) LC0 = %5;\n\t"
|
||||
"1: R3 = 0 (X);\n\t" /* R3: dist */
|
||||
" LSETUP (3f, 4f) LC1 = %6;\n\t"
|
||||
"3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
|
||||
" R1 = B [P2++] (X);\n\t"
|
||||
" R1 <<= 5;\n\t"
|
||||
" R0.L = R0.L - R1.L;\n\t"
|
||||
@ -143,12 +143,12 @@ static int lsp_weight_quant(
|
||||
" A1 = R2.L*R0.L (M,IS);\n\t"
|
||||
" A1 = A1 >>> 16;\n\t"
|
||||
" R1 = (A1 += R2.L*R0.H) (IS);\n\t"
|
||||
"lwq4: R3 = R3 + R1;\n\t"
|
||||
"4: R3 = R3 + R1;\n\t"
|
||||
|
||||
" cc =R3<%0;\n\t"
|
||||
" if cc %0=R3;\n\t"
|
||||
" if cc %1=R5;\n\t"
|
||||
"lwq2: R5 += 1;\n\t"
|
||||
"2: R5 += 1;\n\t"
|
||||
" L0 = 0;\n\t"
|
||||
" L1 = 0;\n\t"
|
||||
: "=&d" (best_dist), "=&d" (best_id)
|
||||
|
1131
libs/speex/libspeex/resample.c
Normal file
1131
libs/speex/libspeex/resample.c
Normal file
File diff suppressed because it is too large
Load Diff
128
libs/speex/libspeex/resample_sse.h
Normal file
128
libs/speex/libspeex/resample_sse.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* Copyright (C) 2007-2008 Jean-Marc Valin
|
||||
* Copyright (C) 2008 Thorvald Natvig
|
||||
*/
|
||||
/**
|
||||
@file resample_sse.h
|
||||
@brief Resampler functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
|
||||
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
|
||||
}
|
||||
sum = _mm_mul_ps(f, sum);
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _USE_SSE2
|
||||
#include <emmintrin.h>
|
||||
#define OVERRIDE_INNER_PRODUCT_DOUBLE
|
||||
|
||||
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum = _mm_setzero_pd();
|
||||
__m128 t;
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
|
||||
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum;
|
||||
__m128d sum1 = _mm_setzero_pd();
|
||||
__m128d sum2 = _mm_setzero_pd();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
__m128d f1 = _mm_cvtps_pd(f);
|
||||
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
|
||||
__m128 t;
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum1 = _mm_mul_pd(f1, sum1);
|
||||
sum2 = _mm_mul_pd(f2, sum2);
|
||||
sum = _mm_add_pd(sum1, sum2);
|
||||
sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -50,46 +50,29 @@ typedef struct SBEncState {
|
||||
int nbSubframes; /**< Number of high-band sub-frames*/
|
||||
int windowSize; /**< Length of high-band LPC window*/
|
||||
int lpcSize; /**< Order of high-band LPC analysis */
|
||||
int bufSize; /**< Buffer size */
|
||||
int first; /**< First frame? */
|
||||
float lag_factor; /**< Lag-windowing control parameter */
|
||||
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
|
||||
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
|
||||
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
|
||||
|
||||
char *stack; /**< Temporary allocation stack */
|
||||
spx_sig_t *x0d, *x1d; /**< QMF filter signals*/
|
||||
spx_sig_t *high; /**< High-band signal (buffer) */
|
||||
spx_sig_t *y0, *y1; /**< QMF synthesis signals */
|
||||
spx_word16_t *high; /**< High-band signal (buffer) */
|
||||
spx_word16_t *h0_mem, *h1_mem;
|
||||
spx_word32_t *g0_mem, *g1_mem; /**< QMF memories */
|
||||
|
||||
spx_sig_t *excBuf; /**< High-band excitation */
|
||||
spx_sig_t *exc; /**< High-band excitation (for QMF only)*/
|
||||
spx_sig_t *res; /**< Zero-input response (ringing) */
|
||||
spx_sig_t *sw; /**< Perceptually weighted signal */
|
||||
const spx_word16_t *window; /**< LPC analysis window */
|
||||
spx_word16_t *lagWindow; /**< Auto-correlation window */
|
||||
spx_word16_t *autocorr; /**< Auto-correlation (for LPC analysis) */
|
||||
spx_coef_t *lpc; /**< LPC coefficients */
|
||||
spx_lsp_t *lsp; /**< LSP coefficients */
|
||||
spx_lsp_t *qlsp; /**< Quantized LSPs */
|
||||
const spx_word16_t *lagWindow; /**< Auto-correlation window */
|
||||
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */
|
||||
spx_lsp_t *interp_lsp; /**< Interpolated LSPs for current sub-frame */
|
||||
spx_lsp_t *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */
|
||||
spx_coef_t *interp_lpc; /**< Interpolated LPCs for current sub-frame */
|
||||
spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
|
||||
spx_coef_t *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */
|
||||
spx_coef_t *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */
|
||||
|
||||
spx_mem_t *mem_sp; /**< Synthesis signal memory */
|
||||
spx_mem_t *mem_sp2;
|
||||
spx_mem_t *mem_sw; /**< Perceptual signal memory */
|
||||
spx_word32_t *pi_gain;
|
||||
spx_sig_t *innov_save; /**< If non-NULL, innovation is copied here */
|
||||
spx_sig_t *low_innov; /**< Lower-band innovation is copied here magically */
|
||||
spx_word16_t *exc_rms;
|
||||
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
||||
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
|
||||
@ -100,7 +83,8 @@ typedef struct SBEncState {
|
||||
float abr_count;
|
||||
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
|
||||
float relative_quality;
|
||||
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
int encode_submode;
|
||||
const SpeexSubmode * const *submodes;
|
||||
int submodeID;
|
||||
@ -125,23 +109,18 @@ typedef struct SBDecState {
|
||||
int lpc_enh_enabled;
|
||||
|
||||
char *stack;
|
||||
spx_sig_t *x0d, *x1d;
|
||||
spx_sig_t *high;
|
||||
spx_sig_t *y0, *y1;
|
||||
spx_word32_t *g0_mem, *g1_mem;
|
||||
spx_word16_t *g0_mem, *g1_mem;
|
||||
|
||||
spx_sig_t *exc;
|
||||
spx_sig_t *excBuf;
|
||||
spx_lsp_t *qlsp;
|
||||
spx_word16_t *excBuf;
|
||||
spx_lsp_t *old_qlsp;
|
||||
spx_lsp_t *interp_qlsp;
|
||||
spx_coef_t *interp_qlpc;
|
||||
|
||||
spx_mem_t *mem_sp;
|
||||
spx_word32_t *pi_gain;
|
||||
spx_sig_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
spx_sig_t *low_innov; /** Lower-band innovation is copied here magically */
|
||||
spx_word16_t *exc_rms;
|
||||
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||
|
||||
spx_word16_t last_ener;
|
||||
spx_int32_t seed;
|
||||
|
||||
int encode_submode;
|
||||
|
289
libs/speex/libspeex/scal.c
Normal file
289
libs/speex/libspeex/scal.c
Normal file
@ -0,0 +1,289 @@
|
||||
/* Copyright (C) 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation
|
||||
|
||||
File: scal.c
|
||||
Shaped comb-allpass filter for channel decorrelation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The algorithm implemented here is described in:
|
||||
|
||||
* J.-M. Valin, Perceptually-Motivated Nonlinear Channel Decorrelation For
|
||||
Stereo Acoustic Echo Cancellation, Accepted for Joint Workshop on
|
||||
Handsfree Speech Communication and Microphone Arrays (HSCMA), 2008.
|
||||
http://people.xiph.org/~jm/papers/valin_hscma2008.pdf
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "speex/speex_echo.h"
|
||||
#include "vorbis_psy.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
#include "smallft.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ALLPASS_ORDER 20
|
||||
|
||||
struct SpeexDecorrState_ {
|
||||
int rate;
|
||||
int channels;
|
||||
int frame_size;
|
||||
#ifdef VORBIS_PSYCHO
|
||||
VorbisPsy *psy;
|
||||
struct drft_lookup lookup;
|
||||
float *wola_mem;
|
||||
float *curve;
|
||||
#endif
|
||||
float *vorbis_win;
|
||||
int seed;
|
||||
float *y;
|
||||
|
||||
/* Per-channel stuff */
|
||||
float *buff;
|
||||
float (*ring)[ALLPASS_ORDER];
|
||||
int *ringID;
|
||||
int *order;
|
||||
float *alpha;
|
||||
};
|
||||
|
||||
|
||||
|
||||
EXPORT SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size)
|
||||
{
|
||||
int i, ch;
|
||||
SpeexDecorrState *st = speex_alloc(sizeof(SpeexDecorrState));
|
||||
st->rate = rate;
|
||||
st->channels = channels;
|
||||
st->frame_size = frame_size;
|
||||
#ifdef VORBIS_PSYCHO
|
||||
st->psy = vorbis_psy_init(rate, 2*frame_size);
|
||||
spx_drft_init(&st->lookup, 2*frame_size);
|
||||
st->wola_mem = speex_alloc(frame_size*sizeof(float));
|
||||
st->curve = speex_alloc(frame_size*sizeof(float));
|
||||
#endif
|
||||
st->y = speex_alloc(frame_size*sizeof(float));
|
||||
|
||||
st->buff = speex_alloc(channels*2*frame_size*sizeof(float));
|
||||
st->ringID = speex_alloc(channels*sizeof(int));
|
||||
st->order = speex_alloc(channels*sizeof(int));
|
||||
st->alpha = speex_alloc(channels*sizeof(float));
|
||||
st->ring = speex_alloc(channels*ALLPASS_ORDER*sizeof(float));
|
||||
|
||||
/*FIXME: The +20 is there only as a kludge for ALL_PASS_OLA*/
|
||||
st->vorbis_win = speex_alloc((2*frame_size+20)*sizeof(float));
|
||||
for (i=0;i<2*frame_size;i++)
|
||||
st->vorbis_win[i] = sin(.5*M_PI* sin(M_PI*i/(2*frame_size))*sin(M_PI*i/(2*frame_size)) );
|
||||
st->seed = rand();
|
||||
|
||||
for (ch=0;ch<channels;ch++)
|
||||
{
|
||||
for (i=0;i<ALLPASS_ORDER;i++)
|
||||
st->ring[ch][i] = 0;
|
||||
st->ringID[ch] = 0;
|
||||
st->alpha[ch] = 0;
|
||||
st->order[ch] = 10;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
static float uni_rand(int *seed)
|
||||
{
|
||||
const unsigned int jflone = 0x3f800000;
|
||||
const unsigned int jflmsk = 0x007fffff;
|
||||
union {int i; float f;} ran;
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
ran.i = jflone | (jflmsk & *seed);
|
||||
ran.f -= 1.5;
|
||||
return 2*ran.f;
|
||||
}
|
||||
|
||||
static unsigned int irand(int *seed)
|
||||
{
|
||||
*seed = 1664525 * *seed + 1013904223;
|
||||
return ((unsigned int)*seed)>>16;
|
||||
}
|
||||
|
||||
|
||||
EXPORT void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength)
|
||||
{
|
||||
int ch;
|
||||
float amount;
|
||||
|
||||
if (strength<0)
|
||||
strength = 0;
|
||||
if (strength>100)
|
||||
strength = 100;
|
||||
|
||||
amount = .01*strength;
|
||||
for (ch=0;ch<st->channels;ch++)
|
||||
{
|
||||
int i;
|
||||
int N=2*st->frame_size;
|
||||
float beta, beta2;
|
||||
float *x;
|
||||
float max_alpha = 0;
|
||||
|
||||
float *buff;
|
||||
float *ring;
|
||||
int ringID;
|
||||
int order;
|
||||
float alpha;
|
||||
|
||||
buff = st->buff+ch*2*st->frame_size;
|
||||
ring = st->ring[ch];
|
||||
ringID = st->ringID[ch];
|
||||
order = st->order[ch];
|
||||
alpha = st->alpha[ch];
|
||||
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
buff[i] = buff[i+st->frame_size];
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
buff[i+st->frame_size] = in[i*st->channels+ch];
|
||||
|
||||
x = buff+st->frame_size;
|
||||
beta = 1.-.3*amount*amount;
|
||||
if (amount>1)
|
||||
beta = 1-sqrt(.4*amount);
|
||||
else
|
||||
beta = 1-0.63246*amount;
|
||||
if (beta<0)
|
||||
beta = 0;
|
||||
|
||||
beta2 = beta;
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
st->y[i] = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[st->frame_size+i+order]
|
||||
+ x[i-ALLPASS_ORDER]*st->vorbis_win[st->frame_size+i]
|
||||
- alpha*(ring[ringID]
|
||||
- beta*ring[ringID+1>=order?0:ringID+1]);
|
||||
ring[ringID++]=st->y[i];
|
||||
st->y[i] *= st->vorbis_win[st->frame_size+i];
|
||||
if (ringID>=order)
|
||||
ringID=0;
|
||||
}
|
||||
order = order+(irand(&st->seed)%3)-1;
|
||||
if (order < 5)
|
||||
order = 5;
|
||||
if (order > 10)
|
||||
order = 10;
|
||||
/*order = 5+(irand(&st->seed)%6);*/
|
||||
max_alpha = pow(.96+.04*(amount-1),order);
|
||||
if (max_alpha > .98/(1.+beta2))
|
||||
max_alpha = .98/(1.+beta2);
|
||||
|
||||
alpha = alpha + .4*uni_rand(&st->seed);
|
||||
if (alpha > max_alpha)
|
||||
alpha = max_alpha;
|
||||
if (alpha < -max_alpha)
|
||||
alpha = -max_alpha;
|
||||
for (i=0;i<ALLPASS_ORDER;i++)
|
||||
ring[i] = 0;
|
||||
ringID = 0;
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
float tmp = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[i+order]
|
||||
+ x[i-ALLPASS_ORDER]*st->vorbis_win[i]
|
||||
- alpha*(ring[ringID]
|
||||
- beta*ring[ringID+1>=order?0:ringID+1]);
|
||||
ring[ringID++]=tmp;
|
||||
tmp *= st->vorbis_win[i];
|
||||
if (ringID>=order)
|
||||
ringID=0;
|
||||
st->y[i] += tmp;
|
||||
}
|
||||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
float frame[N];
|
||||
float scale = 1./N;
|
||||
for (i=0;i<2*st->frame_size;i++)
|
||||
frame[i] = buff[i];
|
||||
//float coef = .5*0.78130;
|
||||
float coef = M_PI*0.075063 * 0.93763 * amount * .8 * 0.707;
|
||||
compute_curve(st->psy, buff, st->curve);
|
||||
for (i=1;i<st->frame_size;i++)
|
||||
{
|
||||
float x1,x2;
|
||||
float gain;
|
||||
do {
|
||||
x1 = uni_rand(&st->seed);
|
||||
x2 = uni_rand(&st->seed);
|
||||
} while (x1*x1+x2*x2 > 1.);
|
||||
gain = coef*sqrt(.1+st->curve[i]);
|
||||
frame[2*i-1] = gain*x1;
|
||||
frame[2*i] = gain*x2;
|
||||
}
|
||||
frame[0] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[0]);
|
||||
frame[2*st->frame_size-1] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[st->frame_size-1]);
|
||||
spx_drft_backward(&st->lookup,frame);
|
||||
for (i=0;i<2*st->frame_size;i++)
|
||||
frame[i] *= st->vorbis_win[i];
|
||||
#endif
|
||||
|
||||
for (i=0;i<st->frame_size;i++)
|
||||
{
|
||||
#ifdef VORBIS_PSYCHO
|
||||
float tmp = st->y[i] + frame[i] + st->wola_mem[i];
|
||||
st->wola_mem[i] = frame[i+st->frame_size];
|
||||
#else
|
||||
float tmp = st->y[i];
|
||||
#endif
|
||||
if (tmp>32767)
|
||||
tmp = 32767;
|
||||
if (tmp < -32767)
|
||||
tmp = -32767;
|
||||
out[i*st->channels+ch] = tmp;
|
||||
}
|
||||
|
||||
st->ringID[ch] = ringID;
|
||||
st->order[ch] = order;
|
||||
st->alpha[ch] = alpha;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void speex_decorrelate_destroy(SpeexDecorrState *st)
|
||||
{
|
||||
#ifdef VORBIS_PSYCHO
|
||||
vorbis_psy_destroy(st->psy);
|
||||
speex_free(st->wola_mem);
|
||||
speex_free(st->curve);
|
||||
#endif
|
||||
speex_free(st->buff);
|
||||
speex_free(st->ring);
|
||||
speex_free(st->ringID);
|
||||
speex_free(st->alpha);
|
||||
speex_free(st->vorbis_win);
|
||||
speex_free(st->order);
|
||||
speex_free(st->y);
|
||||
speex_free(st);
|
||||
}
|
@ -34,7 +34,8 @@
|
||||
|
||||
#include <math.h>
|
||||
#include "smallft.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
static void drfti1(int n, float *wa, int *ifac){
|
||||
static int ntryh[4] = { 4,2,3,5 };
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "modes.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
@ -47,22 +48,22 @@
|
||||
|
||||
|
||||
|
||||
void *speex_encoder_init(const SpeexMode *mode)
|
||||
EXPORT void *speex_encoder_init(const SpeexMode *mode)
|
||||
{
|
||||
return mode->enc_init(mode);
|
||||
}
|
||||
|
||||
void *speex_decoder_init(const SpeexMode *mode)
|
||||
EXPORT void *speex_decoder_init(const SpeexMode *mode)
|
||||
{
|
||||
return mode->dec_init(mode);
|
||||
}
|
||||
|
||||
void speex_encoder_destroy(void *state)
|
||||
EXPORT void speex_encoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->enc_destroy(state);
|
||||
}
|
||||
|
||||
void speex_decoder_destroy(void *state)
|
||||
EXPORT void speex_decoder_destroy(void *state)
|
||||
{
|
||||
(*((SpeexMode**)state))->dec_destroy(state);
|
||||
}
|
||||
@ -83,7 +84,8 @@ int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
@ -100,15 +102,17 @@ int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
}
|
||||
return (*((SpeexMode**)state))->enc(state, short_in, bits);
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
{
|
||||
SpeexMode *mode;
|
||||
mode = *(SpeexMode**)state;
|
||||
return (mode)->enc(state, in, bits);
|
||||
}
|
||||
|
||||
int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
{
|
||||
int i, ret;
|
||||
spx_int32_t N;
|
||||
@ -119,8 +123,9 @@ int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
out[i] = short_out[i];
|
||||
return ret;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
{
|
||||
SpeexMode *mode = *(SpeexMode**)state;
|
||||
return (mode)->dec(state, bits, out);
|
||||
@ -128,12 +133,12 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
|
||||
#else
|
||||
|
||||
int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
EXPORT int speex_encode(void *state, float *in, SpeexBits *bits)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc(state, in, bits);
|
||||
}
|
||||
|
||||
int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
@ -144,12 +149,12 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
|
||||
return (*((SpeexMode**)state))->enc(state, float_in, bits);
|
||||
}
|
||||
|
||||
int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec(state, bits, out);
|
||||
}
|
||||
|
||||
int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
{
|
||||
int i;
|
||||
spx_int32_t N;
|
||||
@ -172,12 +177,12 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
||||
|
||||
|
||||
|
||||
int speex_encoder_ctl(void *state, int request, void *ptr)
|
||||
EXPORT int speex_encoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
|
||||
}
|
||||
|
||||
int speex_decoder_ctl(void *state, int request, void *ptr)
|
||||
EXPORT int speex_decoder_ctl(void *state, int request, void *ptr)
|
||||
{
|
||||
return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
|
||||
}
|
||||
@ -208,32 +213,9 @@ int nb_mode_query(const void *mode, int request, void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wb_mode_query(const void *mode, int request, void *ptr)
|
||||
{
|
||||
const SpeexSBMode *m = (const SpeexSBMode*)mode;
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case SPEEX_MODE_FRAME_SIZE:
|
||||
*((int*)ptr)=2*m->frameSize;
|
||||
break;
|
||||
case SPEEX_SUBMODE_BITS_PER_FRAME:
|
||||
if (*((int*)ptr)==0)
|
||||
*((int*)ptr) = SB_SUBMODE_BITS+1;
|
||||
else if (m->submodes[*((int*)ptr)]==NULL)
|
||||
*((int*)ptr) = -1;
|
||||
else
|
||||
*((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
|
||||
break;
|
||||
default:
|
||||
speex_warning_int("Unknown wb_mode_query request: ", request);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int speex_lib_ctl(int request, void *ptr)
|
||||
EXPORT int speex_lib_ctl(int request, void *ptr)
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
|
@ -37,9 +37,10 @@
|
||||
#endif
|
||||
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
|
||||
EXPORT int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
|
||||
{
|
||||
int id;
|
||||
SpeexCallback *callback;
|
||||
@ -71,7 +72,7 @@ int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *st
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
@ -79,7 +80,7 @@ int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
@ -87,7 +88,7 @@ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t m;
|
||||
m = speex_bits_unpack_unsigned(bits, 4);
|
||||
@ -95,15 +96,17 @@ int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t vbr;
|
||||
vbr = speex_bits_unpack_unsigned(bits, 1);
|
||||
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
spx_int32_t enh;
|
||||
enh = speex_bits_unpack_unsigned(bits, 1);
|
||||
@ -111,16 +114,17 @@ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
#ifndef DISABLE_VBR
|
||||
EXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
float qual;
|
||||
qual = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
||||
|
||||
int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
unsigned char ch;
|
||||
ch = speex_bits_unpack_unsigned(bits, 8);
|
||||
@ -132,7 +136,7 @@ int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||
|
||||
|
||||
/* Default handler for user callbacks: skip it */
|
||||
int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
|
||||
EXPORT int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
int req_size = speex_bits_unpack_unsigned(bits, 4);
|
||||
speex_bits_advance(bits, 5+8*req_size);
|
||||
|
@ -35,14 +35,31 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <speex/speex_header.h>
|
||||
#include <speex/speex.h>
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/** Convert little endian */
|
||||
static inline spx_int32_t le_int(spx_int32_t i)
|
||||
{
|
||||
#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
|
||||
spx_uint32_t ui, ret;
|
||||
ui = i;
|
||||
ret = ui>>24;
|
||||
ret |= (ui>>8)&0x0000ff00;
|
||||
ret |= (ui<<8)&0x00ff0000;
|
||||
ret |= (ui<<24);
|
||||
return ret;
|
||||
#else
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ENDIAN_SWITCH(x) {x=le_int(x);}
|
||||
|
||||
|
||||
@ -66,7 +83,7 @@ typedef struct SpeexHeader {
|
||||
} SpeexHeader;
|
||||
*/
|
||||
|
||||
void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
|
||||
EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
|
||||
{
|
||||
int i;
|
||||
const char *h="Speex ";
|
||||
@ -101,12 +118,12 @@ void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const Spe
|
||||
header->reserved2 = 0;
|
||||
}
|
||||
|
||||
char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
{
|
||||
SpeexHeader *le_header;
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
speex_move(le_header, header, sizeof(SpeexHeader));
|
||||
SPEEX_COPY(le_header, header, 1);
|
||||
|
||||
/*Make sure everything is now little-endian*/
|
||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||
@ -125,7 +142,7 @@ char *speex_header_to_packet(SpeexHeader *header, int *size)
|
||||
return (char *)le_header;
|
||||
}
|
||||
|
||||
SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
{
|
||||
int i;
|
||||
SpeexHeader *le_header;
|
||||
@ -133,20 +150,20 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
for (i=0;i<8;i++)
|
||||
if (packet[i]!=h[i])
|
||||
{
|
||||
speex_warning ("This doesn't look like a Speex file");
|
||||
speex_notify("This doesn't look like a Speex file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*FIXME: Do we allow larger headers?*/
|
||||
if (size < (int)sizeof(SpeexHeader))
|
||||
{
|
||||
speex_warning("Speex header too small");
|
||||
speex_notify("Speex header too small");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
||||
|
||||
speex_move(le_header, packet, sizeof(SpeexHeader));
|
||||
SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);
|
||||
|
||||
/*Make sure everything is converted correctly from little-endian*/
|
||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||
@ -161,6 +178,23 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
|
||||
ENDIAN_SWITCH(le_header->frames_per_packet);
|
||||
ENDIAN_SWITCH(le_header->extra_headers);
|
||||
|
||||
if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0)
|
||||
{
|
||||
speex_notify("Invalid mode specified in Speex header");
|
||||
speex_free (le_header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (le_header->nb_channels>2)
|
||||
le_header->nb_channels = 2;
|
||||
if (le_header->nb_channels<1)
|
||||
le_header->nb_channels = 1;
|
||||
|
||||
return le_header;
|
||||
|
||||
}
|
||||
|
||||
EXPORT void speex_header_free(void *ptr)
|
||||
{
|
||||
speex_free(ptr);
|
||||
}
|
||||
|
@ -36,11 +36,15 @@
|
||||
#define STACK_ALLOC_H
|
||||
|
||||
#ifdef USE_ALLOCA
|
||||
#ifdef WIN32
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
# ifdef WIN32
|
||||
# include <malloc.h>
|
||||
# else
|
||||
# ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -62,15 +66,6 @@
|
||||
* @param type Type of element
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def PUSHS(stack, type)
|
||||
*
|
||||
* Allocates a struct stack
|
||||
*
|
||||
* @param stack Stack
|
||||
* @param type Struct type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def VARDECL(var)
|
||||
*
|
||||
@ -97,16 +92,12 @@
|
||||
|
||||
#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
|
||||
|
||||
#define PUSHS(stack, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(long)),VALGRIND_MAKE_WRITABLE(stack, (sizeof(type))),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
|
||||
|
||||
#else
|
||||
|
||||
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
|
||||
|
||||
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
|
||||
|
||||
#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(VAR_ARRAYS)
|
||||
|
@ -35,13 +35,77 @@
|
||||
|
||||
#include <speex/speex_stereo.h>
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "math_approx.h"
|
||||
#include "vq.h"
|
||||
#include <math.h>
|
||||
#include "os_support.h"
|
||||
|
||||
typedef struct RealSpeexStereoState {
|
||||
spx_word32_t balance; /**< Left/right balance info */
|
||||
spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
|
||||
spx_word32_t smooth_left; /**< Smoothed left channel gain */
|
||||
spx_word32_t smooth_right; /**< Smoothed right channel gain */
|
||||
spx_uint32_t reserved1; /**< Reserved for future use */
|
||||
spx_int32_t reserved2; /**< Reserved for future use */
|
||||
} RealSpeexStereoState;
|
||||
|
||||
|
||||
/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
|
||||
#ifndef FIXED_POINT
|
||||
static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
|
||||
static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};
|
||||
#else
|
||||
static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
|
||||
static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};
|
||||
static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104,
|
||||
134, 172, 221, 284, 364, 468, 600, 771,
|
||||
990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,
|
||||
7314, 9392, 12059, 15484, 19882, 25529, 32766};
|
||||
#endif
|
||||
|
||||
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
/* This is an ugly compatibility hack that properly resets the stereo state
|
||||
In case it it compiled in fixed-point, but initialised with the deprecated
|
||||
floating point static initialiser */
|
||||
#ifdef FIXED_POINT
|
||||
#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0);
|
||||
#else
|
||||
#define COMPATIBILITY_HACK(s)
|
||||
#endif
|
||||
|
||||
EXPORT SpeexStereoState *speex_stereo_state_init()
|
||||
{
|
||||
SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState));
|
||||
speex_stereo_state_reset(stereo);
|
||||
return stereo;
|
||||
}
|
||||
|
||||
EXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo)
|
||||
{
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
#ifdef FIXED_POINT
|
||||
stereo->balance = 65536;
|
||||
stereo->e_ratio = 16384;
|
||||
stereo->smooth_left = 16384;
|
||||
stereo->smooth_right = 16384;
|
||||
stereo->reserved1 = 0xdeadbeef;
|
||||
stereo->reserved2 = 0;
|
||||
#else
|
||||
stereo->balance = 1.0f;
|
||||
stereo->e_ratio = .5f;
|
||||
stereo->smooth_left = 1.f;
|
||||
stereo->smooth_right = 1.f;
|
||||
stereo->reserved1 = 0;
|
||||
stereo->reserved2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo)
|
||||
{
|
||||
speex_free(stereo);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
{
|
||||
int i, tmp;
|
||||
float e_left=0, e_right=0, e_tot=0;
|
||||
@ -73,118 +137,158 @@ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
|
||||
|
||||
speex_bits_pack(bits, (int)balance, 5);
|
||||
|
||||
/*Quantize energy ratio*/
|
||||
tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
|
||||
/* FIXME: this is a hack */
|
||||
tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
|
||||
speex_bits_pack(bits, tmp, 2);
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
|
||||
EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
|
||||
{
|
||||
int i, tmp;
|
||||
float e_left=0, e_right=0, e_tot=0;
|
||||
float balance, e_ratio;
|
||||
spx_word32_t e_left=0, e_right=0, e_tot=0;
|
||||
spx_word32_t balance, e_ratio;
|
||||
spx_word32_t largest, smallest;
|
||||
int balance_id;
|
||||
#ifdef FIXED_POINT
|
||||
int shift;
|
||||
#endif
|
||||
|
||||
/* In band marker */
|
||||
speex_bits_pack(bits, 14, 5);
|
||||
/* Stereo marker */
|
||||
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
||||
|
||||
for (i=0;i<frame_size;i++)
|
||||
{
|
||||
e_left += ((float)data[2*i])*data[2*i];
|
||||
e_right += ((float)data[2*i+1])*data[2*i+1];
|
||||
e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
|
||||
e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);
|
||||
#ifdef FIXED_POINT
|
||||
/* I think this is actually unbiased */
|
||||
data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);
|
||||
#else
|
||||
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
|
||||
e_tot += ((float)data[i])*data[i];
|
||||
#endif
|
||||
e_tot += SHR32(MULT16_16(data[i],data[i]),8);
|
||||
}
|
||||
balance=(e_left+1)/(e_right+1);
|
||||
e_ratio = e_tot/(1+e_left+e_right);
|
||||
|
||||
/*Quantization*/
|
||||
speex_bits_pack(bits, 14, 5);
|
||||
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
||||
|
||||
balance=4*log(balance);
|
||||
|
||||
/*Pack sign*/
|
||||
if (balance>0)
|
||||
if (e_left > e_right)
|
||||
{
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
else
|
||||
largest = e_left;
|
||||
smallest = e_right;
|
||||
} else {
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
balance=floor(.5+fabs(balance));
|
||||
if (balance>30)
|
||||
balance=31;
|
||||
largest = e_right;
|
||||
smallest = e_left;
|
||||
}
|
||||
|
||||
/* Balance quantization */
|
||||
#ifdef FIXED_POINT
|
||||
shift = spx_ilog2(largest)-15;
|
||||
largest = VSHR32(largest, shift-4);
|
||||
smallest = VSHR32(smallest, shift);
|
||||
balance = DIV32(largest, ADD32(smallest, 1));
|
||||
if (balance > 32767)
|
||||
balance = 32767;
|
||||
balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
|
||||
#else
|
||||
balance=(largest+1.)/(smallest+1.);
|
||||
balance=4*log(balance);
|
||||
balance_id=floor(.5+fabs(balance));
|
||||
if (balance_id>30)
|
||||
balance_id=31;
|
||||
#endif
|
||||
|
||||
speex_bits_pack(bits, (int)balance, 5);
|
||||
speex_bits_pack(bits, balance_id, 5);
|
||||
|
||||
/*Quantize energy ratio*/
|
||||
tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
|
||||
/* "coherence" quantisation */
|
||||
#ifdef FIXED_POINT
|
||||
shift = spx_ilog2(e_tot);
|
||||
e_tot = VSHR32(e_tot, shift-25);
|
||||
e_left = VSHR32(e_left, shift-10);
|
||||
e_right = VSHR32(e_right, shift-10);
|
||||
e_ratio = DIV32(e_tot, e_left+e_right+1);
|
||||
#else
|
||||
e_ratio = e_tot/(1.+e_left+e_right);
|
||||
#endif
|
||||
|
||||
tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
|
||||
/*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/
|
||||
speex_bits_pack(bits, tmp, 2);
|
||||
}
|
||||
|
||||
void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
|
||||
{
|
||||
float balance, e_ratio;
|
||||
int i;
|
||||
float e_tot=0, e_left, e_right, e_sum;
|
||||
|
||||
spx_word32_t balance;
|
||||
spx_word16_t e_left, e_right, e_ratio;
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
balance=stereo->balance;
|
||||
e_ratio=stereo->e_ratio;
|
||||
|
||||
/* These two are Q14, with max value just below 2. */
|
||||
e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
|
||||
e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
|
||||
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
e_tot += ((float)data[i])*data[i];
|
||||
spx_word16_t tmp=data[i];
|
||||
stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
|
||||
stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
|
||||
data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||
data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||
}
|
||||
e_sum=e_tot/e_ratio;
|
||||
e_left = e_sum*balance / (1+balance);
|
||||
e_right = e_sum-e_left;
|
||||
}
|
||||
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||
|
||||
e_left = sqrt(e_left/(e_tot+.01));
|
||||
e_right = sqrt(e_right/(e_tot+.01));
|
||||
EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
|
||||
{
|
||||
int i;
|
||||
spx_word32_t balance;
|
||||
spx_word16_t e_left, e_right, e_ratio;
|
||||
RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
balance=stereo->balance;
|
||||
e_ratio=stereo->e_ratio;
|
||||
|
||||
/* These two are Q14, with max value just below 2. */
|
||||
e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
|
||||
e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
|
||||
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
float ftmp=data[i];
|
||||
stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
|
||||
stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
|
||||
data[2*i] = stereo->smooth_left*ftmp;
|
||||
data[2*i+1] = stereo->smooth_right*ftmp;
|
||||
spx_int16_t tmp=data[i];
|
||||
stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
|
||||
stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
|
||||
data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||
data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo)
|
||||
EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
float balance, e_ratio;
|
||||
int i;
|
||||
float e_tot=0, e_left, e_right, e_sum;
|
||||
|
||||
balance=stereo->balance;
|
||||
e_ratio=stereo->e_ratio;
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
e_tot += ((float)data[i])*data[i];
|
||||
}
|
||||
e_sum=e_tot/e_ratio;
|
||||
e_left = e_sum*balance / (1+balance);
|
||||
e_right = e_sum-e_left;
|
||||
|
||||
e_left = sqrt(e_left/(e_tot+.01));
|
||||
e_right = sqrt(e_right/(e_tot+.01));
|
||||
|
||||
for (i=frame_size-1;i>=0;i--)
|
||||
{
|
||||
float ftmp=data[i];
|
||||
stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
|
||||
stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
|
||||
data[2*i] = stereo->smooth_left*ftmp;
|
||||
data[2*i+1] = stereo->smooth_right*ftmp;
|
||||
}
|
||||
}
|
||||
|
||||
int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||
{
|
||||
SpeexStereoState *stereo;
|
||||
float sign=1;
|
||||
RealSpeexStereoState *stereo;
|
||||
spx_word16_t sign=1, dexp;
|
||||
int tmp;
|
||||
|
||||
stereo = (SpeexStereoState*)data;
|
||||
stereo = (RealSpeexStereoState*)data;
|
||||
|
||||
COMPATIBILITY_HACK(stereo);
|
||||
|
||||
if (speex_bits_unpack_unsigned(bits, 1))
|
||||
sign=-1;
|
||||
tmp = speex_bits_unpack_unsigned(bits, 5);
|
||||
stereo->balance = exp(sign*.25*tmp);
|
||||
|
||||
dexp = speex_bits_unpack_unsigned(bits, 5);
|
||||
#ifndef FIXED_POINT
|
||||
stereo->balance = exp(sign*.25*dexp);
|
||||
#else
|
||||
stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9)));
|
||||
#endif
|
||||
tmp = speex_bits_unpack_unsigned(bits, 2);
|
||||
stereo->e_ratio = e_ratio_quant[tmp];
|
||||
|
||||
|
@ -20,13 +20,13 @@ int main()
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
i=0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
f=8000;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
|
||||
i=8000;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
|
||||
i=0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
|
||||
f=.4;
|
||||
f=.0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
|
||||
f=.3;
|
||||
f=.0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
|
||||
while (1)
|
||||
{
|
||||
@ -34,7 +34,7 @@ int main()
|
||||
fread(in, sizeof(short), NN, stdin);
|
||||
if (feof(stdin))
|
||||
break;
|
||||
vad = speex_preprocess(st, in, NULL);
|
||||
vad = speex_preprocess_run(st, in);
|
||||
/*fprintf (stderr, "%d\n", vad);*/
|
||||
fwrite(in, sizeof(short), NN, stdout);
|
||||
count++;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "speex/speex_echo.h"
|
||||
#include "speex/speex_preprocess.h"
|
||||
|
||||
@ -17,37 +16,38 @@
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int echo_fd, ref_fd, e_fd;
|
||||
spx_int32_t noise[NN+1];
|
||||
FILE *echo_fd, *ref_fd, *e_fd;
|
||||
short echo_buf[NN], ref_buf[NN], e_buf[NN];
|
||||
SpeexEchoState *st;
|
||||
SpeexPreprocessState *den;
|
||||
int sampleRate = 8000;
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
fprintf (stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
|
||||
fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
|
||||
exit(1);
|
||||
}
|
||||
echo_fd = open (argv[2], O_RDONLY);
|
||||
ref_fd = open (argv[1], O_RDONLY);
|
||||
e_fd = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
echo_fd = fopen(argv[2], "rb");
|
||||
ref_fd = fopen(argv[1], "rb");
|
||||
e_fd = fopen(argv[3], "wb");
|
||||
|
||||
st = speex_echo_state_init(NN, TAIL);
|
||||
den = speex_preprocess_state_init(NN, 8000);
|
||||
int tmp = 8000;
|
||||
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);
|
||||
den = speex_preprocess_state_init(NN, sampleRate);
|
||||
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
|
||||
speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
|
||||
|
||||
while (read(ref_fd, ref_buf, NN*2))
|
||||
while (!feof(ref_fd) && !feof(echo_fd))
|
||||
{
|
||||
read(echo_fd, echo_buf, NN*2);
|
||||
speex_echo_cancel(st, ref_buf, echo_buf, e_buf, noise);
|
||||
/*speex_preprocess(den, e_buf, noise);*/
|
||||
write(e_fd, e_buf, NN*2);
|
||||
fread(ref_buf, sizeof(short), NN, ref_fd);
|
||||
fread(echo_buf, sizeof(short), NN, echo_fd);
|
||||
speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
|
||||
speex_preprocess_run(den, e_buf);
|
||||
fwrite(e_buf, sizeof(short), NN, e_fd);
|
||||
}
|
||||
speex_echo_state_destroy(st);
|
||||
speex_preprocess_state_destroy(den);
|
||||
close(e_fd);
|
||||
close(echo_fd);
|
||||
close(ref_fd);
|
||||
fclose(e_fd);
|
||||
fclose(echo_fd);
|
||||
fclose(ref_fd);
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ int main(int argc, char **argv)
|
||||
FILE *fin, *fout, *fbits=NULL;
|
||||
short in_short[FRAME_SIZE];
|
||||
short out_short[FRAME_SIZE];
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
int snr_frames = 0;
|
||||
char cbits[200];
|
||||
int nbBits;
|
||||
@ -32,11 +31,8 @@ int main(int argc, char **argv)
|
||||
spx_int32_t skip_group_delay;
|
||||
SpeexCallback callback;
|
||||
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
st = speex_encoder_init(&speex_nb_mode);
|
||||
dec = speex_decoder_init(&speex_nb_mode);
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||
|
||||
/* BEGIN: You probably don't need the following in a real application */
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
@ -74,13 +70,13 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "r");
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "w+");
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "w");
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
@ -109,6 +105,12 @@ int main(int argc, char **argv)
|
||||
speex_decoder_destroy(dec);
|
||||
speex_bits_destroy(&bits);
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
{
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
/* This code just computes SNR, so you don't need it either */
|
||||
rewind(fin);
|
||||
rewind(fout);
|
||||
@ -127,9 +129,6 @@ int main(int argc, char **argv)
|
||||
errpow += e;
|
||||
snr_frames++;
|
||||
}
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
snr = 10 * log10( sigpow / errpow );
|
||||
seg_snr /= snr_frames;
|
||||
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
||||
@ -137,6 +136,11 @@ int main(int argc, char **argv)
|
||||
#ifdef FIXED_DEBUG
|
||||
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ int main(int argc, char **argv)
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
st = speex_encoder_init(&speex_uwb_mode);
|
||||
dec = speex_decoder_init(&speex_uwb_mode);
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
callback.func = speex_std_char_handler;
|
||||
@ -69,13 +69,13 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "r");
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "w+");
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "w");
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
|
@ -19,7 +19,6 @@ int main(int argc, char **argv)
|
||||
FILE *fin, *fout, *fbits=NULL;
|
||||
short in_short[FRAME_SIZE];
|
||||
short out_short[FRAME_SIZE];
|
||||
float in_float[FRAME_SIZE];
|
||||
float sigpow,errpow,snr, seg_snr=0;
|
||||
int snr_frames = 0;
|
||||
char cbits[200];
|
||||
@ -36,8 +35,8 @@ int main(int argc, char **argv)
|
||||
sigpow = 0;
|
||||
errpow = 0;
|
||||
|
||||
st = speex_encoder_init(&speex_wb_mode);
|
||||
dec = speex_decoder_init(&speex_wb_mode);
|
||||
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||
|
||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||
callback.func = speex_std_char_handler;
|
||||
@ -74,13 +73,13 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "r");
|
||||
fin = fopen(inFile, "rb");
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "w+");
|
||||
fout = fopen(outFile, "wb+");
|
||||
if (argc==4)
|
||||
{
|
||||
bitsFile = argv[3];
|
||||
fbits = fopen(bitsFile, "w");
|
||||
fbits = fopen(bitsFile, "wb");
|
||||
}
|
||||
speex_bits_init(&bits);
|
||||
while (!feof(fin))
|
||||
@ -88,8 +87,6 @@ int main(int argc, char **argv)
|
||||
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
||||
if (feof(fin))
|
||||
break;
|
||||
for (i=0;i<FRAME_SIZE;i++)
|
||||
in_float[i]=in_short[i];
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
speex_encode_int(st, in_short, &bits);
|
||||
|
75
libs/speex/libspeex/testjitter.c
Normal file
75
libs/speex/libspeex/testjitter.c
Normal file
@ -0,0 +1,75 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <speex/speex_jitter.h>
|
||||
#include <stdio.h>
|
||||
|
||||
union jbpdata {
|
||||
unsigned int idx;
|
||||
unsigned char data[4];
|
||||
};
|
||||
|
||||
void synthIn(JitterBufferPacket *in, int idx, int span) {
|
||||
union jbpdata d;
|
||||
d.idx = idx;
|
||||
|
||||
in->data = d.data;
|
||||
in->len = sizeof(d);
|
||||
in->timestamp = idx * 10;
|
||||
in->span = span * 10;
|
||||
in->sequence = idx;
|
||||
in->user_data = 0;
|
||||
}
|
||||
|
||||
void jitterFill(JitterBuffer *jb) {
|
||||
char buffer[65536];
|
||||
JitterBufferPacket in, out;
|
||||
int i;
|
||||
|
||||
out.data = buffer;
|
||||
|
||||
jitter_buffer_reset(jb);
|
||||
|
||||
for(i=0;i<100;++i) {
|
||||
synthIn(&in, i, 1);
|
||||
jitter_buffer_put(jb, &in);
|
||||
|
||||
out.len = 65536;
|
||||
if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
|
||||
printf("Fill test failed iteration %d\n", i);
|
||||
}
|
||||
if (out.timestamp != i * 10) {
|
||||
printf("Fill test expected %d got %d\n", i*10, out.timestamp);
|
||||
}
|
||||
jitter_buffer_tick(jb);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char buffer[65536];
|
||||
JitterBufferPacket in, out;
|
||||
int i;
|
||||
|
||||
JitterBuffer *jb = jitter_buffer_init(10);
|
||||
|
||||
out.data = buffer;
|
||||
|
||||
/* Frozen sender case */
|
||||
jitterFill(jb);
|
||||
for(i=0;i<100;++i) {
|
||||
out.len = 65536;
|
||||
jitter_buffer_get(jb, &out, 10, NULL);
|
||||
jitter_buffer_tick(jb);
|
||||
}
|
||||
synthIn(&in, 100, 1);
|
||||
jitter_buffer_put(jb, &in);
|
||||
out.len = 65536;
|
||||
if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
|
||||
printf("Failed frozen sender resynchronize\n");
|
||||
} else {
|
||||
printf("Frozen sender: Jitter %d\n", out.timestamp - 100*10);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -45,31 +45,32 @@
|
||||
#define MIN_ENERGY 6000
|
||||
#define NOISE_POW .3
|
||||
|
||||
#ifndef DISABLE_VBR
|
||||
|
||||
const float vbr_nb_thresh[9][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */
|
||||
{ 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */
|
||||
{10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */
|
||||
{11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */
|
||||
{11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */
|
||||
{ 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */
|
||||
{ 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */
|
||||
{10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.5f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */
|
||||
{11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 3.9f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */
|
||||
{11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 6.0f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 7.0f, 6.0f, 5.0f, 3.0f}, /* 15 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 7.0f, 6.0f, 5.0f}, /* 18 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 9.5f, 7.5f}, /* 24 kbps */
|
||||
{ 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */
|
||||
};
|
||||
|
||||
|
||||
const float vbr_hb_thresh[5][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */
|
||||
{11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */
|
||||
{11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 2 kbps */
|
||||
{11.0f, 11.0f, 9.5f, 8.5f, 7.5f, 6.0f, 5.0f, 3.9f, 3.0f, 2.0f, 1.0f}, /* 6 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.7f, 7.8f, 7.0f, 6.5f, 4.0f}, /* 10 kbps */
|
||||
{11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f} /* 18 kbps */
|
||||
};
|
||||
|
||||
const float vbr_uhb_thresh[2][11]={
|
||||
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
|
||||
{ 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */
|
||||
{ 3.9f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f} /* 2 kbps */
|
||||
};
|
||||
|
||||
void vbr_init(VBRState *vbr)
|
||||
@ -270,3 +271,5 @@ float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float p
|
||||
void vbr_destroy(VBRState *vbr)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* #ifndef DISABLE_VBR */
|
||||
|
@ -37,7 +37,7 @@
|
||||
#ifndef VBR_H
|
||||
#define VBR_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define VBR_MEMORY_SIZE 5
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#define NOISE_COMPAND_LEVELS 40
|
||||
|
||||
|
||||
#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
|
||||
#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
|
||||
#define fromdB(x) (exp((x)*.11512925f))
|
||||
|
||||
/* The bark scale equations are approximations, since the original
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include "vq.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include <xmmintrin.h>
|
||||
@ -70,29 +70,6 @@ int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
|
||||
return i;
|
||||
}
|
||||
|
||||
/*Finds the index of the entry in a codebook that best matches the input*/
|
||||
int vq_index(float *in, const float *codebook, int len, int entries)
|
||||
{
|
||||
int i,j;
|
||||
float min_dist=0;
|
||||
int best_index=0;
|
||||
for (i=0;i<entries;i++)
|
||||
{
|
||||
float dist=0;
|
||||
for (j=0;j<len;j++)
|
||||
{
|
||||
float tmp = in[j]-*codebook++;
|
||||
dist += tmp*tmp;
|
||||
}
|
||||
if (i==0 || dist<min_dist)
|
||||
{
|
||||
min_dist=dist;
|
||||
best_index=i;
|
||||
}
|
||||
}
|
||||
return best_index;
|
||||
}
|
||||
|
||||
|
||||
#ifndef OVERRIDE_VQ_NBEST
|
||||
/*Finds the indices of the n-best entries in a codebook*/
|
||||
|
@ -35,12 +35,11 @@
|
||||
#ifndef VQ_H
|
||||
#define VQ_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);
|
||||
int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);
|
||||
|
||||
int vq_index(float *in, const float *codebook, int len, int entries);
|
||||
#ifdef _USE_SSE
|
||||
#include <xmmintrin.h>
|
||||
void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
|
||||
|
@ -33,9 +33,13 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
const spx_word16_t lag_window[11] = {
|
||||
16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330
|
||||
};
|
||||
|
||||
const spx_word16_t lpc_window[200] = {
|
||||
1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,
|
||||
1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884,
|
||||
@ -64,31 +68,35 @@ const spx_word16_t lpc_window[200] = {
|
||||
6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696
|
||||
};
|
||||
#else
|
||||
const spx_word16_t lag_window[11] = {
|
||||
1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258
|
||||
};
|
||||
|
||||
const spx_word16_t lpc_window[200] = {
|
||||
0.080000, 0.080158, 0.080630, 0.081418, 0.082520, 0.083935, 0.085663, 0.087703,
|
||||
0.090052, 0.092710, 0.095674, 0.098943, 0.102514, 0.106385, 0.110553, 0.115015,
|
||||
0.119769, 0.124811, 0.130137, 0.135744, 0.141628, 0.147786, 0.154212, 0.160902,
|
||||
0.167852, 0.175057, 0.182513, 0.190213, 0.198153, 0.206328, 0.214731, 0.223357,
|
||||
0.232200, 0.241254, 0.250513, 0.259970, 0.269619, 0.279453, 0.289466, 0.299651,
|
||||
0.310000, 0.320507, 0.331164, 0.341965, 0.352901, 0.363966, 0.375151, 0.386449,
|
||||
0.397852, 0.409353, 0.420943, 0.432615, 0.444361, 0.456172, 0.468040, 0.479958,
|
||||
0.491917, 0.503909, 0.515925, 0.527959, 0.540000, 0.552041, 0.564075, 0.576091,
|
||||
0.588083, 0.600042, 0.611960, 0.623828, 0.635639, 0.647385, 0.659057, 0.670647,
|
||||
0.682148, 0.693551, 0.704849, 0.716034, 0.727099, 0.738035, 0.748836, 0.759493,
|
||||
0.770000, 0.780349, 0.790534, 0.800547, 0.810381, 0.820030, 0.829487, 0.838746,
|
||||
0.847800, 0.856643, 0.865269, 0.873672, 0.881847, 0.889787, 0.897487, 0.904943,
|
||||
0.912148, 0.919098, 0.925788, 0.932214, 0.938372, 0.944256, 0.949863, 0.955189,
|
||||
0.960231, 0.964985, 0.969447, 0.973615, 0.977486, 0.981057, 0.984326, 0.987290,
|
||||
0.989948, 0.992297, 0.994337, 0.996065, 0.997480, 0.998582, 0.999370, 0.999842,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
1.000000, 1.000000, 1.000000, 0.998640, 0.994566, 0.987787, 0.978324, 0.966203,
|
||||
0.951458, 0.934131, 0.914270, 0.891931, 0.867179, 0.840084, 0.810723, 0.779182,
|
||||
0.745551, 0.709930, 0.672424, 0.633148, 0.592223, 0.549781, 0.505964, 0.460932,
|
||||
0.414863, 0.367968, 0.320511, 0.272858, 0.225569, 0.179655, 0.137254, 0.103524
|
||||
0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,
|
||||
0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,
|
||||
0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f,
|
||||
0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f,
|
||||
0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f,
|
||||
0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f,
|
||||
0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f,
|
||||
0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f,
|
||||
0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f,
|
||||
0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f,
|
||||
0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f,
|
||||
0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f,
|
||||
0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f,
|
||||
0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f,
|
||||
0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f,
|
||||
0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f,
|
||||
0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f,
|
||||
0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f
|
||||
};
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@ AC_ARG_ENABLE(speextest, [ --disable-speextest Do not try to compile and
|
||||
elif test "x$speex_prefix" != "x" ; then
|
||||
SPEEX_LIBS="-L$speex_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE" ; then
|
||||
SPEEX_LIBS=""
|
||||
SPEEX_LIBS="-L$prefix/lib"
|
||||
fi
|
||||
|
||||
SPEEX_LIBS="$SPEEX_LIBS -lspeex"
|
||||
|
@ -11,4 +11,5 @@ Version: @SPEEX_VERSION@
|
||||
Requires:
|
||||
Conflicts:
|
||||
Libs: -L${libdir} -lspeex
|
||||
Libs.private: -lm
|
||||
Cflags: -I${includedir}
|
||||
|
15
libs/speex/speexdsp.pc.in
Normal file
15
libs/speex/speexdsp.pc.in
Normal file
@ -0,0 +1,15 @@
|
||||
# libspeexdsp pkg-config source file
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: speexdsp
|
||||
Description: Speexdsp is a speech processing library that goes along with the Speex codec
|
||||
Version: @SPEEX_VERSION@
|
||||
Requires: @FFT_PKGCONFIG@
|
||||
Conflicts:
|
||||
Libs: -L${libdir} -lspeexdsp
|
||||
Libs.private: -lm
|
||||
Cflags: -I${includedir}
|
@ -7,7 +7,6 @@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@
|
||||
|
||||
mandir = $(prefix)/share/man
|
||||
man_MANS = speexenc.1 speexdec.1
|
||||
|
||||
EXTRA_DIST = $(man_MANS) getopt_win.h getopt.c getopt1.c wave_out.c wave_out.h skeleton.h
|
||||
@ -18,9 +17,9 @@ noinst_HEADERS = wav_io.h
|
||||
bin_PROGRAMS = speexenc speexdec
|
||||
|
||||
speexenc_SOURCES = speexenc.c wav_io.c skeleton.c
|
||||
speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la \
|
||||
$(OGG_LIBS)
|
||||
speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la $(top_builddir)/libspeex/libspeexdsp.la \
|
||||
$(OGG_LIBS) @FFT_LIBS@
|
||||
|
||||
speexdec_SOURCES = speexdec.c wav_io.c
|
||||
speexdec_LDADD = $(top_builddir)/libspeex/libspeex.la \
|
||||
$(OGG_LIBS)
|
||||
$(OGG_LIBS) @FFT_LIBS@
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
|
||||
.TH SPEEXDEC "1" "September 2003" "speexdec version 1.1" "User Commands"
|
||||
.SH NAME
|
||||
speexdec \- manual page for speexdec version 1.1
|
||||
speexdec \- The reference implementation speex decoder.
|
||||
.SH SYNOPSIS
|
||||
.B speexdec
|
||||
[\fIoptions\fR] \fIinput_file.spx \fR[\fIoutput_file\fR]
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <stdio.h>
|
||||
#if !defined WIN32 && !defined _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
@ -48,8 +50,6 @@
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
#include <windows.h>
|
||||
#include "getopt_win.h"
|
||||
#include "wave_out.h"
|
||||
/* We need the following two to set stdout to binary */
|
||||
#include <io.h>
|
||||
@ -84,7 +84,6 @@
|
||||
#include <speex/speex_header.h>
|
||||
#include <speex/speex_stereo.h>
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "wav_io.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 2000
|
||||
|
||||
@ -107,7 +106,7 @@ static void print_comments(char *comments, int length)
|
||||
end = c+length;
|
||||
len=readint(c, 0);
|
||||
c+=4;
|
||||
if (c+len>end)
|
||||
if (len < 0 || c+len>end)
|
||||
{
|
||||
fprintf (stderr, "Invalid/corrupted comments\n");
|
||||
return;
|
||||
@ -131,7 +130,7 @@ static void print_comments(char *comments, int length)
|
||||
}
|
||||
len=readint(c, 0);
|
||||
c+=4;
|
||||
if (c+len>end)
|
||||
if (len < 0 || c+len>end)
|
||||
{
|
||||
fprintf (stderr, "Invalid/corrupted comments\n");
|
||||
return;
|
||||
@ -232,6 +231,8 @@ FILE *out_file_open(char *outFile, int rate, int *channels)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#elif defined OS2
|
||||
_fsetmode(stdout,"b");
|
||||
#endif
|
||||
fout=stdout;
|
||||
}
|
||||
@ -289,13 +290,17 @@ void usage()
|
||||
|
||||
void version()
|
||||
{
|
||||
printf ("speexdec (Speex decoder) version " SPEEX_VERSION " (compiled " __DATE__ ")\n");
|
||||
const char* speex_version;
|
||||
speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
|
||||
printf ("speexdec (Speex decoder) version %s (compiled " __DATE__ ")\n", speex_version);
|
||||
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||
}
|
||||
|
||||
void version_short()
|
||||
{
|
||||
printf ("speexdec version " SPEEX_VERSION "\n");
|
||||
const char* speex_version;
|
||||
speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
|
||||
printf ("speexdec version %s\n", speex_version);
|
||||
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||
}
|
||||
|
||||
@ -317,6 +322,7 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
||||
{
|
||||
fprintf (stderr, "Mode number %d does not (yet/any longer) exist in this version\n",
|
||||
header->mode);
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -329,17 +335,20 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
||||
if (header->speex_version_id > 1)
|
||||
{
|
||||
fprintf (stderr, "This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", header->speex_version_id);
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode->bitstream_version < header->mode_bitstream_version)
|
||||
{
|
||||
fprintf (stderr, "The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n");
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
if (mode->bitstream_version > header->mode_bitstream_version)
|
||||
{
|
||||
fprintf (stderr, "The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n");
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -347,19 +356,13 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
||||
if (!st)
|
||||
{
|
||||
fprintf (stderr, "Decoder initialization failed.\n");
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
|
||||
speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
|
||||
*granule_frame_size = *frame_size;
|
||||
|
||||
if (!(*channels==1))
|
||||
{
|
||||
callback.callback_id = SPEEX_INBAND_STEREO;
|
||||
callback.func = speex_std_stereo_request_handler;
|
||||
callback.data = stereo;
|
||||
speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback);
|
||||
}
|
||||
if (!*rate)
|
||||
*rate = header->rate;
|
||||
/* Adjust rate if --force-* options are used */
|
||||
@ -384,6 +387,15 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
||||
|
||||
if (*channels==-1)
|
||||
*channels = header->nb_channels;
|
||||
|
||||
if (!(*channels==1))
|
||||
{
|
||||
*channels = 2;
|
||||
callback.callback_id = SPEEX_INBAND_STEREO;
|
||||
callback.func = speex_std_stereo_request_handler;
|
||||
callback.data = stereo;
|
||||
speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback);
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
{
|
||||
@ -630,7 +642,7 @@ int main(int argc, char **argv)
|
||||
packet_no=0;
|
||||
while (!eos && ogg_stream_packetout(&os, &op) == 1)
|
||||
{
|
||||
if (!memcmp(op.packet, "Speex", 5)) {
|
||||
if (op.bytes>=5 && !memcmp(op.packet, "Speex", 5)) {
|
||||
speex_serialno = os.serialno;
|
||||
}
|
||||
if (speex_serialno == -1 || os.serialno != speex_serialno)
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
|
||||
.TH SPEEXENC "1" "September 2003" "speexenc version 1.1" "User Commands"
|
||||
.SH NAME
|
||||
speexenc \- manual page for speexenc version 1.1
|
||||
speexenc \- The reference implementation speex encoder.
|
||||
.SH SYNOPSIS
|
||||
.B speexenc
|
||||
[\fIoptions\fR] \fIinput_file output_file\fR
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <stdio.h>
|
||||
#if !defined WIN32 && !defined _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
@ -53,7 +55,6 @@
|
||||
#include <speex/speex_preprocess.h>
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
#include "getopt_win.h"
|
||||
/* We need the following two to set stdout to binary */
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
@ -182,13 +183,17 @@ void add_fisbone_packet (ogg_stream_state *os, spx_int32_t serialno, SpeexHeader
|
||||
|
||||
void version()
|
||||
{
|
||||
printf ("speexenc (Speex encoder) version " SPEEX_VERSION " (compiled " __DATE__ ")\n");
|
||||
const char* speex_version;
|
||||
speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
|
||||
printf ("speexenc (Speex encoder) version %s (compiled " __DATE__ ")\n", speex_version);
|
||||
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||
}
|
||||
|
||||
void version_short()
|
||||
{
|
||||
printf ("speexenc version " SPEEX_VERSION "\n");
|
||||
const char* speex_version;
|
||||
speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
|
||||
printf ("speexenc version %s\n", speex_version);
|
||||
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||
}
|
||||
|
||||
@ -316,7 +321,8 @@ int main(int argc, char **argv)
|
||||
SpeexHeader header;
|
||||
int nframes=1;
|
||||
spx_int32_t complexity=3;
|
||||
char *vendor_string = "Encoded with Speex " SPEEX_VERSION;
|
||||
const char* speex_version;
|
||||
char vendor_string[64];
|
||||
char *comments;
|
||||
int comments_length;
|
||||
int close_in=0, close_out=0;
|
||||
@ -329,6 +335,9 @@ int main(int argc, char **argv)
|
||||
SpeexPreprocessState *preprocess = NULL;
|
||||
int denoise_enabled=0, agc_enabled=0;
|
||||
spx_int32_t lookahead = 0;
|
||||
|
||||
speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
|
||||
snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version);
|
||||
|
||||
comment_init(&comments, &comments_length, vendor_string);
|
||||
|
||||
@ -505,6 +514,8 @@ int main(int argc, char **argv)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
#elif defined OS2
|
||||
_fsetmode(stdin,"b");
|
||||
#endif
|
||||
fin=stdin;
|
||||
}
|
||||
@ -949,6 +960,8 @@ void comment_init(char **comments, int* length, char *vendor_string)
|
||||
int len=4+vendor_length+4;
|
||||
char *p=(char*)malloc(len);
|
||||
if(p==NULL){
|
||||
fprintf (stderr, "malloc failed in comment_init()\n");
|
||||
exit(1);
|
||||
}
|
||||
writeint(p, 0, vendor_length);
|
||||
memcpy(p+4, vendor_string, vendor_length);
|
||||
@ -967,6 +980,8 @@ void comment_add(char **comments, int* length, char *tag, char *val)
|
||||
|
||||
p=(char*)realloc(p, len);
|
||||
if(p==NULL){
|
||||
fprintf (stderr, "realloc failed in comment_add()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
writeint(p, *length, tag_len+val_len); /* length of comment */
|
||||
|
@ -37,38 +37,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "speex/speex_types.h"
|
||||
|
||||
static spx_uint32_t le_int(spx_uint32_t i)
|
||||
{
|
||||
spx_uint32_t ret=i;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = i>>24;
|
||||
ret += (i>>8)&0x0000ff00;
|
||||
ret += (i<<8)&0x00ff0000;
|
||||
ret += (i<<24);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short be_short(unsigned short s)
|
||||
{
|
||||
unsigned short ret=s;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
ret = s>>8;
|
||||
ret += s<<8;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short le_short(unsigned short s)
|
||||
{
|
||||
unsigned short ret=s;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = s>>8;
|
||||
ret += s<<8;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#include "wav_io.h"
|
||||
|
||||
|
||||
int read_wav_header(FILE *file, int *rate, int *channels, int *format, spx_int32_t *size)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user