mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-15 05:48:33 +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:
1 parent
d885488f15
commit
4ee40ddc34
181 files changed
+24231
-5233
No files matched your search
+8
-7
@@ -1,10 +1,11 @@
|
|||||||
Copyright 2002-2006
|
Copyright 2002-2008 Xiph.org Foundation
|
||||||
Xiph.org Foundation
|
Copyright 2002-2008 Jean-Marc Valin
|
||||||
Jean-Marc Valin
|
Copyright 2005-2007 Analog Devices Inc.
|
||||||
David Rowe
|
Copyright 2005-2008 Commonwealth Scientific and Industrial Research
|
||||||
EpicGames
|
Organisation (CSIRO)
|
||||||
Analog Devices
|
Copyright 1993, 2002, 2006 David Rowe
|
||||||
Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
Copyright 2003 EpicGames
|
||||||
|
Copyright 1992-1994 Jutta Degener, Carsten Bormann
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
|
|
||||||
# To disable automatic dependency tracking if using other tools than
|
# To disable automatic dependency tracking if using other tools than
|
||||||
# gcc and gmake, add the option 'no-dependencies'
|
# gcc and gmake, add the option 'no-dependencies'
|
||||||
AUTOMAKE_OPTIONS = 1.7
|
AUTOMAKE_OPTIONS = 1.8
|
||||||
|
|
||||||
m4datadir = $(datadir)/aclocal
|
m4datadir = $(datadir)/aclocal
|
||||||
m4data_DATA = speex.m4
|
m4data_DATA = speex.m4
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
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
|
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
|
#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
|
DIST_SUBDIRS = libspeex include src doc win32 symbian ti
|
||||||
|
|
||||||
|
|||||||
+96
-18
@@ -11,11 +11,14 @@
|
|||||||
<absoluteprojectpath>false</absoluteprojectpath>
|
<absoluteprojectpath>false</absoluteprojectpath>
|
||||||
<description/>
|
<description/>
|
||||||
<secondaryLanguages/>
|
<secondaryLanguages/>
|
||||||
|
<versioncontrol>kdevsubversion</versioncontrol>
|
||||||
|
<defaultencoding/>
|
||||||
|
<projectname>Speex</projectname>
|
||||||
</general>
|
</general>
|
||||||
<kdevautoproject>
|
<kdevautoproject>
|
||||||
<general>
|
<general>
|
||||||
<activetarget>libspeex/libspeex.la</activetarget>
|
<activetarget>libspeex/libspeex.la</activetarget>
|
||||||
<useconfiguration>default</useconfiguration>
|
<useconfiguration>float</useconfiguration>
|
||||||
</general>
|
</general>
|
||||||
<run>
|
<run>
|
||||||
<mainprogram>src/Speex</mainprogram>
|
<mainprogram>src/Speex</mainprogram>
|
||||||
@@ -25,23 +28,47 @@
|
|||||||
<terminal>false</terminal>
|
<terminal>false</terminal>
|
||||||
<autocompile>true</autocompile>
|
<autocompile>true</autocompile>
|
||||||
<envvars/>
|
<envvars/>
|
||||||
|
<autoinstall>false</autoinstall>
|
||||||
|
<autokdesu>false</autokdesu>
|
||||||
</run>
|
</run>
|
||||||
<configurations>
|
<configurations>
|
||||||
<optimized>
|
<float>
|
||||||
<builddir>optimized</builddir>
|
<builddir>float</builddir>
|
||||||
<ccompiler>GccOptions</ccompiler>
|
<ccompiler>kdevgccoptions</ccompiler>
|
||||||
<cxxcompiler>GppOptions</cxxcompiler>
|
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||||
<f77compiler>G77Options</f77compiler>
|
<f77compiler>kdevpgf77options</f77compiler>
|
||||||
<cflags>-O2 -g0</cflags>
|
<cflags>-O2 -g -Wall</cflags>
|
||||||
</optimized>
|
<envvars/>
|
||||||
<debug>
|
<configargs>--disable-shared</configargs>
|
||||||
<configargs>--enable-debug=full</configargs>
|
<topsourcedir/>
|
||||||
<builddir>debug</builddir>
|
<cppflags/>
|
||||||
<ccompiler>GccOptions</ccompiler>
|
<ldflags/>
|
||||||
<cxxcompiler>GppOptions</cxxcompiler>
|
<ccompilerbinary/>
|
||||||
<f77compiler>G77Options</f77compiler>
|
<cxxcompilerbinary/>
|
||||||
<cflags>-O0 -g3</cflags>
|
<f77compilerbinary/>
|
||||||
</debug>
|
<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>
|
</configurations>
|
||||||
<make>
|
<make>
|
||||||
<envvars>
|
<envvars>
|
||||||
@@ -49,9 +76,11 @@
|
|||||||
<envvar value="1" name="WANT_AUTOMAKE_1_6" />
|
<envvar value="1" name="WANT_AUTOMAKE_1_6" />
|
||||||
</envvars>
|
</envvars>
|
||||||
<abortonerror>false</abortonerror>
|
<abortonerror>false</abortonerror>
|
||||||
<numberofjobs>1</numberofjobs>
|
<numberofjobs>4</numberofjobs>
|
||||||
<dontact>false</dontact>
|
<dontact>false</dontact>
|
||||||
<makebin/>
|
<makebin/>
|
||||||
|
<runmultiplejobs>true</runmultiplejobs>
|
||||||
|
<prio>0</prio>
|
||||||
</make>
|
</make>
|
||||||
</kdevautoproject>
|
</kdevautoproject>
|
||||||
<kdevdebugger>
|
<kdevdebugger>
|
||||||
@@ -69,6 +98,7 @@
|
|||||||
<display>
|
<display>
|
||||||
<staticmembers>false</staticmembers>
|
<staticmembers>false</staticmembers>
|
||||||
<demanglenames>true</demanglenames>
|
<demanglenames>true</demanglenames>
|
||||||
|
<outputradix>10</outputradix>
|
||||||
</display>
|
</display>
|
||||||
</kdevdebugger>
|
</kdevdebugger>
|
||||||
<kdevfilecreate>
|
<kdevfilecreate>
|
||||||
@@ -88,10 +118,50 @@
|
|||||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||||
<automaticArgumentsHint>true</automaticArgumentsHint>
|
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||||
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||||
<codeCompletionDelay>250</codeCompletionDelay>
|
<codeCompletionDelay>350</codeCompletionDelay>
|
||||||
<argumentsHintDelay>400</argumentsHintDelay>
|
<argumentsHintDelay>400</argumentsHintDelay>
|
||||||
<headerCompletionDelay>250</headerCompletionDelay>
|
<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>
|
</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>
|
</kdevcppsupport>
|
||||||
<kdevfileview>
|
<kdevfileview>
|
||||||
<groups>
|
<groups>
|
||||||
@@ -101,6 +171,7 @@
|
|||||||
<tree>
|
<tree>
|
||||||
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
||||||
<hidenonprojectfiles>true</hidenonprojectfiles>
|
<hidenonprojectfiles>true</hidenonprojectfiles>
|
||||||
|
<showvcsfields>false</showvcsfields>
|
||||||
</tree>
|
</tree>
|
||||||
</kdevfileview>
|
</kdevfileview>
|
||||||
<kdevdoctreeview>
|
<kdevdoctreeview>
|
||||||
@@ -120,4 +191,11 @@
|
|||||||
<implementationsuffix>.cpp</implementationsuffix>
|
<implementationsuffix>.cpp</implementationsuffix>
|
||||||
</filetemplates>
|
</filetemplates>
|
||||||
</cppsupportpart>
|
</cppsupportpart>
|
||||||
|
<kdevdocumentation>
|
||||||
|
<projectdoc>
|
||||||
|
<docsystem/>
|
||||||
|
<docurl/>
|
||||||
|
<usermanualurl/>
|
||||||
|
</projectdoc>
|
||||||
|
</kdevdocumentation>
|
||||||
</kdevelop>
|
</kdevelop>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
%define name speex
|
%define name speex
|
||||||
%define ver 1.2beta1
|
%define ver 1.2rc1
|
||||||
%define rel 1
|
%define rel 1
|
||||||
|
|
||||||
Summary: An open-source, patent-free speech codec
|
Summary: An open-source, patent-free speech codec
|
||||||
@@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install
|
|||||||
%{_includedir}/speex/speex*.h
|
%{_includedir}/speex/speex*.h
|
||||||
/usr/share/aclocal/speex.m4
|
/usr/share/aclocal/speex.m4
|
||||||
%{_libdir}/pkgconfig/speex.pc
|
%{_libdir}/pkgconfig/speex.pc
|
||||||
|
%{_libdir}/pkgconfig/speexdsp.pc
|
||||||
%{_libdir}/libspeex*.a
|
%{_libdir}/libspeex*.a
|
||||||
@@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install
|
|||||||
%{_includedir}/speex/speex*.h
|
%{_includedir}/speex/speex*.h
|
||||||
/usr/share/aclocal/speex.m4
|
/usr/share/aclocal/speex.m4
|
||||||
%{_libdir}/pkgconfig/speex.pc
|
%{_libdir}/pkgconfig/speex.pc
|
||||||
|
%{_libdir}/pkgconfig/speexdsp.pc
|
||||||
%{_libdir}/libspeex*.a
|
%{_libdir}/libspeex*.a
|
||||||
+32
-19
@@ -1,29 +1,43 @@
|
|||||||
Better saturation handling in mdf?
|
For 1.2:
|
||||||
get rid of crap that shouldn't be exposed in speex.h
|
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:
|
Would be nice:
|
||||||
|
Implement wideband split as IIR instead of QMF?
|
||||||
|
|
||||||
Allocator override (speex_lib_ctl)
|
Allocator override (speex_lib_ctl?)
|
||||||
Better error handling
|
|
||||||
Fixed-point:
|
Fixed-point:
|
||||||
- Wideband
|
- VBR
|
||||||
- Initialization
|
|
||||||
- Jitter buffer
|
- Jitter buffer
|
||||||
|
- AGC
|
||||||
Denoiser:
|
Denoiser:
|
||||||
- Smooth gain (remove musical noise)
|
|
||||||
- Better noise adaptation
|
- Better noise adaptation
|
||||||
- Do some tuning
|
|
||||||
AGC:
|
AGC:
|
||||||
- Use median filtering instead of "non-linear mean"
|
- 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)
|
|
||||||
|
|
||||||
Standards
|
Standards
|
||||||
-Complete Speex RTP profile
|
-Complete Speex RTP profile
|
||||||
@@ -32,4 +46,3 @@ Standards
|
|||||||
ideas:
|
ideas:
|
||||||
Peelable stream (double codebook, higher bands, stereo)
|
Peelable stream (double codebook, higher bands, stereo)
|
||||||
LPC from spectral domain
|
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
|
elif test "x$ogg_prefix" != "x" ; then
|
||||||
OGG_LIBS="-L$ogg_prefix/lib"
|
OGG_LIBS="-L$ogg_prefix/lib"
|
||||||
elif test "x$prefix" != "xNONE" ; then
|
elif test "x$prefix" != "xNONE" ; then
|
||||||
OGG_LIBS=""
|
OGG_LIBS="-L$prefix/lib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
OGG_LIBS="$OGG_LIBS -logg"
|
OGG_LIBS="$OGG_LIBS -logg"
|
||||||
|
|||||||
+31
-13
@@ -9,14 +9,17 @@
|
|||||||
/* Make use of Blackfin assembly optimizations */
|
/* Make use of Blackfin assembly optimizations */
|
||||||
#undef BFIN_ASM
|
#undef BFIN_ASM
|
||||||
|
|
||||||
/* Disable wideband codec */
|
/* Disable all parts of the API that are using floats */
|
||||||
#undef DISABLE_WIDEBAND
|
#undef DISABLE_FLOAT_API
|
||||||
|
|
||||||
|
/* Disable VBR and VAD from the codec */
|
||||||
|
#undef DISABLE_VBR
|
||||||
|
|
||||||
/* Enable valgrind extra checks */
|
/* Enable valgrind extra checks */
|
||||||
#undef ENABLE_VALGRIND
|
#undef ENABLE_VALGRIND
|
||||||
|
|
||||||
/* Enable support for Epic 4.8 kbps mode */
|
/* Symbol visibility prefix */
|
||||||
#undef EPIC_48K
|
#undef EXPORT
|
||||||
|
|
||||||
/* Debug fixed-point implementation */
|
/* Debug fixed-point implementation */
|
||||||
#undef FIXED_DEBUG
|
#undef FIXED_DEBUG
|
||||||
@@ -24,9 +27,18 @@
|
|||||||
/* Compile as fixed-point */
|
/* Compile as fixed-point */
|
||||||
#undef 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. */
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
#undef HAVE_DLFCN_H
|
#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. */
|
/* Define to 1 if you have the `getopt_long' function. */
|
||||||
#undef HAVE_GETOPT_LONG
|
#undef HAVE_GETOPT_LONG
|
||||||
|
|
||||||
@@ -84,16 +96,13 @@
|
|||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#undef PACKAGE_VERSION
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
/* Reduce precision to 16 bits (EXPERIMENTAL) */
|
/* The size of `int', as computed by sizeof. */
|
||||||
#undef PRECISION16
|
|
||||||
|
|
||||||
/* The size of a `int', as computed by sizeof. */
|
|
||||||
#undef SIZEOF_INT
|
#undef SIZEOF_INT
|
||||||
|
|
||||||
/* The size of a `long', as computed by sizeof. */
|
/* The size of `long', as computed by sizeof. */
|
||||||
#undef SIZEOF_LONG
|
#undef SIZEOF_LONG
|
||||||
|
|
||||||
/* The size of a `short', as computed by sizeof. */
|
/* The size of `short', as computed by sizeof. */
|
||||||
#undef SIZEOF_SHORT
|
#undef SIZEOF_SHORT
|
||||||
|
|
||||||
/* Version extra */
|
/* Version extra */
|
||||||
@@ -120,12 +129,21 @@
|
|||||||
/* Make use of alloca */
|
/* Make use of alloca */
|
||||||
#undef USE_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 */
|
/* Use C99 variable-size arrays */
|
||||||
#undef VAR_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
|
/* Define to 1 if your processor stores words with the most significant byte
|
||||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||||
#undef WORDS_BIGENDIAN
|
#undef WORDS_BIGENDIAN
|
||||||
|
|||||||
+133
-61
@@ -6,15 +6,15 @@ AM_CONFIG_HEADER([config.h])
|
|||||||
|
|
||||||
SPEEX_MAJOR_VERSION=1
|
SPEEX_MAJOR_VERSION=1
|
||||||
SPEEX_MINOR_VERSION=1
|
SPEEX_MINOR_VERSION=1
|
||||||
SPEEX_MICRO_VERSION=13
|
SPEEX_MICRO_VERSION=16
|
||||||
SPEEX_EXTRA_VERSION=
|
SPEEX_EXTRA_VERSION=
|
||||||
#SPEEX_VERSION=
|
#SPEEX_VERSION=
|
||||||
SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION
|
#SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION
|
||||||
SPEEX_VERSION="1.2beta1"
|
SPEEX_VERSION="1.2rc1"
|
||||||
|
|
||||||
SPEEX_LT_CURRENT=5
|
SPEEX_LT_CURRENT=6
|
||||||
SPEEX_LT_REVISION=0
|
SPEEX_LT_REVISION=0
|
||||||
SPEEX_LT_AGE=4
|
SPEEX_LT_AGE=5
|
||||||
|
|
||||||
AC_SUBST(SPEEX_LT_CURRENT)
|
AC_SUBST(SPEEX_LT_CURRENT)
|
||||||
AC_SUBST(SPEEX_LT_REVISION)
|
AC_SUBST(SPEEX_LT_REVISION)
|
||||||
@@ -30,6 +30,7 @@ AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
|
|||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
AC_LIBTOOL_WIN32_DLL
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
AC_C_BIGENDIAN
|
AC_C_BIGENDIAN
|
||||||
@@ -40,7 +41,8 @@ AC_C_RESTRICT
|
|||||||
|
|
||||||
AC_MSG_CHECKING(for C99 variable-size arrays)
|
AC_MSG_CHECKING(for C99 variable-size arrays)
|
||||||
AC_TRY_COMPILE( , [
|
AC_TRY_COMPILE( , [
|
||||||
int foo=10;
|
int foo;
|
||||||
|
foo = 10;
|
||||||
int array[foo];
|
int array[foo];
|
||||||
],
|
],
|
||||||
[has_var_arrays=yes;AC_DEFINE([VAR_ARRAYS], [], [Use C99 variable-size arrays])
|
[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_MSG_RESULT($has_var_arrays)
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([alloca.h getopt.h])
|
||||||
AC_MSG_CHECKING(for alloca)
|
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 foo=10;
|
||||||
int *array = alloca(foo);
|
int *array = alloca(foo);
|
||||||
],
|
],
|
||||||
@@ -64,9 +72,49 @@ has_alloca=no
|
|||||||
)
|
)
|
||||||
AC_MSG_RESULT($has_alloca)
|
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)
|
AC_CHECK_HEADERS(sys/soundcard.h sys/audioio.h)
|
||||||
|
|
||||||
|
XIPH_PATH_OGG([src="src"], [src=""])
|
||||||
|
AC_SUBST(src)
|
||||||
|
|
||||||
AC_CHECK_LIB(m, sin)
|
AC_CHECK_LIB(m, sin)
|
||||||
|
|
||||||
# Check for getopt_long; if not found, use included source.
|
# 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_MICRO_VERSION, ${SPEEX_MICRO_VERSION}, [Version micro])
|
||||||
AC_DEFINE_UNQUOTED(SPEEX_EXTRA_VERSION, "${SPEEX_EXTRA_VERSION}", [Version extra])
|
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],
|
AC_ARG_ENABLE(valgrind, [ --enable-valgrind Enable valgrind extra checks],
|
||||||
[if test "$enableval" = yes; then
|
[if test "$enableval" = yes; then
|
||||||
AC_DEFINE([ENABLE_VALGRIND], , [Enable valgrind extra checks])
|
AC_DEFINE([ENABLE_VALGRIND], , [Enable valgrind extra checks])
|
||||||
fi])
|
fi])
|
||||||
|
|
||||||
AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [if test "$enableval" = yes; then
|
AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [
|
||||||
AC_DEFINE([_USE_SSE], , [Enable SSE support])
|
if test "x$enableval" != xno; then
|
||||||
|
has_sse=yes
|
||||||
CFLAGS="$CFLAGS -O3 -msse"
|
CFLAGS="$CFLAGS -O3 -msse"
|
||||||
|
else
|
||||||
|
has_sse=no
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
FFT=smallft
|
||||||
|
|
||||||
AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point],
|
AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point],
|
||||||
[if test "$enableval" = yes; then
|
[if test "$enableval" = yes; then
|
||||||
|
FFT=kiss
|
||||||
|
has_sse=no
|
||||||
AC_DEFINE([FIXED_POINT], , [Compile as fixed-point])
|
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])
|
fi])
|
||||||
|
|
||||||
AC_ARG_ENABLE(arm4-asm, [ --enable-arm4-asm Make use of ARM4 assembly optimizations],
|
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])
|
AC_DEFINE([ARM5E_ASM], , [Make use of ARM5E assembly optimizations])
|
||||||
fi])
|
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
|
[if test "$enableval" = yes; then
|
||||||
AC_DEFINE([BFIN_ASM], , [Make use of Blackfin assembly optimizations])
|
AC_DEFINE([BFIN_ASM], , [Make use of Blackfin assembly optimizations])
|
||||||
LDFLAGS="-Wl,-elf2flt=-s100000"
|
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])
|
AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation])
|
||||||
fi])
|
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],
|
AC_ARG_ENABLE(ti-c55x, [ --enable-ti-c55x Enable support for TI C55X DSP],
|
||||||
[if test "$enableval" = yes; then
|
[if test "$enableval" = yes; then
|
||||||
has_char16=yes;
|
has_char16=yes;
|
||||||
AC_DEFINE([TI_C55X], , [Enable support for TI C55X DSP])
|
AC_DEFINE([TI_C55X], , [Enable support for TI C55X DSP])
|
||||||
fi])
|
fi])
|
||||||
|
|
||||||
AC_ARG_ENABLE(16bit-precision, [ --enable-16bit-precision Reduce precision to 16 bits (EXPERIMENTAL)],
|
AC_ARG_WITH([fft], [AS_HELP_STRING([--with-fft=choice],[use an alternate FFT implementation. The available choices are
|
||||||
[if test "$enableval" = yes; then
|
kiss (default fixed point), smallft (default floating point), gpl-fftw3 and proprietary-intel-mkl])],
|
||||||
AC_DEFINE([PRECISION16], , [Reduce precision to 16 bits (EXPERIMENTAL)])
|
[FFT=$withval]
|
||||||
fi])
|
)
|
||||||
|
|
||||||
|
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(short)
|
||||||
AC_CHECK_SIZEOF(int)
|
AC_CHECK_SIZEOF(int)
|
||||||
@@ -182,47 +273,28 @@ fi
|
|||||||
AC_SUBST(SIZE16)
|
AC_SUBST(SIZE16)
|
||||||
AC_SUBST(SIZE32)
|
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
|
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/Makefile win32/libspeex/Makefile win32/speexenc/Makefile
|
||||||
win32/speexdec/Makefile symbian/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/libspeex/Makefile
|
||||||
|
win32/VS2003/libspeexdsp/Makefile
|
||||||
win32/VS2003/speexdec/Makefile
|
win32/VS2003/speexdec/Makefile
|
||||||
win32/VS2003/speexenc/Makefile
|
win32/VS2003/speexenc/Makefile
|
||||||
|
win32/VS2005/Makefile
|
||||||
win32/VS2005/libspeex/Makefile
|
win32/VS2005/libspeex/Makefile
|
||||||
win32/VS2005/speexdec/Makefile
|
win32/VS2005/speexdec/Makefile
|
||||||
win32/VS2005/speexenc/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
|
include/speex/speex_config_types.h ti/Makefile
|
||||||
ti/speex_C54_test/Makefile ti/speex_C55_test/Makefile
|
ti/speex_C54_test/Makefile ti/speex_C55_test/Makefile
|
||||||
ti/speex_C64_test/Makefile ])
|
ti/speex_C64_test/Makefile ])
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
docdir=$(prefix)/share/doc/@PACKAGE@-@VERSION@
|
|
||||||
|
|
||||||
doc_DATA = manual.pdf
|
doc_DATA = manual.pdf
|
||||||
|
|
||||||
EXTRA_DIST = $(doc_DATA)
|
EXTRA_DIST = $(doc_DATA)
|
||||||
Binary file not shown.
@@ -3,13 +3,7 @@
|
|||||||
|
|
||||||
nodist_pkginclude_HEADERS = speex_config_types.h
|
nodist_pkginclude_HEADERS = speex_config_types.h
|
||||||
|
|
||||||
pkginclude_HEADERS = speex.h \
|
pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \
|
||||||
speex_types.h \
|
speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \
|
||||||
speex_bits.h \
|
speex_stereo.h speex_types.h
|
||||||
speex_header.h \
|
|
||||||
speex_callbacks.h \
|
|
||||||
speex_stereo.h \
|
|
||||||
speex_preprocess.h \
|
|
||||||
speex_jitter.h \
|
|
||||||
speex_echo.h
|
|
||||||
|
|
||||||
@@ -35,6 +35,10 @@
|
|||||||
|
|
||||||
#ifndef SPEEX_H
|
#ifndef SPEEX_H
|
||||||
#define 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_bits.h"
|
||||||
#include "speex/speex_types.h"
|
#include "speex/speex_types.h"
|
||||||
@@ -151,19 +155,9 @@ extern "C" {
|
|||||||
/** Get status of input/output high-pass filtering */
|
/** Get status of input/output high-pass filtering */
|
||||||
#define SPEEX_GET_HIGHPASS 45
|
#define SPEEX_GET_HIGHPASS 45
|
||||||
|
|
||||||
/* Used internally, NOT TO BE USED in applications */
|
/** Get "activity level" of the last decoded frame, i.e.
|
||||||
/** Used internally*/
|
how much damage we cause if we remove the frame */
|
||||||
#define SPEEX_GET_PI_GAIN 100
|
#define SPEEX_GET_ACTIVITY 47
|
||||||
/** 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
|
|
||||||
|
|
||||||
|
|
||||||
/* Preserving compatibility:*/
|
/* Preserving compatibility:*/
|
||||||
@@ -218,11 +212,6 @@ extern "C" {
|
|||||||
/** modeID for the defined ultra-wideband mode */
|
/** modeID for the defined ultra-wideband mode */
|
||||||
#define SPEEX_MODEID_UWB 2
|
#define SPEEX_MODEID_UWB 2
|
||||||
|
|
||||||
#ifdef EPIC_48K
|
|
||||||
/** modeID for the Epic 48K mode */
|
|
||||||
#define SPEEX_MODEID_NB_48K 1000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct SpeexMode;
|
struct SpeexMode;
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +296,7 @@ typedef struct SpeexMode {
|
|||||||
* encode, you need one state per channel.
|
* encode, you need one state per channel.
|
||||||
*
|
*
|
||||||
* @param mode The mode to use (either speex_nb_mode or speex_wb.mode)
|
* @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);
|
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
|
/** Uses an existing encoder state to encode one frame of speech pointed to by
|
||||||
"in". The encoded bit-stream is saved in "bits".
|
"in". The encoded bit-stream is saved in "bits".
|
||||||
@param state Encoder state
|
@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
|
@param bits Bit-stream where the data will be written
|
||||||
@return 0 if frame needs not be transmitted (DTX only), 1 otherwise
|
@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 state Encoder state
|
||||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||||
* @param ptr Data exchanged to-from function
|
* @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);
|
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.
|
* decode, you need one state per channel.
|
||||||
*
|
*
|
||||||
* @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
|
* @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);
|
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 state Decoder state
|
||||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||||
* @param ptr Data exchanged to-from function
|
* @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);
|
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 mode Speex mode
|
||||||
* @param request ioctl-type request (one of the SPEEX_* macros)
|
* @param request ioctl-type request (one of the SPEEX_* macros)
|
||||||
* @param ptr Data exchanged to-from function
|
* @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);
|
int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
|
||||||
|
|
||||||
/** Functions for controlling the behavior of libspeex
|
/** Functions for controlling the behavior of libspeex
|
||||||
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
|
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
|
||||||
* @param ptr Data exchanged to-from function
|
* @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);
|
int speex_lib_ctl(int request, void *ptr);
|
||||||
|
|
||||||
@@ -412,20 +405,20 @@ extern const SpeexMode speex_wb_mode;
|
|||||||
/** Default "ultra-wideband" mode */
|
/** Default "ultra-wideband" mode */
|
||||||
extern const SpeexMode speex_uwb_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 */
|
/** List of all modes available */
|
||||||
extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
|
extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
|
||||||
|
|
||||||
/** Obtain one of the modes available */
|
/** Obtain one of the modes available */
|
||||||
const SpeexMode * speex_lib_get_mode (int mode);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @}*/
|
||||||
#endif
|
#endif
|
||||||
@@ -35,6 +35,11 @@
|
|||||||
|
|
||||||
#ifndef BITS_H
|
#ifndef BITS_H
|
||||||
#define 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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -59,6 +64,9 @@ void speex_bits_init(SpeexBits *bits);
|
|||||||
/** Initializes SpeexBits struct using a pre-allocated buffer*/
|
/** Initializes SpeexBits struct using a pre-allocated buffer*/
|
||||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
|
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.*/
|
/** 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);
|
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);
|
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len);
|
||||||
|
|
||||||
/** Append bytes to the bit-stream
|
/** Append bytes to the bit-stream
|
||||||
|
*
|
||||||
* @param bits Bit-stream to operate on
|
* @param bits Bit-stream to operate on
|
||||||
* @param bytes pointer to the bytes what will be appended
|
* @param bytes pointer to the bytes what will be appended
|
||||||
* @param len Number of bytes of append
|
* @param len Number of bytes of append
|
||||||
*/
|
*/
|
||||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);
|
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);
|
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 */
|
/** 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);
|
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);
|
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);
|
||||||
|
|
||||||
/** Get the value of the next bit in the stream, without modifying the
|
/** Get the value of the next bit in the stream, without modifying the
|
||||||
* "cursor" position
|
* "cursor" position
|
||||||
*
|
*
|
||||||
* @param bits Bit-stream to operate on
|
* @param bits Bit-stream to operate on
|
||||||
|
* @return Value of the bit peeked (one bit only)
|
||||||
*/
|
*/
|
||||||
int speex_bits_peek(SpeexBits *bits);
|
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
|
/** Returns the number of bits remaining to be read in a stream
|
||||||
*
|
*
|
||||||
* @param bits Bit-stream to operate on
|
* @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);
|
int speex_bits_remaining(SpeexBits *bits);
|
||||||
|
|
||||||
@@ -148,4 +170,5 @@ void speex_bits_insert_terminator(SpeexBits *bits);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* @} */
|
||||||
#endif
|
#endif
|
||||||
@@ -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
|
#ifndef SPEEX_CALLBACKS_H
|
||||||
#define SPEEX_CALLBACKS_H
|
#define SPEEX_CALLBACKS_H
|
||||||
|
/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
#include "speex.h"
|
#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);
|
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);
|
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);
|
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);
|
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
|
||||||
|
|
||||||
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
@@ -33,7 +33,10 @@
|
|||||||
|
|
||||||
#ifndef SPEEX_ECHO_H
|
#ifndef SPEEX_ECHO_H
|
||||||
#define 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"
|
#include "speex/speex_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -48,41 +51,120 @@ extern "C" {
|
|||||||
/** Get sampling rate */
|
/** Get sampling rate */
|
||||||
#define SPEEX_ECHO_GET_SAMPLING_RATE 25
|
#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_;
|
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;
|
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);
|
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);
|
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);
|
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 */
|
/** Perform echo cancellation using internal playback buffer, which is delayed by two frames
|
||||||
void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out, spx_int32_t *Yout);
|
* 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);
|
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);
|
void speex_echo_state_reset(SpeexEchoState *st);
|
||||||
|
|
||||||
/** Used like the ioctl function to control the echo canceller parameters
|
/** 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 request ioctl-type request (one of the SPEEX_ECHO_* macros)
|
||||||
* @param ptr Data exchanged to-from function
|
* @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
|
||||||
*/
|
*/
|
||||||
int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** @}*/
|
||||||
#endif
|
#endif
|
||||||
@@ -36,6 +36,10 @@
|
|||||||
|
|
||||||
#ifndef SPEEX_HEADER_H
|
#ifndef SPEEX_HEADER_H
|
||||||
#define 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"
|
#include "speex/speex_types.h"
|
||||||
|
|
||||||
@@ -45,6 +49,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct SpeexMode;
|
struct SpeexMode;
|
||||||
|
|
||||||
|
/** Length of the Speex header identifier */
|
||||||
#define SPEEX_HEADER_STRING_LENGTH 8
|
#define SPEEX_HEADER_STRING_LENGTH 8
|
||||||
|
|
||||||
/** Maximum number of characters for encoding the Speex version number in the header */
|
/** 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 */
|
/** Creates a SpeexHeader from a packet */
|
||||||
SpeexHeader *speex_packet_to_header(char *packet, int size);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
@@ -35,83 +35,163 @@
|
|||||||
|
|
||||||
#ifndef SPEEX_JITTER_H
|
#ifndef SPEEX_JITTER_H
|
||||||
#define 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/speex_types.h"
|
||||||
#include "speex_bits.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Generic adaptive jitter buffer state */
|
||||||
struct JitterBuffer_;
|
struct JitterBuffer_;
|
||||||
|
|
||||||
|
/** Generic adaptive jitter buffer state */
|
||||||
typedef struct JitterBuffer_ JitterBuffer;
|
typedef struct JitterBuffer_ JitterBuffer;
|
||||||
|
|
||||||
|
/** Definition of an incoming packet */
|
||||||
typedef struct _JitterBufferPacket JitterBufferPacket;
|
typedef struct _JitterBufferPacket JitterBufferPacket;
|
||||||
|
|
||||||
|
/** Definition of an incoming packet */
|
||||||
struct _JitterBufferPacket {
|
struct _JitterBufferPacket {
|
||||||
char *data;
|
char *data; /**< Data bytes contained in the packet */
|
||||||
spx_uint32_t len;
|
spx_uint32_t len; /**< Length of the packet in bytes */
|
||||||
spx_uint32_t timestamp;
|
spx_uint32_t timestamp; /**< Timestamp for the packet */
|
||||||
spx_uint32_t span;
|
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
|
#define JITTER_BUFFER_OK 0
|
||||||
|
/** Packet is lost or is late */
|
||||||
#define JITTER_BUFFER_MISSING 1
|
#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
|
#define JITTER_BUFFER_INTERNAL_ERROR -1
|
||||||
|
/** Invalid argument */
|
||||||
#define JITTER_BUFFER_BAD_ARGUMENT -2
|
#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);
|
void jitter_buffer_reset(JitterBuffer *jitter);
|
||||||
|
|
||||||
/** Destroy jitter buffer */
|
/** Destroys jitter buffer
|
||||||
|
*
|
||||||
|
* @param jitter Jitter buffer state
|
||||||
|
*/
|
||||||
void jitter_buffer_destroy(JitterBuffer *jitter);
|
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);
|
void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet);
|
||||||
|
|
||||||
/** Get one packet from the jitter buffer */
|
/** Get one packet from the jitter buffer
|
||||||
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *current_timestamp);
|
*
|
||||||
|
* @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);
|
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);
|
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. */
|
/** Used like the ioctl function to control the jitter buffer parameters
|
||||||
typedef struct SpeexJitter {
|
*
|
||||||
SpeexBits current_packet; /**< Current Speex packet */
|
* @param jitter Jitter buffer state
|
||||||
int valid_bits; /**< True if Speex bits are valid */
|
* @param request ioctl-type request (one of the JITTER_BUFFER_* macros)
|
||||||
JitterBuffer *packets;
|
* @param ptr Data exchanged to-from function
|
||||||
void *dec; /**< Pointer to Speex decoder */
|
* @return 0 if no error, -1 if request in unknown
|
||||||
spx_int32_t frame_size; /**< Frame size of Speex decoder */
|
*/
|
||||||
} SpeexJitter;
|
int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr);
|
||||||
|
|
||||||
/** Initialise jitter buffer */
|
int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset);
|
||||||
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate);
|
|
||||||
|
|
||||||
/** 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
/* Copyright (C) 2003 Epic Games
|
/* Copyright (C) 2003 Epic Games
|
||||||
Written by Jean-Marc Valin */
|
Written by Jean-Marc Valin */
|
||||||
/**
|
/**
|
||||||
@file speex_preprocess.h
|
* @file speex_preprocess.h
|
||||||
@brief Speex preprocessor
|
* @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
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -34,6 +36,12 @@
|
|||||||
|
|
||||||
#ifndef SPEEX_PREPROCESS_H
|
#ifndef SPEEX_PREPROCESS_H
|
||||||
#define 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"
|
#include "speex/speex_types.h"
|
||||||
|
|
||||||
@@ -41,84 +49,48 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct drft_lookup;
|
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||||
|
struct SpeexPreprocessState_;
|
||||||
|
|
||||||
/** Speex pre-processor state. */
|
/** State of the preprocessor (one per channel). Should never be accessed directly. */
|
||||||
typedef struct SpeexPreprocessState {
|
typedef struct SpeexPreprocessState_ 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) */
|
/** Creates a new preprocessing state. You MUST create one state per channel processed.
|
||||||
float *ps; /**< Current power spectrum */
|
* @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be
|
||||||
float *gain2; /**< Adjusted gains */
|
* the same value as that used for the echo canceller for residual echo cancellation to work.
|
||||||
float *window; /**< Analysis/Synthesis window */
|
* @param sampling_rate Sampling rate used for the input.
|
||||||
float *noise; /**< Noise estimate */
|
* @return Newly created preprocessor state
|
||||||
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 */
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
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 */
|
|
||||||
SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);
|
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);
|
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);
|
int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
|
||||||
|
|
||||||
/** Preprocess a frame */
|
/** Update preprocessor state, but do not compute the output
|
||||||
void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo);
|
* @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);
|
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 */
|
/** Get preprocessor Voice Activity Detection state */
|
||||||
#define SPEEX_PREPROCESS_GET_VAD 5
|
#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
|
#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
|
#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7
|
||||||
|
|
||||||
/** Set preprocessor dereverb state */
|
/** Set preprocessor dereverb state */
|
||||||
@@ -158,14 +130,90 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
|
|||||||
/** Get preprocessor dereverb decay */
|
/** Get preprocessor dereverb decay */
|
||||||
#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13
|
#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
|
#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
|
#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
|
#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
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @}*/
|
||||||
#endif
|
#endif
|
||||||
@@ -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
|
#ifndef STEREO_H
|
||||||
#define 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_types.h"
|
||||||
#include "speex/speex_bits.h"
|
#include "speex/speex_bits.h"
|
||||||
@@ -42,7 +46,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 {
|
typedef struct SpeexStereoState {
|
||||||
float balance; /**< Left/right balance info */
|
float balance; /**< Left/right balance info */
|
||||||
float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
|
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 */
|
float reserved2; /**< Reserved for future use */
|
||||||
} SpeexStereoState;
|
} 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}
|
#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' */
|
/** 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);
|
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
|
||||||
|
|
||||||
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
typedef SInt32 spx_int32_t;
|
typedef SInt32 spx_int32_t;
|
||||||
typedef UInt32 spx_uint32_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>
|
# include <sys/types.h>
|
||||||
typedef int16_t spx_int16_t;
|
typedef int16_t spx_int16_t;
|
||||||
|
|||||||
@@ -2,41 +2,54 @@
|
|||||||
#AUTOMAKE_OPTIONS = no-dependencies
|
#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
|
# Sources for compilation in the library
|
||||||
libspeex_la_SOURCES = nb_celp.c sb_celp.c lpc.c ltp.c lsp.c quant_lsp.c \
|
libspeex_la_SOURCES = cb_search.c exc_10_32_table.c exc_8_128_table.c \
|
||||||
lsp_tables_nb.c gain_table.c gain_table_lbr.c cb_search.c filters.c bits.c \
|
filters.c gain_table.c hexc_table.c high_lsp_tables.c lsp.c \
|
||||||
modes.c speex.c vq.c high_lsp_tables.c vbr.c hexc_table.c \
|
ltp.c speex.c stereo.c vbr.c vq.c bits.c exc_10_16_table.c \
|
||||||
exc_5_256_table.c exc_5_64_table.c exc_8_128_table.c exc_10_32_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 \
|
||||||
exc_10_16_table.c exc_20_32_table.c hexc_10_32_table.c misc.c speex_header.c \
|
lpc.c lsp_tables_nb.c modes.c modes_wb.c nb_celp.c quant_lsp.c sb_celp.c \
|
||||||
speex_callbacks.c math_approx.c stereo.c preprocess.c smallft.c lbr_48k_tables.c \
|
speex_callbacks.c speex_header.c window.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
|
|
||||||
|
|
||||||
noinst_HEADERS = lsp.h nb_celp.h lpc.h lpc_bfin.h ltp.h quant_lsp.h \
|
if BUILD_KISS_FFT
|
||||||
cb_search.h filters.h stack_alloc.h vq.h vq_sse.h vq_arm4.h vq_bfin.h \
|
FFTSRC=kiss_fft.c _kiss_fft_guts.h kiss_fft.h kiss_fftr.c kiss_fftr.h
|
||||||
modes.h sb_celp.h vbr.h misc.h misc_bfin.h ltp_sse.h ltp_arm4.h \
|
else
|
||||||
ltp_bfin.h filters_sse.h filters_arm4.h filters_bfin.h math_approx.h \
|
if BUILD_SMALLFT
|
||||||
smallft.h arch.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h \
|
FFTSRC=smallft.c
|
||||||
fixed_generic.h cb_search_sse.h cb_search_arm4.h cb_search_bfin.h vorbis_psy.h \
|
else
|
||||||
fftwrap.h pseudofloat.h lsp_bfin.h quant_lsp_bfin.h
|
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@
|
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_SOURCES = testenc.c
|
||||||
testenc_LDADD = $(top_builddir)/libspeex/libspeex.la
|
testenc_LDADD = libspeex.la
|
||||||
testenc_wb_SOURCES = testenc_wb.c
|
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_SOURCES = testenc_uwb.c
|
||||||
testenc_uwb_LDADD = $(top_builddir)/libspeex/libspeex.la
|
testenc_uwb_LDADD = libspeex.la
|
||||||
testdenoise_SOURCES = testdenoise.c
|
testdenoise_SOURCES = testdenoise.c
|
||||||
testdenoise_LDADD = $(top_builddir)/libspeex/libspeex.la
|
testdenoise_LDADD = libspeexdsp.la @FFT_LIBS@
|
||||||
testecho_SOURCES = testecho.c
|
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
|
and defines
|
||||||
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
|
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
|
||||||
#include "kiss_fft.h"
|
#include "kiss_fft.h"
|
||||||
|
#include "math_approx.h"
|
||||||
|
|
||||||
#define MAXFACTORS 32
|
#define MAXFACTORS 32
|
||||||
/* e.g. an fft of length 128 has 4 factors
|
/* e.g. an fft of length 128 has 4 factors
|
||||||
@@ -44,7 +45,7 @@ struct kiss_fft_state{
|
|||||||
C_ADDTO( res , a) : res += a
|
C_ADDTO( res , a) : res += a
|
||||||
* */
|
* */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
# define FRACBITS 15
|
# define FRACBITS 15
|
||||||
# define SAMPPROD spx_int32_t
|
# define SAMPPROD spx_int32_t
|
||||||
#define SAMP_MAX 32767
|
#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) ); \
|
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)
|
(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) \
|
# define DIVSCALAR(x,k) \
|
||||||
(x) = sround( smul( x, SAMP_MAX/k ) )
|
(x) = sround( smul( x, SAMP_MAX/k ) )
|
||||||
|
|
||||||
@@ -84,6 +89,9 @@ struct kiss_fft_state{
|
|||||||
#define C_MUL(m,a,b) \
|
#define C_MUL(m,a,b) \
|
||||||
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
|
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
|
||||||
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
|
(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_FIXDIV(c,div) /* NOOP */
|
||||||
# define C_MULBYSCALAR( c, s ) \
|
# define C_MULBYSCALAR( c, s ) \
|
||||||
do{ (c).r *= (s);\
|
do{ (c).r *= (s);\
|
||||||
@@ -140,6 +148,11 @@ struct kiss_fft_state{
|
|||||||
(x)->r = KISS_FFT_COS(phase);\
|
(x)->r = KISS_FFT_COS(phase);\
|
||||||
(x)->i = KISS_FFT_SIN(phase);\
|
(x)->i = KISS_FFT_SIN(phase);\
|
||||||
}while(0)
|
}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 */
|
/* a debugging function */
|
||||||
|
|||||||
@@ -35,12 +35,55 @@
|
|||||||
#ifndef ARCH_H
|
#ifndef ARCH_H
|
||||||
#define 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"
|
#include "speex/speex_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
|
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
|
||||||
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit 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 MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||||
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-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. */
|
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
@@ -64,10 +107,12 @@ typedef spx_word32_t spx_sig_t;
|
|||||||
#define LPC_SHIFT 13
|
#define LPC_SHIFT 13
|
||||||
#define LSP_SHIFT 13
|
#define LSP_SHIFT 13
|
||||||
#define SIG_SHIFT 14
|
#define SIG_SHIFT 14
|
||||||
|
#define GAIN_SHIFT 6
|
||||||
|
|
||||||
#define VERY_SMALL 0
|
#define VERY_SMALL 0
|
||||||
#define VERY_LARGE32 ((spx_word32_t)2147483647)
|
#define VERY_LARGE32 ((spx_word32_t)2147483647)
|
||||||
#define VERY_LARGE16 ((spx_word16_t)32767)
|
#define VERY_LARGE16 ((spx_word16_t)32767)
|
||||||
|
#define Q15_ONE ((spx_word16_t)32767)
|
||||||
|
|
||||||
|
|
||||||
#ifdef FIXED_DEBUG
|
#ifdef FIXED_DEBUG
|
||||||
@@ -80,8 +125,6 @@ typedef spx_word32_t spx_sig_t;
|
|||||||
#include "fixed_arm5e.h"
|
#include "fixed_arm5e.h"
|
||||||
#elif defined (ARM4_ASM)
|
#elif defined (ARM4_ASM)
|
||||||
#include "fixed_arm4.h"
|
#include "fixed_arm4.h"
|
||||||
#elif defined (ARM5E_ASM)
|
|
||||||
#include "fixed_arm5e.h"
|
|
||||||
#elif defined (BFIN_ASM)
|
#elif defined (BFIN_ASM)
|
||||||
#include "fixed_bfin.h"
|
#include "fixed_bfin.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -106,13 +149,11 @@ typedef float spx_word32_t;
|
|||||||
#define GAIN_SCALING 1.f
|
#define GAIN_SCALING 1.f
|
||||||
#define GAIN_SCALING_1 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_SMALL 1e-15f
|
||||||
#define VERY_LARGE32 1e15f
|
#define VERY_LARGE32 1e15f
|
||||||
#define VERY_LARGE16 1e15f
|
#define VERY_LARGE16 1e15f
|
||||||
|
#define Q15_ONE ((spx_word16_t)1.f)
|
||||||
|
|
||||||
#define QCONST16(x,bits) (x)
|
#define QCONST16(x,bits) (x)
|
||||||
#define QCONST32(x,bits) (x)
|
#define QCONST32(x,bits) (x)
|
||||||
@@ -127,6 +168,7 @@ typedef float spx_word32_t;
|
|||||||
#define SHL32(a,shift) (a)
|
#define SHL32(a,shift) (a)
|
||||||
#define PSHR16(a,shift) (a)
|
#define PSHR16(a,shift) (a)
|
||||||
#define PSHR32(a,shift) (a)
|
#define PSHR32(a,shift) (a)
|
||||||
|
#define VSHR32(a,shift) (a)
|
||||||
#define SATURATE16(x,a) (x)
|
#define SATURATE16(x,a) (x)
|
||||||
#define SATURATE32(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_Q13(a,b) ((a)*(b))
|
||||||
#define MULT16_32_Q14(a,b) ((a)*(b))
|
#define MULT16_32_Q14(a,b) ((a)*(b))
|
||||||
#define MULT16_32_Q15(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_Q11(c,a,b) ((c)+(a)*(b))
|
||||||
#define MAC16_32_Q15(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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FIXED_DEBUG
|
||||||
|
extern long long spx_mips;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+42
-33
@@ -37,14 +37,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <speex/speex_bits.h>
|
#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) */
|
/* Maximum size of the bit-stream (for fixed-size allocation) */
|
||||||
#ifndef MAX_CHARS_PER_FRAME
|
#ifndef MAX_CHARS_PER_FRAME
|
||||||
#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
|
#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void speex_bits_init(SpeexBits *bits)
|
EXPORT void speex_bits_init(SpeexBits *bits)
|
||||||
{
|
{
|
||||||
bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
|
bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
|
||||||
if (!bits->chars)
|
if (!bits->chars)
|
||||||
@@ -57,7 +58,7 @@ void speex_bits_init(SpeexBits *bits)
|
|||||||
speex_bits_reset(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->chars = (char*)buff;
|
||||||
bits->buf_size = buf_size;
|
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);
|
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)
|
if (bits->owner)
|
||||||
speex_free(bits->chars);
|
speex_free(bits->chars);
|
||||||
/* Will do something once the allocation is dynamic */
|
/* 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->chars[0]=0;
|
||||||
bits->nbBits=0;
|
bits->nbBits=0;
|
||||||
bits->charPtr=0;
|
bits->charPtr=0;
|
||||||
@@ -83,20 +99,20 @@ void speex_bits_reset(SpeexBits *bits)
|
|||||||
bits->overflow=0;
|
bits->overflow=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void speex_bits_rewind(SpeexBits *bits)
|
EXPORT void speex_bits_rewind(SpeexBits *bits)
|
||||||
{
|
{
|
||||||
bits->charPtr=0;
|
bits->charPtr=0;
|
||||||
bits->bitPtr=0;
|
bits->bitPtr=0;
|
||||||
bits->overflow=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 i;
|
||||||
int nchars = len / BYTES_PER_CHAR;
|
int nchars = len / BYTES_PER_CHAR;
|
||||||
if (nchars > bits->buf_size)
|
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)
|
if (bits->owner)
|
||||||
{
|
{
|
||||||
char *tmp = (char*)speex_realloc(bits->chars, nchars);
|
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");
|
speex_warning("Could not resize input buffer: truncating input");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
speex_warning("Do not own input buffer: truncating input");
|
speex_warning("Do not own input buffer: truncating oversize input");
|
||||||
nchars=bits->buf_size;
|
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)
|
static void speex_bits_flush(SpeexBits *bits)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
|
||||||
if (bits->charPtr>0)
|
if (bits->charPtr>0)
|
||||||
{
|
SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
|
||||||
for (i=bits->charPtr;i<nchars; i++)
|
|
||||||
bits->chars[i-bits->charPtr]=bits->chars[i];
|
|
||||||
}
|
|
||||||
bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
|
bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
|
||||||
bits->charPtr=0;
|
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 i,pos;
|
||||||
int nchars = nbytes/BYTES_PER_CHAR;
|
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;
|
bits->chars=tmp;
|
||||||
} else {
|
} else {
|
||||||
nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
|
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 {
|
} else {
|
||||||
speex_warning("Do not own input buffer: truncating input");
|
speex_warning("Do not own input buffer: truncating oversize input");
|
||||||
nchars=bits->buf_size;
|
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;
|
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 i;
|
||||||
int max_nchars = max_nbytes/BYTES_PER_CHAR;
|
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;
|
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 max_nchars = max_nbytes/BYTES_PER_CHAR;
|
||||||
int i;
|
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];
|
bits->chars[0]=bits->chars[max_nchars];
|
||||||
else
|
else
|
||||||
bits->chars[0]=0;
|
bits->chars[0]=0;
|
||||||
for (i=1;i<((bits->nbBits)>>LOG2_BITS_PER_CHAR)+1;i++)
|
|
||||||
bits->chars[i]=0;
|
|
||||||
bits->charPtr=0;
|
bits->charPtr=0;
|
||||||
bits->nbBits &= (BITS_PER_CHAR-1);
|
bits->nbBits &= (BITS_PER_CHAR-1);
|
||||||
return max_nchars*BYTES_PER_CHAR;
|
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;
|
unsigned int d=data;
|
||||||
|
|
||||||
if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
|
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)
|
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);
|
char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
speex_memset_bytes(tmp, 0, new_nchars);
|
|
||||||
bits->buf_size=new_nchars;
|
bits->buf_size=new_nchars;
|
||||||
bits->chars=tmp;
|
bits->chars=tmp;
|
||||||
} else {
|
} 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);
|
unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
|
||||||
/* If number is negative */
|
/* If number is negative */
|
||||||
@@ -271,7 +280,7 @@ int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
|||||||
return d;
|
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;
|
unsigned int d=0;
|
||||||
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
|
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;
|
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;
|
unsigned int d=0;
|
||||||
int bitPtr, charPtr;
|
int bitPtr, charPtr;
|
||||||
@@ -322,7 +331,7 @@ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
|||||||
return d;
|
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)
|
if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
|
||||||
bits->overflow=1;
|
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;
|
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){
|
if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
|
||||||
bits->overflow=1;
|
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 */
|
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)
|
if (bits->overflow)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -349,12 +358,12 @@ int speex_bits_remaining(SpeexBits *bits)
|
|||||||
return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
|
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);
|
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)
|
if (bits->bitPtr)
|
||||||
speex_bits_pack(bits, 0, 1);
|
speex_bits_pack(bits, 0, 1);
|
||||||
|
|||||||
@@ -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 "filters.h"
|
||||||
#include "stack_alloc.h"
|
#include "stack_alloc.h"
|
||||||
#include "vq.h"
|
#include "vq.h"
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
#include "math_approx.h"
|
||||||
|
#include "os_support.h"
|
||||||
|
|
||||||
#ifdef _USE_SSE
|
#ifdef _USE_SSE
|
||||||
#include "cb_search_sse.h"
|
#include "cb_search_sse.h"
|
||||||
@@ -146,8 +148,7 @@ int update_target
|
|||||||
ALLOC(e, nsf, spx_sig_t);
|
ALLOC(e, nsf, spx_sig_t);
|
||||||
|
|
||||||
/* FIXME: Do we still need to copy the target? */
|
/* FIXME: Do we still need to copy the target? */
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_COPY(t, target, nsf);
|
||||||
t[i]=target[i];
|
|
||||||
|
|
||||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
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]);
|
t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
if (sign)
|
if (sign==1)
|
||||||
{
|
{
|
||||||
for (j=0;j<subvect_size;j++)
|
for (j=0;j<subvect_size;j++)
|
||||||
e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
|
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 */
|
/* Update target: only update target if necessary */
|
||||||
if (update_target)
|
if (update_target)
|
||||||
{
|
{
|
||||||
VARDECL(spx_sig_t *r2);
|
VARDECL(spx_word16_t *r2);
|
||||||
ALLOC(r2, nsf, spx_sig_t);
|
ALLOC(r2, nsf, spx_word16_t);
|
||||||
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
|
|
||||||
for (j=0;j<nsf;j++)
|
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
|
#endif
|
||||||
VARDECL(spx_word16_t *t);
|
VARDECL(spx_word16_t *t);
|
||||||
VARDECL(spx_sig_t *e);
|
VARDECL(spx_sig_t *e);
|
||||||
VARDECL(spx_sig_t *r2);
|
|
||||||
VARDECL(spx_word16_t *tmp);
|
VARDECL(spx_word16_t *tmp);
|
||||||
VARDECL(spx_word32_t *ndist);
|
VARDECL(spx_word32_t *ndist);
|
||||||
VARDECL(spx_word32_t *odist);
|
VARDECL(spx_word32_t *odist);
|
||||||
@@ -316,7 +318,6 @@ int update_target
|
|||||||
#endif
|
#endif
|
||||||
ALLOC(t, nsf, spx_word16_t);
|
ALLOC(t, nsf, spx_word16_t);
|
||||||
ALLOC(e, nsf, spx_sig_t);
|
ALLOC(e, nsf, spx_sig_t);
|
||||||
ALLOC(r2, nsf, spx_sig_t);
|
|
||||||
ALLOC(ind, nb_subvect, int);
|
ALLOC(ind, nb_subvect, int);
|
||||||
|
|
||||||
ALLOC(tmp, 2*N*nsf, spx_word16_t);
|
ALLOC(tmp, 2*N*nsf, spx_word16_t);
|
||||||
@@ -341,11 +342,10 @@ int update_target
|
|||||||
oind[i]=itmp+(2*i+1)*nb_subvect;
|
oind[i]=itmp+(2*i+1)*nb_subvect;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_COPY(t, target, nsf);
|
||||||
t[i]=target[i];
|
|
||||||
|
|
||||||
for (j=0;j<N;j++)
|
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 */
|
/* Pre-compute codewords response and energy */
|
||||||
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
|
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*/
|
/*"erase" nbest list*/
|
||||||
for (j=0;j<N;j++)
|
for (j=0;j<N;j++)
|
||||||
ndist[j]=VERY_LARGE32;
|
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 all n-bests of previous subvector*/
|
||||||
for (j=0;j<N;j++)
|
for (j=0;j<N;j++)
|
||||||
{
|
{
|
||||||
@@ -397,6 +401,7 @@ int update_target
|
|||||||
best_nind[n] = best_nind[n-1];
|
best_nind[n] = best_nind[n-1];
|
||||||
best_ntarget[n] = best_ntarget[n-1];
|
best_ntarget[n] = best_ntarget[n-1];
|
||||||
}
|
}
|
||||||
|
/* n is equal to m here, so they're interchangeable */
|
||||||
ndist[m] = err;
|
ndist[m] = err;
|
||||||
best_nind[n] = best_index[k];
|
best_nind[n] = best_index[k];
|
||||||
best_ntarget[n] = j;
|
best_ntarget[n] = j;
|
||||||
@@ -495,9 +500,13 @@ int update_target
|
|||||||
/* Update target: only update target if necessary */
|
/* Update target: only update target if necessary */
|
||||||
if (update_target)
|
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++)
|
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;
|
int i;
|
||||||
VARDECL(spx_sig_t *tmp);
|
VARDECL(spx_word16_t *tmp);
|
||||||
ALLOC(tmp, nsf, spx_sig_t);
|
ALLOC(tmp, nsf, spx_word16_t);
|
||||||
for (i=0;i<nsf;i++)
|
residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||||
tmp[i]=PSHR32(EXTEND32(target[i]),SIG_SHIFT);
|
|
||||||
residue_percep_zero(tmp, ak, awk1, awk2, tmp, nsf, p, stack);
|
|
||||||
|
|
||||||
for (i=0;i<nsf;i++)
|
for (i=0;i<nsf;i++)
|
||||||
exc[i]+=tmp[i];
|
exc[i]+=SHL32(EXTEND32(tmp[i]),8);
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_MEMSET(target, 0, nsf);
|
||||||
target[i]=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#define CB_SEARCH_H
|
#define CB_SEARCH_H
|
||||||
|
|
||||||
#include <speex/speex_bits.h>
|
#include <speex/speex_bits.h>
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
/** Split codebook parameters. */
|
/** Split codebook parameters. */
|
||||||
typedef struct split_cb_params {
|
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)
|
: "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E)
|
||||||
: "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0",
|
: "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;
|
shape_cb += subvect_size;
|
||||||
resp += subvect_size;
|
resp += subvect_size;
|
||||||
|
|||||||
@@ -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);
|
||||||
+123
-41
@@ -36,11 +36,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*#define USE_SMALLFT*/
|
#include "arch.h"
|
||||||
#define USE_KISS_FFT
|
#include "os_support.h"
|
||||||
|
|
||||||
|
|
||||||
#include "misc.h"
|
|
||||||
|
|
||||||
#define MAX_FFT_SIZE 2048
|
#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++)
|
for (i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
out[i] = in[i] << shift;
|
out[i] = SHL16(in[i], shift);
|
||||||
}
|
}
|
||||||
return 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;
|
int i;
|
||||||
for (i=0;i<len;i++)
|
for (i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
out[i] = (in[i] + (1<<(shift-1))) >> shift;
|
out[i] = PSHR16(in[i], shift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -103,8 +100,8 @@ void spx_fft(void *table, float *in, float *out)
|
|||||||
if (in==out)
|
if (in==out)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
speex_warning("FFT should not be done in-place");
|
|
||||||
float scale = 1./((struct drft_lookup *)table)->n;
|
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++)
|
for (i=0;i<((struct drft_lookup *)table)->n;i++)
|
||||||
out[i] = scale*in[i];
|
out[i] = scale*in[i];
|
||||||
} else {
|
} else {
|
||||||
@@ -120,7 +117,6 @@ void spx_ifft(void *table, float *in, float *out)
|
|||||||
{
|
{
|
||||||
if (in==out)
|
if (in==out)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
speex_warning("FFT should not be done in-place");
|
speex_warning("FFT should not be done in-place");
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
@@ -130,6 +126,119 @@ void spx_ifft(void *table, float *in, float *out)
|
|||||||
spx_drft_backward((struct drft_lookup *)table, 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)
|
#elif defined(USE_KISS_FFT)
|
||||||
|
|
||||||
#include "kiss_fftr.h"
|
#include "kiss_fftr.h"
|
||||||
@@ -138,7 +247,6 @@ void spx_ifft(void *table, float *in, float *out)
|
|||||||
struct kiss_config {
|
struct kiss_config {
|
||||||
kiss_fftr_cfg forward;
|
kiss_fftr_cfg forward;
|
||||||
kiss_fftr_cfg backward;
|
kiss_fftr_cfg backward;
|
||||||
kiss_fft_cpx *freq_data;
|
|
||||||
int N;
|
int N;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -146,7 +254,6 @@ void *spx_fft_init(int size)
|
|||||||
{
|
{
|
||||||
struct kiss_config *table;
|
struct kiss_config *table;
|
||||||
table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));
|
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->forward = kiss_fftr_alloc(size,0,NULL,NULL);
|
||||||
table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
|
table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
|
||||||
table->N = size;
|
table->N = size;
|
||||||
@@ -158,7 +265,6 @@ void spx_fft_destroy(void *table)
|
|||||||
struct kiss_config *t = (struct kiss_config *)table;
|
struct kiss_config *t = (struct kiss_config *)table;
|
||||||
kiss_fftr_free(t->forward);
|
kiss_fftr_free(t->forward);
|
||||||
kiss_fftr_free(t->backward);
|
kiss_fftr_free(t->backward);
|
||||||
speex_free(t->freq_data);
|
|
||||||
speex_free(table);
|
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)
|
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int shift;
|
int shift;
|
||||||
struct kiss_config *t = (struct kiss_config *)table;
|
struct kiss_config *t = (struct kiss_config *)table;
|
||||||
shift = maximize_range(in, in, 32000, t->N);
|
shift = maximize_range(in, in, 32000, t->N);
|
||||||
kiss_fftr(t->forward, in, t->freq_data);
|
kiss_fftr2(t->forward, in, out);
|
||||||
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;
|
|
||||||
renorm_range(in, in, shift, t->N);
|
renorm_range(in, in, shift, t->N);
|
||||||
renorm_range(out, out, 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;
|
float scale;
|
||||||
struct kiss_config *t = (struct kiss_config *)table;
|
struct kiss_config *t = (struct kiss_config *)table;
|
||||||
scale = 1./t->N;
|
scale = 1./t->N;
|
||||||
kiss_fftr(t->forward, in, t->freq_data);
|
kiss_fftr2(t->forward, in, out);
|
||||||
out[0] = scale*t->freq_data[0].r;
|
for (i=0;i<t->N;i++)
|
||||||
for (i=1;i<t->N>>1;i++)
|
out[i] *= scale;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct kiss_config *t = (struct kiss_config *)table;
|
struct kiss_config *t = (struct kiss_config *)table;
|
||||||
t->freq_data[0].r = in[0];
|
kiss_fftri2(t->backward, in, out);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#ifndef FFTWRAP_H
|
#ifndef FFTWRAP_H
|
||||||
#define FFTWRAP_H
|
#define FFTWRAP_H
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
/** Compute tables for an FFT */
|
/** Compute tables for an FFT */
|
||||||
void *spx_fft_init(int size);
|
void *spx_fft_init(int size);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
+160
-241
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "stack_alloc.h"
|
#include "stack_alloc.h"
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
#include "math_approx.h"
|
#include "math_approx.h"
|
||||||
#include "ltp.h"
|
#include "ltp.h"
|
||||||
#include <math.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)
|
void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
|
||||||
{
|
{
|
||||||
int i;
|
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_word16_t yi;
|
||||||
spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);
|
spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]);
|
||||||
yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767));
|
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[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]), MULT16_32_Q14(-den[2],vout));
|
mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1));
|
||||||
y[i] = yi;
|
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)
|
for (i=0;i<len;i+=4)
|
||||||
{
|
{
|
||||||
spx_word32_t sum2=0;
|
spx_word32_t sum2=0;
|
||||||
sum2 = MAC16_16(sum2,PSHR16(x[i],1),PSHR16(x[i],1));
|
sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1));
|
||||||
sum2 = MAC16_16(sum2,PSHR16(x[i+1],1),PSHR16(x[i+1],1));
|
sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1));
|
||||||
sum2 = MAC16_16(sum2,PSHR16(x[i+2],1),PSHR16(x[i+2],1));
|
sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(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+3],1),SHR16(x[i+3],1));
|
||||||
sum = ADD32(sum,SHR32(sum2,6));
|
sum = ADD32(sum,SHR32(sum2,6));
|
||||||
}
|
}
|
||||||
return SHL16(spx_sqrt(DIV32(sum,len)),4);
|
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
|
#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)
|
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
|
#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
|
#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)
|
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
|
#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
|
#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)
|
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
|
#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_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 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)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VARDECL(spx_mem_t *mem);
|
VARDECL(spx_mem_t *mem);
|
||||||
ALLOC(mem, ord, spx_mem_t);
|
ALLOC(mem, ord, spx_mem_t);
|
||||||
for (i=0;i<ord;i++)
|
for (i=0;i<ord;i++)
|
||||||
mem[i]=0;
|
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++)
|
for (i=0;i<ord;i++)
|
||||||
mem[i]=0;
|
mem[i]=0;
|
||||||
fir_mem2(y, awk2, y, N, ord, mem);
|
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
|
#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)
|
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
|
#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;
|
int i,j,k,M2;
|
||||||
VARDECL(spx_word16_t *a);
|
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;
|
M2=M>>1;
|
||||||
for (i=0;i<M;i++)
|
for (i=0;i<M;i++)
|
||||||
a[M-i-1]= aa[i];
|
a[M-i-1]= aa[i];
|
||||||
|
|
||||||
for (i=0;i<M-1;i++)
|
for (i=0;i<M-1;i++)
|
||||||
x[i]=mem[M-i-2];
|
x[i]=mem[M-i-2];
|
||||||
for (i=0;i<N;i++)
|
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++)
|
for (i=0,k=0;i<N;i+=2,k++)
|
||||||
{
|
{
|
||||||
y1[k]=0;
|
spx_word32_t y1k=0, y2k=0;
|
||||||
y2[k]=0;
|
|
||||||
for (j=0;j<M2;j++)
|
for (j=0;j<M2;j++)
|
||||||
{
|
{
|
||||||
y1[k]=ADD32(y1[k],MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
y1k=ADD32(y1k,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])));
|
y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||||
j++;
|
j++;
|
||||||
y1[k]=ADD32(y1[k],MULT16_16(a[j],ADD16(x[i+j],x2[i-j])));
|
y1k=ADD32(y1k,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])));
|
y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j])));
|
||||||
}
|
}
|
||||||
y1[k] = SHR32(y1[k],1);
|
y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767));
|
||||||
y2[k] = SHR32(y2[k],1);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Re-synthesised a signal from the QMF low-band and high-band signals */
|
||||||
/* By segher */
|
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 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)
|
|
||||||
/* assumptions:
|
/* assumptions:
|
||||||
all odd x[i] are zero -- well, actually they are left out of the array now
|
all odd x[i] are zero -- well, actually they are left out of the array now
|
||||||
N and M are multiples of 4 */
|
N and M are multiples of 4 */
|
||||||
{
|
{
|
||||||
int i, j;
|
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++)
|
for (i = 0; i < N2; i++)
|
||||||
xx[2*i] = PSHR32(x[N/2-1-i],SIG_SHIFT);
|
xx1[i] = x1[N2-1-i];
|
||||||
for (i = 0; i < M - 1; i += 2)
|
for (i = 0; i < M2; i++)
|
||||||
xx[N+i] = mem[i+1];
|
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_sig_t y0, y1, y2, y3;
|
||||||
spx_word16_t x0;
|
spx_word16_t x10, x20;
|
||||||
|
|
||||||
y0 = y1 = y2 = y3 = 0;
|
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) {
|
for (j = 0; j < M2; j += 2) {
|
||||||
spx_word16_t x1;
|
spx_word16_t x11, x21;
|
||||||
spx_word16_t a0, a1;
|
spx_word16_t a0, a1;
|
||||||
|
|
||||||
a0 = a[j];
|
a0 = a[2*j];
|
||||||
a1 = a[j+1];
|
a1 = a[2*j+1];
|
||||||
x1 = xx[N-2+j-i];
|
x11 = xx1[N2-1+j-i];
|
||||||
|
x21 = xx2[N2-1+j-i];
|
||||||
|
|
||||||
y0 = ADD32(y0,SHR(MULT16_16(a0, x1),2));
|
#ifdef FIXED_POINT
|
||||||
y1 = ADD32(y1,SHR(MULT16_16(a1, x1),2));
|
/* We multiply twice by the same coef to avoid overflows */
|
||||||
y2 = ADD32(y2,SHR(MULT16_16(a0, x0),2));
|
y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21);
|
||||||
y3 = ADD32(y3,SHR(MULT16_16(a1, x0),2));
|
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];
|
#ifdef FIXED_POINT
|
||||||
a1 = a[j+3];
|
/* We multiply twice by the same coef to avoid overflows */
|
||||||
x0 = xx[N+j-i];
|
y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20);
|
||||||
|
y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20);
|
||||||
y0 = ADD32(y0,SHR(MULT16_16(a0, x0),2));
|
y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21);
|
||||||
y1 = ADD32(y1,SHR(MULT16_16(a1, x0),2));
|
y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21);
|
||||||
y2 = ADD32(y2,SHR(MULT16_16(a0, x1),2));
|
#else
|
||||||
y3 = ADD32(y3,SHR(MULT16_16(a1, x1),2));
|
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;
|
#ifdef FIXED_POINT
|
||||||
y[i+1] = y1;
|
y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767));
|
||||||
y[i+2] = y2;
|
y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767));
|
||||||
y[i+3] = y3;
|
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)
|
for (i = 0; i < M2; i++)
|
||||||
mem[i+1] = xx[i];
|
mem1[2*i+1] = xx1[i];
|
||||||
|
for (i = 0; i < M2; i++)
|
||||||
|
mem2[2*i+1] = xx2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
#if 0
|
#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},
|
{-98, 1133, -4425, 29179, 8895, -2328, 444},
|
||||||
{444, -2328, 8895, 29179, -4425, 1133, -98}};
|
{444, -2328, 8895, 29179, -4425, 1133, -98}};
|
||||||
#else
|
#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},
|
{-1064, 2817, -6694, 31589, 6837, -990, -209},
|
||||||
{-209, -990, 6837, 31589, -6694, 2817, -1064}};
|
{-209, -990, 6837, 31589, -6694, 2817, -1064}};
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if 0
|
#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.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}};
|
{0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}};
|
||||||
#else
|
#else
|
||||||
float shift_filt[3][7] = {{-0.011915, 0.046995, -0.152373, 0.614108, 0.614108, -0.152373, 0.046995},
|
const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f},
|
||||||
{-0.0324855, 0.0859768, -0.2042986, 0.9640297, 0.2086420, -0.0302054, -0.0063646},
|
{-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f},
|
||||||
{-0.0063646, -0.0302054, 0.2086420, 0.9640297, -0.2042986, 0.0859768, -0.0324855}};
|
{-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}};
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -784,7 +675,9 @@ char *stack
|
|||||||
spx_word16_t g1, g2;
|
spx_word16_t g1, g2;
|
||||||
spx_word16_t ngain;
|
spx_word16_t ngain;
|
||||||
spx_word16_t gg1, gg2;
|
spx_word16_t gg1, gg2;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
int scaledown=0;
|
||||||
|
#endif
|
||||||
#if 0 /* Set to 1 to enable full pitch search */
|
#if 0 /* Set to 1 to enable full pitch search */
|
||||||
int nol_pitch[6];
|
int nol_pitch[6];
|
||||||
spx_word16_t nol_pitch_coef[6];
|
spx_word16_t nol_pitch_coef[6];
|
||||||
@@ -819,6 +712,23 @@ char *stack
|
|||||||
else
|
else
|
||||||
interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
|
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);*/
|
/*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/
|
||||||
|
|
||||||
/*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
|
/*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
|
||||||
@@ -898,5 +808,14 @@ char *stack
|
|||||||
|
|
||||||
for (i=0;i<nsf;i++)
|
for (i=0;i<nsf;i++)
|
||||||
new_exc[i] = MULT16_16_Q14(ngain, new_exc[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
|
#ifndef FILTERS_H
|
||||||
#define 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_rms(const spx_sig_t *x, int len);
|
||||||
spx_word16_t compute_rms16(const spx_word16_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 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 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 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 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_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 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 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);
|
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 */
|
/* 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 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_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 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_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_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 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);
|
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
|
#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;
|
spx_sig_t max_val=1;
|
||||||
int sig_shift;
|
int sig_shift;
|
||||||
int dead1, dead2, dead3, dead4, dead5, dead6;
|
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"
|
"\tmov %5, %5, asr %3 \n"
|
||||||
"\tstrh %5, [%1], #2 \n"
|
"\tstrh %5, [%1], #2 \n"
|
||||||
|
|
||||||
"\tbge .normalize16loop%=\n"
|
"\tbgt .normalize16loop%=\n"
|
||||||
: "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
: "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
|
||||||
"=r" (dead5), "=r" (dead6)
|
"=r" (dead5), "=r" (dead6)
|
||||||
: "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift)
|
: "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;
|
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;
|
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
|
#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
|
#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)
|
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
|
#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)
|
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>
|
#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];
|
__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]);
|
_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];
|
__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
|
#define OVERRIDE_FILTER_MEM16
|
||||||
void filter_mem2(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
|
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)
|
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)
|
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];
|
__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];
|
__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]);
|
_mm_storeu_ps(_mem+4, mem[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OVERRIDE_IIR_MEM2
|
#define OVERRIDE_IIR_MEM16
|
||||||
void iir_mem2(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
|
void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack)
|
||||||
{
|
{
|
||||||
if(ord==10)
|
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)
|
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];
|
__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]);
|
_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];
|
__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]);
|
_mm_storeu_ps(_mem+4, mem[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OVERRIDE_FIR_MEM2
|
#define OVERRIDE_FIR_MEM16
|
||||||
void fir_mem2(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
|
void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack)
|
||||||
{
|
{
|
||||||
if(ord==10)
|
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)
|
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;
|
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;
|
int res;
|
||||||
if (!VERIFY_SHORT(x))
|
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;
|
res = x;
|
||||||
spx_mips++;
|
spx_mips++;
|
||||||
return res;
|
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;
|
int res;
|
||||||
if (!VERIFY_SHORT(x))
|
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;
|
res = x;
|
||||||
spx_mips++;
|
spx_mips++;
|
||||||
return res;
|
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;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
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;
|
res = a>>shift;
|
||||||
if (!VERIFY_SHORT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
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;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
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;
|
res = a<<shift;
|
||||||
if (!VERIFY_SHORT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -134,7 +138,9 @@ static inline int SHR32(long long a, int shift)
|
|||||||
}
|
}
|
||||||
res = a>>shift;
|
res = a>>shift;
|
||||||
if (!VERIFY_INT(res))
|
if (!VERIFY_INT(res))
|
||||||
|
{
|
||||||
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
||||||
|
}
|
||||||
spx_mips++;
|
spx_mips++;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -143,62 +149,71 @@ static inline int SHL32(long long a, int shift)
|
|||||||
long long res;
|
long long res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
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;
|
res = a<<shift;
|
||||||
if (!VERIFY_INT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
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 SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||||
#define SATURATE32(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 SHR(a,shift) ((a) >> (shift))
|
||||||
#define SHL(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;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
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;
|
res = a+b;
|
||||||
if (!VERIFY_SHORT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
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;
|
long long res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
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;
|
res = a+b;
|
||||||
if (!VERIFY_INT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
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 ADD64(a,b) (MIPS_INC(a)+(b))
|
||||||
|
|
||||||
#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
|
|
||||||
|
|
||||||
/* result fits in 16 bits */
|
/* result fits in 16 bits */
|
||||||
static inline short MULT16_16_16(int a, int b)
|
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;
|
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;
|
long long res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
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;
|
res = ((long long)a)*b;
|
||||||
if (!VERIFY_INT(res))
|
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++;
|
spx_mips++;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b))))
|
#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_Q11(c,a,b) (EXTRACT16(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_Q13(c,a,b) (EXTRACT16(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_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;
|
long long res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
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;
|
res = (((long long)a)*(long long)b) >> Q;
|
||||||
if (!VERIFY_INT(res))
|
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;
|
spx_mips+=5;
|
||||||
return res;
|
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_Q13(a,b) MULT16_32_QX(a,b,13)
|
||||||
#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
|
#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_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)))
|
#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
|
||||||
|
|
||||||
static inline int SATURATE(int a, int 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 = ((long long)a)*b;
|
||||||
res >>= 15;
|
res >>= 15;
|
||||||
if (!VERIFY_SHORT(res))
|
if (!VERIFY_SHORT(res))
|
||||||
|
{
|
||||||
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
|
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
|
||||||
|
}
|
||||||
spx_mips+=3;
|
spx_mips+=3;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -398,23 +434,24 @@ static inline short MULT16_16_P15(int a, int b)
|
|||||||
return res;
|
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;
|
long long res;
|
||||||
if (b==0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
|
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;
|
res = a/b;
|
||||||
if (!VERIFY_SHORT(res))
|
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)
|
if (res>32767)
|
||||||
res = 32767;
|
res = 32767;
|
||||||
if (res<-32768)
|
if (res<-32768)
|
||||||
@@ -423,22 +460,24 @@ static inline int DIV32_16(long long a, long long b)
|
|||||||
spx_mips+=20;
|
spx_mips+=20;
|
||||||
return res;
|
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;
|
long long res;
|
||||||
if (b==0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
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;
|
res = a/b;
|
||||||
if (!VERIFY_INT(res))
|
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;
|
spx_mips+=36;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,14 +46,15 @@
|
|||||||
#define SHL16(a,shift) ((a) << (shift))
|
#define SHL16(a,shift) ((a) << (shift))
|
||||||
#define SHR32(a,shift) ((a) >> (shift))
|
#define SHR32(a,shift) ((a) >> (shift))
|
||||||
#define SHL32(a,shift) ((a) << (shift))
|
#define SHL32(a,shift) ((a) << (shift))
|
||||||
#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift))
|
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
|
||||||
#define PSHR32(a,shift) (SHR32((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 SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||||
#define SATURATE32(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 SHR(a,shift) ((a) >> (shift))
|
||||||
#define SHL(a,shift) ((spx_word32_t)(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)))
|
#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 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 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 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)))
|
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||||
|
|
||||||
|
|||||||
+639
-304
File diff suppressed because it is too large.
Load diff
+220
-127
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2003-2004, Mark Borgerding
|
Copyright (c) 2003-2004, Mark Borgerding
|
||||||
|
Copyright (c) 2005-2007, Jean-Marc Valin
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
@@ -18,127 +19,149 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "_kiss_fft_guts.h"
|
#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
|
/* 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.
|
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(
|
static void kf_bfly2(
|
||||||
kiss_fft_cpx * Fout,
|
kiss_fft_cpx * Fout,
|
||||||
const size_t fstride,
|
const size_t fstride,
|
||||||
const kiss_fft_cfg st,
|
const kiss_fft_cfg st,
|
||||||
int m
|
int m,
|
||||||
|
int N,
|
||||||
|
int mm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
kiss_fft_cpx * Fout2;
|
kiss_fft_cpx * Fout2;
|
||||||
kiss_fft_cpx * tw1 = st->twiddles;
|
kiss_fft_cpx * tw1;
|
||||||
kiss_fft_cpx t;
|
kiss_fft_cpx t;
|
||||||
Fout2 = Fout + m;
|
|
||||||
if (!st->inverse) {
|
if (!st->inverse) {
|
||||||
int i;
|
int i,j;
|
||||||
kiss_fft_cpx *x=Fout;
|
kiss_fft_cpx * Fout_beg = Fout;
|
||||||
for (i=0;i<2*m;i++)
|
for (i=0;i<N;i++)
|
||||||
{
|
{
|
||||||
x[i].r = SHR(x[i].r,1);
|
Fout = Fout_beg + i*mm;
|
||||||
x[i].i = SHR(x[i].i,1);
|
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(
|
static void kf_bfly4(
|
||||||
kiss_fft_cpx * Fout,
|
kiss_fft_cpx * Fout,
|
||||||
const size_t fstride,
|
const size_t fstride,
|
||||||
const kiss_fft_cfg st,
|
const kiss_fft_cfg st,
|
||||||
const size_t m
|
int m,
|
||||||
|
int N,
|
||||||
|
int mm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
kiss_fft_cpx *tw1,*tw2,*tw3;
|
kiss_fft_cpx *tw1,*tw2,*tw3;
|
||||||
kiss_fft_cpx scratch[6];
|
kiss_fft_cpx scratch[6];
|
||||||
size_t k=m;
|
|
||||||
const size_t m2=2*m;
|
const size_t m2=2*m;
|
||||||
const size_t m3=3*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)
|
if (st->inverse)
|
||||||
{
|
{
|
||||||
do {
|
kiss_fft_cpx * Fout_beg = Fout;
|
||||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
for (i=0;i<N;i++)
|
||||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
{
|
||||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
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_SUB( scratch[5] , *Fout, scratch[1] );
|
||||||
C_ADDTO(*Fout, scratch[1]);
|
C_ADDTO(*Fout, scratch[1]);
|
||||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||||
tw1 += fstride;
|
tw1 += fstride;
|
||||||
tw2 += fstride*2;
|
tw2 += fstride*2;
|
||||||
tw3 += fstride*3;
|
tw3 += fstride*3;
|
||||||
C_ADDTO( *Fout , scratch[3] );
|
C_ADDTO( *Fout , scratch[3] );
|
||||||
|
|
||||||
Fout[m].r = scratch[5].r - scratch[4].i;
|
Fout[m].r = scratch[5].r - scratch[4].i;
|
||||||
Fout[m].i = scratch[5].i + scratch[4].r;
|
Fout[m].i = scratch[5].i + scratch[4].r;
|
||||||
Fout[m3].r = scratch[5].r + scratch[4].i;
|
Fout[m3].r = scratch[5].r + scratch[4].i;
|
||||||
Fout[m3].i = scratch[5].i - scratch[4].r;
|
Fout[m3].i = scratch[5].i - scratch[4].r;
|
||||||
++Fout;
|
++Fout;
|
||||||
} while(--k);
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
do {
|
kiss_fft_cpx * Fout_beg = Fout;
|
||||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
for (i=0;i<N;i++)
|
||||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
{
|
||||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
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 );
|
||||||
|
|
||||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
Fout->r = PSHR16(Fout->r, 2);
|
||||||
C_ADDTO(*Fout, scratch[1]);
|
Fout->i = PSHR16(Fout->i, 2);
|
||||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
C_ADDTO(*Fout, scratch[1]);
|
||||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||||
tw1 += fstride;
|
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||||
tw2 += fstride*2;
|
Fout[m2].r = PSHR16(Fout[m2].r, 2);
|
||||||
tw3 += fstride*3;
|
Fout[m2].i = PSHR16(Fout[m2].i, 2);
|
||||||
C_ADDTO( *Fout , scratch[3] );
|
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].r = scratch[5].r + scratch[4].i;
|
||||||
Fout[m].i = scratch[5].i - scratch[4].r;
|
Fout[m].i = scratch[5].i - scratch[4].r;
|
||||||
Fout[m3].r = scratch[5].r - scratch[4].i;
|
Fout[m3].r = scratch[5].r - scratch[4].i;
|
||||||
Fout[m3].i = scratch[5].i + scratch[4].r;
|
Fout[m3].i = scratch[5].i + scratch[4].r;
|
||||||
++Fout;
|
++Fout;
|
||||||
}while(--k);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,9 +286,12 @@ static void kf_bfly_generic(
|
|||||||
int u,k,q1,q;
|
int u,k,q1,q;
|
||||||
kiss_fft_cpx * twiddles = st->twiddles;
|
kiss_fft_cpx * twiddles = st->twiddles;
|
||||||
kiss_fft_cpx t;
|
kiss_fft_cpx t;
|
||||||
|
kiss_fft_cpx scratchbuf[17];
|
||||||
int Norig = st->nfft;
|
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 ) {
|
for ( u=0; u<m; ++u ) {
|
||||||
k=u;
|
k=u;
|
||||||
@@ -292,6 +318,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
|
static
|
||||||
void kf_work(
|
void kf_work(
|
||||||
kiss_fft_cpx * Fout,
|
kiss_fft_cpx * Fout,
|
||||||
@@ -299,24 +358,34 @@ void kf_work(
|
|||||||
const size_t fstride,
|
const size_t fstride,
|
||||||
int in_stride,
|
int in_stride,
|
||||||
int * factors,
|
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;
|
kiss_fft_cpx * Fout_beg=Fout;
|
||||||
const int p=*factors++; /* the radix */
|
const int p=*factors++; /* the radix */
|
||||||
const int m=*factors++; /* stage's fft length/p */
|
const int m=*factors++; /* stage's fft length/p */
|
||||||
const kiss_fft_cpx * Fout_end = Fout + p*m;
|
#if 0
|
||||||
|
/*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
|
||||||
if (m==1) {
|
if (m==1)
|
||||||
do{
|
{
|
||||||
*Fout = *f;
|
/* int j;
|
||||||
f += fstride*in_stride;
|
for (j=0;j<p;j++)
|
||||||
}while(++Fout != Fout_end );
|
{
|
||||||
}else{
|
Fout[j] = *f;
|
||||||
do{
|
f += fstride*in_stride;
|
||||||
kf_work( Fout , f, fstride*p, in_stride, factors,st);
|
}*/
|
||||||
f += fstride*in_stride;
|
} else {
|
||||||
}while( (Fout += m) != Fout_end );
|
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;
|
Fout=Fout_beg;
|
||||||
@@ -328,6 +397,36 @@ void kf_work(
|
|||||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||||
default: kf_bfly_generic(Fout,fstride,st,m,p); 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, ...
|
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||||
@@ -338,8 +437,6 @@ static
|
|||||||
void kf_factor(int n,int * facbuf)
|
void kf_factor(int n,int * facbuf)
|
||||||
{
|
{
|
||||||
int p=4;
|
int p=4;
|
||||||
double floor_sqrt;
|
|
||||||
floor_sqrt = floor( sqrt((double)n) );
|
|
||||||
|
|
||||||
/*factor out powers of 4, powers of 2, then any remaining primes */
|
/*factor out powers of 4, powers of 2, then any remaining primes */
|
||||||
do {
|
do {
|
||||||
@@ -349,7 +446,7 @@ void kf_factor(int n,int * facbuf)
|
|||||||
case 2: p = 3; break;
|
case 2: p = 3; break;
|
||||||
default: p += 2; 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 */
|
p = n; /* no more factors, skip to end */
|
||||||
}
|
}
|
||||||
n /= p;
|
n /= p;
|
||||||
@@ -357,7 +454,6 @@ void kf_factor(int n,int * facbuf)
|
|||||||
*facbuf++ = n;
|
*facbuf++ = n;
|
||||||
} while (n > 1);
|
} while (n > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* User-callable function to allocate all necessary storage space for the fft.
|
* 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;
|
int i;
|
||||||
st->nfft=nfft;
|
st->nfft=nfft;
|
||||||
st->inverse = inverse_fft;
|
st->inverse = inverse_fft;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
for (i=0;i<nfft;++i) {
|
for (i=0;i<nfft;++i) {
|
||||||
const double pi=3.14159265358979323846264338327;
|
spx_word32_t phase = i;
|
||||||
double phase = ( -2*pi /nfft ) * i;
|
if (!st->inverse)
|
||||||
if (st->inverse)
|
phase = -phase;
|
||||||
phase *= -1;
|
kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft));
|
||||||
kf_cexp(st->twiddles+i, phase );
|
|
||||||
}
|
}
|
||||||
|
#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);
|
kf_factor(nfft,st->factors);
|
||||||
}
|
}
|
||||||
return st;
|
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)
|
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
|
||||||
{
|
{
|
||||||
if (fin == fout) {
|
if (fin == fout)
|
||||||
CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
|
{
|
||||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
speex_fatal("In-place FFT not supported");
|
||||||
speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
|
/*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
|
||||||
}else{
|
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||||
kf_work( fout, 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);
|
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 <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -32,7 +32,7 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
# define kiss_fft_scalar spx_int16_t
|
# define kiss_fft_scalar spx_int16_t
|
||||||
#else
|
#else
|
||||||
# ifndef kiss_fft_scalar
|
# ifndef kiss_fft_scalar
|
||||||
|
|||||||
+145
-11
@@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "os_support.h"
|
||||||
#include "kiss_fftr.h"
|
#include "kiss_fftr.h"
|
||||||
#include "_kiss_fft_guts.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;
|
st->super_twiddles = st->tmpbuf + nfft;
|
||||||
kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
|
kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
|
||||||
|
|
||||||
for (i = 0; i < nfft; ++i) {
|
#ifdef FIXED_POINT
|
||||||
double phase =
|
for (i=0;i<nfft;++i) {
|
||||||
-3.14159265358979323846264338327 * ((double) i / nfft + .5);
|
spx_word32_t phase = i+(nfft>>1);
|
||||||
if (inverse_fft)
|
if (!inverse_fft)
|
||||||
phase *= -1;
|
phase = -phase;
|
||||||
kf_cexp (st->super_twiddles+i,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;
|
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;
|
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
|
||||||
|
|
||||||
if ( st->substate->inverse) {
|
if ( st->substate->inverse) {
|
||||||
speex_warning("kiss fft usage error: improper alloc\n");
|
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ncfft = st->substate->nfft;
|
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 */
|
/* input buffer timedata is stored row-wise */
|
||||||
int k, ncfft;
|
int k, ncfft;
|
||||||
|
|
||||||
if (st->substate->inverse == 0) {
|
if (st->substate->inverse == 0) {
|
||||||
speex_warning ("kiss fft usage error: improper alloc\n");
|
speex_fatal("kiss fft usage error: improper alloc\n");
|
||||||
exit (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ncfft = st->substate->nfft;
|
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);
|
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
|
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_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
|
input freqdata has nfft/2+1 complex points
|
||||||
output timedata has nfft scalar points
|
output timedata has nfft scalar points
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#ifndef LPC_H
|
#ifndef LPC_H
|
||||||
#define LPC_H
|
#define LPC_H
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
void _spx_autocorr(
|
void _spx_autocorr(
|
||||||
const spx_word16_t * x, /* in: [0...n-1] samples x */
|
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 */
|
/* hard limit ak's to +/- 32767 */
|
||||||
|
|
||||||
if (a < -32767) a = 32767;
|
if (a < -32767) a = -32767;
|
||||||
if (a > 32767) a = 32767;
|
if (a > 32767) a = 32767;
|
||||||
ak[j-1] = (short)a;
|
ak[j-1] = (short)a;
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ Modified by Jean-Marc Valin
|
|||||||
#ifndef __AK2LSPD__
|
#ifndef __AK2LSPD__
|
||||||
#define __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);
|
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);
|
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||||
|
|||||||
+145
-84
@@ -40,6 +40,7 @@
|
|||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include <speex/speex_bits.h>
|
#include <speex/speex_bits.h>
|
||||||
#include "math_approx.h"
|
#include "math_approx.h"
|
||||||
|
#include "os_support.h"
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
@@ -176,13 +177,31 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
|||||||
VARDECL(spx_word32_t *best_ener);
|
VARDECL(spx_word32_t *best_ener);
|
||||||
spx_word32_t e0;
|
spx_word32_t e0;
|
||||||
VARDECL(spx_word32_t *corr);
|
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);
|
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_score, N, spx_word32_t);
|
||||||
ALLOC(best_ener, 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++)
|
for (i=0;i<N;i++)
|
||||||
{
|
{
|
||||||
best_score[i]=-1;
|
best_score[i]=-1;
|
||||||
@@ -190,6 +209,24 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
|||||||
pitch[i]=start;
|
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);
|
energy[0]=inner_prod(sw-start, sw-start, len);
|
||||||
e0=inner_prod(sw, sw, len);
|
e0=inner_prod(sw, sw, len);
|
||||||
for (i=start;i<end;i++)
|
for (i=start;i<end;i++)
|
||||||
@@ -200,58 +237,41 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p
|
|||||||
energy[i-start+1] = 0;
|
energy[i-start+1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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);
|
pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
|
||||||
|
|
||||||
/* FIXME: Fixed-point and floating-point code should be merged */
|
|
||||||
#ifdef FIXED_POINT
|
#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);
|
for (i=-end;i<len;i++)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
sw[i]=SHL16(sw[i],1);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
/* Search for the best pitch prediction gain */
|
||||||
for (i=start;i<=end;i++)
|
for (i=start;i<=end;i++)
|
||||||
{
|
{
|
||||||
float tmp = corr[i-start]*corr[i-start];
|
spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
|
||||||
if (tmp*best_ener[N-1]>best_score[N-1]*(1+energy[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--)
|
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];
|
pitch[k]=pitch[k-1];
|
||||||
}
|
}
|
||||||
best_score[j]=tmp;
|
best_score[j]=tmp;
|
||||||
best_ener[j]=energy[i-start]+1;
|
best_ener[j]=ener16[i-start]+1;
|
||||||
pitch[j]=i;
|
pitch[j]=i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Compute open-loop gain */
|
/* Compute open-loop gain if necessary */
|
||||||
if (gain)
|
if (gain)
|
||||||
{
|
{
|
||||||
for (j=0;j<N;j++)
|
for (j=0;j<N;j++)
|
||||||
{
|
{
|
||||||
spx_word16_t g;
|
spx_word16_t g;
|
||||||
i=pitch[j];
|
i=pitch[j];
|
||||||
g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
|
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) */
|
/* FIXME: g = max(g,corr/energy) */
|
||||||
if (g<0)
|
if (g<0)
|
||||||
g = 0;
|
g = 0;
|
||||||
gain[j]=g;
|
gain[j]=g;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -342,7 +363,8 @@ const spx_word16_t *r,
|
|||||||
spx_word16_t *new_target,
|
spx_word16_t *new_target,
|
||||||
int *cdbk_index,
|
int *cdbk_index,
|
||||||
int plc_tuning,
|
int plc_tuning,
|
||||||
spx_word32_t cumul_gain
|
spx_word32_t cumul_gain,
|
||||||
|
int scaledown
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
@@ -366,6 +388,9 @@ spx_word32_t cumul_gain
|
|||||||
x[1]=tmp1+nsf;
|
x[1]=tmp1+nsf;
|
||||||
x[2]=tmp1+2*nsf;
|
x[2]=tmp1+2*nsf;
|
||||||
|
|
||||||
|
for (j=0;j<nsf;j++)
|
||||||
|
new_target[j] = target[j];
|
||||||
|
|
||||||
{
|
{
|
||||||
VARDECL(spx_mem_t *mm);
|
VARDECL(spx_mem_t *mm);
|
||||||
int pp=pitch-1;
|
int pp=pitch-1;
|
||||||
@@ -379,6 +404,16 @@ spx_word32_t cumul_gain
|
|||||||
else
|
else
|
||||||
e[j]=0;
|
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++)
|
for (j=0;j<p;j++)
|
||||||
mm[j] = 0;
|
mm[j] = 0;
|
||||||
iir_mem16(e, ak, e, nsf, p, mm, stack);
|
iir_mem16(e, ak, e, nsf, p, mm, stack);
|
||||||
@@ -391,13 +426,18 @@ spx_word32_t cumul_gain
|
|||||||
for (i=1;i>=0;i--)
|
for (i=1;i>=0;i--)
|
||||||
{
|
{
|
||||||
spx_word16_t e0=exc2[-pitch-1+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);
|
x[i][0]=MULT16_16_Q14(r[0], e0);
|
||||||
for (j=0;j<nsf-1;j++)
|
for (j=0;j<nsf-1;j++)
|
||||||
x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
|
x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<3;i++)
|
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 (i=0;i<3;i++)
|
||||||
for (j=0;j<=i;j++)
|
for (j=0;j<=i;j++)
|
||||||
A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
|
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;
|
*cdbk_index=best_cdbk;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_MEMSET(exc, 0, nsf);
|
||||||
exc[i]=0;
|
|
||||||
for (i=0;i<3;i++)
|
for (i=0;i<3;i++)
|
||||||
{
|
{
|
||||||
int j;
|
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])),
|
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]));
|
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);
|
err = inner_prod(new_target, new_target, nsf);
|
||||||
|
|
||||||
@@ -509,7 +548,7 @@ int plc_tuning,
|
|||||||
spx_word32_t *cumul_gain
|
spx_word32_t *cumul_gain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i;
|
||||||
int cdbk_index, pitch=0, best_gain_index=0;
|
int cdbk_index, pitch=0, best_gain_index=0;
|
||||||
VARDECL(spx_sig_t *best_exc);
|
VARDECL(spx_sig_t *best_exc);
|
||||||
VARDECL(spx_word16_t *new_target);
|
VARDECL(spx_word16_t *new_target);
|
||||||
@@ -520,6 +559,7 @@ spx_word32_t *cumul_gain
|
|||||||
const ltp_params *params;
|
const ltp_params *params;
|
||||||
const signed char *gain_cdbk;
|
const signed char *gain_cdbk;
|
||||||
int gain_cdbk_size;
|
int gain_cdbk_size;
|
||||||
|
int scaledown=0;
|
||||||
|
|
||||||
VARDECL(int *nbest);
|
VARDECL(int *nbest);
|
||||||
|
|
||||||
@@ -540,11 +580,29 @@ spx_word32_t *cumul_gain
|
|||||||
{
|
{
|
||||||
speex_bits_pack(bits, 0, params->pitch_bits);
|
speex_bits_pack(bits, 0, params->pitch_bits);
|
||||||
speex_bits_pack(bits, 0, params->gain_bits);
|
speex_bits_pack(bits, 0, params->gain_bits);
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_MEMSET(exc, 0, nsf);
|
||||||
exc[i]=0;
|
|
||||||
return start;
|
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)
|
if (N>end-start+1)
|
||||||
N=end-start+1;
|
N=end-start+1;
|
||||||
if (end != start)
|
if (end != start)
|
||||||
@@ -559,16 +617,13 @@ spx_word32_t *cumul_gain
|
|||||||
for (i=0;i<N;i++)
|
for (i=0;i<N;i++)
|
||||||
{
|
{
|
||||||
pitch=nbest[i];
|
pitch=nbest[i];
|
||||||
for (j=0;j<nsf;j++)
|
SPEEX_MEMSET(exc, 0, nsf);
|
||||||
exc[j]=0;
|
|
||||||
err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, 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)
|
if (err<best_err || best_err<0)
|
||||||
{
|
{
|
||||||
for (j=0;j<nsf;j++)
|
SPEEX_COPY(best_exc, exc, nsf);
|
||||||
best_exc[j]=exc[j];
|
SPEEX_COPY(best_target, new_target, nsf);
|
||||||
for (j=0;j<nsf;j++)
|
|
||||||
best_target[j]=new_target[j];
|
|
||||||
best_err=err;
|
best_err=err;
|
||||||
best_pitch=pitch;
|
best_pitch=pitch;
|
||||||
best_gain_index=cdbk_index;
|
best_gain_index=cdbk_index;
|
||||||
@@ -584,11 +639,16 @@ spx_word32_t *cumul_gain
|
|||||||
#endif
|
#endif
|
||||||
/*printf ("%f\n", cumul_gain);*/
|
/*printf ("%f\n", cumul_gain);*/
|
||||||
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
|
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_COPY(exc, best_exc, nsf);
|
||||||
exc[i]=best_exc[i];
|
SPEEX_COPY(target, best_target, nsf);
|
||||||
for (i=0;i<nsf;i++)
|
#ifdef FIXED_POINT
|
||||||
target[i]=best_target[i];
|
/* Scale target back up if needed */
|
||||||
|
if (scaledown)
|
||||||
|
{
|
||||||
|
for (i=0;i<nsf;i++)
|
||||||
|
target[i]=SHL16(target[i],1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return pitch;
|
return pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,8 +729,7 @@ int cdbk_offset
|
|||||||
gain[0] = SHL16(gain[0],7);
|
gain[0] = SHL16(gain[0],7);
|
||||||
gain[1] = SHL16(gain[1],7);
|
gain[1] = SHL16(gain[1],7);
|
||||||
gain[2] = SHL16(gain[2],7);
|
gain[2] = SHL16(gain[2],7);
|
||||||
for (i=0;i<nsf;i++)
|
SPEEX_MEMSET(exc_out, 0, nsf);
|
||||||
exc_out[i]=0;
|
|
||||||
for (i=0;i<3;i++)
|
for (i=0;i<3;i++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
@@ -717,8 +776,8 @@ spx_word32_t *cumul_gain
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VARDECL(spx_sig_t *res);
|
VARDECL(spx_word16_t *res);
|
||||||
ALLOC(res, nsf, spx_sig_t);
|
ALLOC(res, nsf, spx_word16_t);
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
if (pitch_coef>63)
|
if (pitch_coef>63)
|
||||||
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]);
|
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++)
|
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;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,7 +831,7 @@ int cdbk_offset
|
|||||||
for (i=0;i<nsf;i++)
|
for (i=0;i<nsf;i++)
|
||||||
{
|
{
|
||||||
exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
|
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;
|
*pitch_val = start;
|
||||||
gain_val[0]=gain_val[2]=0;
|
gain_val[0]=gain_val[2]=0;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <speex/speex_bits.h>
|
#include <speex/speex_bits.h>
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
/** LTP parameters. */
|
/** LTP parameters. */
|
||||||
typedef struct {
|
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 %2, %2, %7, asr #5\n"
|
||||||
"\tadd %3, %3, %10, asr #5\n"
|
"\tadd %3, %3, %10, asr #5\n"
|
||||||
"\tbne .inner_prod_loop%=\n"
|
"\tbne .inner_prod_loop%=\n"
|
||||||
: "=r" (deadx), "=r" (deady), "=r" (sum1), "=r" (sum2), "=r" (deadlen),
|
: "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2),
|
||||||
"=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6)
|
"=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3),
|
||||||
: "0" (x), "1" (y), "2" (sum1), "3" (sum2), "4" (len>>3)
|
"=r" (dead4), "=r" (dead5), "=r" (dead6)
|
||||||
|
: "0" (x), "1" (y), "4" (len>>3)
|
||||||
: "cc"
|
: "cc"
|
||||||
);
|
);
|
||||||
return (sum1+sum2)>>1;
|
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 %6, %13 \n"
|
||||||
"\tstr %7, %14 \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" (part1), "=r" (part2), "=r" (part3), "=r" (part4),
|
||||||
"=r" (x), "=r" (y), "=r" (x0),
|
"+r" (x), "+r" (y), "=r" (x0), "+m" (sum1),
|
||||||
"=m" (sum1), "=m" (sum2), "=m" (sum3), "=m" (sum4), "=r" (dead1)
|
"+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)
|
|
||||||
: "cc", "memory"
|
: "cc", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,7 +330,6 @@ static int pitch_gain_search_3tap_vq(
|
|||||||
" %0 = 0;\n\t" /* %0: best_sum */
|
" %0 = 0;\n\t" /* %0: best_sum */
|
||||||
" %1 = 0;\n\t" /* %1: best_cbdk */
|
" %1 = 0;\n\t" /* %1: best_cbdk */
|
||||||
" P1 = 0;\n\t" /* P1: loop counter */
|
" P1 = 0;\n\t" /* P1: loop counter */
|
||||||
" R5 = 64;\n\t" /* R5: pitch_control */
|
|
||||||
|
|
||||||
" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
|
" LSETUP (pgs1, pgs2) LC1 = %4;\n\t"
|
||||||
"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */
|
"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"
|
" R2 += 32;\n\t"
|
||||||
" R3 += 32;\n\t"
|
" R3 += 32;\n\t"
|
||||||
" R4 += 32;\n\t"
|
" R4 += 32;\n\t"
|
||||||
|
" R4.H = 64;\n\t" /* R4.H: pitch_control */
|
||||||
|
|
||||||
" R0 = B [P0++] (X);\n\t"
|
" R0 = B [P0++] (X);\n\t"
|
||||||
" B0 = R0;\n\t" /* BO: gain_sum */
|
" B0 = R0;\n\t" /* BO: gain_sum */
|
||||||
@@ -349,13 +349,13 @@ static int pitch_gain_search_3tap_vq(
|
|||||||
" A0 = 0;\n\t"
|
" A0 = 0;\n\t"
|
||||||
|
|
||||||
" R0.L = W[I1++];\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"
|
" 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"
|
" 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"
|
" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t"
|
||||||
|
|
||||||
" R1.L = R2.L*R3.L (IS);\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)
|
: "=&d" (best_sum), "=&d" (best_cdbk)
|
||||||
: "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
|
: "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain),
|
||||||
"b" (-VERY_LARGE32)
|
"b" (-VERY_LARGE32)
|
||||||
: "R0", "R1", "R2", "R3", "R4", "R5", "P0",
|
: "R0", "R1", "R2", "R3", "R4", "P0",
|
||||||
"P1", "I1", "L1", "A0", "B0"
|
"P1", "I1", "L1", "A0", "B0"
|
||||||
#if (__GNUC__ == 4)
|
#if (__GNUC__ == 4)
|
||||||
, "LC1"
|
, "LC1"
|
||||||
|
|||||||
@@ -35,16 +35,298 @@
|
|||||||
#ifndef MATH_APPROX_H
|
#ifndef MATH_APPROX_H
|
||||||
#define 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_sqrt sqrt
|
||||||
#define spx_acos acos
|
#define spx_acos acos
|
||||||
|
#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
|
#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
|
#endif
|
||||||
+706
-286
File diff suppressed because it is too large.
Load diff
+5
-312
@@ -43,28 +43,23 @@
|
|||||||
#include "sb_celp.h"
|
#include "sb_celp.h"
|
||||||
#include "nb_celp.h"
|
#include "nb_celp.h"
|
||||||
#include "vbr.h"
|
#include "vbr.h"
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#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 declarations for all codebooks we use here */
|
||||||
extern const signed char gain_cdbk_nb[];
|
extern const signed char gain_cdbk_nb[];
|
||||||
extern const signed char gain_cdbk_lbr[];
|
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_256_table[];
|
||||||
extern const signed char exc_5_64_table[];
|
extern const signed char exc_5_64_table[];
|
||||||
extern const signed char exc_8_128_table[];
|
extern const signed char exc_8_128_table[];
|
||||||
extern const signed char exc_10_32_table[];
|
extern const signed char exc_10_32_table[];
|
||||||
extern const signed char exc_10_16_table[];
|
extern const signed char exc_10_16_table[];
|
||||||
extern const signed char exc_20_32_table[];
|
extern const signed char exc_20_32_table[];
|
||||||
extern const signed char hexc_10_32_table[];
|
|
||||||
|
|
||||||
|
|
||||||
/* Parameters for Long-Term Prediction (LTP)*/
|
/* Parameters for Long-Term Prediction (LTP)*/
|
||||||
@@ -150,28 +145,7 @@ static const split_cb_params split_cb_sb = {
|
|||||||
0,
|
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 */
|
/* 2150 bps "vocoder-like" mode for comfort noise */
|
||||||
static const SpeexSubmode nb_submode1 = {
|
static const SpeexSubmode nb_submode1 = {
|
||||||
@@ -354,11 +328,7 @@ static const SpeexNBMode nb_mode = {
|
|||||||
#else
|
#else
|
||||||
0.9, 0.6, /* gamma1, gamma2 */
|
0.9, 0.6, /* gamma1, gamma2 */
|
||||||
#endif
|
#endif
|
||||||
.012, /*lag_factor*/
|
|
||||||
QCONST16(.0002,15), /*lpc_floor*/
|
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,
|
{NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
|
||||||
&nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
|
&nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||||
5,
|
5,
|
||||||
@@ -367,7 +337,7 @@ static const SpeexNBMode nb_mode = {
|
|||||||
|
|
||||||
|
|
||||||
/* Default mode for narrowband */
|
/* Default mode for narrowband */
|
||||||
const SpeexMode speex_nb_mode = {
|
EXPORT const SpeexMode speex_nb_mode = {
|
||||||
&nb_mode,
|
&nb_mode,
|
||||||
nb_mode_query,
|
nb_mode_query,
|
||||||
"narrowband",
|
"narrowband",
|
||||||
@@ -384,290 +354,13 @@ const SpeexMode speex_nb_mode = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Wideband part */
|
|
||||||
|
|
||||||
static const SpeexSubmode wb_submode1 = {
|
EXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return mode->query(mode->mode, request, ptr);
|
return mode->query(mode->mode, request, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpeexMode * speex_lib_get_mode (int mode)
|
#ifdef FIXED_DEBUG
|
||||||
{
|
long long spx_mips=0;
|
||||||
#ifdef EPIC_48K
|
|
||||||
if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mode < 0 || mode > SPEEX_NB_MODES) return NULL;
|
|
||||||
|
|
||||||
return speex_mode_list[mode];
|
|
||||||
}
|
|
||||||
+22
-10
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#include <speex/speex.h>
|
#include <speex/speex.h>
|
||||||
#include <speex/speex_bits.h>
|
#include <speex/speex_bits.h>
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#define NB_SUBMODES 16
|
#define NB_SUBMODES 16
|
||||||
#define NB_SUBMODE_BITS 4
|
#define NB_SUBMODE_BITS 4
|
||||||
@@ -46,6 +46,23 @@
|
|||||||
#define SB_SUBMODES 8
|
#define SB_SUBMODES 8
|
||||||
#define SB_SUBMODE_BITS 3
|
#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 */
|
/** Quantizes LSPs */
|
||||||
typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
|
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_quant_func lsp_quant; /**< LSP quantization function */
|
||||||
lsp_unquant_func lsp_unquant; /**< LSP unquantization 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_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
|
||||||
ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
|
ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
|
||||||
const void *ltp_params; /**< Pitch parameters (options) */
|
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 gamma1; /**< Perceptual filter parameter #1 */
|
||||||
spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
|
spx_word16_t gamma2; /**< Perceptual filter parameter #2 */
|
||||||
float lag_factor; /**< Lag-windowing parameter */
|
|
||||||
spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */
|
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 */
|
const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||||
int quality_map[11]; /**< Mode corresponding to each quality setting */
|
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 frameSize; /**< Size of frames used for encoding */
|
||||||
int subframeSize; /**< Size of sub-frames used for encoding */
|
int subframeSize; /**< Size of sub-frames used for encoding */
|
||||||
int lpcSize; /**< Order of LPC filter */
|
int lpcSize; /**< Order of LPC filter */
|
||||||
int bufSize; /**< Signal buffer size in encoder */
|
|
||||||
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
spx_word16_t gamma1; /**< Perceptual filter parameter #1 */
|
||||||
spx_word16_t gamma2; /**< 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 */
|
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 */
|
const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
|
||||||
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
int defaultSubmode; /**< Default sub-mode to use when encoding */
|
||||||
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
|
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
|
||||||
int 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];
|
const float (*vbr_thresh)[11];
|
||||||
|
#endif
|
||||||
int nb_modes;
|
int nb_modes;
|
||||||
} SpeexSBMode;
|
} SpeexSBMode;
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+259
-411
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 ol_voiced; /**< Open-loop voiced/non-voiced decision */
|
||||||
int *pitch;
|
int *pitch;
|
||||||
|
|
||||||
#ifdef EPIC_48K
|
|
||||||
int lbr_48k;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VORBIS_PSYCHO
|
#ifdef VORBIS_PSYCHO
|
||||||
VorbisPsy *psy;
|
VorbisPsy *psy;
|
||||||
float *psy_window;
|
float *psy_window;
|
||||||
@@ -77,7 +73,6 @@ typedef struct EncState {
|
|||||||
|
|
||||||
spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
|
spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */
|
||||||
spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */
|
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*/
|
spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/
|
||||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
||||||
spx_word16_t *winBuf; /**< Input buffer (original signal) */
|
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 *swBuf; /**< Weighted signal buffer */
|
||||||
spx_word16_t *sw; /**< Start of weighted signal frame */
|
spx_word16_t *sw; /**< Start of weighted signal frame */
|
||||||
const spx_word16_t *window; /**< Temporary (Hanning) window */
|
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_lsp; /**< LSPs for previous frame */
|
||||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
|
spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */
|
||||||
spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */
|
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_exc2; /**< Filter memory for excitation (whole frame) */
|
||||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
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_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 */
|
VBRState *vbr; /**< State of the VBR data */
|
||||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||||
float relative_quality; /**< Relative quality that will be needed by VBR */
|
float relative_quality; /**< Relative quality that will be needed by VBR */
|
||||||
@@ -110,6 +106,8 @@ typedef struct EncState {
|
|||||||
float abr_drift;
|
float abr_drift;
|
||||||
float abr_drift2;
|
float abr_drift2;
|
||||||
float abr_count;
|
float abr_count;
|
||||||
|
#endif /* #ifndef DISABLE_VBR */
|
||||||
|
|
||||||
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
|
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
|
||||||
spx_int32_t sampling_rate;
|
spx_int32_t sampling_rate;
|
||||||
int plc_tuning;
|
int plc_tuning;
|
||||||
@@ -134,10 +132,6 @@ typedef struct DecState {
|
|||||||
int max_pitch; /**< Maximum pitch value allowed */
|
int max_pitch; /**< Maximum pitch value allowed */
|
||||||
spx_int32_t sampling_rate;
|
spx_int32_t sampling_rate;
|
||||||
|
|
||||||
#ifdef EPIC_48K
|
|
||||||
int lbr_48k;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
|
spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */
|
||||||
|
|
||||||
char *stack; /**< Pseudo-stack allocation for temporary memory */
|
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_sp; /**< Filter memory for synthesis signal */
|
||||||
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
|
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_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 */
|
/* This is used in packet loss concealment */
|
||||||
int last_pitch; /**< Pitch of last correctly decoded frame */
|
int last_pitch; /**< Pitch of last correctly decoded frame */
|
||||||
@@ -168,7 +166,7 @@ typedef struct DecState {
|
|||||||
/*Vocoder data*/
|
/*Vocoder data*/
|
||||||
spx_word16_t voc_m1;
|
spx_word16_t voc_m1;
|
||||||
spx_word32_t voc_m2;
|
spx_word32_t voc_m2;
|
||||||
float voc_mean;
|
spx_word16_t voc_mean;
|
||||||
int voc_offset;
|
int voc_offset;
|
||||||
|
|
||||||
int dtx_enabled;
|
int dtx_enabled;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
+819
-626
File diff suppressed because it is too large.
Load diff
@@ -2,6 +2,15 @@
|
|||||||
/**
|
/**
|
||||||
@file pseudofloat.h
|
@file pseudofloat.h
|
||||||
@brief Pseudo-floating point
|
@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
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -35,7 +44,8 @@
|
|||||||
#ifndef PSEUDOFLOAT_H
|
#ifndef PSEUDOFLOAT_H
|
||||||
#define PSEUDOFLOAT_H
|
#define PSEUDOFLOAT_H
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
#include "os_support.h"
|
||||||
#include "math_approx.h"
|
#include "math_approx.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -65,18 +75,8 @@ static inline spx_float_t PSEUDOFLOAT(spx_int32_t x)
|
|||||||
spx_float_t r = {0,0};
|
spx_float_t r = {0,0};
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
while (x>32767)
|
e = spx_ilog2(ABS32(x))-14;
|
||||||
{
|
x = VSHR32(x, e);
|
||||||
x >>= 1;
|
|
||||||
/*x *= .5;*/
|
|
||||||
e++;
|
|
||||||
}
|
|
||||||
while (x<16383)
|
|
||||||
{
|
|
||||||
x <<= 1;
|
|
||||||
/*x *= 2;*/
|
|
||||||
e--;
|
|
||||||
}
|
|
||||||
if (sign)
|
if (sign)
|
||||||
{
|
{
|
||||||
spx_float_t r;
|
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;
|
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)
|
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)
|
static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b)
|
||||||
{
|
{
|
||||||
if (a.e<-15)
|
return VSHR32(MULT16_32_Q15(a.m, b),-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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b)
|
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;
|
spx_float_t r;
|
||||||
/* FIXME: Handle the sign */
|
if (a==0 || b==0)
|
||||||
if (a==0)
|
|
||||||
{
|
{
|
||||||
return FLOAT_ZERO;
|
return FLOAT_ZERO;
|
||||||
}
|
}
|
||||||
while (a>32767)
|
e1 = spx_ilog2(ABS32(a));
|
||||||
{
|
a = VSHR32(a, e1-14);
|
||||||
a >>= 1;
|
e2 = spx_ilog2(ABS32(b));
|
||||||
e++;
|
b = VSHR32(b, e2-14);
|
||||||
}
|
|
||||||
while (a<16384)
|
|
||||||
{
|
|
||||||
a <<= 1;
|
|
||||||
e--;
|
|
||||||
}
|
|
||||||
while (b>32767)
|
|
||||||
{
|
|
||||||
b >>= 1;
|
|
||||||
e++;
|
|
||||||
}
|
|
||||||
while (b<16384)
|
|
||||||
{
|
|
||||||
b <<= 1;
|
|
||||||
e--;
|
|
||||||
}
|
|
||||||
r.m = MULT16_16_Q15(a,b);
|
r.m = MULT16_16_Q15(a,b);
|
||||||
r.e = e+15;
|
r.e = e1+e2-13;
|
||||||
return r;
|
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)
|
static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b)
|
||||||
{
|
{
|
||||||
int e=0;
|
int e=0;
|
||||||
spx_float_t r;
|
spx_float_t r;
|
||||||
/* FIXME: Handle the sign */
|
|
||||||
if (a==0)
|
if (a==0)
|
||||||
{
|
{
|
||||||
return FLOAT_ZERO;
|
return FLOAT_ZERO;
|
||||||
}
|
}
|
||||||
while (a<SHL32(EXTEND32(b.m),14))
|
e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15;
|
||||||
{
|
a = VSHR32(a, e);
|
||||||
a <<= 1;
|
if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15))
|
||||||
e--;
|
|
||||||
}
|
|
||||||
while (a>=SHL32(EXTEND32(b.m-1),15))
|
|
||||||
{
|
{
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
e++;
|
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)
|
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;
|
spx_float_t r;
|
||||||
/* FIXME: Handle the sign */
|
|
||||||
if (a==0)
|
if (a==0)
|
||||||
{
|
{
|
||||||
return FLOAT_ZERO;
|
return FLOAT_ZERO;
|
||||||
}
|
}
|
||||||
while (b>32767)
|
if (b>32767)
|
||||||
{
|
{
|
||||||
b >>= 1;
|
e0 = spx_ilog2(b)-14;
|
||||||
e--;
|
b = VSHR32(b, e0);
|
||||||
|
e0 = -e0;
|
||||||
}
|
}
|
||||||
while (a<SHL32(b,14))
|
e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15;
|
||||||
{
|
a = VSHR32(a, e);
|
||||||
a <<= 1;
|
if (ABS32(a)>=SHL32(EXTEND32(b-1),15))
|
||||||
e--;
|
|
||||||
}
|
|
||||||
while (a>=SHL32(b-1,15))
|
|
||||||
{
|
{
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
|
e += e0;
|
||||||
r.m = DIV32_16(a,b);
|
r.m = DIV32_16(a,b);
|
||||||
r.e = e;
|
r.e = e;
|
||||||
return r;
|
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)
|
static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b)
|
||||||
{
|
{
|
||||||
int e=0;
|
int e=0;
|
||||||
spx_int32_t num;
|
spx_int32_t num;
|
||||||
spx_float_t r;
|
spx_float_t r;
|
||||||
|
if (b.m<=0)
|
||||||
|
{
|
||||||
|
speex_warning_int("Attempted to divide by", b.m);
|
||||||
|
return FLOAT_ONE;
|
||||||
|
}
|
||||||
num = a.m;
|
num = a.m;
|
||||||
|
a.m = ABS16(a.m);
|
||||||
while (a.m >= b.m)
|
while (a.m >= b.m)
|
||||||
{
|
{
|
||||||
e++;
|
e++;
|
||||||
@@ -347,7 +338,7 @@ static inline spx_float_t FLOAT_SQRT(spx_float_t a)
|
|||||||
{
|
{
|
||||||
spx_float_t r;
|
spx_float_t r;
|
||||||
spx_int32_t m;
|
spx_int32_t m;
|
||||||
m = a.m << 14;
|
m = SHL32(EXTEND32(a.m), 14);
|
||||||
r.e = a.e - 14;
|
r.e = a.e - 14;
|
||||||
if (r.e & 1)
|
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 FLOAT_HALF 0.5f
|
||||||
#define PSEUDOFLOAT(x) (x)
|
#define PSEUDOFLOAT(x) (x)
|
||||||
#define FLOAT_MULT(a,b) ((a)*(b))
|
#define FLOAT_MULT(a,b) ((a)*(b))
|
||||||
|
#define FLOAT_AMULT(a,b) ((a)*(b))
|
||||||
#define FLOAT_MUL32(a,b) ((a)*(b))
|
#define FLOAT_MUL32(a,b) ((a)*(b))
|
||||||
#define FLOAT_DIV32(a,b) ((a)/(b))
|
#define FLOAT_DIV32(a,b) ((a)/(b))
|
||||||
#define FLOAT_EXTRACT16(a) (a)
|
#define FLOAT_EXTRACT16(a) (a)
|
||||||
|
|||||||
@@ -35,12 +35,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "quant_lsp.h"
|
#include "quant_lsp.h"
|
||||||
|
#include "os_support.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#ifdef BFIN_ASM
|
#ifdef BFIN_ASM
|
||||||
#include "quant_lsp_bfin.h"
|
#include "quant_lsp_bfin.h"
|
||||||
@@ -304,11 +305,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
|||||||
#ifdef DISABLE_WIDEBAND
|
#ifdef DISABLE_WIDEBAND
|
||||||
void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
|
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)
|
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
|
#else
|
||||||
extern const signed char high_lsp_cdbk[];
|
extern const signed char high_lsp_cdbk[];
|
||||||
@@ -382,66 +383,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
|
|||||||
|
|
||||||
#endif
|
#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
|
#define QUANT_LSP_H
|
||||||
|
|
||||||
#include <speex/speex_bits.h>
|
#include <speex/speex_bits.h>
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#define MAX_LSP_SIZE 20
|
#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 */
|
/* Decodes high-band LSPs */
|
||||||
void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
|
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
|
#endif
|
||||||
@@ -68,19 +68,19 @@ static int lsp_quant(
|
|||||||
" B0 = %2;\n\t"
|
" B0 = %2;\n\t"
|
||||||
|
|
||||||
" R2.L = W [I0++];\n\t"
|
" R2.L = W [I0++];\n\t"
|
||||||
" LSETUP (lq1, lq2) LC0 = %4;\n\t"
|
" LSETUP (1f, 2f) LC0 = %4;\n\t"
|
||||||
"lq1: R3 = 0;\n\t" /* R3: dist */
|
"1: R3 = 0;\n\t" /* R3: dist */
|
||||||
" LSETUP (lq3, lq4) LC1 = %5;\n\t"
|
" LSETUP (3f, 4f) LC1 = %5;\n\t"
|
||||||
"lq3: R1 = B [P2++] (X);\n\t"
|
"3: R1 = B [P2++] (X);\n\t"
|
||||||
" R1 <<= 5;\n\t"
|
" R1 <<= 5;\n\t"
|
||||||
" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
|
" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
|
||||||
" R0 = R0.L*R0.L;\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"
|
" cc =R3<%0;\n\t"
|
||||||
" if cc %0=R3;\n\t"
|
" if cc %0=R3;\n\t"
|
||||||
" if cc %1=R5;\n\t"
|
" if cc %1=R5;\n\t"
|
||||||
"lq2: R5 += 1;\n\t"
|
"2: R5 += 1;\n\t"
|
||||||
" L0 = 0;\n\t"
|
" L0 = 0;\n\t"
|
||||||
: "=&d" (best_dist), "=&d" (best_id)
|
: "=&d" (best_dist), "=&d" (best_id)
|
||||||
: "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
|
: "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
|
||||||
@@ -132,10 +132,10 @@ static int lsp_weight_quant(
|
|||||||
" B0 = %2;\n\t"
|
" B0 = %2;\n\t"
|
||||||
" B1 = %3;\n\t"
|
" B1 = %3;\n\t"
|
||||||
|
|
||||||
" LSETUP (lwq1, lwq2) LC0 = %5;\n\t"
|
" LSETUP (1f, 2f) LC0 = %5;\n\t"
|
||||||
"lwq1: R3 = 0 (X);\n\t" /* R3: dist */
|
"1: R3 = 0 (X);\n\t" /* R3: dist */
|
||||||
" LSETUP (lwq3, lwq4) LC1 = %6;\n\t"
|
" LSETUP (3f, 4f) LC1 = %6;\n\t"
|
||||||
"lwq3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
|
"3: R0.L = W [I0++] || R2.L = W [I1++];\n\t"
|
||||||
" R1 = B [P2++] (X);\n\t"
|
" R1 = B [P2++] (X);\n\t"
|
||||||
" R1 <<= 5;\n\t"
|
" R1 <<= 5;\n\t"
|
||||||
" R0.L = R0.L - R1.L;\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 = R2.L*R0.L (M,IS);\n\t"
|
||||||
" A1 = A1 >>> 16;\n\t"
|
" A1 = A1 >>> 16;\n\t"
|
||||||
" R1 = (A1 += R2.L*R0.H) (IS);\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"
|
" cc =R3<%0;\n\t"
|
||||||
" if cc %0=R3;\n\t"
|
" if cc %0=R3;\n\t"
|
||||||
" if cc %1=R5;\n\t"
|
" if cc %1=R5;\n\t"
|
||||||
"lwq2: R5 += 1;\n\t"
|
"2: R5 += 1;\n\t"
|
||||||
" L0 = 0;\n\t"
|
" L0 = 0;\n\t"
|
||||||
" L1 = 0;\n\t"
|
" L1 = 0;\n\t"
|
||||||
: "=&d" (best_dist), "=&d" (best_id)
|
: "=&d" (best_dist), "=&d" (best_id)
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||||
+328
-490
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 nbSubframes; /**< Number of high-band sub-frames*/
|
||||||
int windowSize; /**< Length of high-band LPC window*/
|
int windowSize; /**< Length of high-band LPC window*/
|
||||||
int lpcSize; /**< Order of high-band LPC analysis */
|
int lpcSize; /**< Order of high-band LPC analysis */
|
||||||
int bufSize; /**< Buffer size */
|
|
||||||
int first; /**< First frame? */
|
int first; /**< First frame? */
|
||||||
float lag_factor; /**< Lag-windowing control parameter */
|
|
||||||
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
|
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
|
||||||
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
|
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
|
||||||
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
|
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
|
||||||
|
|
||||||
char *stack; /**< Temporary allocation stack */
|
char *stack; /**< Temporary allocation stack */
|
||||||
spx_sig_t *x0d, *x1d; /**< QMF filter signals*/
|
spx_word16_t *high; /**< High-band signal (buffer) */
|
||||||
spx_sig_t *high; /**< High-band signal (buffer) */
|
|
||||||
spx_sig_t *y0, *y1; /**< QMF synthesis signals */
|
|
||||||
spx_word16_t *h0_mem, *h1_mem;
|
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 */
|
const spx_word16_t *window; /**< LPC analysis window */
|
||||||
spx_word16_t *lagWindow; /**< Auto-correlation window */
|
const 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 */
|
|
||||||
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
|
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
|
||||||
spx_lsp_t *old_qlsp; /**< Quantized 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 *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_sp; /**< Synthesis signal memory */
|
||||||
spx_mem_t *mem_sp2;
|
spx_mem_t *mem_sp2;
|
||||||
spx_mem_t *mem_sw; /**< Perceptual signal memory */
|
spx_mem_t *mem_sw; /**< Perceptual signal memory */
|
||||||
spx_word32_t *pi_gain;
|
spx_word32_t *pi_gain;
|
||||||
spx_sig_t *innov_save; /**< If non-NULL, innovation is copied here */
|
spx_word16_t *exc_rms;
|
||||||
spx_sig_t *low_innov; /**< Lower-band innovation is copied here magically */
|
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
|
||||||
|
|
||||||
|
#ifndef DISABLE_VBR
|
||||||
float vbr_quality; /**< Quality setting for VBR encoding */
|
float vbr_quality; /**< Quality setting for VBR encoding */
|
||||||
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
|
||||||
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
|
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
|
||||||
@@ -100,6 +83,7 @@ typedef struct SBEncState {
|
|||||||
float abr_count;
|
float abr_count;
|
||||||
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
|
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
|
||||||
float relative_quality;
|
float relative_quality;
|
||||||
|
#endif /* #ifndef DISABLE_VBR */
|
||||||
|
|
||||||
int encode_submode;
|
int encode_submode;
|
||||||
const SpeexSubmode * const *submodes;
|
const SpeexSubmode * const *submodes;
|
||||||
@@ -125,23 +109,18 @@ typedef struct SBDecState {
|
|||||||
int lpc_enh_enabled;
|
int lpc_enh_enabled;
|
||||||
|
|
||||||
char *stack;
|
char *stack;
|
||||||
spx_sig_t *x0d, *x1d;
|
spx_word16_t *g0_mem, *g1_mem;
|
||||||
spx_sig_t *high;
|
|
||||||
spx_sig_t *y0, *y1;
|
|
||||||
spx_word32_t *g0_mem, *g1_mem;
|
|
||||||
|
|
||||||
spx_sig_t *exc;
|
spx_word16_t *excBuf;
|
||||||
spx_sig_t *excBuf;
|
|
||||||
spx_lsp_t *qlsp;
|
|
||||||
spx_lsp_t *old_qlsp;
|
spx_lsp_t *old_qlsp;
|
||||||
spx_lsp_t *interp_qlsp;
|
|
||||||
spx_coef_t *interp_qlpc;
|
spx_coef_t *interp_qlpc;
|
||||||
|
|
||||||
spx_mem_t *mem_sp;
|
spx_mem_t *mem_sp;
|
||||||
spx_word32_t *pi_gain;
|
spx_word32_t *pi_gain;
|
||||||
spx_sig_t *innov_save; /** If non-NULL, innovation is copied here */
|
spx_word16_t *exc_rms;
|
||||||
spx_sig_t *low_innov; /** Lower-band innovation is copied here magically */
|
spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */
|
||||||
|
|
||||||
|
spx_word16_t last_ener;
|
||||||
spx_int32_t seed;
|
spx_int32_t seed;
|
||||||
|
|
||||||
int encode_submode;
|
int encode_submode;
|
||||||
|
|||||||
@@ -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 <math.h>
|
||||||
#include "smallft.h"
|
#include "smallft.h"
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
#include "os_support.h"
|
||||||
|
|
||||||
static void drfti1(int n, float *wa, int *ifac){
|
static void drfti1(int n, float *wa, int *ifac){
|
||||||
static int ntryh[4] = { 4,2,3,5 };
|
static int ntryh[4] = { 4,2,3,5 };
|
||||||
|
|||||||
+20
-38
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include "modes.h"
|
#include "modes.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "os_support.h"
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#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);
|
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);
|
return mode->dec_init(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void speex_encoder_destroy(void *state)
|
EXPORT void speex_encoder_destroy(void *state)
|
||||||
{
|
{
|
||||||
(*((SpeexMode**)state))->enc_destroy(state);
|
(*((SpeexMode**)state))->enc_destroy(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void speex_decoder_destroy(void *state)
|
EXPORT void speex_decoder_destroy(void *state)
|
||||||
{
|
{
|
||||||
(*((SpeexMode**)state))->dec_destroy(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
|
#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;
|
int i;
|
||||||
spx_int32_t N;
|
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);
|
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;
|
SpeexMode *mode;
|
||||||
mode = *(SpeexMode**)state;
|
mode = *(SpeexMode**)state;
|
||||||
return (mode)->enc(state, in, bits);
|
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;
|
int i, ret;
|
||||||
spx_int32_t N;
|
spx_int32_t N;
|
||||||
@@ -119,8 +123,9 @@ int speex_decode(void *state, SpeexBits *bits, float *out)
|
|||||||
out[i] = short_out[i];
|
out[i] = short_out[i];
|
||||||
return ret;
|
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;
|
SpeexMode *mode = *(SpeexMode**)state;
|
||||||
return (mode)->dec(state, bits, out);
|
return (mode)->dec(state, bits, out);
|
||||||
@@ -128,12 +133,12 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
|
|||||||
|
|
||||||
#else
|
#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);
|
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;
|
int i;
|
||||||
spx_int32_t N;
|
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);
|
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);
|
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;
|
int i;
|
||||||
spx_int32_t N;
|
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);
|
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);
|
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;
|
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)
|
switch (request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,9 +37,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <speex/speex_callbacks.h>
|
#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;
|
int id;
|
||||||
SpeexCallback *callback;
|
SpeexCallback *callback;
|
||||||
@@ -71,7 +72,7 @@ int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *st
|
|||||||
return 0;
|
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;
|
spx_int32_t m;
|
||||||
m = speex_bits_unpack_unsigned(bits, 4);
|
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;
|
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;
|
spx_int32_t m;
|
||||||
m = speex_bits_unpack_unsigned(bits, 4);
|
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;
|
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;
|
spx_int32_t m;
|
||||||
m = speex_bits_unpack_unsigned(bits, 4);
|
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;
|
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;
|
spx_int32_t vbr;
|
||||||
vbr = speex_bits_unpack_unsigned(bits, 1);
|
vbr = speex_bits_unpack_unsigned(bits, 1);
|
||||||
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
|
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
|
||||||
return 0;
|
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;
|
spx_int32_t enh;
|
||||||
enh = speex_bits_unpack_unsigned(bits, 1);
|
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;
|
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;
|
float qual;
|
||||||
qual = speex_bits_unpack_unsigned(bits, 4);
|
qual = speex_bits_unpack_unsigned(bits, 4);
|
||||||
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
|
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* #ifndef DISABLE_VBR */
|
||||||
|
|
||||||
|
EXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
||||||
int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
|
|
||||||
{
|
{
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
ch = speex_bits_unpack_unsigned(bits, 8);
|
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 */
|
/* 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);
|
int req_size = speex_bits_unpack_unsigned(bits, 4);
|
||||||
speex_bits_advance(bits, 5+8*req_size);
|
speex_bits_advance(bits, 5+8*req_size);
|
||||||
|
|||||||
@@ -35,14 +35,31 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
#include <speex/speex_header.h>
|
#include <speex/speex_header.h>
|
||||||
#include <speex/speex.h>
|
#include <speex/speex.h>
|
||||||
|
#include "os_support.h"
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#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);}
|
#define ENDIAN_SWITCH(x) {x=le_int(x);}
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +83,7 @@ typedef struct SpeexHeader {
|
|||||||
} 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;
|
int i;
|
||||||
const char *h="Speex ";
|
const char *h="Speex ";
|
||||||
@@ -101,12 +118,12 @@ void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const Spe
|
|||||||
header->reserved2 = 0;
|
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;
|
SpeexHeader *le_header;
|
||||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
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*/
|
/*Make sure everything is now little-endian*/
|
||||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
ENDIAN_SWITCH(le_header->speex_version_id);
|
||||||
@@ -125,7 +142,7 @@ char *speex_header_to_packet(SpeexHeader *header, int *size)
|
|||||||
return (char *)le_header;
|
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;
|
int i;
|
||||||
SpeexHeader *le_header;
|
SpeexHeader *le_header;
|
||||||
@@ -133,20 +150,20 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
|
|||||||
for (i=0;i<8;i++)
|
for (i=0;i<8;i++)
|
||||||
if (packet[i]!=h[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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*FIXME: Do we allow larger headers?*/
|
/*FIXME: Do we allow larger headers?*/
|
||||||
if (size < (int)sizeof(SpeexHeader))
|
if (size < (int)sizeof(SpeexHeader))
|
||||||
{
|
{
|
||||||
speex_warning("Speex header too small");
|
speex_notify("Speex header too small");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
|
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*/
|
/*Make sure everything is converted correctly from little-endian*/
|
||||||
ENDIAN_SWITCH(le_header->speex_version_id);
|
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->frames_per_packet);
|
||||||
ENDIAN_SWITCH(le_header->extra_headers);
|
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;
|
return le_header;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void speex_header_free(void *ptr)
|
||||||
|
{
|
||||||
|
speex_free(ptr);
|
||||||
|
}
|
||||||
@@ -36,11 +36,15 @@
|
|||||||
#define STACK_ALLOC_H
|
#define STACK_ALLOC_H
|
||||||
|
|
||||||
#ifdef USE_ALLOCA
|
#ifdef USE_ALLOCA
|
||||||
#ifdef WIN32
|
# ifdef WIN32
|
||||||
#include <malloc.h>
|
# include <malloc.h>
|
||||||
#else
|
# else
|
||||||
#include <alloca.h>
|
# ifdef HAVE_ALLOCA_H
|
||||||
#endif
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# include <stdlib.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,15 +66,6 @@
|
|||||||
* @param type Type of element
|
* @param type Type of element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @def PUSHS(stack, type)
|
|
||||||
*
|
|
||||||
* Allocates a struct stack
|
|
||||||
*
|
|
||||||
* @param stack Stack
|
|
||||||
* @param type Struct type
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def VARDECL(var)
|
* @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 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
|
#else
|
||||||
|
|
||||||
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
|
#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 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
|
#endif
|
||||||
|
|
||||||
#if defined(VAR_ARRAYS)
|
#if defined(VAR_ARRAYS)
|
||||||
|
|||||||
+172
-68
@@ -35,13 +35,77 @@
|
|||||||
|
|
||||||
#include <speex/speex_stereo.h>
|
#include <speex/speex_stereo.h>
|
||||||
#include <speex/speex_callbacks.h>
|
#include <speex/speex_callbacks.h>
|
||||||
|
#include "math_approx.h"
|
||||||
#include "vq.h"
|
#include "vq.h"
|
||||||
#include <math.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};*/
|
/*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[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;
|
int i, tmp;
|
||||||
float e_left=0, e_right=0, e_tot=0;
|
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);
|
speex_bits_pack(bits, (int)balance, 5);
|
||||||
|
|
||||||
/*Quantize energy ratio*/
|
/* FIXME: this is a hack */
|
||||||
tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
|
tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
|
||||||
speex_bits_pack(bits, tmp, 2);
|
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;
|
int i, tmp;
|
||||||
float e_left=0, e_right=0, e_tot=0;
|
spx_word32_t e_left=0, e_right=0, e_tot=0;
|
||||||
float balance, e_ratio;
|
spx_word32_t balance, e_ratio;
|
||||||
for (i=0;i<frame_size;i++)
|
spx_word32_t largest, smallest;
|
||||||
{
|
int balance_id;
|
||||||
e_left += ((float)data[2*i])*data[2*i];
|
#ifdef FIXED_POINT
|
||||||
e_right += ((float)data[2*i+1])*data[2*i+1];
|
int shift;
|
||||||
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
|
#endif
|
||||||
e_tot += ((float)data[i])*data[i];
|
|
||||||
}
|
|
||||||
balance=(e_left+1)/(e_right+1);
|
|
||||||
e_ratio = e_tot/(1+e_left+e_right);
|
|
||||||
|
|
||||||
/*Quantization*/
|
/* In band marker */
|
||||||
speex_bits_pack(bits, 14, 5);
|
speex_bits_pack(bits, 14, 5);
|
||||||
|
/* Stereo marker */
|
||||||
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
|
||||||
|
|
||||||
balance=4*log(balance);
|
for (i=0;i<frame_size;i++)
|
||||||
|
{
|
||||||
/*Pack sign*/
|
e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
|
||||||
if (balance>0)
|
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]);
|
||||||
|
#endif
|
||||||
|
e_tot += SHR32(MULT16_16(data[i],data[i]),8);
|
||||||
|
}
|
||||||
|
if (e_left > e_right)
|
||||||
|
{
|
||||||
speex_bits_pack(bits, 0, 1);
|
speex_bits_pack(bits, 0, 1);
|
||||||
else
|
largest = e_left;
|
||||||
|
smallest = e_right;
|
||||||
|
} else {
|
||||||
speex_bits_pack(bits, 1, 1);
|
speex_bits_pack(bits, 1, 1);
|
||||||
balance=floor(.5+fabs(balance));
|
largest = e_right;
|
||||||
if (balance>30)
|
smallest = e_left;
|
||||||
balance=31;
|
}
|
||||||
|
|
||||||
speex_bits_pack(bits, (int)balance, 5);
|
/* 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
|
||||||
|
|
||||||
/*Quantize energy ratio*/
|
speex_bits_pack(bits, balance_id, 5);
|
||||||
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);
|
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;
|
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;
|
balance=stereo->balance;
|
||||||
e_ratio=stereo->e_ratio;
|
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));
|
/* These two are Q14, with max value just below 2. */
|
||||||
e_right = sqrt(e_right/(e_tot+.01));
|
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--)
|
for (i=frame_size-1;i>=0;i--)
|
||||||
{
|
{
|
||||||
float ftmp=data[i];
|
spx_word16_t tmp=data[i];
|
||||||
stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
|
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 = .98*stereo->smooth_right + .02*e_right;
|
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] = stereo->smooth_left*ftmp;
|
data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||||
data[2*i+1] = stereo->smooth_right*ftmp;
|
data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* #ifndef DISABLE_FLOAT_API */
|
||||||
|
|
||||||
void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo)
|
EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
|
||||||
{
|
{
|
||||||
float balance, e_ratio;
|
|
||||||
int i;
|
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;
|
balance=stereo->balance;
|
||||||
e_ratio=stereo->e_ratio;
|
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));
|
/* These two are Q14, with max value just below 2. */
|
||||||
e_right = sqrt(e_right/(e_tot+.01));
|
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--)
|
for (i=frame_size-1;i>=0;i--)
|
||||||
{
|
{
|
||||||
float ftmp=data[i];
|
spx_int16_t tmp=data[i];
|
||||||
stereo->smooth_left = .98*stereo->smooth_left + .02*e_left;
|
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 = .98*stereo->smooth_right + .02*e_right;
|
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] = stereo->smooth_left*ftmp;
|
data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
|
||||||
data[2*i+1] = stereo->smooth_right*ftmp;
|
data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
|
||||||
{
|
{
|
||||||
SpeexStereoState *stereo;
|
RealSpeexStereoState *stereo;
|
||||||
float sign=1;
|
spx_word16_t sign=1, dexp;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
stereo = (SpeexStereoState*)data;
|
stereo = (RealSpeexStereoState*)data;
|
||||||
|
|
||||||
|
COMPATIBILITY_HACK(stereo);
|
||||||
|
|
||||||
if (speex_bits_unpack_unsigned(bits, 1))
|
if (speex_bits_unpack_unsigned(bits, 1))
|
||||||
sign=-1;
|
sign=-1;
|
||||||
tmp = speex_bits_unpack_unsigned(bits, 5);
|
dexp = speex_bits_unpack_unsigned(bits, 5);
|
||||||
stereo->balance = exp(sign*.25*tmp);
|
#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);
|
tmp = speex_bits_unpack_unsigned(bits, 2);
|
||||||
stereo->e_ratio = e_ratio_quant[tmp];
|
stereo->e_ratio = e_ratio_quant[tmp];
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ int main()
|
|||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||||
i=0;
|
i=0;
|
||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||||
f=8000;
|
i=8000;
|
||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
|
||||||
i=0;
|
i=0;
|
||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
|
||||||
f=.4;
|
f=.0;
|
||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
|
||||||
f=.3;
|
f=.0;
|
||||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
|
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -34,7 +34,7 @@ int main()
|
|||||||
fread(in, sizeof(short), NN, stdin);
|
fread(in, sizeof(short), NN, stdin);
|
||||||
if (feof(stdin))
|
if (feof(stdin))
|
||||||
break;
|
break;
|
||||||
vad = speex_preprocess(st, in, NULL);
|
vad = speex_preprocess_run(st, in);
|
||||||
/*fprintf (stderr, "%d\n", vad);*/
|
/*fprintf (stderr, "%d\n", vad);*/
|
||||||
fwrite(in, sizeof(short), NN, stdout);
|
fwrite(in, sizeof(short), NN, stdout);
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include "speex/speex_echo.h"
|
#include "speex/speex_echo.h"
|
||||||
#include "speex/speex_preprocess.h"
|
#include "speex/speex_preprocess.h"
|
||||||
|
|
||||||
@@ -17,37 +16,38 @@
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int echo_fd, ref_fd, e_fd;
|
FILE *echo_fd, *ref_fd, *e_fd;
|
||||||
spx_int32_t noise[NN+1];
|
|
||||||
short echo_buf[NN], ref_buf[NN], e_buf[NN];
|
short echo_buf[NN], ref_buf[NN], e_buf[NN];
|
||||||
SpeexEchoState *st;
|
SpeexEchoState *st;
|
||||||
SpeexPreprocessState *den;
|
SpeexPreprocessState *den;
|
||||||
|
int sampleRate = 8000;
|
||||||
|
|
||||||
if (argc != 4)
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
echo_fd = open (argv[2], O_RDONLY);
|
echo_fd = fopen(argv[2], "rb");
|
||||||
ref_fd = open (argv[1], O_RDONLY);
|
ref_fd = fopen(argv[1], "rb");
|
||||||
e_fd = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
e_fd = fopen(argv[3], "wb");
|
||||||
|
|
||||||
st = speex_echo_state_init(NN, TAIL);
|
st = speex_echo_state_init(NN, TAIL);
|
||||||
den = speex_preprocess_state_init(NN, 8000);
|
den = speex_preprocess_state_init(NN, sampleRate);
|
||||||
int tmp = 8000;
|
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
|
||||||
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);
|
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);
|
fread(ref_buf, sizeof(short), NN, ref_fd);
|
||||||
speex_echo_cancel(st, ref_buf, echo_buf, e_buf, noise);
|
fread(echo_buf, sizeof(short), NN, echo_fd);
|
||||||
/*speex_preprocess(den, e_buf, noise);*/
|
speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
|
||||||
write(e_fd, e_buf, NN*2);
|
speex_preprocess_run(den, e_buf);
|
||||||
|
fwrite(e_buf, sizeof(short), NN, e_fd);
|
||||||
}
|
}
|
||||||
speex_echo_state_destroy(st);
|
speex_echo_state_destroy(st);
|
||||||
speex_preprocess_state_destroy(den);
|
speex_preprocess_state_destroy(den);
|
||||||
close(e_fd);
|
fclose(e_fd);
|
||||||
close(echo_fd);
|
fclose(echo_fd);
|
||||||
close(ref_fd);
|
fclose(ref_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,6 @@ int main(int argc, char **argv)
|
|||||||
FILE *fin, *fout, *fbits=NULL;
|
FILE *fin, *fout, *fbits=NULL;
|
||||||
short in_short[FRAME_SIZE];
|
short in_short[FRAME_SIZE];
|
||||||
short out_short[FRAME_SIZE];
|
short out_short[FRAME_SIZE];
|
||||||
float sigpow,errpow,snr, seg_snr=0;
|
|
||||||
int snr_frames = 0;
|
int snr_frames = 0;
|
||||||
char cbits[200];
|
char cbits[200];
|
||||||
int nbBits;
|
int nbBits;
|
||||||
@@ -32,11 +31,8 @@ int main(int argc, char **argv)
|
|||||||
spx_int32_t skip_group_delay;
|
spx_int32_t skip_group_delay;
|
||||||
SpeexCallback callback;
|
SpeexCallback callback;
|
||||||
|
|
||||||
sigpow = 0;
|
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||||
errpow = 0;
|
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
|
||||||
|
|
||||||
st = speex_encoder_init(&speex_nb_mode);
|
|
||||||
dec = speex_decoder_init(&speex_nb_mode);
|
|
||||||
|
|
||||||
/* BEGIN: You probably don't need the following in a real application */
|
/* BEGIN: You probably don't need the following in a real application */
|
||||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||||
@@ -74,13 +70,13 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
inFile = argv[1];
|
inFile = argv[1];
|
||||||
fin = fopen(inFile, "r");
|
fin = fopen(inFile, "rb");
|
||||||
outFile = argv[2];
|
outFile = argv[2];
|
||||||
fout = fopen(outFile, "w+");
|
fout = fopen(outFile, "wb+");
|
||||||
if (argc==4)
|
if (argc==4)
|
||||||
{
|
{
|
||||||
bitsFile = argv[3];
|
bitsFile = argv[3];
|
||||||
fbits = fopen(bitsFile, "w");
|
fbits = fopen(bitsFile, "wb");
|
||||||
}
|
}
|
||||||
speex_bits_init(&bits);
|
speex_bits_init(&bits);
|
||||||
while (!feof(fin))
|
while (!feof(fin))
|
||||||
@@ -109,6 +105,12 @@ int main(int argc, char **argv)
|
|||||||
speex_decoder_destroy(dec);
|
speex_decoder_destroy(dec);
|
||||||
speex_bits_destroy(&bits);
|
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 */
|
/* This code just computes SNR, so you don't need it either */
|
||||||
rewind(fin);
|
rewind(fin);
|
||||||
rewind(fout);
|
rewind(fout);
|
||||||
@@ -127,9 +129,6 @@ int main(int argc, char **argv)
|
|||||||
errpow += e;
|
errpow += e;
|
||||||
snr_frames++;
|
snr_frames++;
|
||||||
}
|
}
|
||||||
fclose(fin);
|
|
||||||
fclose(fout);
|
|
||||||
|
|
||||||
snr = 10 * log10( sigpow / errpow );
|
snr = 10 * log10( sigpow / errpow );
|
||||||
seg_snr /= snr_frames;
|
seg_snr /= snr_frames;
|
||||||
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
|
||||||
@@ -137,6 +136,11 @@ int main(int argc, char **argv)
|
|||||||
#ifdef FIXED_DEBUG
|
#ifdef FIXED_DEBUG
|
||||||
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fclose(fin);
|
||||||
|
fclose(fout);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,8 @@ int main(int argc, char **argv)
|
|||||||
sigpow = 0;
|
sigpow = 0;
|
||||||
errpow = 0;
|
errpow = 0;
|
||||||
|
|
||||||
st = speex_encoder_init(&speex_uwb_mode);
|
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||||
dec = speex_decoder_init(&speex_uwb_mode);
|
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||||
|
|
||||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||||
callback.func = speex_std_char_handler;
|
callback.func = speex_std_char_handler;
|
||||||
@@ -69,13 +69,13 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
inFile = argv[1];
|
inFile = argv[1];
|
||||||
fin = fopen(inFile, "r");
|
fin = fopen(inFile, "rb");
|
||||||
outFile = argv[2];
|
outFile = argv[2];
|
||||||
fout = fopen(outFile, "w+");
|
fout = fopen(outFile, "wb+");
|
||||||
if (argc==4)
|
if (argc==4)
|
||||||
{
|
{
|
||||||
bitsFile = argv[3];
|
bitsFile = argv[3];
|
||||||
fbits = fopen(bitsFile, "w");
|
fbits = fopen(bitsFile, "wb");
|
||||||
}
|
}
|
||||||
speex_bits_init(&bits);
|
speex_bits_init(&bits);
|
||||||
while (!feof(fin))
|
while (!feof(fin))
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ int main(int argc, char **argv)
|
|||||||
FILE *fin, *fout, *fbits=NULL;
|
FILE *fin, *fout, *fbits=NULL;
|
||||||
short in_short[FRAME_SIZE];
|
short in_short[FRAME_SIZE];
|
||||||
short out_short[FRAME_SIZE];
|
short out_short[FRAME_SIZE];
|
||||||
float in_float[FRAME_SIZE];
|
|
||||||
float sigpow,errpow,snr, seg_snr=0;
|
float sigpow,errpow,snr, seg_snr=0;
|
||||||
int snr_frames = 0;
|
int snr_frames = 0;
|
||||||
char cbits[200];
|
char cbits[200];
|
||||||
@@ -36,8 +35,8 @@ int main(int argc, char **argv)
|
|||||||
sigpow = 0;
|
sigpow = 0;
|
||||||
errpow = 0;
|
errpow = 0;
|
||||||
|
|
||||||
st = speex_encoder_init(&speex_wb_mode);
|
st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||||
dec = speex_decoder_init(&speex_wb_mode);
|
dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
|
||||||
|
|
||||||
callback.callback_id = SPEEX_INBAND_CHAR;
|
callback.callback_id = SPEEX_INBAND_CHAR;
|
||||||
callback.func = speex_std_char_handler;
|
callback.func = speex_std_char_handler;
|
||||||
@@ -74,13 +73,13 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
inFile = argv[1];
|
inFile = argv[1];
|
||||||
fin = fopen(inFile, "r");
|
fin = fopen(inFile, "rb");
|
||||||
outFile = argv[2];
|
outFile = argv[2];
|
||||||
fout = fopen(outFile, "w+");
|
fout = fopen(outFile, "wb+");
|
||||||
if (argc==4)
|
if (argc==4)
|
||||||
{
|
{
|
||||||
bitsFile = argv[3];
|
bitsFile = argv[3];
|
||||||
fbits = fopen(bitsFile, "w");
|
fbits = fopen(bitsFile, "wb");
|
||||||
}
|
}
|
||||||
speex_bits_init(&bits);
|
speex_bits_init(&bits);
|
||||||
while (!feof(fin))
|
while (!feof(fin))
|
||||||
@@ -88,8 +87,6 @@ int main(int argc, char **argv)
|
|||||||
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
fread(in_short, sizeof(short), FRAME_SIZE, fin);
|
||||||
if (feof(fin))
|
if (feof(fin))
|
||||||
break;
|
break;
|
||||||
for (i=0;i<FRAME_SIZE;i++)
|
|
||||||
in_float[i]=in_short[i];
|
|
||||||
speex_bits_reset(&bits);
|
speex_bits_reset(&bits);
|
||||||
|
|
||||||
speex_encode_int(st, in_short, &bits);
|
speex_encode_int(st, in_short, &bits);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
+19
-16
@@ -45,31 +45,32 @@
|
|||||||
#define MIN_ENERGY 6000
|
#define MIN_ENERGY 6000
|
||||||
#define NOISE_POW .3
|
#define NOISE_POW .3
|
||||||
|
|
||||||
|
#ifndef DISABLE_VBR
|
||||||
|
|
||||||
const float vbr_nb_thresh[9][11]={
|
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 */
|
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 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 */
|
{ 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.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 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.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 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.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 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.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 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.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 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.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 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 */
|
||||||
{ 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 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]={
|
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.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 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 */
|
{-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.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 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.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 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.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 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]={
|
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 */
|
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 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 */
|
{ 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)
|
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)
|
void vbr_destroy(VBRState *vbr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* #ifndef DISABLE_VBR */
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
#ifndef VBR_H
|
#ifndef VBR_H
|
||||||
#define VBR_H
|
#define VBR_H
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#define VBR_MEMORY_SIZE 5
|
#define VBR_MEMORY_SIZE 5
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
#define NOISE_COMPAND_LEVELS 40
|
#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))
|
#define fromdB(x) (exp((x)*.11512925f))
|
||||||
|
|
||||||
/* The bark scale equations are approximations, since the original
|
/* The bark scale equations are approximations, since the original
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "vq.h"
|
#include "vq.h"
|
||||||
#include "stack_alloc.h"
|
#include "stack_alloc.h"
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#ifdef _USE_SSE
|
#ifdef _USE_SSE
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
@@ -70,29 +70,6 @@ int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
|
|||||||
return i;
|
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
|
#ifndef OVERRIDE_VQ_NBEST
|
||||||
/*Finds the indices of the n-best entries in a codebook*/
|
/*Finds the indices of the n-best entries in a codebook*/
|
||||||
|
|||||||
@@ -35,12 +35,11 @@
|
|||||||
#ifndef VQ_H
|
#ifndef VQ_H
|
||||||
#define 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_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 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
|
#ifdef _USE_SSE
|
||||||
#include <xmmintrin.h>
|
#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);
|
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"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "misc.h"
|
#include "arch.h"
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#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] = {
|
const spx_word16_t lpc_window[200] = {
|
||||||
1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,
|
1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436,
|
||||||
1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884,
|
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
|
6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696
|
||||||
};
|
};
|
||||||
#else
|
#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] = {
|
const spx_word16_t lpc_window[200] = {
|
||||||
0.080000, 0.080158, 0.080630, 0.081418, 0.082520, 0.083935, 0.085663, 0.087703,
|
0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f,
|
||||||
0.090052, 0.092710, 0.095674, 0.098943, 0.102514, 0.106385, 0.110553, 0.115015,
|
0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f,
|
||||||
0.119769, 0.124811, 0.130137, 0.135744, 0.141628, 0.147786, 0.154212, 0.160902,
|
0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f,
|
||||||
0.167852, 0.175057, 0.182513, 0.190213, 0.198153, 0.206328, 0.214731, 0.223357,
|
0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f,
|
||||||
0.232200, 0.241254, 0.250513, 0.259970, 0.269619, 0.279453, 0.289466, 0.299651,
|
0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f,
|
||||||
0.310000, 0.320507, 0.331164, 0.341965, 0.352901, 0.363966, 0.375151, 0.386449,
|
0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f,
|
||||||
0.397852, 0.409353, 0.420943, 0.432615, 0.444361, 0.456172, 0.468040, 0.479958,
|
0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f,
|
||||||
0.491917, 0.503909, 0.515925, 0.527959, 0.540000, 0.552041, 0.564075, 0.576091,
|
0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f,
|
||||||
0.588083, 0.600042, 0.611960, 0.623828, 0.635639, 0.647385, 0.659057, 0.670647,
|
0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f,
|
||||||
0.682148, 0.693551, 0.704849, 0.716034, 0.727099, 0.738035, 0.748836, 0.759493,
|
0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f,
|
||||||
0.770000, 0.780349, 0.790534, 0.800547, 0.810381, 0.820030, 0.829487, 0.838746,
|
0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f,
|
||||||
0.847800, 0.856643, 0.865269, 0.873672, 0.881847, 0.889787, 0.897487, 0.904943,
|
0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f,
|
||||||
0.912148, 0.919098, 0.925788, 0.932214, 0.938372, 0.944256, 0.949863, 0.955189,
|
0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f,
|
||||||
0.960231, 0.964985, 0.969447, 0.973615, 0.977486, 0.981057, 0.984326, 0.987290,
|
0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f,
|
||||||
0.989948, 0.992297, 0.994337, 0.996065, 0.997480, 0.998582, 0.999370, 0.999842,
|
0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||||
1.000000, 1.000000, 1.000000, 0.998640, 0.994566, 0.987787, 0.978324, 0.966203,
|
1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f,
|
||||||
0.951458, 0.934131, 0.914270, 0.891931, 0.867179, 0.840084, 0.810723, 0.779182,
|
0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f,
|
||||||
0.745551, 0.709930, 0.672424, 0.633148, 0.592223, 0.549781, 0.505964, 0.460932,
|
0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f,
|
||||||
0.414863, 0.367968, 0.320511, 0.272858, 0.225569, 0.179655, 0.137254, 0.103524
|
0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
+1
-1
@@ -21,7 +21,7 @@ AC_ARG_ENABLE(speextest, [ --disable-speextest Do not try to compile and
|
|||||||
elif test "x$speex_prefix" != "x" ; then
|
elif test "x$speex_prefix" != "x" ; then
|
||||||
SPEEX_LIBS="-L$speex_prefix/lib"
|
SPEEX_LIBS="-L$speex_prefix/lib"
|
||||||
elif test "x$prefix" != "xNONE" ; then
|
elif test "x$prefix" != "xNONE" ; then
|
||||||
SPEEX_LIBS=""
|
SPEEX_LIBS="-L$prefix/lib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SPEEX_LIBS="$SPEEX_LIBS -lspeex"
|
SPEEX_LIBS="$SPEEX_LIBS -lspeex"
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ Version: @SPEEX_VERSION@
|
|||||||
Requires:
|
Requires:
|
||||||
Conflicts:
|
Conflicts:
|
||||||
Libs: -L${libdir} -lspeex
|
Libs: -L${libdir} -lspeex
|
||||||
|
Libs.private: -lm
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
@@ -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@
|
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@
|
||||||
|
|
||||||
mandir = $(prefix)/share/man
|
|
||||||
man_MANS = speexenc.1 speexdec.1
|
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
|
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
|
bin_PROGRAMS = speexenc speexdec
|
||||||
|
|
||||||
speexenc_SOURCES = speexenc.c wav_io.c skeleton.c
|
speexenc_SOURCES = speexenc.c wav_io.c skeleton.c
|
||||||
speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la \
|
speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la $(top_builddir)/libspeex/libspeexdsp.la \
|
||||||
$(OGG_LIBS)
|
$(OGG_LIBS) @FFT_LIBS@
|
||||||
|
|
||||||
speexdec_SOURCES = speexdec.c wav_io.c
|
speexdec_SOURCES = speexdec.c wav_io.c
|
||||||
speexdec_LDADD = $(top_builddir)/libspeex/libspeex.la \
|
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.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
|
||||||
.TH SPEEXDEC "1" "September 2003" "speexdec version 1.1" "User Commands"
|
.TH SPEEXDEC "1" "September 2003" "speexdec version 1.1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
speexdec \- manual page for speexdec version 1.1
|
speexdec \- The reference implementation speex decoder.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B speexdec
|
.B speexdec
|
||||||
[\fIoptions\fR] \fIinput_file.spx \fR[\fIoutput_file\fR]
|
[\fIoptions\fR] \fIinput_file.spx \fR[\fIoutput_file\fR]
|
||||||
|
|||||||
+27
-15
@@ -36,6 +36,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#if !defined WIN32 && !defined _WIN32
|
#if !defined WIN32 && !defined _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GETOPT_LONG
|
#ifndef HAVE_GETOPT_LONG
|
||||||
@@ -48,8 +50,6 @@
|
|||||||
#include <ogg/ogg.h>
|
#include <ogg/ogg.h>
|
||||||
|
|
||||||
#if defined WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32
|
||||||
#include <windows.h>
|
|
||||||
#include "getopt_win.h"
|
|
||||||
#include "wave_out.h"
|
#include "wave_out.h"
|
||||||
/* We need the following two to set stdout to binary */
|
/* We need the following two to set stdout to binary */
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@@ -84,7 +84,6 @@
|
|||||||
#include <speex/speex_header.h>
|
#include <speex/speex_header.h>
|
||||||
#include <speex/speex_stereo.h>
|
#include <speex/speex_stereo.h>
|
||||||
#include <speex/speex_callbacks.h>
|
#include <speex/speex_callbacks.h>
|
||||||
#include "wav_io.h"
|
|
||||||
|
|
||||||
#define MAX_FRAME_SIZE 2000
|
#define MAX_FRAME_SIZE 2000
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ static void print_comments(char *comments, int length)
|
|||||||
end = c+length;
|
end = c+length;
|
||||||
len=readint(c, 0);
|
len=readint(c, 0);
|
||||||
c+=4;
|
c+=4;
|
||||||
if (c+len>end)
|
if (len < 0 || c+len>end)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Invalid/corrupted comments\n");
|
fprintf (stderr, "Invalid/corrupted comments\n");
|
||||||
return;
|
return;
|
||||||
@@ -131,7 +130,7 @@ static void print_comments(char *comments, int length)
|
|||||||
}
|
}
|
||||||
len=readint(c, 0);
|
len=readint(c, 0);
|
||||||
c+=4;
|
c+=4;
|
||||||
if (c+len>end)
|
if (len < 0 || c+len>end)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Invalid/corrupted comments\n");
|
fprintf (stderr, "Invalid/corrupted comments\n");
|
||||||
return;
|
return;
|
||||||
@@ -232,6 +231,8 @@ FILE *out_file_open(char *outFile, int rate, int *channels)
|
|||||||
{
|
{
|
||||||
#if defined WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32
|
||||||
_setmode(_fileno(stdout), _O_BINARY);
|
_setmode(_fileno(stdout), _O_BINARY);
|
||||||
|
#elif defined OS2
|
||||||
|
_fsetmode(stdout,"b");
|
||||||
#endif
|
#endif
|
||||||
fout=stdout;
|
fout=stdout;
|
||||||
}
|
}
|
||||||
@@ -289,13 +290,17 @@ void usage()
|
|||||||
|
|
||||||
void version()
|
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");
|
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void version_short()
|
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");
|
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",
|
fprintf (stderr, "Mode number %d does not (yet/any longer) exist in this version\n",
|
||||||
header->mode);
|
header->mode);
|
||||||
|
free(header);
|
||||||
return NULL;
|
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)
|
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);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode->bitstream_version < header->mode_bitstream_version)
|
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");
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (mode->bitstream_version > header->mode_bitstream_version)
|
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");
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,19 +356,13 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
|||||||
if (!st)
|
if (!st)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Decoder initialization failed.\n");
|
fprintf (stderr, "Decoder initialization failed.\n");
|
||||||
|
free(header);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
|
speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
|
||||||
speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
|
speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
|
||||||
*granule_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)
|
if (!*rate)
|
||||||
*rate = header->rate;
|
*rate = header->rate;
|
||||||
/* Adjust rate if --force-* options are used */
|
/* Adjust rate if --force-* options are used */
|
||||||
@@ -385,6 +388,15 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t
|
|||||||
if (*channels==-1)
|
if (*channels==-1)
|
||||||
*channels = header->nb_channels;
|
*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)
|
if (!quiet)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Decoding %d Hz audio using %s mode",
|
fprintf (stderr, "Decoding %d Hz audio using %s mode",
|
||||||
@@ -630,7 +642,7 @@ int main(int argc, char **argv)
|
|||||||
packet_no=0;
|
packet_no=0;
|
||||||
while (!eos && ogg_stream_packetout(&os, &op) == 1)
|
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;
|
speex_serialno = os.serialno;
|
||||||
}
|
}
|
||||||
if (speex_serialno == -1 || os.serialno != speex_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.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29.
|
||||||
.TH SPEEXENC "1" "September 2003" "speexenc version 1.1" "User Commands"
|
.TH SPEEXENC "1" "September 2003" "speexenc version 1.1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
speexenc \- manual page for speexenc version 1.1
|
speexenc \- The reference implementation speex encoder.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B speexenc
|
.B speexenc
|
||||||
[\fIoptions\fR] \fIinput_file output_file\fR
|
[\fIoptions\fR] \fIinput_file output_file\fR
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#if !defined WIN32 && !defined _WIN32
|
#if !defined WIN32 && !defined _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GETOPT_LONG
|
#ifndef HAVE_GETOPT_LONG
|
||||||
@@ -53,7 +55,6 @@
|
|||||||
#include <speex/speex_preprocess.h>
|
#include <speex/speex_preprocess.h>
|
||||||
|
|
||||||
#if defined WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32
|
||||||
#include "getopt_win.h"
|
|
||||||
/* We need the following two to set stdout to binary */
|
/* We need the following two to set stdout to binary */
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -182,13 +183,17 @@ void add_fisbone_packet (ogg_stream_state *os, spx_int32_t serialno, SpeexHeader
|
|||||||
|
|
||||||
void version()
|
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");
|
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void version_short()
|
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");
|
printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +321,8 @@ int main(int argc, char **argv)
|
|||||||
SpeexHeader header;
|
SpeexHeader header;
|
||||||
int nframes=1;
|
int nframes=1;
|
||||||
spx_int32_t complexity=3;
|
spx_int32_t complexity=3;
|
||||||
char *vendor_string = "Encoded with Speex " SPEEX_VERSION;
|
const char* speex_version;
|
||||||
|
char vendor_string[64];
|
||||||
char *comments;
|
char *comments;
|
||||||
int comments_length;
|
int comments_length;
|
||||||
int close_in=0, close_out=0;
|
int close_in=0, close_out=0;
|
||||||
@@ -330,6 +336,9 @@ int main(int argc, char **argv)
|
|||||||
int denoise_enabled=0, agc_enabled=0;
|
int denoise_enabled=0, agc_enabled=0;
|
||||||
spx_int32_t lookahead = 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);
|
comment_init(&comments, &comments_length, vendor_string);
|
||||||
|
|
||||||
/*Process command-line options*/
|
/*Process command-line options*/
|
||||||
@@ -505,6 +514,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
#if defined WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32
|
||||||
_setmode(_fileno(stdin), _O_BINARY);
|
_setmode(_fileno(stdin), _O_BINARY);
|
||||||
|
#elif defined OS2
|
||||||
|
_fsetmode(stdin,"b");
|
||||||
#endif
|
#endif
|
||||||
fin=stdin;
|
fin=stdin;
|
||||||
}
|
}
|
||||||
@@ -949,6 +960,8 @@ void comment_init(char **comments, int* length, char *vendor_string)
|
|||||||
int len=4+vendor_length+4;
|
int len=4+vendor_length+4;
|
||||||
char *p=(char*)malloc(len);
|
char *p=(char*)malloc(len);
|
||||||
if(p==NULL){
|
if(p==NULL){
|
||||||
|
fprintf (stderr, "malloc failed in comment_init()\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
writeint(p, 0, vendor_length);
|
writeint(p, 0, vendor_length);
|
||||||
memcpy(p+4, vendor_string, 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);
|
p=(char*)realloc(p, len);
|
||||||
if(p==NULL){
|
if(p==NULL){
|
||||||
|
fprintf (stderr, "realloc failed in comment_add()\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeint(p, *length, tag_len+val_len); /* length of comment */
|
writeint(p, *length, tag_len+val_len); /* length of comment */
|
||||||
|
|||||||
+1
-32
@@ -37,38 +37,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "speex/speex_types.h"
|
#include "speex/speex_types.h"
|
||||||
|
#include "wav_io.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int read_wav_header(FILE *file, int *rate, int *channels, int *format, spx_int32_t *size)
|
int read_wav_header(FILE *file, int *rate, int *channels, int *format, spx_int32_t *size)
|
||||||
|
|||||||
Loaded 100 of 181 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user