From 4ee40ddc340d1271eafba2cbb37322c0baa0c5c8 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 13 Feb 2009 06:02:32 +0000 Subject: [PATCH] update speex to 1.2rc1 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11979 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/speex/COPYING | 15 +- libs/speex/Makefile.am | 6 +- libs/speex/Speex.kdevelop | 114 +- libs/speex/Speex.spec | 3 +- libs/speex/Speex.spec.in | 1 + libs/speex/TODO | 51 +- libs/speex/acinclude.m4 | 2 +- libs/speex/config.h.in | 44 +- libs/speex/configure.ac | 194 +- libs/speex/doc/Makefile.am | 2 - libs/speex/doc/manual.pdf | Bin 415934 -> 439545 bytes libs/speex/include/speex/Makefile.am | 12 +- libs/speex/include/speex/speex.h | 51 +- libs/speex/include/speex/speex_bits.h | 27 +- libs/speex/include/speex/speex_buffer.h | 68 + libs/speex/include/speex/speex_callbacks.h | 10 +- libs/speex/include/speex/speex_echo.h | 102 +- libs/speex/include/speex/speex_header.h | 10 +- libs/speex/include/speex/speex_jitter.h | 158 +- libs/speex/include/speex/speex_preprocess.h | 192 +- libs/speex/include/speex/speex_resampler.h | 340 ++++ libs/speex/include/speex/speex_stereo.h | 19 +- libs/speex/include/speex/speex_types.h | 10 +- libs/speex/libspeex/Makefile.am | 61 +- libs/speex/libspeex/_kiss_fft_guts.h | 15 +- libs/speex/libspeex/arch.h | 60 +- libs/speex/libspeex/bits.c | 75 +- libs/speex/libspeex/buffer.c | 176 ++ libs/speex/libspeex/cb_search.c | 54 +- libs/speex/libspeex/cb_search.h | 2 +- libs/speex/libspeex/cb_search_bfin.h | 5 +- libs/speex/libspeex/echo_diagnostic.m | 72 + libs/speex/libspeex/fftwrap.c | 164 +- libs/speex/libspeex/fftwrap.h | 2 +- libs/speex/libspeex/filterbank.c | 227 +++ libs/speex/libspeex/filterbank.h | 66 + libs/speex/libspeex/filters.c | 401 ++-- libs/speex/libspeex/filters.h | 18 +- libs/speex/libspeex/filters_arm4.h | 297 +-- libs/speex/libspeex/filters_bfin.h | 273 --- libs/speex/libspeex/filters_sse.h | 36 +- libs/speex/libspeex/fixed_debug.h | 143 +- libs/speex/libspeex/fixed_generic.h | 8 +- libs/speex/libspeex/jitter.c | 941 ++++++--- libs/speex/libspeex/kiss_fft.c | 357 ++-- libs/speex/libspeex/kiss_fft.h | 4 +- libs/speex/libspeex/kiss_fftr.c | 156 +- libs/speex/libspeex/kiss_fftr.h | 5 + libs/speex/libspeex/lpc.h | 2 +- libs/speex/libspeex/lsp.c | 2 +- libs/speex/libspeex/lsp.h | 2 +- libs/speex/libspeex/ltp.c | 245 ++- libs/speex/libspeex/ltp.h | 2 +- libs/speex/libspeex/ltp_arm4.h | 17 +- libs/speex/libspeex/ltp_bfin.h | 10 +- libs/speex/libspeex/math_approx.h | 296 ++- libs/speex/libspeex/mdf.c | 1008 +++++++--- libs/speex/libspeex/modes.c | 317 +-- libs/speex/libspeex/modes.h | 32 +- libs/speex/libspeex/modes_wb.c | 300 +++ libs/speex/libspeex/nb_celp.c | 692 +++---- libs/speex/libspeex/nb_celp.h | 26 +- libs/speex/libspeex/os_support.h | 169 ++ libs/speex/libspeex/preprocess.c | 1459 ++++++++------ libs/speex/libspeex/pseudofloat.h | 112 +- libs/speex/libspeex/quant_lsp.c | 70 +- libs/speex/libspeex/quant_lsp.h | 11 +- libs/speex/libspeex/quant_lsp_bfin.h | 24 +- libs/speex/libspeex/resample.c | 1131 +++++++++++ libs/speex/libspeex/resample_sse.h | 128 ++ libs/speex/libspeex/sb_celp.c | 826 ++++---- libs/speex/libspeex/sb_celp.h | 45 +- libs/speex/libspeex/scal.c | 289 +++ libs/speex/libspeex/smallft.c | 3 +- libs/speex/libspeex/speex.c | 58 +- libs/speex/libspeex/speex_callbacks.c | 26 +- libs/speex/libspeex/speex_header.c | 50 +- libs/speex/libspeex/stack_alloc.h | 27 +- libs/speex/libspeex/stereo.c | 260 ++- libs/speex/libspeex/testdenoise.c | 10 +- libs/speex/libspeex/testecho.c | 36 +- libs/speex/libspeex/testenc.c | 30 +- libs/speex/libspeex/testenc_uwb.c | 10 +- libs/speex/libspeex/testenc_wb.c | 13 +- libs/speex/libspeex/testjitter.c | 75 + libs/speex/libspeex/vbr.c | 35 +- libs/speex/libspeex/vbr.h | 2 +- libs/speex/libspeex/vorbis_psy.h | 2 +- libs/speex/libspeex/vq.c | 25 +- libs/speex/libspeex/vq.h | 3 +- libs/speex/libspeex/window.c | 60 +- libs/speex/speex.m4 | 2 +- libs/speex/speex.pc.in | 1 + libs/speex/speexdsp.pc.in | 15 + libs/speex/src/Makefile.am | 7 +- libs/speex/src/speexdec.1 | 2 +- libs/speex/src/speexdec.c | 42 +- libs/speex/src/speexenc.1 | 2 +- libs/speex/src/speexenc.c | 23 +- libs/speex/src/wav_io.c | 33 +- libs/speex/src/wav_io.h | 26 +- libs/speex/symbian/bld.inf | 14 + libs/speex/symbian/speex.mmp | 4 +- libs/speex/ti/Makefile.am | 2 +- libs/speex/ti/config.h | 18 +- libs/speex/ti/os_support_custom.h | 128 ++ .../ti/speex_C54_test/speex_C54_test.pjt | 4 +- .../ti/speex_C55_test/speex_C55_test.pjt | 4 +- .../ti/speex_C64_test/speex_C64_test.pjt | 6 +- libs/speex/ti/testenc-TI-C5x.c | 9 +- libs/speex/ti/testenc-TI-C64x.c | 7 + libs/speex/win32/Makefile.am | 4 +- libs/speex/win32/VS2003/Makefile.am | 4 +- libs/speex/win32/VS2003/libspeex.sln | 146 ++ libs/speex/win32/VS2003/libspeex/Makefile.am | 2 +- .../win32/VS2003/libspeex/libspeex.vcproj | 196 +- .../win32/VS2003/libspeexdsp/Makefile.am | 8 + .../win32/VS2003/libspeexdsp/Makefile.in | 341 ++++ .../VS2003/libspeexdsp/libspeexdsp.vcproj | 342 ++++ .../win32/VS2003/speexdec/speexdec.vcproj | 88 +- .../win32/VS2003/speexenc/speexenc.vcproj | 96 +- libs/speex/win32/VS2003/tests/Makefile.am | 9 + libs/speex/win32/VS2003/tests/Makefile.in | 343 ++++ .../win32/VS2003/tests/testdenoise.vcproj | 213 +++ libs/speex/win32/VS2003/tests/testecho.vcproj | 213 +++ libs/speex/win32/VS2003/tests/testenc.vcproj | 213 +++ .../win32/VS2003/tests/testenc_uwb.vcproj | 213 +++ .../win32/VS2003/tests/testenc_wb.vcproj | 213 +++ .../win32/VS2003/tests/testresample.vcproj | 213 +++ libs/speex/win32/VS2005/Makefile.am | 4 +- libs/speex/win32/VS2005/libspeex.sln | 259 +++ .../win32/VS2005/libspeex/libspeex.vcproj | 254 ++- .../win32/VS2005/libspeexdsp/Makefile.am | 8 + .../win32/VS2005/libspeexdsp/Makefile.in | 341 ++++ .../VS2005/libspeexdsp/libspeexdsp.vcproj | 1624 ++++++++++++++++ .../win32/VS2005/speexdec/speexdec.vcproj | 106 +- .../win32/VS2005/speexenc/speexenc.vcproj | 109 +- libs/speex/win32/VS2005/tests/Makefile.am | 9 + libs/speex/win32/VS2005/tests/Makefile.in | 343 ++++ .../win32/VS2005/tests/testdenoise.vcproj | 307 +++ libs/speex/win32/VS2005/tests/testecho.vcproj | 307 +++ libs/speex/win32/VS2005/tests/testenc.vcproj | 307 +++ .../win32/VS2005/tests/testenc_uwb.vcproj | 307 +++ .../win32/VS2005/tests/testenc_wb.vcproj | 307 +++ .../win32/VS2005/tests/testresample.vcproj | 307 +++ libs/speex/win32/VS2008/Makefile.am | 8 + libs/speex/win32/VS2008/Makefile.in | 485 +++++ libs/speex/win32/VS2008/libspeex.sln | 439 +++++ libs/speex/win32/VS2008/libspeex/Makefile.am | 8 + libs/speex/win32/VS2008/libspeex/Makefile.in | 341 ++++ .../win32/VS2008/libspeex/libspeex.vcproj | 1704 +++++++++++++++++ .../win32/VS2008/libspeexdsp/Makefile.am | 8 + .../win32/VS2008/libspeexdsp/Makefile.in | 341 ++++ .../VS2008/libspeexdsp/libspeexdsp.vcproj | 470 +++++ libs/speex/win32/VS2008/speexdec/Makefile.am | 8 + libs/speex/win32/VS2008/speexdec/Makefile.in | 341 ++++ .../win32/VS2008/speexdec/speexdec.vcproj | 427 +++++ libs/speex/win32/VS2008/speexenc/Makefile.am | 8 + libs/speex/win32/VS2008/speexenc/Makefile.in | 341 ++++ .../win32/VS2008/speexenc/speexenc.vcproj | 427 +++++ libs/speex/win32/VS2008/tests/Makefile.am | 9 + libs/speex/win32/VS2008/tests/Makefile.in | 343 ++++ .../win32/VS2008/tests/testdenoise.vcproj | 305 +++ libs/speex/win32/VS2008/tests/testecho.vcproj | 305 +++ libs/speex/win32/VS2008/tests/testenc.vcproj | 305 +++ .../win32/VS2008/tests/testenc_uwb.vcproj | 305 +++ .../win32/VS2008/tests/testenc_wb.vcproj | 305 +++ .../win32/VS2008/tests/testresample.vcproj | 305 +++ libs/speex/win32/config.h | 21 +- libs/speex/win32/libspeex.def | 75 + libs/speex/win32/libspeex/Makefile.am | 2 +- libs/speex/win32/libspeex/libspeex.dsp | 124 +- libs/speex/win32/libspeex/libspeex.dsw | 24 + .../speex/win32/libspeex/libspeex_dynamic.dsp | 134 +- libs/speex/win32/libspeex/libspeexdsp.dsp | 224 +++ .../win32/libspeex/libspeexdsp_dynamic.dsp | 233 +++ libs/speex/win32/libspeexdsp.def | 72 + libs/speex/win32/speexdec/speexdec.dsp | 8 +- libs/speex/win32/speexdec/speexdec.dsw | 2 +- libs/speex/win32/speexenc/speexenc.dsp | 16 +- libs/speex/win32/speexenc/speexenc.dsw | 17 +- 181 files changed, 24291 insertions(+), 5293 deletions(-) create mode 100644 libs/speex/include/speex/speex_buffer.h create mode 100644 libs/speex/include/speex/speex_resampler.h create mode 100644 libs/speex/libspeex/buffer.c create mode 100644 libs/speex/libspeex/echo_diagnostic.m create mode 100644 libs/speex/libspeex/filterbank.c create mode 100644 libs/speex/libspeex/filterbank.h create mode 100644 libs/speex/libspeex/modes_wb.c create mode 100644 libs/speex/libspeex/os_support.h create mode 100644 libs/speex/libspeex/resample.c create mode 100644 libs/speex/libspeex/resample_sse.h create mode 100644 libs/speex/libspeex/scal.c create mode 100644 libs/speex/libspeex/testjitter.c create mode 100644 libs/speex/speexdsp.pc.in create mode 100644 libs/speex/ti/os_support_custom.h create mode 100644 libs/speex/win32/VS2003/libspeex.sln create mode 100644 libs/speex/win32/VS2003/libspeexdsp/Makefile.am create mode 100644 libs/speex/win32/VS2003/libspeexdsp/Makefile.in create mode 100644 libs/speex/win32/VS2003/libspeexdsp/libspeexdsp.vcproj create mode 100644 libs/speex/win32/VS2003/tests/Makefile.am create mode 100644 libs/speex/win32/VS2003/tests/Makefile.in create mode 100644 libs/speex/win32/VS2003/tests/testdenoise.vcproj create mode 100644 libs/speex/win32/VS2003/tests/testecho.vcproj create mode 100644 libs/speex/win32/VS2003/tests/testenc.vcproj create mode 100644 libs/speex/win32/VS2003/tests/testenc_uwb.vcproj create mode 100644 libs/speex/win32/VS2003/tests/testenc_wb.vcproj create mode 100644 libs/speex/win32/VS2003/tests/testresample.vcproj create mode 100644 libs/speex/win32/VS2005/libspeex.sln create mode 100644 libs/speex/win32/VS2005/libspeexdsp/Makefile.am create mode 100644 libs/speex/win32/VS2005/libspeexdsp/Makefile.in create mode 100644 libs/speex/win32/VS2005/libspeexdsp/libspeexdsp.vcproj create mode 100644 libs/speex/win32/VS2005/tests/Makefile.am create mode 100644 libs/speex/win32/VS2005/tests/Makefile.in create mode 100644 libs/speex/win32/VS2005/tests/testdenoise.vcproj create mode 100644 libs/speex/win32/VS2005/tests/testecho.vcproj create mode 100644 libs/speex/win32/VS2005/tests/testenc.vcproj create mode 100644 libs/speex/win32/VS2005/tests/testenc_uwb.vcproj create mode 100644 libs/speex/win32/VS2005/tests/testenc_wb.vcproj create mode 100644 libs/speex/win32/VS2005/tests/testresample.vcproj create mode 100644 libs/speex/win32/VS2008/Makefile.am create mode 100644 libs/speex/win32/VS2008/Makefile.in create mode 100644 libs/speex/win32/VS2008/libspeex.sln create mode 100644 libs/speex/win32/VS2008/libspeex/Makefile.am create mode 100644 libs/speex/win32/VS2008/libspeex/Makefile.in create mode 100644 libs/speex/win32/VS2008/libspeex/libspeex.vcproj create mode 100644 libs/speex/win32/VS2008/libspeexdsp/Makefile.am create mode 100644 libs/speex/win32/VS2008/libspeexdsp/Makefile.in create mode 100644 libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj create mode 100644 libs/speex/win32/VS2008/speexdec/Makefile.am create mode 100644 libs/speex/win32/VS2008/speexdec/Makefile.in create mode 100644 libs/speex/win32/VS2008/speexdec/speexdec.vcproj create mode 100644 libs/speex/win32/VS2008/speexenc/Makefile.am create mode 100644 libs/speex/win32/VS2008/speexenc/Makefile.in create mode 100644 libs/speex/win32/VS2008/speexenc/speexenc.vcproj create mode 100644 libs/speex/win32/VS2008/tests/Makefile.am create mode 100644 libs/speex/win32/VS2008/tests/Makefile.in create mode 100644 libs/speex/win32/VS2008/tests/testdenoise.vcproj create mode 100644 libs/speex/win32/VS2008/tests/testecho.vcproj create mode 100644 libs/speex/win32/VS2008/tests/testenc.vcproj create mode 100644 libs/speex/win32/VS2008/tests/testenc_uwb.vcproj create mode 100644 libs/speex/win32/VS2008/tests/testenc_wb.vcproj create mode 100644 libs/speex/win32/VS2008/tests/testresample.vcproj create mode 100644 libs/speex/win32/libspeex.def create mode 100644 libs/speex/win32/libspeex/libspeexdsp.dsp create mode 100644 libs/speex/win32/libspeex/libspeexdsp_dynamic.dsp create mode 100644 libs/speex/win32/libspeexdsp.def diff --git a/libs/speex/COPYING b/libs/speex/COPYING index 3b6b579cf3..de6fbe2c91 100644 --- a/libs/speex/COPYING +++ b/libs/speex/COPYING @@ -1,10 +1,11 @@ -Copyright 2002-2006 - Xiph.org Foundation - Jean-Marc Valin - David Rowe - EpicGames - Analog Devices - Commonwealth Scientific and Industrial Research Organisation (CSIRO) +Copyright 2002-2008 Xiph.org Foundation +Copyright 2002-2008 Jean-Marc Valin +Copyright 2005-2007 Analog Devices Inc. +Copyright 2005-2008 Commonwealth Scientific and Industrial Research + Organisation (CSIRO) +Copyright 1993, 2002, 2006 David Rowe +Copyright 2003 EpicGames +Copyright 1992-1994 Jutta Degener, Carsten Bormann Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/libs/speex/Makefile.am b/libs/speex/Makefile.am index 5f6c7bbdf8..4b99faf55e 100644 --- a/libs/speex/Makefile.am +++ b/libs/speex/Makefile.am @@ -2,18 +2,18 @@ # To disable automatic dependency tracking if using other tools than # gcc and gmake, add the option 'no-dependencies' -AUTOMAKE_OPTIONS = 1.7 +AUTOMAKE_OPTIONS = 1.8 m4datadir = $(datadir)/aclocal m4data_DATA = speex.m4 pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = speex.pc +pkgconfig_DATA = speex.pc speexdsp.pc EXTRA_DIST = Speex.spec Speex.spec.in Speex.kdevelop speex.m4 speex.pc.in README.blackfin README.symbian README.TI-DSP #Fools KDevelop into including all files -SUBDIRS = libspeex include doc win32 symbian ti +SUBDIRS = libspeex include @src@ doc win32 symbian ti DIST_SUBDIRS = libspeex include src doc win32 symbian ti diff --git a/libs/speex/Speex.kdevelop b/libs/speex/Speex.kdevelop index e4e07493ca..1b3d683b07 100644 --- a/libs/speex/Speex.kdevelop +++ b/libs/speex/Speex.kdevelop @@ -11,11 +11,14 @@ false + kdevsubversion + + Speex libspeex/libspeex.la - default + float src/Speex @@ -25,23 +28,47 @@ false true + false + false - - optimized - GccOptions - GppOptions - G77Options - -O2 -g0 - - - --enable-debug=full - debug - GccOptions - GppOptions - G77Options - -O0 -g3 - + + float + kdevgccoptions + kdevgppoptions + kdevpgf77options + -O2 -g -Wall + + --disable-shared + + + + + + + + + + + --enable-fixed-point --disable-shared + fixed + kdevgccoptions + kdevgppoptions + kdevpgf77options + -O2 -g -Wall + + + + + + + + + + + + + @@ -49,9 +76,11 @@ false - 1 + 4 false + true + 0 @@ -69,6 +98,7 @@ false true + 10 @@ -88,10 +118,50 @@ true true true - 250 + 350 400 250 + false + 0 + true + true + false + std=_GLIBCXX_STD;__gnu_cxx=std + true + true + false + false + true + true + true + true + .; + false + false + + false + 3 + /usr/share/qt3 + 3 + EmbeddedKDevDesigner + /usr/share/qt3/bin/qmake + /usr/bin/designer-qt3 + + + + + set + m_,_ + theValue + true + true + + + true + true + Horizontal + @@ -101,6 +171,7 @@ *.o,*.lo,CVS true + false @@ -120,4 +191,11 @@ .cpp + + + + + + + diff --git a/libs/speex/Speex.spec b/libs/speex/Speex.spec index 4aab2877ce..e0ae03024c 100644 --- a/libs/speex/Speex.spec +++ b/libs/speex/Speex.spec @@ -1,5 +1,5 @@ %define name speex -%define ver 1.2beta1 +%define ver 1.2rc1 %define rel 1 Summary: An open-source, patent-free speech codec @@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install %{_includedir}/speex/speex*.h /usr/share/aclocal/speex.m4 %{_libdir}/pkgconfig/speex.pc +%{_libdir}/pkgconfig/speexdsp.pc %{_libdir}/libspeex*.a diff --git a/libs/speex/Speex.spec.in b/libs/speex/Speex.spec.in index 416f435699..bccfc2351a 100644 --- a/libs/speex/Speex.spec.in +++ b/libs/speex/Speex.spec.in @@ -67,4 +67,5 @@ make DESTDIR=$RPM_BUILD_ROOT install %{_includedir}/speex/speex*.h /usr/share/aclocal/speex.m4 %{_libdir}/pkgconfig/speex.pc +%{_libdir}/pkgconfig/speexdsp.pc %{_libdir}/libspeex*.a diff --git a/libs/speex/TODO b/libs/speex/TODO index 61f8f99d4d..fd3c953aa2 100644 --- a/libs/speex/TODO +++ b/libs/speex/TODO @@ -1,29 +1,43 @@ -Better saturation handling in mdf? -get rid of crap that shouldn't be exposed in speex.h +For 1.2: +Major points: +- Make documentation match the actual code (especially jitter buffer, AEC and preprocessor) +- Get AGC to work in fixed-point even if not totally converted +- Stabilise all APIs (need feedback) +- Short-term estimate in jitter buffer +- Control delay in new AEC API. +- NaN checks? +- Better error reporting +- Make kiss-fft 32-bit safe + +Minor issues: +- Fix last frame of speexenc + + +Post 1.2: +improve float<->int conversion +split encoder and decoder? +Merge TriMedia stuff +packet dump +Do VAD properly +--enable-{aec,preprocessor,jitter,resampler} + +Optimisations +- Add restrict in a few places? +- enable 4x4 version of pitch_xcorr() at least on some archs? +- use __builtin_expect() (likely()/unlikely()) Would be nice: +Implement wideband split as IIR instead of QMF? -Allocator override (speex_lib_ctl) -Better error handling +Allocator override (speex_lib_ctl?) Fixed-point: - - Wideband - - Initialization + - VBR - Jitter buffer + - AGC Denoiser: - - Smooth gain (remove musical noise) - Better noise adaptation - - Do some tuning AGC: - - Use median filtering instead of "non-linear mean" - - - -Features --Add maximum/minimum bit-rate control for VBR --Improve error handling (with perror-like call?) - -Long-term quality improvements --Improve perceptual enhancement (including wideband) + - Use median filtering instead of "non-linear mean"? Standards -Complete Speex RTP profile @@ -32,4 +46,3 @@ Standards ideas: Peelable stream (double codebook, higher bands, stereo) LPC from spectral domain -Better psycho-acoustic model. Masking curve from Vorbis? diff --git a/libs/speex/acinclude.m4 b/libs/speex/acinclude.m4 index 9f9333b010..0e1f1abf59 100644 --- a/libs/speex/acinclude.m4 +++ b/libs/speex/acinclude.m4 @@ -19,7 +19,7 @@ AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run elif test "x$ogg_prefix" != "x" ; then OGG_LIBS="-L$ogg_prefix/lib" elif test "x$prefix" != "xNONE" ; then - OGG_LIBS="" + OGG_LIBS="-L$prefix/lib" fi OGG_LIBS="$OGG_LIBS -logg" diff --git a/libs/speex/config.h.in b/libs/speex/config.h.in index 05399fc597..959340983f 100644 --- a/libs/speex/config.h.in +++ b/libs/speex/config.h.in @@ -9,14 +9,17 @@ /* Make use of Blackfin assembly optimizations */ #undef BFIN_ASM -/* Disable wideband codec */ -#undef DISABLE_WIDEBAND +/* Disable all parts of the API that are using floats */ +#undef DISABLE_FLOAT_API + +/* Disable VBR and VAD from the codec */ +#undef DISABLE_VBR /* Enable valgrind extra checks */ #undef ENABLE_VALGRIND -/* Enable support for Epic 4.8 kbps mode */ -#undef EPIC_48K +/* Symbol visibility prefix */ +#undef EXPORT /* Debug fixed-point implementation */ #undef FIXED_DEBUG @@ -24,9 +27,18 @@ /* Compile as fixed-point */ #undef FIXED_POINT +/* Compile as floating-point */ +#undef FLOATING_POINT + +/* Define to 1 if you have the header file. */ +#undef HAVE_ALLOCA_H + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG @@ -84,16 +96,13 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Reduce precision to 16 bits (EXPERIMENTAL) */ -#undef PRECISION16 - -/* The size of a `int', as computed by sizeof. */ +/* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT -/* The size of a `long', as computed by sizeof. */ +/* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG -/* The size of a `short', as computed by sizeof. */ +/* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* Version extra */ @@ -120,12 +129,21 @@ /* Make use of alloca */ #undef USE_ALLOCA +/* Use FFTW3 for FFT */ +#undef USE_GPL_FFTW3 + +/* Use Intel Math Kernel Library for FFT */ +#undef USE_INTEL_MKL + +/* Use KISS Fast Fourier Transform */ +#undef USE_KISS_FFT + +/* Use FFT from OggVorbis */ +#undef USE_SMALLFT + /* Use C99 variable-size arrays */ #undef VAR_ARRAYS -/* Enable Vorbis-style psychoacoustics (EXPERIMENTAL) */ -#undef VORBIS_PSYCHO - /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN diff --git a/libs/speex/configure.ac b/libs/speex/configure.ac index a3a2395c7f..df7f01dc6b 100644 --- a/libs/speex/configure.ac +++ b/libs/speex/configure.ac @@ -6,15 +6,15 @@ AM_CONFIG_HEADER([config.h]) SPEEX_MAJOR_VERSION=1 SPEEX_MINOR_VERSION=1 -SPEEX_MICRO_VERSION=13 +SPEEX_MICRO_VERSION=16 SPEEX_EXTRA_VERSION= #SPEEX_VERSION= -SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION -SPEEX_VERSION="1.2beta1" +#SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION$SPEEX_EXTRA_VERSION +SPEEX_VERSION="1.2rc1" -SPEEX_LT_CURRENT=5 +SPEEX_LT_CURRENT=6 SPEEX_LT_REVISION=0 -SPEEX_LT_AGE=4 +SPEEX_LT_AGE=5 AC_SUBST(SPEEX_LT_CURRENT) AC_SUBST(SPEEX_LT_REVISION) @@ -30,6 +30,7 @@ AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define) AM_MAINTAINER_MODE AC_CANONICAL_HOST +AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL AC_C_BIGENDIAN @@ -40,7 +41,8 @@ AC_C_RESTRICT AC_MSG_CHECKING(for C99 variable-size arrays) AC_TRY_COMPILE( , [ -int foo=10; +int foo; +foo = 10; int array[foo]; ], [has_var_arrays=yes;AC_DEFINE([VAR_ARRAYS], [], [Use C99 variable-size arrays]) @@ -49,8 +51,14 @@ has_var_arrays=no ) AC_MSG_RESULT($has_var_arrays) +AC_CHECK_HEADERS([alloca.h getopt.h]) AC_MSG_CHECKING(for alloca) -AC_TRY_COMPILE( [#include ], [ +AC_TRY_COMPILE( [ +#ifdef HAVE_ALLOCA_H +# include +#endif +#include +], [ int foo=10; int *array = alloca(foo); ], @@ -64,9 +72,49 @@ has_alloca=no ) AC_MSG_RESULT($has_alloca) +AC_MSG_CHECKING(for SSE in current arch/CFLAGS) +AC_LINK_IFELSE([ +AC_LANG_PROGRAM([[ +#include +__m128 testfunc(float *a, float *b) { + return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b)); +} +]])], +[ +has_sse=yes +], +[ +has_sse=no +] +) +AC_MSG_RESULT($has_sse) + +SAVE_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fvisibility=hidden" +AC_MSG_CHECKING(for ELF visibility) +AC_COMPILE_IFELSE([ +AC_LANG_PROGRAM([[ +#pragma GCC visibility push(hidden) +__attribute__((visibility("default"))) +int var=10; +]])], +[ +has_visibility=yes +AC_DEFINE([EXPORT], [__attribute__((visibility("default")))], [Symbol visibility prefix]) +], +[ +has_visibility=no +AC_DEFINE([EXPORT], [], [Symbol visibility prefix]) +CFLAGS="$SAVE_CFLAGS" +] +) +AC_MSG_RESULT($has_visibility) AC_CHECK_HEADERS(sys/soundcard.h sys/audioio.h) +XIPH_PATH_OGG([src="src"], [src=""]) +AC_SUBST(src) + AC_CHECK_LIB(m, sin) # Check for getopt_long; if not found, use included source. @@ -86,30 +134,45 @@ AC_DEFINE_UNQUOTED(SPEEX_MINOR_VERSION, ${SPEEX_MINOR_VERSION}, [Version minor]) AC_DEFINE_UNQUOTED(SPEEX_MICRO_VERSION, ${SPEEX_MICRO_VERSION}, [Version micro]) AC_DEFINE_UNQUOTED(SPEEX_EXTRA_VERSION, "${SPEEX_EXTRA_VERSION}", [Version extra]) -AC_ARG_ENABLE(wideband, [ --disable-wideband Disable wideband codec], -[if test "$enableval" = no; then - AC_DEFINE([DISABLE_WIDEBAND], , [Disable wideband codec]) -fi]) - -AC_ARG_ENABLE(vorbis-psy, [ --enable-vorbis-psy Enable Vorbis-style psychoacoustics (EXPERIMENTAL)], -[if test "$enableval" = yes; then - AC_DEFINE([VORBIS_PSYCHO], , [Enable Vorbis-style psychoacoustics (EXPERIMENTAL)]) -fi]) - AC_ARG_ENABLE(valgrind, [ --enable-valgrind Enable valgrind extra checks], [if test "$enableval" = yes; then AC_DEFINE([ENABLE_VALGRIND], , [Enable valgrind extra checks]) fi]) -AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [if test "$enableval" = yes; then -AC_DEFINE([_USE_SSE], , [Enable SSE support]) +AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [ +if test "x$enableval" != xno; then +has_sse=yes CFLAGS="$CFLAGS -O3 -msse" +else +has_sse=no fi ]) + +FFT=smallft + AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point], [if test "$enableval" = yes; then + FFT=kiss + has_sse=no AC_DEFINE([FIXED_POINT], , [Compile as fixed-point]) +else + AC_DEFINE([FLOATING_POINT], , [Compile as floating-point]) +fi], +AC_DEFINE([FLOATING_POINT], , [Compile as floating-point])) + +if test "$has_sse" = yes; then + AC_DEFINE([_USE_SSE], , [Enable SSE support]) +fi + +AC_ARG_ENABLE(float-api, [ --disable-float-api Disable the floating-point API], +[if test "$enableval" = no; then + AC_DEFINE([DISABLE_FLOAT_API], , [Disable all parts of the API that are using floats]) +fi]) + +AC_ARG_ENABLE(vbr, [ --disable-vbr Disable VBR and VAD from the codec], +[if test "$enableval" = no; then + AC_DEFINE([DISABLE_VBR], , [Disable VBR and VAD from the codec]) fi]) AC_ARG_ENABLE(arm4-asm, [ --enable-arm4-asm Make use of ARM4 assembly optimizations], @@ -122,7 +185,7 @@ AC_ARG_ENABLE(arm5e-asm, [ --enable-arm5e-asm Make use of ARM5E assembly o AC_DEFINE([ARM5E_ASM], , [Make use of ARM5E assembly optimizations]) fi]) -AC_ARG_ENABLE(blackfin-asm, [ --enable-blackfin-asm Make use of Blackfin assembly optimizations], +AC_ARG_ENABLE(blackfin-asm, [ --enable-blackfin-asm Make use of Blackfin assembly optimizations], [if test "$enableval" = yes; then AC_DEFINE([BFIN_ASM], , [Make use of Blackfin assembly optimizations]) LDFLAGS="-Wl,-elf2flt=-s100000" @@ -133,21 +196,49 @@ AC_ARG_ENABLE(fixed-point-debug, [ --enable-fixed-point-debug Debug fixed-poin AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation]) fi]) -AC_ARG_ENABLE(epic-48k, [ --enable-epic-48k Enable support for Epic 4.8 kbps mode], -[if test "$enableval" = yes; then - AC_DEFINE([EPIC_48K], , [Enable support for Epic 4.8 kbps mode]) -fi]) - AC_ARG_ENABLE(ti-c55x, [ --enable-ti-c55x Enable support for TI C55X DSP], [if test "$enableval" = yes; then has_char16=yes; AC_DEFINE([TI_C55X], , [Enable support for TI C55X DSP]) fi]) -AC_ARG_ENABLE(16bit-precision, [ --enable-16bit-precision Reduce precision to 16 bits (EXPERIMENTAL)], -[if test "$enableval" = yes; then - AC_DEFINE([PRECISION16], , [Reduce precision to 16 bits (EXPERIMENTAL)]) -fi]) +AC_ARG_WITH([fft], [AS_HELP_STRING([--with-fft=choice],[use an alternate FFT implementation. The available choices are +kiss (default fixed point), smallft (default floating point), gpl-fftw3 and proprietary-intel-mkl])], +[FFT=$withval] +) + +FFT_PKGCONFIG= +AS_CASE([$FFT], + [kiss], [ + AC_DEFINE([USE_KISS_FFT], [], [Use KISS Fast Fourier Transform]) + ], + [smallft], [ + AC_DEFINE([USE_SMALLFT], [], [Use FFT from OggVorbis]) + ], + [gpl-fftw3], [ + AC_DEFINE([USE_GPL_FFTW3], [], [Use FFTW3 for FFT]) + PKG_CHECK_MODULES(FFT, fftw3f) + ], + [proprietary-intel-mkl], [ + AC_DEFINE([USE_INTEL_MKL], [], [Use Intel Math Kernel Library for FFT]) + AC_MSG_CHECKING(for valid MKL) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#include +void func() { + DFTI_DESCRIPTOR_HANDLE h; + MKL_LONG result=DftiCreateDescriptor(&h, DFTI_SINGLE, DFTI_REAL, 0); +}]])], + [AC_MSG_RESULT(yes)], + [AC_MSG_FAILURE([Failed to compile MKL test program. Make sure you set CFLAGS to include the include directory and set LDFLAGS to include the library directory and all necesarry libraries.])] + ) + ], + [AC_MSG_FAILURE([Unknown FFT $FFT specified for --with-fft])] +) +AM_CONDITIONAL(BUILD_KISS_FFT, [test "$FFT" = "kiss"]) +AM_CONDITIONAL(BUILD_SMALLFT, [test "$FFT" = "smallft"]) +AC_SUBST(FFT_PKGCONFIG) + AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) @@ -182,47 +273,28 @@ fi AC_SUBST(SIZE16) AC_SUBST(SIZE32) - -AC_DEFUN([AX_COMPILER_VENDOR], -[ -AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, - [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown - # note: don't check for gcc first since some other compilers define __GNUC__ - for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do - vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ -#if !($vencpp) - thisisanerror; -#endif -])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) - done - ]) -]) - -AX_COMPILER_VENDOR - -# Enable 64 bit build -AC_ARG_ENABLE(64, -[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="no"]) - -if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then - if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -m64" - CXXFLAGS="$CXXFLAGS -m64" - fi -fi - AC_OUTPUT([Makefile libspeex/Makefile src/Makefile doc/Makefile Speex.spec - include/Makefile include/speex/Makefile speex.pc + include/Makefile include/speex/Makefile speex.pc speexdsp.pc win32/Makefile win32/libspeex/Makefile win32/speexenc/Makefile win32/speexdec/Makefile symbian/Makefile - win32/VS2003/Makefile win32/VS2005/Makefile + win32/VS2003/Makefile + win32/VS2003/tests/Makefile win32/VS2003/libspeex/Makefile + win32/VS2003/libspeexdsp/Makefile win32/VS2003/speexdec/Makefile win32/VS2003/speexenc/Makefile + win32/VS2005/Makefile win32/VS2005/libspeex/Makefile win32/VS2005/speexdec/Makefile win32/VS2005/speexenc/Makefile + win32/VS2005/libspeexdsp/Makefile + win32/VS2005/tests/Makefile + win32/VS2008/libspeexdsp/Makefile + win32/VS2008/Makefile + win32/VS2008/speexdec/Makefile + win32/VS2008/tests/Makefile + win32/VS2008/libspeex/Makefile + win32/VS2008/speexenc/Makefile include/speex/speex_config_types.h ti/Makefile ti/speex_C54_test/Makefile ti/speex_C55_test/Makefile ti/speex_C64_test/Makefile ]) diff --git a/libs/speex/doc/Makefile.am b/libs/speex/doc/Makefile.am index a70a97b31a..d2896efabb 100644 --- a/libs/speex/doc/Makefile.am +++ b/libs/speex/doc/Makefile.am @@ -1,5 +1,3 @@ -docdir=$(prefix)/share/doc/@PACKAGE@-@VERSION@ - doc_DATA = manual.pdf EXTRA_DIST = $(doc_DATA) diff --git a/libs/speex/doc/manual.pdf b/libs/speex/doc/manual.pdf index ec77341ead229c575b3b8397c8e6814d0469e1bd..292f304defd312957dbf95c66b3afc6316cfc255 100644 GIT binary patch literal 439545 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
1^XyR#Dk$4xJE#!`bg0D7so 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 *p|siy!m$>rpxsm=X{o5!dj3Pf9)klUwi*np zQ8oj3C|gvz@EB7*Bg5?4AFqn`=WX+TIp4?y+W4b+SAp3L%l#CZkqlUJkz|1bUTH;| zslaVIQn%(hv){wRo|oT!FqbFpgq(9~F-fd`^EkCw(;1*Y^Fq0`h3bI<9Co z&1tT8+QxOx^@-jd)J-B5I6p1}E|4vU+~0np5N!XLf{AQtca3)R=_gsBSvpFBkQ82! z3O1GBVSSnD;H8Z(_O$Y?MH_w_QY-(j2-Q#*D46&3K8Y3R2GV?Ch!dI?&f+e73wS+{ zvf^+Z2M+2!zKL=p3v8jt`5Q0xeq+I&Kt-tDZ0S1=K!)OgF6q>zWu^P?;q2b>_pV#A z7SBZB*4fo)Rme~p=r;QAcHPNU9N=Y&Sn95LJruH=X-!w7!7IkhguZX*cUz>5Q%lfn z&kPZ)x)gy#OW!Bx<^c*{cuJRUb6{}$#ybMpRsnNAxxDx}GHxb?I^DdMUB$Q2%n>$& z@d*S&tBfn{ExW>CWCH_UF?xYuuh(_YwCP*ttpU=I}g^s{B z_IHUFPOVHMk!Vz#pva$=8^0NDfK_n@Y5uv0j&2IlR8QSOFU+K0Ln!`Bi4>tX+j|LkWGAEOgZ%n-Je z#7`lOg~twPh-o@5MCMj)231bXhGfLknAI7JTxSr(Ck+K==ZexS%+4y^uapFI8>gdK#cU=&KY#0YZpVLy>sPv?PL*LE|_CWbqgMOWHUW6Nc0=5;3@@UIGekigN zv<^ERx$`TV9CrFr2zX7d1xB%V&4l%8ygt_W-=~OmId!?!2R^`;b~&-3*z6GtO@)>& zea`=hS~(AgKHra#w!f$NCx0F*sfc?qtc3LaCXWEu>iu`PhdE)k{z8$3QOagHS3q4* zuCB<2%bhuaI*yLnF3B#o8Ht_WJCQ>vUkEJ%8;Pqkj@;1p;gpQagNB}r8XD#LN|bh! zZXdfNxljyoJ_yPPnYFBA>RPT7S+n;qP16r=y4;;ba_9^Fu@D^%Chq#}WbTOB04g)9 zxN05s%*X}=ex7mT zz7*nym-D%Brc1`%wqH&vdlA(e*j92U@uDTloKPHS}^pA*&UDw zrNeEK?vv?#eKSmDAmLCI<2mX0Re2?}Rzvc}a_&Lj_Z<3P9&*t?Sg%wWV&}r9S(Jx_ z{3+3@^+BBTbS4lLn+TMC)OIS6{lg28$3Mc-%~Mvy7)9<&sw+Irp7Hn!q3p zskRHBw^KSgM!P~0o3gKs22sBdTeu(YksXvL)bwJ4B!uGKNYal3KAHjt%S?0twYV)* zXSGc{Kxq7BEzWLp96X}wY_NVEr{66`_mP!YhYrQ+)p?3c&cS_H92_3(%QCk^5~ppI zBkzGAcx7)0vM(v%abcvBmVU#`aH7aWEZL78HD<7H*dG+!ic4NNlJ-ZgB1G|a3`hY4 zcG1zCQA6(xzfrFjw+u75ey)X3p(zwvny$f^qGM83;L0=_LB39nGSf;bwBnWJRZ+yL zFL>=-bRm52=sYJ8Jzej_cB7_|jOjiF;Q5Q=PVlH@&VQxyK;v}Lt`Jh4vWiafxnt8u{4@0yem{u%|Um-}e3)s;QkiB^v2C78%qv`@*^! zCTQd>{znFmeno|JykKoQ-Zy5-Xmp{g=Jf|U5$KUzAxaUbgLFtG=AWK~IEjt8%(!dD zwc_*+#GUb^MT;~-fZCh3G)pzB0FIT%kFF^LV|&D?XCjb{)80Nj;JcPk4HHKik*Uvu z7)yWL6=d4wB2co%tQz_x2xmE6vL8fttIhqI}%? z+Er=zKvyFt13NRC4Y{A1J_>`~?6gT6!!}`U(Pr-DU*ZF+iD+r!YpqWZ2t`cwSsl<# zXV-Ossv&ZSSPyxAV)CoYRa8=$lEW5k=*6ldiTh1OW2Rb}IPKR*i#0zT(h`;Jh$N|( z`aURXz}+Xrj5LQdmvL3bvv;kFC|tVKV=7Z)0C! zN!JiN@ZbL!H{4%J<|n2IZoeHdOf{8?-l{IJ=--U;~axRYVk_Vl4u10Q{ zs-UA3uo|=sLVF+B@I0<8$ne8kjN#h^SMa@g(2Ahz=l5Wd7YI^kY#DfUEz^3BrxhJn zRtY$@q#dz>*ZjRER()+K+?I%umG4q_Gus=UoH&Lq;@XZz(GpsCKQuy1J37@IJ>v6(U7IAqWn`JUY z_mt0AyV8r|03N}dC6{6TpNf4Su@br?*n{1|OdtBkzqg-<2Sh~6katfS(^v~>0H3Wm={X!R1|x&UG&#BLuHThaJw=$U*LtRP5-PI5d@}70 z7}|+`j-IpHt+we69bZYbJw8?`E7Opxub$fW!M|deVPIp+v~JU82UZ&kA---`rA2iV zrq_r@(#G4_#=n8c4u0N#YQw&((vm}wQ| zjIsxRMYNjyTJPP(9IU5^WW+@Hc*n*q(~j?~H~j)oy3dl}Y?2Dd;jaTy zRqT=EDuVGn97RrmfoQEr-i0}3$y8lq2sqV@%=4Do)(gxYVJgs1fV)kRfNhA)-Y;b3 zRb%55#9T(~?8ZjrzP2>_1#%E|BGmV{F$SPyfHWK>UNpp(Bh-dZ^WME$z*SQP9IL(F zd%EvOI9|!H(oxqxJYM*t@UQaEcPc6(0rVC!4Jca#Z~|*~VKIKZTO#YK?$@$LE@!fL zN9DaREb?brnr4lAxi0slpP~CtoU$xkDGVuhx1StJUCDID6o_LozGc|<&}cbo(9cGT-_#qVWwqD;e#O?hQETZPaTMuuk33?7a^nIkVD9x`Szt zVr1OPo|MWoPCiT&Do|lql>3d!$_5sTsp>Y!F81mme^l~+CwSb6bf=kIY@QaCg|<`B zXy1oyMki~}0>3$>Gbl*Z8bgd$8A^^`y_G2%m4dv`}YU4owM&B12^evIKEAdz-8(SdF3Sf3nc7)RI;vW+Qz4d7Yl= zI0g0b75(dE_*K0cGHPf5Te`7sef_E)#^YOSe3794q{#M#&HD)Eg=mymr_nY!%09lIUE8r((=rJ!k1)GdvRLDA7l3$v+6k(S+Z`1f7C zPlX)2;#Kb@_!hzhOkL|!j3NvBb6t1GCsZaKB@yO?rKgd{6)N*IujXwWU6=-KtYMy= z*tn=uncbkc_HRsL463as4Cs2^`s~z`HeE_I2HlhIsT3{%d=pzaN1wn%tO(udxOsYs zQwUnUnvy|%<-uQ~FO^Fep$a6q03L%b+aF(Kyp@x=diA?aomA$~zX&uwkk25zf&VqG z`(;XGP43oA%NX)dY5x`5xkHWvOAJS~hs@KSr{=L}N#Ey{z#3r1Q)s}5GdAa;Kx~)x zCMw4rwzALSK}2zpRfS@gC4BPBir{XedsEXWq@sDWUpmFrVjVA?=ILuKyTVMK+|p2W z)IW3cWHJauN~HE+%@wz0lM~Acar&KiGjIELSTqG0TG$N-9w>Vf{OGylj<$+5}2MG~_r%)~qx9@~xw z48XetFG$3vDKrJF70){2B6B(p`qlVA_ZIX|;yt~{jrvL%o4@u(x#l9=)yP4< zpQXTA&8E$DB7RguahANB8VnT!)r|FeF`2H!p{7t#-_JT=BPyqQ;>jE%3j-7vE@>SS zP7Q{uOZz@kd5Hm6wQ6Dr_so79`bNZI#!n;)&;+{%$5NeoGK98reBuF zxWdZ_M>u5t!ACe|T@WJGSV57~fC(uM;U{c-);QpAXP?}0s~gx6RRG3B3Z7a&hcRN= za~u0!&g)6R(?M20I-tU*@lR4VZ%W>w3lP&Rq z)2imUX!G#JLM_Qz(fEAfaD4Z(hN)?FOTP$g^&E!qLTYdclR*vJ*BX{XSx}S1jz_*W z9zidvGR)Y!KM-0-F|hnRZ-q(Gc9IXm?NZ*M6o|(Ng6RHMKz3jp%!no4N4fjJd@8jw z#^L0wT#x_C?{_X6QW3bH%aMyg|B3Ps0=SL|?XWUnj`3t;xv$t#9 z?rzCiRj~mWjYiQS`iuu^!(o{w-u?LYZ`-N1L~s!FnwIm3#@J=r9+#>%q~B@ZW-+9( zCZUUNEvtc@c{M)HlECWPV=`cd#XZWF&9xw-JYxfs&x6%pCx&GoSQ%#n?%3oC6fnTt zLu@hmU)6hJ| z^6Dq7ccFSMMy7mKX7p6qOVi4eh%}c?I!|NJko{r|a06l<%B=1%9AUcxqAUNZoNlw& z7zR2_!Tbju0rmPMFh=`_pYoH>B4Qn+J|anO+SAYXFM>TL^e~bH(yo|2wk>+|Id(3s z_#6CCkfWbY?QsXu$nuvz<6 zJ6m{vy)Z}sR{Xr3jlb`B>z23DXH#Llk4$?q=hZn_ZTAHmz?UQ_;1r0A$Cfj8t^=s= z3e08LHh98`b&Wk5o+c8>1&x*s$$v<;750|nS*+nhPd3%2!Fu_AJ$9a)nfJ&c9^}NmuaeJ_1k}$`i0VTXawiS}>?QuGoH_B4$*R+09NgNPgoG&F0r4IaNH- zHi~05dl77vgCz$J$~)42R?`qY2GHpIs>C|~*0fqqla2ihPb6l+zYncmZX+~|>7jD< z>^5*tZcwPD9Poh26T=de*4U*Ux3mB`XGvY_Ly9pyxIreSsvF^b6G&pfkbebdoy=`_ zdL8iJg2vJE{T_{W#{TRYj7(IUIm&|};CCvggbOFG=9pV|l~pr=9*sJ=-4LnjZnjU_ z@u7AK0rLTH%*LaN`Trod2=R~QE+dIXU!?$ZN#pN}GwbEe#L^ZUf($^D;zaeiMM_u6 z;z*ptq&;C8roK6_-1bnq9MC4_`r?%a8^_jc*1=sPqFkTandLxHN~*GowzE6CTDW-S zUE7a)f-(80WaPlsMRTw2#G#xVK(y!6Cm0WPg}1s#?$eh>cD#u3gh{W^M?(|X^at@4 zytBigC7aF`&qWF~56avF$+ylDd*mX}n1yz8{?p-Oq_2k9VXXD1(uQ)oKbMA(;I!Tt zn{pUbGPns$atrXGIm`10t%BP(gRyz21oQymDw*`gLRoRjNS@<|UY?-hHew^o&f1ev z-?b16<)qfDY9j>p6!rq`aIb#-3$_s|$NW#i!5W2%&~dil{kUCykZ+JApswz)q~W>h z^AP}aZn|G|{*G?G-uW%Lorvadlt)4Axu-wD+9p`d8cyjMwAsGw8hj+({HE9NY#J3E zU8JhWBihmG{Y?>8=W6WTk~R|S*9V*>R%hMVEmr69kid_dy2lNgn>(tmF&jHIZ6w2O zuP!g$UkTKy-)v|$p6nY#iuBgawKswCRK{-HlOGr466B#eo4>rbG3&cjYt(y25A^sn zt$|%cubFJmIUS@=Bxu{^6^8Rwcqq>1Ifex9ZCO5pErXkB4Wg2y_9mur%mxVFHYep3 z^V@loO-guNW1Qz*aG_W6q0PdPaSgriLXq`%Z9G989lFXH$c1{>J37tvb9Kic8Jn0F z^ftKDXT(F1wsUnc`K3P#;e$eVjaKdI9lq&R5@hCw%-enCR@wQ!53G)=eZgK|g(0nw z=%1-sEbl@elbb;HpNf#P_L!DfF)La&j|xsanq{1m^$e%fu~NW<6MwoaNUhe!JQIJUIa1y=jwP3J{m-S6>yON$B zo>zzy^u36d@jc`jh_M>W-6*tIEXVqqKnCI@Zn5vobMQqq6@bQ(t#95pr>k#7!u^Ib z-s*1Ol!A!mw3QZgmY2n9eaKa@R`|Hx<|pW!~^1=ZQfp2xCH=J{1zUK>4khbdoj%r8}M6WjY8CAT-tUzo|BA%X%M!S zdqXZTBR&iaof_a?4Zk0-+MjgoBLHTK%%_ zbOMfoLrHccE=aU6ZT}N|V3vV%@sc5sWvchO;NEh8Psj3(IFB^2yE%9$;VD{QoninJ zeISix&RfUvecw-n;5Z|Fzn@oPh-NGOoZdf5xGCAd?nGA^4a$8ls?xyDroZMH*!DM7 z%r*>PQ06=~c2t{czv5sv>IQgSZU+6(inZ6i))0YK9R2iX4YKtuAJ{&^mzgSJ%S4!@ zPftIS&FB5p>)376%mtdbia@>0p5C9U5&U`Jv#)yLF>xe0CKWbObt_aYqLe8w)aK?S z^WooBlq?k$LEH>Q-?XVI#!d?B6p3vv>lDYtbgF>wS7povKi&{d&(;Upq#NVo5421{ zk4l&_LHuyAy=lMdc_h_Os_9|dhxjS0AC^X(1m#=^e{(V1}lf!Li&q8dVRD{n|=18qqA0C=C>)-ZTv)p;*jG!khYiRe^d zrBZFrKF=Qdqu|t=+t+YAGuQu0!B{ZZiSj_S#W}(Jdb^lI#ipD!k|)PnuurejGVDLX zm74peeG`EoC@E0o>LS3GDzrSMko0Stc(17`g|HmmI$nQz)L}EIW2D+q2`c+$X1We)+uw4#@_oajiY!+_;t6kSF!H3m%L06Fn7LD=;EdR=(?O zob++5;+~T&VZ7&~WA>g+VLbV;G>bi#kx|D=*v`=gat}cDtlG?#%qnlH%u#o4F_E z2zz0W&a;s3aqduf(ohO#R4^MlQ4*rrIcLi>pWI%ITJ&g~@nTNY#aLW%Rp-64Wk;P7 zEYv{PK-d5;VwJsV$#2k?)2`eLu^lu~t^3`7u$o}B)4OS9Al{^UC2QO1Q6Es7K!0X8 zfFxJjAc8fRE+ycZ&t%U-%PP6~yKMtiEcTe_EG+V}vHi@;m9X%&u}lcVLb}0UI5@2w z8RcB}v^8hXr9%Iz_~Y~F8IVt{__km>*p?);X9wt6}JemsWpWukHonvNqu zFi1~iide4e_w>^uG8Y(V3G3 z=v|k1M4Y-K*SWl55r_`)t&`^Q21@1i=QU^M75Apc|Dn3FAPr1$4Rd4b`}vh7cn-{n zAPo#_JTx(esRl3((OV}WHgQA0u}d4a)94nyn*(JVqJB>@sq1O?`Mm>D0h0i7bo+iz zml3a-Pw;%|Q6K`mkj@I)?i>0}wR`%N#~Im^GqwAPI%j|oAKaK&wz{fm&{nH+i7I;q z;CJOizTfpjcx0b+D=&UHKlL`B}u4>$FBC1Qb3@` zH)X9;VmV60Ft8vgq05H`85wFhJw#(g6#q;t>$v*2RE)s)m7ruyhgGz2;ZePdK0`3m zc82Tr-dFypK8xbH5Djy@_K=;us_wkqhW8iN+ps7WzNB-k#@Rli5;N?+_xOzw$1F^v z@k3F~spw6EdK(<=3;1!o3C|eA8_8c1y)p(959rvqirzfpAO~PLR=rv2Vt9F=`Arrq z^SwazOeeArQ{$YijAX3OZu8Y?%qgeAx94_`SzK+&J{1v=QnbKaA3F2g3)m zSQ&X%S5+Cq^hytvO8QHY?+XS=yOwcYMbblvb9^UVWUP9kmC*zDy)xb#w{UWz$)6ip zN_&rzH(E4=ktM)nu?KAj3*2oT_}fzr?9?IKjh~xIblu| zGRhWZ+p9T58T-CsyNC>a31J9>WQPIv<*?hrDEQo6ff0ZjN+Jt1^9+uX_OXjnJk^OZ zvbwZhAO{AntOyST{^iKS!>TrK%d%IB4#96`o7efZ9QHS2;@AQK8h`uTe62eKf~H_D zo#;g8-##ya8gRN4$oU=whD8{F#iW5z6(V&fN)1tt#gB$_nFg^jow=@QJeNQ8z#GI3 zuZ&OaGttP{tQilBbm8`%hp6Z*t=k^T3nANr*l;neK?8pq+A3+t@3<35`-}KTc-2Wi z78BM@GYWxg-nwv*5t5d9Qfc7z-a(aVJf{ml-5{gEh8iEaWar2RTW>O2JEZ*|ae~{- zUcm+_HN$a5OjMqRHS(Z=zxJt1qRs z+D`Dj+8x3ezKel^Kwm6bGqj6I?DTZuqA-IksO@UT8&hKDJsm9q2YI#8^=(HQw)1Xd zMObg%4yoQConGL_)tfPp5!GKQ%!Vp$E-kL?JoTFL(hA0dQqNoTIg9owSRRQ`-<(Q@Evq`r`%DA|SWIc+7RaE&zF7XvWv&I%kc&fAjo z(&N|()|twS_f|RWZF6jMD4SJNz{Q{wEld4!6uqe=LB1Si>{C7)Fk<&C6sCa~a z__w&2MM<40eWl+qFBj-zyV5ORy7 z;j&Mqf%Yo;x=rtLf&J;2aj$lpA_=lgcY`5-a-?=NaZi?}lu z31Kffzpsm(v_*%qNb|whvA<}3k3iZ<+4{1g(Uzj?jRe|ctlFCOpLMElsLZ6a^G3@5 zw`wgt(6cU#0WP0c>o=avS;5zJT3-%Cx%z2qw&=VgE$XZu?K0?!{{RVVf)w!k}Oeu;05n@q-hOi#buod%FXhh&|06qUGdU^{~k#n`=-Al2n}^#-S*) zS=-}Qd^x|%Z=C2S8kigJm(2XrMePYRhY*QAsliAdN%|O+Ml_lxhI)-?_=v1E-eVfG zjf3EWvr<0n#u)~|YCIx2zo#ogd#UOTEwiW5SdE~JQ)m5-UK|G7m{3i98^mtiofLy- z{_6^nY`hnrNgdY{v{3EH0&jPw&+m%-`5oOYnznloFb8dPEsqIrYF?ovH%Cs}P!Li3 z4$~Df2UJfqJ4dA8F3~3^)!>$2jZLWb+AFc{sH!iZ#t4{#?bL^rBtbH$(N!`3UjVv5 zMZdEiidcyf1hy6o-rrD+nJU)8>g9PHD_Y8IcrjIaj_Qm~8vUfZO*K^vcHcFOS{l~E z;&gU&emD5BVSX;W780<@SI#9&!e!Qso-5+7+Q^9@lJwOg_Ugzdy*=~ zh^{RxrZhe(;MoRec6KE?GdArO4Bp>R%wn6iuzGnOhp=to7Tcf)t0T#5r8=$&=)Wom zBe_;zEU|%Yp4B3*Ju6Weu(4Y(cz;4Mi)q@z>f(728k=%dwJQ?tTHwexsMC2lCAiX_ zJU5u(RGbGB(|gQPdejQz3bWOq)w;llqnQCuQ8sd;%L2oQrjt=9Q9T}U9+e($*LLTU zLLA9)^2lrq-LSyOlX`0fK$LT>(s)izZosKqeljD9NP!M zD21w?K`SxXD|LAz3Pi2TqH!aNkN_Wr8m~?g6n{D2mt{bM*y&O2a0Err7_NL{f}aNm zkiS((0Fy#M4Kd+9QGcHbE3vZ&ot6m75Z4&*!fO1`*ciqj$>}b>ShEC~kVKWQCXz(7 zRPmU-e6xy}OpB<8CktyTm=#0$M4Mb-4oc4jtc3C&O)|~}$Zhgu6 z?Lqows*mhLFkT%-&uT}vlNULO#X~jwEb}H)XjE6A+2O7n)h>7))ozR&)uIJ4T;-^C z^rBmI+k@LAv9nrCqNJt;2fK!0hqZSDlLRM6VDQjhUm22hG9?yfE!C^mBgQGsjk6=4 zjWP3Lf9(-t2R!%fXvY!w-A)~kQRQQGTrsYjv5Oi0fPp3{`HbO7YdVr_;6!aEJP|Xt z=EwBN!Ry%xCvjU*kuFfQ8_TCt(AY$b2M~T>$;>5SV9vh@=+<8*#q3SzN#U9{6O)`{ zKOOR_r+F0}-So`*o{}W*@$}md;pxA9_~lc0p0j`U>v;NnJWa8lN^NSp`RCK^Rqr;= z?v{@p%L!kc4(_i3(N*uDx7)GleQS^CZ^hn^? znB`l?agD&dsW9QLZ_XeL6gm;7S#+aAxlb@Py%j8A33@No5O_eFeq-h*FYvAN+@kV5 zCWCLT+k$y{7>JxWA?XJ?iu(<6;w0Cp4a32Sou(KL28LXPq2|Cm^lIC}B)lEM`Z#kz zQi7vNU$GJ@d~>}J%*#W+)L#T|91aA9@qAi307F+8FWZ8pNPkH8z1%Q0nC?-=1g!!= zi8i^?^_&5&5FDB5l`r_p`{q&;3!~t84-Zc?G1liui(S3W)R%^N5e%pf+XxO~zPCF$ z%K&QnuAzJ?%sX)ri=785l_oCRyok+vw~O}dq4r3BmmBM|Ifm_RIB81LjlmrR837Iu z<&2c=FNnR7utWP9@d~V5gyfm4g)!xJ=8-rjjYN4Jy9B1ln|-8l9ue?bIpQGqm5px# zlW#)=%1WrG9LHoSi6=d9x)dX#iU!^ieInRZM7!MEX7Q|B-1|AI#rgm|27lv#{W_?r>s@fdNWbLlcv)F#AXnk8f2`=24Epu^4L&6Bs*8 z7kk^Hq29|aI@6MX@uR<+7m=wN3*ag$Gc@zV9(?_&Am|{i`eB?3ljh@J-Aiid~Djlis-m{8TP0C#c9f~oRRtj-RM3uFU)E_MH& zWCDk#-dTe+dFsZLr1$w3rZRsD2}M%soF7H>>Cy>eHm={vW?UvKPn+#HQC@eQPm`%t z8DFV-+q=+OR|&s8$h^9xi%jA~*Z8Z$AU;Dq_f07i={Y`RVhGH3CDLY<=$kMKh#r;` zA$%;z=>sQ2%6bi#k2_7cN^Z_Q9dvOuhrTLB*Y_c*Ht$Cx`hc$rqYsBXh;9B(Ml#R| zW&UJ`NkbIm+Li!wPy`FNGCk2GD9EQBy1)lTFsi>kG03MN(~>x)Gr7xbt6jXV&^HRx zFH3pfCDg5r_eCNd;k<)DxQUP&rfcS4`gXC;14eu;Xa&18X0t-aBhAMRC%!mkFkR3R zin2;%i9bTn6Z}IxcU^xElYLxMIuo!oF&;MN#0Ig=L+T=tjZT?Yhlx?MCgK&lP95Ln zX6t<|u|wy|P^V6u=IHUm<|y;6BWWuh0C`$4XNII`4bwQu4ndRhh_YVIDZn>bn>Ysn z;sM*iZ2&z=atp_oXD@%qN;V5vKZ|dSCX0-9WMR4lH%Zqr-Xuaki5#j#5=@M|u$$#3 z+sniZhOy64^RbGThg$FHV-B4MPoy26RmmxK$*L@lX zFqjL(FdWB0(@!xGDna0UhFjN5cN-HW=ajXeL#GC43%>cTb-fjS*E0(yl$fSmd6$mC zgc3)FPcdtmM!X?hy-UCwY-a(v|6n5A_50Lft+?t2<49aK0Sm)aD3KO4xk^X5We=Nh zl7|J@g`t9wWvhbqoMm_`C&E;L6ArgnLh;9kC>6f#ILlpv>BMbrZvkk=CfyP*B3{7@4NHY+UP(yY!=oKPaaRKjO z$Rl_A7@K6KQ}EDDpCNGBx9_k`Fo@+V?+Gf%E;bsLt3Z+9ztsSewvsX==KTN|;D<*c3BA)~Mo5_O9v*?@v2sJ~(%H2Yjj zqQ>hX3RC?`V2i5hDk0&jhF?}5L@Mq`*3q&pxU!g%hiwsBm=;wW#6ZPbQC+yJ!Z&fb zQQ}q!-tpfpR3^MMnY}$ov4ywFWhy9xCho3<8DaxQ6CJSLT&4lD_T(?y5AON!M z^+J7sDY_D&EZxTKuE9$+ZH&6?0$+?V)zskg_nHabDza#4CiIFtP|XB?6^E;;X~U+Q z7Djao!epIp!mvj2$_c&5#gzy{*CTB}((gIt1aD{Yx~WN^{?bht_Yt>xg1ht>UOgeW z7cmT`p3sTtl#j))ZuNw5`2zV6E~|Q4@X}8kV`&1rt`nl5%;~!oREu)NzZF!Aasky8 z6hwe#g(|2G_mz%MF{)l#R#5227_LNO1mkW&vI;r{btlX!;fJ;S#avb)t=U@inLu&GHG5<V!bP;7!0M@^{#zx)d+TBLqidAa zLQLvr^-^jRf&uJ-!W#+-vw=gFGb^F~Z#-AQFB;s7hDjTmNc`LA^P#GKE*DprOqnA-1R&7IBi7L3%Lsf-FJ3jWa{d3it2OP zm_>q=M7kd_YkWz)5f2ElMNSxzUyJkA!A`iTeUmir(wQ1cq0)uP%ijY`R|~r`$o9~M zi2fW48(sb$gzc5Me{Z^TvFZjdf6vBtsJ9|IN!>XN zwn|UV;e$vF+s5UwgN@DMgZtsS;^~P7Zo8}{?h%Z#P?^cT5$5l~7n<|l0JgoY!N>kx z`)F;jMC;P0vIdo&oVUji%h_WH_4O<&*$h(GznfwvaaN+JcSx7I#r);#=|z`M_4NQ2 z*{81upe(=U>$wwqImr^AiaB}&R4)%hRh0-_&?P9;xp|PQGYwb5I;}?Zf|r|TW5msa z7T8O5^Jr$z?dDk%L)|=x*rp+=ZXO+g`FQ+zbh7v6#N|~&u7|gn7NS~e{Ed-QLdHGD zy-YGta>F-7SJM)9CDhl1%$N>b%vc!fg+-J{tF+(#gs^`-_Dw!62w_=jHW+kxT zsf?W9s;@C_%<6_@w!A=?7;Q`|5{Nw4-0t?JBOYG*@s&_@sn-%r0!m?L_C_2mH4$yu zmf|iJSALxii+t7q-t#=KSwjMO)`S}B+m`c$6?yNLiiKHAl*!H`##z@E8;;GT2GJMY z?PLvCmNb6Lw9^!O&iIoIgu6hN8)xc6Kg_xvX`iGhr05@-vaq{pq$v>< z!FYEGX0dG|V6zOF+cAkVPgb;>q|hwLc_Z04ST^4)^iN`U;j8Jqj77k0vTJ~;VX{m<16|y@Z{LX@7K3} zd} z&)27ZO|qt=1syh!uF+lnXS?Lz&gK*1|HsGw`jK?6p(GulYXDuj?Y6!|3;ga__+LM* zzyJE1|M=l^h>Vf`jJUft=j%5=7U95y#Cd4T<0u)82<<-pNLnuQ&z~zjM!zeHt{)g;VX*u>pmc)%GtOC?Dr3}02_b$DZo{o{RbRtfA;VJU@ygN zNz@fp!@*?2N~|AQ{Z$k%7{??Gm`ZC-wx`cX--AC`S>4D@2vO-}Q||9J*3r{_;9C{r zso36{x7O>+X}^)Kx?}RzTbI0vOmcCO`Kb=2=v<0iQ9M97dfr0+8DiG2+r{GO3g0z+ zH<{L)d)XtnCYF=KADwgzWxg1RQiu;EDm_LaQ9JVdQ<`ca_6HK>(&^3Hgrs(;ngd*~tL=MErzT zRVU?81+V<_mp}jT&AyoJHY(lKB3krriH8zW3rA|1snochZaNb&%de=*l{}*(-%#z>_FW$)A5r zx|Ux4h)0yLo_Foi@3nFC9P_POp~uG4w0AzIulz-uZPu~hXP+;$2d@eLK9$G+*EK3G zhB#C1e;zT4Z}^{Vex7@AM~r`fx`RAp%m2?@$)9ai+@H!gfjYQLl{)DQwrabyRofSA z)%FEjwVZ9$J7XQrlop>pm(GpwX%jKGfp5_D%sv)GdOS);fk*f(<&#C&q} zi4Q4{V>nmj8=K?!xFD8vO~`8&)pj|V?^yJ@d-_f$t#-dODZa-4>b%as*#%rR=U@H2 z9MH~p?|$D7>a%NdA08|ZuXAJmdSicf`B`|w`PN|b*mdaeg)u%j7u})2K9zA!xF6kj z7Dca(CSG(>g8%)O7o$6$)?a;bxAfe+kLl-Mqu>7e-0=89yGum+BQHq_cP8|UtMjWz z7d>?;Kr;p!!LSCAwye^I~QFN=_m&+B>ed~YhT2Sn`b&|^4XKr}IbgD5I4DgdryqO!b z9_pc_TPyd$=vL+5U#*{?_X*6ucgHpR_|X{#fAhwduz=JNuh(L?Y`ewE9sIbqF30~W zW<#H*k6ZZMi5q&*j@fXTJ%sec#Fw*GT8w_vw*1WnRh+fsf(DE!vH5k?4e-Bz^--!b zcUI&F`C8mT;q|%g^(y{gds*ZK<#iI~Y!i}3wft~zesRer_ldu`?4&a)?$0nosb}BC zV$T2d3AwU!T9(44*9hU7%YpeXJ|WW>9t^zFi%3n$7Ye86p%DV!yl!WeKC!r#lHOPqZ7bAFd)iJ1FT|E% zYsPsq_WdVBJ*HXx@77;VPt7(F$yQpv)|jWQn)L6iyqtD^(E>|dT&zBLJ$xP3-^Hoy zzfKW2vl5;bNavU{t$w*Z!{zd2qx{=H+z#S@oTG#8TD~j%MgP-XFW!#xQTq9Ch=)b* zULT*egRQVX#G=cnp*wNKZMA+{OI>GN&u^FV;eWBGgJSaCLc~B&?{ao!@51rUdnT38p6gdgXvyQ<5<0DcuaMBy z@;LXo`(5gt-5ksF$&PwKwBvD1ljpaekc=(W)6Z8iO!($!MB}D1wu^L||Bh2mCpt~| zXg{EUspw`wvn6>KpoQvUY5ZH+qbTE3_$`_Qh7I4kVEU02$k*`1O zdAkhEcBFLjK7}dpO_lEL`@I!#F@Zlejro=r@2p+VbffnC*^V{*<;J@2o+7e!^$zzt z2+H==jtJHMJ4}^SSlh|*o67-QE1O?jmi^rq4_yLY6}vlf$?f`B)u=go%(W{aBde0 zZlj#G3+6StR7CcBJ6*8Yo!*Pbo#n=!#Pean#FpnWiMB7kxZ5y`gAaePC%cZ`$zV?` zjJUrUM*OyMNnSqK158hSQgpxEjs3=}N>Mnx2Bxy|cc1V=_h{p6FTH&wL47ro#z+x< ze>}$?=I9%9zNa5ws%@vtzg1_>>0{qtQs!zo5&amDpurh!cRd_a&Rf4Qwc%rc@U;Hy zm8kpXx2J1!T2K^`5T+L ztu^*trSCs6VNOAvSj%L>$;|kEPwzLkcl@NAa@P()Cj!o`dwD;~89$dX_?`nl(g_jW zgm_p+Y$%VK#ttrXy_m^&&g8orW}=ku?uBt4pG>`nc`U8siDPVvj{VLQQjINsRunrIwxx&4keE>&D8yF0Vb zDVWta0r3^N#L()Q+a^BaynE z3rAW-bdgGcO`lap>J8>3Qelq{ziF9v^b{9f6P;u)6gK_&*ZAJtVO8=L88@OXmB>lc ztWK_KfrbQ){1bj>%*p!WPe|I+Ldm<$+v8{d*S%DI5P=|M>ylXt{sgxllQ9lC8c(^1UP+hZK~NKKI-}6 z;%sM9tNK=dE&3!Uw*>uASDljD&0o42-aO9|w%jk)RLLh}{d6wqEpTP4``uARh4rL^ zP7BcewiHDB_R)kdCxr}W4&P|H5Vs3IX*y^J{_vsS!|iY?dM%sJ!u`9woH^RAZPv-~ z{l&v4utK-Kf5xH8YGQSUZM2O*3^T$z9Z!&QHl9?0*Mqdl#Y2omu!)!hv315{IDV$%& z++H|CUm!;Se?FyZ-J@lHYgn=k0HxmZ_j ze)?l5{PoGy<@V^3W>sQx{m|gAzUW2&;z1$K*Xoy|w)OPc*{s)5Z+A8;jx=_(@>{u4 z-dGm5f8~$v_Dx?Q?E$H~`qSVokLbm{&W~IWYGo2?6(MG)ihlsAT{%URYTsV1DA(SF z=WS^J-=C(T-$Oc`d0ihLI#c*%hYh?Z;6#hQe0e2tmaOwuUFQvPTk}^0zm(@Wzkcx8 z@dtMx@9<*D5nZ_6SpEEJu{GA_yLe9Vh#W5a%qnT?cR883Us}NLw*~JB3uMet372x3 z-q-+~ZwkDdn&)buVHy1mAJwHZ>2jqBK3d~GU&wnFm*cp+IT!8&@lKg>1U+hySqU6v7H$8XWxAIi}~OG3jwMT{bg=sb98cLVQmU!Ze(v_ zY6>wmH6Sn`Z(?c+GBYqTHwtBLWN%_>3Nbb@ATS_rVrmLJJTFXTZfA68ATc&FATS_O zFGgu>bY*fNFGg%(bY(0{p@qPsFC0l zmZe;M{`%Q+YFmjZNJ%Bt(5_szrf_QORn76VrmN52J^S_bc5|CrJJo#s8U1uxOUUv1 z{mpGYZQE9_zrCTGOI&KW{)Yda+p=AM;J>#J^7Tu<^gI9Q#m#Lvl~UrS_vgHZ>#urI zAN*2!(n_^2X&WC!e_!)<+SYRYH#g~&saEa!=Qp=h?G|&s{$>C1AL!D!;RT0Fd-*SW zO~2|@dEcdP?9zYv{J%f@`RC96@mZwj=Bs~uCXM{7zkL?kN(I-eoHx2OU%ewq+D@fQ z?w+NX%Kn-Z*Y%XfYr@t@l80-a>qEY|+_|B|t9+t2Md!-M2v=bXr@Wx-!j+|-yuMA# z&FBA1Ucqa;t?d-nvBoMHYV6l|jr|(0v0wB2i4~=PLtdq#@w}pCsp~1Wp`s?~746qp zMf){Y(SFSnD_WL(N}JSkozydiOe1@&r%Hx;`ZZopzsBq7*F3eJ)FB)F%M}fiiqarE zwK!H(B|}C18n38d;}!L59$nFNso9nAdJ-1~&jRRB#LoMwJucTe!b+jv< z(3aa0u1eibsRXIwq%G@`G9KJ3X_8*cevMVLUt{&`*F3SJmEN;%GCHp&qqDBtcB*Nt zs7i*4`ZZorzs4)-*F3eNYdwXaoj#fFqb5~JS=yfy2NVQ%Xwl= zTP6G8F!kfurZbCECB3E-rEe0ish9J#nkLe5jqe|7n#MLg*ZRl0pV#z!9k@Fy=kB3Z zMKy0x-%zmtlf|%70aezgU%mSH^@sN#UtRs?`sL4lbAwvDvS^w7s&rAe=m-<^_by>w)K-EyUdUK2E?zJciL zDzltW4D{hC2GoVj%_fp`!Yg4((n}iJF}F(pt}LNiBs{6m5J@6wrv>98a>GJG1yUo? zNQrm=OQ=ccQCRFYk)Wm|Kzqoup-AbaXrhYgw=RiHHtM=WZNEg3R19bGcq6%^ETLA5 z5vF$0MQ)*=$WJd7?J3t3vaIN}8dbDNIi8%!^H$@^+=Xupkitk2{{h* zD2y9^sSxOesr}Ha?6i@D<_nqc=oqU>5 zSu_brGNxpyv=~JxhiZ}Fl9B3IRDxUR)nw?cr1BablolCQYbE7~0RfLk1dU%PrDl(z z)(#jC^wLr$mJ|#JnuA)~7NLcyWBn#-?-gCtSoxA9lKZtGL_ls_2_mWJi(F}dB<|Qq zEuNqWF|1aRR8}N`?pmarH9##EHV{QX+7U{Znxk?BVc&(*IeF-Qcn1fV|4Esp#_{JK4!DM7fLxEJApmRA=Z%8b~A4RQ_U;?47 zc|?#Uc7p4?grW*FR=>cbL_w$QXHx>hC9H0UqV5KUgbY*=lm<+DtHRJnb+RYZ~moj&+liTYr{c*?M3 z_!=@YNXwOFu@RQGiea5MSgzcqsUfbC8;$ZTH?;yCLG5P?Cz=4Si8ZHHk&qfy+eBV7 zQ%BHGxzYoYN;1|rT9Sk6oJ^)o4q|1U!Z9$SK*3=3`L2a8is-S3NGJR1Ek|gabM7<(rBnGuyL;Vo5G=``Qnhj9R zWbiGj`DqbALqUzpuNBK16ruEPrZ&equx@4^&?9*r!0IbAKexc^Ti7^&!;*q=S70~< zZghGXC>JWumS2P|X?@GIxa#6i0`wy_4c#QaXI|YfVc9@Lpqy8?g=$r~!Uc9_9+d;a zjG2c(#&QG+49$SfEZTYnh9-=()dUzo=s8TqCXx-)f~?Ajbq*3qLC`Ei&Osy<>l-zB z(qUX+SHak$RWYliqQu;qDVaheh~`D!$fT2Zs2bI#2_ti}AY=;Dm`3xWlEVIOqdpZI zqQKHbi;`worFCFw;>DX96_qSawv`tfBo&QPQ1GJawk~YRP{CQ%S%s;YWEBw&OvV_m zaAcFnVpOrtV&D6@ZcVjsrMZO_E>R1KrB`8RW>$&(D@;IWC{p3l;1xzDv|;3> z91<9rSi!UQK&8^KzI7#5VPnEpB@H7Apu)z)lc`RdJek@X>sy3nDUZTWSX`-`%!8)F z$b&lDS|;%anLvZ-5PWulwtB_iL2(Gpkb6|r#9VRQ+i zLeexF<~imv4M#C~HnK7k<}x&a+_bWROdXfhoY`P!;^D>guEm+Q>UY7;q)S4!N71+p zJQ_{Y@odACq9scd(w5mCCM7|wR78?bJ8ivDN034vBV*Jk{F-pEq+r;cyxdmxMmE@; zm~}R;Hui1B@(}A}gV|Zc-xDpn(Ic?9(W0;V8`Gq)shnkwJwKD7La;{Z@rjg*6hyDg z>s_(ct&t_jj!t7+h9w&>1UcAB+Nf`^-eHN51*O3p#cGdt=PqtAM^_B?MRi+SxqS*& zczO3meY3#Ll97z@0p|^Is6}ppHHuj!_Ag5cF9S5aR2etw8JJ~cZ-_2t>ua~THPVBT zmmo8ZFtK@YGyk&{4z(0`VNwc>7hc+ysH+0}&J2x7ji~j9Jvxr-MlH@u8_nx1H?=5B z8*F@e66{foB)W^WO#&ZI zr0B|4pu8Y~J&Gkfs#6$Yp#*45nB9>ju+e8?=ZCqGMvWe?PU6|z>n4?&ZX-Qk97?`6d z2X?)@IJG*vZd-E+Jm&%rZk5O{a!oMaFP+iG&w))4TL* z<)sbp9pr+>dRzVAh{+gu{aj@kjw|fTBqp9T_X_h5O+^-C6bbB0IJr&ygNU#MoSZ=2 zDHDTyV_w?Uq={IPWM0}LJJArpyv(drWD$+fl33Xi-7NJ(*aRzEDnaynT=8-e%vt4k zHaogPiwGc9tf57njtI0tTpSxhYmvxYY{8xl<1)Z8vM~<+cSsn%Zl7~pMf?;1`G*Wfg;*40zLz8eGdrl>8xx)64HjdQl zw2smEED}znOW2O&QK64Y9N`#LR?HkmBt>kKEW*Nsa`d+<5}ZQ}OpAem$&o=dW@$|c z5->qfP422}LDS+=tSw++a`#nU9-kjY?;zlIqG6E4bcyI}tYVo|^eXM%vSjM1Lphv4 zE_NKHDSy`Z%M&q0wIusIE~E4lqF&ZuV3CAhAcdquxTJA zVnVUbr%K4gPolzj6(~{;OwS-uG?~MxjzQdrn&X`id6eY_vk;au0?7K_u+`xXV$l;p zX4^RgDY7+*3o{()k-cYGnR7JpkVL=dz{kVu!3>3^pYrV{I z37lwK?zurc_phYr~=F| zClTXYblPQ!sL>lV9YwiGJ_GJ6n@ACXMFdOm-ZGyHdUciHjZDN6I5baAP8R)FU`;}= zY9y29H|HZbfNPQ}q5mbQ0-{cnY(}v$Qlext)-|djQ(#Xb(vO8DibN9{X%Rn&mJLa0 zESoKNMN9-%9rCEcgMkcHGfD~uF9rpII&u@5e;ub7f^Ja!2y{ldhK5Jt+)0wIq8^dO zEGB!;O%fV?r7Ex}p-SjoWWJOp2@SNqyk}iFp@El^XV--ru9VG&XeDh`Ijp0}+22a22Ut^j_2`O9a2f;eToZSp+xOlskR6VU>W{ zQzU3ig2JmAt;6z~+seiRvwE9KI26a>5_VZ5mf4nvFdIoY7~ie!EwTPDV0omqwxkJ- zw(3&P)|gzv9lnuGSvb^NbzpC>DWUXf)=CRQjj#unGzmfy4#bsJ5-*UzrVL`Ev)}go zO!f{E4$hI8v#I{wXi10WN32kE!v<56Q>GeNi(s4ZqR{M3p5G+TfrO8ki4E2!$1->l zvZU~G7FUgl(5f9cZbA#Dj)E2>Ko^m<=*jHTutfq%l0?Uv%{f7SHE4uUERmKa(}8A}9&cGv9bwUsR7BK^qbizfBEcpO zjO8`RXyLqLfzPDXg{{e!c~Xx6W)x>Sa?wfNwyG)9RcB0tvB_3!)N#=yJU|Um#X}_v zhvQELIR;*FNg}BZ`16}w6C~9E30vX`0ba3~v-Dn2T@mMFQ7BEe;ru$@l&BZ}c+Cv`dQ^ zXufbKj8kD- zRxWW!PoyCCb3}*xGw}ckGGgGez}9*mct>)uSluX@9FfQR5u1(ZZLNo_CMy&r@^2VS*hB={v z#KC@=(PHM1gu`zc>0)hV7?+$_*pw_VC^F&QbREUe3kec%q7ufF-rWcRvRf19kVUPS!{{ERcgj00a)L7 z@JO~TqDZbx71I8f|L`|gAHRS9?b}x$zxsIf`m4KdUwz{!(yy}nv8T8%PNoIq+d%P@5U3D>U58wr7gJYbMgl|VvNx9kuk zl-E?k2ol1)k_=V^so(*Uw=x6?50FfOAxMb)N}9?LB&?ajVJL!BdCg=26G#6QfDS7B1oISZpI%W6{WZl<44GFNygszBV;IKOdEfMgxj7!+Auza#Zmr<-6FY5 z`6FZvg(Wlo$lXWdkE*1I?>c}~b1;<10Hn0o!wo=+i>7BCKteECupa}Eg7HPd9|gsE zoIjF0{apu;=q)v2YXlOE7a5#JAi>|4q?I8^MNF2vjvy6U%j8i?Ai?^R{I?NEB}(wm z0Hjh@4fQ#IM9!HGR|Aj=(tv{eD1Zd&MUvY}Ady47Y3nJ0RKO$1urdNEV-*&O5=d@N zJAnieLI58IkV-C=6*K@Tmqkeh1CVmg%6J)olvC3LnF2@!G=~f=1CVmGWVHfFIVzH7 z{1L)z`cBFpxkKRm5yEwG#~*P>4}y*#*-JWVWcKy*gKXX5M~g-s96v(HQA<+%D2bnR z*YP93I70U*ePkI1hmTUV#&P(lY7W=oBZN$4!W(>)K+_10r0|gkq#Zu;n32Iph}Q}N zXYdhj7QK<+o)@7nl_L_?s3g(31{$GGvi2!xH1LH28kH2)1$59T#bUILf<_2RryXeI z;XVV67*`PDOF<(J*+`QcXyid{2aS;C*~T3+H19O(ZlqB`7ut>)A&n4hR}@M~qa-u% z&Pk*0WEp8x$ZOMCucXnC-B!|wBuN=vC5=jw>3`QrBl3go=>i*(gKZC2*vOI+&Ki-w zuLH+eBRJ8b-HbKr)S9wJB}(|@&RHW)RxQdFL01Z~B7lv;MwoDl7Ab5Lw`$~$!bV7p z2sR|F5eYQDZ>$kXk`5GQjUbTq+E^n@cA3)38j(b@Vul(Oq+~?fDQd(LC4v++ikndf ziW-qStf3%7jaZ^BQFX&-HELX0qXJ!|=##KUEYa2y)@Ucm{8rS3vQQaoH7OB4(0?`>F6Z!N`w zc9JZ?Ad(n5)Fc?>t*%(m&@+MsjRL`fhVE1>h`U@E8=-=RF`!h?Fiw;T+DTxUu|SC= zp@N3tW>gSHM5eBG_ePe(i5zEOKpiv?WP@h9a_ly$3 zdmzcW!X0Gq2Fk{+a>}Ncq?FAl5Xz=k$S9jpB9u*kF~e*IiEuVUYba;an@}*D@pq78eAOYd^!TZVC>e9JK2jBoK#YJ7{2edk+zRyp5-wNqFE=UWgS78b++m#rELqJRq) zZh4aOEwLHyq=Z%K>Vtj@Qj zB`PdtfD0f9!66KANlUed3*gd?E(cuPFmu3#NePt*;F82yx^uv#fSnLJL--c56IUf0 zly4alg37ma3sm_QGE;&kWR!0qNz&Aw@+~Bh?J0)06d3lBQB}N!jc6@K@Rq{7g*=Jz zmTrhU-jcGKPmZ@FNebO{yd}}KZHKqOQwTe}1>S^YjvZ#HSu;Hbvp7BS{7m+)11{h) zB$H@>3%HC$krx46;3X}JyeQ$aED9ew;j-u^uuixH&A4^I#WbD)F7Ev~;F8y7yo~}b zKnf&DsDR6WXB2SBRcUJnT)=wBCCazttr`P^X_cFX44iL) z+pZvu@+}}C_IwM-2N~-IxPWue`YPj6(yG9xF)j$KOD5D97Z}D$qA26yc`;{P3VKuS zQpTk;YYAgqd;^y=F0fW5Cuocdviib$IO769QtmRyMOI29Tzuo05iXr4Fv6u``4^x? z2^S;+^vR020L>MBVu*`Jqa1OmO_O~C;$j_Th)au#UpV5jZK~c3ap~1D#HAwsyhB_% z0%3?t%^FiT#>Mx?Ipcyb*Qyd>T+p725-k!gM{hg{&V8}=fQ3kIH&ItsaD0lu7Y*^1%?PPkb3&Iy;i zMb)cDxFB}0D$gQ>3m@Pl*9hU_`{SH&fg)4jMhO>>3p(KfiA-@LT(U%q?wnQ`B}%Id zcPXthl&rXlt5Ks>Izy+l3Tmt3U!|97^79t!CCngiHhfDwxiK1eOMT+lACF5qg8U#ox4t} zV0ejDV6;kKX$)7vn3R!WxC)3V1xsRDn?)$uY!$e!W0;&)IlytfUr=gi&H8(cFtWV#TR`BUVb< z)Xp+ur6By>goQ~O2)DSr6D!!Vt9*(QE7%>NP-ulW$_FV%pcRs+YwXYp%wQF0Bs}TRHe|(v_l~R}c;8ea$O?R(qJ#>N zmA=c{kd+?IH)N%6J~U*dAW70jWTksxhOG4Xz9B2{+papV(sy+jufpMefijd=VQ)~z zjq)m-0FbGuyb4KdRw=JS5az!8!;F1!k- z5d<7kUZp1%j92NNvGFP_VPDI5l~E$R3a2CFN!%%xoG@IajGa|f9YK_?10)cFyK8WF zcMlreA;JCN?k)-L?(PJ4cXtl%?tVCjVP+m?t$XKTUb^?{uCABv>c7_BRo^d{9bMty zDVm%!shJnvY#~rBv2?-^afu(UL5HtbRSK%ifJKI%Qp%~HWQ3-!@Jd~ ziUstGSfT@U(%FRDL`{dOHIF2ndih^R>ZlEx(Bd9Rba>JHN9uGeM0xayngNqEmZW>? zR*nCvZs>e9qIT$H=Hx1u6(<}@CKM+E#=mRR@w1l5(j8Rir0xOn-UbM@O5&SpF`Puy zPvll3cv)`u@da5+?2-jF4MOx;icHJV4-XUZYE^zcG3~|iGW_U=;^hwr{vK-dS!pMX zUW(lPn_M6?{hty<=HJx&+ma!zu`rG^df$FOL-9`89>eo?8lMLf-q)DOf1F6DeZ`PN zOHGzO;(b4CK@@4lk&`ggRd`-bTUWE_>{wM*4l4<$Bzz>JMmi}$B$Ml&LMsUqr^yC-?PNXEE6CtmX#E5@i=XgO-3)0Y8`uUrpk}i z=w?>gFDHW7xP|CdP(&(q+dH4iN>2`B$E+CFXtDU$^Hk}6#K5u1m^Lz~hp8<%o+ZlG z{;R^E6$LLInb*guu(p3RllXK{Nm8K3rstYe`eBQ{UnlOETzVw7?j)nA>Q?MTSGD$= zf2fQ@mn>7&64r*NWG+x^ZK_NQwbh9(V-od9t;vcf+JP?PFM_oCn+2D&`ox5rnyKn^ zSpl7TkTj8cnN^mHT2Z;%qH@ydN?0BpCkUP=vV6fLY!$a$<${J>TD=@uj#|AuflR90 zKN|~uKqhG}x-gOiyi*tnBd%DkWt5vhHyDBbU46pqq)^sjNJ0k7Ub_AlUK#XgJwJ8{ z3G?q#Svpxays}+`xP*`2zh(XS|Fhn3vuQ*HB0=8Ft-(`9ebn6YgXLdLc+fH*LZjW z5uH-TGYVf6I)XUxJN4urXi-^D&4&cDf85|)yes?fvQiPKls>7r%5!L3-(_F7+42ix zgulyvj5qVoG!6kb6h4^rN^@{+Hx#innt1|0a)@CQMaYNJp(uS+@P4w%;?nfW>kS*5 zg|=FXM3B&Ki;U9HMn0_)a_4_WucP`)bCNC^5wA=t0Z(D1i>nMBku6XlF-jBnL6k$k z#V~=5ASN^ZvwO$B+PpD#Tkk`Fgc)6OOntnXlY zhB-)s7TE`IBsGeqL7lytyAySdC*KJve@x5y$|iF!foh0+E)lDozwnvD(Jo931657% zyF_k;X#Pxa%?E_qeSa)3BKwBZ;^T3S9qV*)44*KsmEBrIJ`Sje!Yicop54~VTzHg9 zUXGowmEssOaaMDNxe>nU0iqaPj{F<}gZk*munHpiYJp-HEb#T&82KfEHs5?7RYfOa zk4pkEhiT5WPR_nD}ISOfXd$O=7`vv<;o>GlRKsu;G5@*l@Zu2_D~-(2b? zROhwDiV7U#g}j`iPAbO;1yt+#PFCd16|Cs!e%Gj#su0k;ZJ9Vt(N=IuvsCIsVP zJyiaTp)z=6XhPatV<6IMK=v8?(~2 zQu;?pYjO83O;D#sqeSu|EE3i}4z=N;7?jx36ra4n<3KVJFUQi(gQt6Wszt>w@?c&b6$x$L`Aw%h&f0l z6_Jg&%l$G+YEYYlXykxBOyvp2%s8(3wemR@7H=R_A(xgy$z~<^V#L8JP=k0w9Q^ZRcTHZ-9cmRG&e9o%db#4nvsWBEycm-ctp#m#&ekDD`|>TZEw*! zI*A))=vV`y9g(|qeuGYcBas5fZerr|5$TsG-%4a8% zQs5|<%}lpnJX{E-e$Gm_fSp=tB^5MfgbPBn2q#8ltN$FT(_-MVV8lMNq8v3vfooNF zQu9q`rAAg8H)e$vp}&yNYzKXq!KTlxG+&NSjf^f=9E)yM6ic$Jjza{?H%A<+n2#_I zmm>0~jT9=s7^_TVjcUIAe_!FT+xt40j2VO;Z1k*-_KjMeFps4^_dDiP5sw&IZ$&#) z-gU?#>bE`p%v}5OVfb&uo*zNwM_|~Om0OBmboE)X@q2J)?s0Aq8m9X3=Z~eSt*Vyr zK+TrZA9&G9pT+SBbABSN-M}}93z8q6W6Fh6 z=CPy{Q@xf)BMv)4;xH6qD$lNi_t=q@II>ix6jPg5S0l_4CRX9^l==B*34tuGeFDHK zMUF4m{QSQm_F>dA`Gmo}7`Cj)Vmt6o75oCfUxJX8Y%VymA6UO(X4%Wg$V5OY;?P}v zSMJQaH5_-KKHSxJx?=B7YKF--JLhn5g=0$$IeSaA5BTf4TLNzIlMA<$i;|hZdu5L| z%S-vb)X5X~XPVs20uxRC(-Ui3N)$yWlIb^|51{wRV2j!GnjBCnj7FBMf2zQ*R6U!;P3{}Qlne@lFwLO-ie8_8+qA+j zi>`wN)s~zEJDvoTe_RP1^ypi0->xrUsdsD|XC|LZm4Ve5i-GsFCsAk9@{bT$5V9!Q zaSX8Dq#WRnKXLGC2pAdir3#}_^twLm(h}pq4wu*1pyTM}??1c>n4v`UzIw+rG zz=J?kvhh3|wek!fyZw&+-e=D4b=%d_e{mb{{0v#D7J5Hun0~*jsS!@e6OU>^*3NcZ z_=g7PKhN@tQu-)coH_aRO`ktmqvwpjEfG5+mS6*`#Yn*`gV|@6nJDya=C`=EIf>sP ziST`&C)WO?#Rh?aEsUj7O|kK55)K0nT>V98MV&`oT;OtrpASq}x<;+`sFpG|+u!>& zV@_ns@9nIKZ_J>0AVlRpRVm1?Ut;h@(4mC%a)<=bD^|HMZg>eoi1HxFu%FA}MWj1z z7nIzUW@Jk4#Ky_ zJI~QW8ca2C-lCRw2xi7mddj!NK=j-S4mh9H&NPuhm#;EobEI+ zgT9ay3qzW=9#iU1mEQ|2?Ofn)7{&RTCdz))&(!BB{iugdyO&H!S5Uoem8wI34qO;Q zht-E5Uq~OC;+x&uh+s)U^6p?lDTJT&T**PS2 zxncJD9V7_yRjI2(>k@_9f9q#ZC3qNCb$P`=B=v5kk?E^y$vZ5`B6|yUIGq?3e5eSgN-G8UO?;(X(3CW*r>>}=lFjRIA`H;o+a_gss zK5U;23+xP6@{x0X*v7mcK+2`IG<*oHzW5I61TCQJ8>T4tlk}Mmo-%p8Cwz=4>XDl9=sI4AMCf$3L`*95EEqk^e zOx?d$BSy_`cSo=(+FBOuLi(MNyuww7(AsS=yP9&RD5Y)nck^K0Cx{vaT(_A}C71-j z9viNgz^(+?pkLuGH^b!fzvvzgYQs{x215!VXPcb5bpb+^IQs0w*iRwu-aZFo%f=n> zCv_tlm)`~wlMj@_vh8}|zj(g%Zt=4_!CAwH_9IkYuUP%l|H{^R%DJLVWdLkX<7Hjg zjw-`yY@Tkv_^d`X`0(0b0CN>^5%|ExS5F8Wdm}pWA%s@qgRQaJ{xvs2Br(krNKB30 zlIC!{XWEG>=Pmf~3$|Nom`MFtj38^$jj6XF4j7Vt@hzbkc>87fsQt3v8Q|<39*Xm- z#QmVw-1c`G%MH#y-ksmB!>9F0Jy!Rz+5dXHfJ*?jV2Z%yI&*^GKWlYKna_=m$tozx z$xdG%8Q*B8_-Y`g)TDk(q5TN_?~U0k=Ji!<-^ZO11Zt&6f0}fejn@Q$`dL`-U(UV< zNv>S0ouLph>}t0erDU{6HRK}jtJZ!RT_(Wn^Qu}}Vk+PA5-{+N1roo)Apqr*2?s92 z7EfGLidPP(uIIhkuEM_ZYjGe!Y)9Z$_O-^pWSuY*5a)vRngwJ}e$bh>7b*$#)+5Iy z%b_tkXsHqq^KSd^br19R&I(m9WggrWSasRoJiO|95V#w@n@tGVGN$<0_}5nOk@QixI)8}A@# z-Y#{fQSA~-KEe^~66=^m@x+%LllMxJJI2s>kG3k^&HN1$FEU-zT%#VHifMQy~Gi|=F+iqi&;WA*0J!k*a}o_-1co`g3@jWc-d0e+Xw9VhU! z&EVmN^@=0=muYaZN3wGx=E>IgCgLB{%d@`c@F{?zbS)VR_pxtU6Ln@JphgprX@lW-q;+C|TUePJ}2SH^=hoI-uE3;;lfJ>A^v})r|U{w?!Rwl09 zsReH`8i6;S73?7O`AI}Kx~7|Il=Sh6hgZKR=r)p#$%fxZZ=OaC`tKwzKjvLm+cjeD zJ72x(GMrI*C076h4rmo`8iz6KjcJI@oL3j-B*9Lb`{xSGUhCpBJ{Ipgoo$v67tZ0n z0Lw*Z4iVPSInS7^FjobfTYK?AKet0sE2yAFE8=~GDLsw@b(VXlb)2Yf&DWF3e`iAS zwo=xGYOaU(KucR!CF2zJ&A9pZ3IbT8G!GY<`Q8fXg%!c9{x3moczOdthod|t zz63BqD_dz6NhBA*5-g_dk3MYS)bk*~M7dsu{eQ_tD z#sjwYUk1}GH{B}_sg37kL|+(}rl^Nn&8<*Y&Pw$gV@~Z9^~&O*NLoU(x3QI|mkQAL zJGtuMYDfy>YHx~)j8T6^y?Pe&g|Yg4rJ<^)NP+o5uJ65S*yOOOzPoJBPWyO&(VMs2 zR`_$+e~v$b*9N5Q&HFRNXIHNMI(jn?$g@B7U0YnJTQlnel^akPH6NS=<}B6QmNpCTeEROv5$b`Sl-TeWip1y-AgO=`YdSbM$d9Z%>7)MA%^Wa;_xrG z>jY;)9R(k;WO6`%;zXRe@+?U72V%LgMVjx4z)rxSj!3k%(~OCXaj6Y%;E@%oa92{P z=3-FP?ubyzfNCwvv11k?MdN;&3FryG9+_=Gbi-S!(dQeT7I zutuY3xCWAg@XerwPOWAU+-RK(-#jUyY}T0>63ZoHDSOm*eOq6H{j=CAGT*nYoQ^Qp zy$q|a+}bdbr{7A6I&Idq=Z9~CZ7*M2>vv-MPG`%-jDtO6)CU3QP6JPJGpq`^@$;ze@?jK$0yw8%AASq#+ms01AB80($tk!-pdy)ULa}esA^9|n&ej(aT*n8%a zoJyqBbPeT9uUDhLT2CAJ!u4@j}4g z$MCW}N|Iv5RizC5$IcK0d{>K(RyfZy&nFbsd54svBo8dNPon}QZ^gpR({+Fn?1Ng* z&e=HZ@$Z}z$f1S&M~8dAc)X!Uy;nK!&-NyA$d-7Fi#9QQ<{_ySl~3jgtWA5!R8G<) zN$S`z!AcwaFnc74Sj$YQy2t&hrh6D-a-GeGl^1$Hh*;1e*Ya!Hx$Hiy7TBrju4SPr zvDrTC>Q3UNwn99YtSDceYFpOvr7IlEpHaLH?yH$&tb6K=#D$}!Mt)w8Ti!hsiTr# zD-CaSp^j`zX|AWW+0tsh$rE+rvPB11rhnsP;%(9z zQFm#6o!vIwEF`#N!UdT(rcN*R7l!FB$;9Yp5%l1CTO9YM7maKmat0=z3ziFUA-JeF z;@A_i&87?PHj`9hoXe&Yn??VB=Tw=bHX4bxKAz4rFvSfbUf%JhXT@c-hn%)3oW5G> z*;O5xPJ&v(vO+{h@Id)H%;8ulT(#%n&K(cL+1rTi=2Qa|Cqi@V>zI)7ZT~c-3(~TB z#rr#BxB?!sH3w{lvC7uj__s-8$i7MH@Eur%EJ+CG*IAztB zLmGan^i%65HbkkQFOCT?@gDcz<4(*(*Jn(z(S|GBEagbTd8%Gvbl73983<(*;u_h?A$ zAAvuhiu?UX3K@$+?tO!MsI=j|fwN$aVuWL=1+Re)vKhw357yT(E&nb@0W;J6n2y

DUQI#oWMmmb$c_X1i3=j9*Yox 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ΞC&*Q=SxkgptYm-!@=$ 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 ZSRUWWpN~w3Qo-Q`OeR5D*}%+@@PB+?|H1$O literal 415934 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%0Aq!lAV*c?&L6uWc`U2t6!hG$;Eb@V9 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�!Kd|ha=V01EX$(YBUi`9QSN9~tC7+jh&+5QaK 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%0Dx^r)x10N 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%0D+Po}ZZ`EhoDGG~EF;@d-qAP|MsR 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 diff --git a/libs/speex/include/speex/Makefile.am b/libs/speex/include/speex/Makefile.am index f7b65faf58..2ae34f9f80 100644 --- a/libs/speex/include/speex/Makefile.am +++ b/libs/speex/include/speex/Makefile.am @@ -3,13 +3,7 @@ nodist_pkginclude_HEADERS = speex_config_types.h -pkginclude_HEADERS = speex.h \ - speex_types.h \ - speex_bits.h \ - speex_header.h \ - speex_callbacks.h \ - speex_stereo.h \ - speex_preprocess.h \ - speex_jitter.h \ - speex_echo.h +pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \ + speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \ + speex_stereo.h speex_types.h diff --git a/libs/speex/include/speex/speex.h b/libs/speex/include/speex/speex.h index 7f8afa6062..82ba016237 100644 --- a/libs/speex/include/speex/speex.h +++ b/libs/speex/include/speex/speex.h @@ -35,6 +35,10 @@ #ifndef SPEEX_H #define SPEEX_H +/** @defgroup Codec Speex encoder and decoder + * This is the Speex codec itself. + * @{ + */ #include "speex/speex_bits.h" #include "speex/speex_types.h" @@ -151,19 +155,9 @@ extern "C" { /** Get status of input/output high-pass filtering */ #define SPEEX_GET_HIGHPASS 45 -/* Used internally, NOT TO BE USED in applications */ -/** Used internally*/ -#define SPEEX_GET_PI_GAIN 100 -/** Used internally*/ -#define SPEEX_GET_EXC 101 -/** Used internally*/ -#define SPEEX_GET_INNOV 102 -/** Used internally*/ -#define SPEEX_GET_DTX_STATUS 103 -/** Used internally*/ -#define SPEEX_SET_INNOVATION_SAVE 104 -/** Used internally*/ -#define SPEEX_SET_WIDEBAND 105 +/** Get "activity level" of the last decoded frame, i.e. + how much damage we cause if we remove the frame */ +#define SPEEX_GET_ACTIVITY 47 /* Preserving compatibility:*/ @@ -218,11 +212,6 @@ extern "C" { /** modeID for the defined ultra-wideband mode */ #define SPEEX_MODEID_UWB 2 -#ifdef EPIC_48K -/** modeID for the Epic 48K mode */ -#define SPEEX_MODEID_NB_48K 1000 -#endif - struct SpeexMode; @@ -307,7 +296,7 @@ typedef struct SpeexMode { * encode, you need one state per channel. * * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) - * @return A newly created encoder + * @return A newly created encoder state or NULL if state allocation fails */ void *speex_encoder_init(const SpeexMode *mode); @@ -318,7 +307,9 @@ void speex_encoder_destroy(void *state); /** Uses an existing encoder state to encode one frame of speech pointed to by "in". The encoded bit-stream is saved in "bits". @param state Encoder state - @param in Frame that will be encoded with a +-2^15 range + @param in Frame that will be encoded with a +-2^15 range. This data MAY be + overwritten by the encoder and should be considered uninitialised + after the call. @param bits Bit-stream where the data will be written @return 0 if frame needs not be transmitted (DTX only), 1 otherwise */ @@ -338,7 +329,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits); * @param state Encoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 if no error, -1 if request in unknown + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_encoder_ctl(void *state, int request, void *ptr); @@ -349,7 +340,7 @@ int speex_encoder_ctl(void *state, int request, void *ptr); * decode, you need one state per channel. * * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) - * @return A newly created decoder state + * @return A newly created decoder state or NULL if state allocation fails */ void *speex_decoder_init(const SpeexMode *mode); @@ -384,7 +375,7 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out); * @param state Decoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 if no error, -1 if request in unknown + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_decoder_ctl(void *state, int request, void *ptr); @@ -394,12 +385,14 @@ int speex_decoder_ctl(void *state, int request, void *ptr); * @param mode Speex mode * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_mode_query(const SpeexMode *mode, int request, void *ptr); /** Functions for controlling the behavior of libspeex * @param request ioctl-type request (one of the SPEEX_LIB_* macros) * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_lib_ctl(int request, void *ptr); @@ -412,20 +405,20 @@ extern const SpeexMode speex_wb_mode; /** Default "ultra-wideband" mode */ extern const SpeexMode speex_uwb_mode; -#ifdef EPIC_48K -/** 4.8 kbps narrowband mode */ -extern const SpeexMode speex_nb_48k_mode; -#endif - /** List of all modes available */ extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES]; /** Obtain one of the modes available */ const SpeexMode * speex_lib_get_mode (int mode); +#ifndef WIN32 +/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */ +#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode)) +#endif + #ifdef __cplusplus } #endif - +/** @}*/ #endif diff --git a/libs/speex/include/speex/speex_bits.h b/libs/speex/include/speex/speex_bits.h index b77202fde2..a26fb4ce0c 100644 --- a/libs/speex/include/speex/speex_bits.h +++ b/libs/speex/include/speex/speex_bits.h @@ -35,6 +35,11 @@ #ifndef BITS_H #define BITS_H +/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations + * This is the structure that holds the bit-stream when encoding or decoding + * with Speex. It allows some manipulations as well. + * @{ + */ #ifdef __cplusplus extern "C" { @@ -59,6 +64,9 @@ void speex_bits_init(SpeexBits *bits); /** Initializes SpeexBits struct using a pre-allocated buffer*/ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size); +/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */ +void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size); + /** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/ void speex_bits_destroy(SpeexBits *bits); @@ -72,13 +80,20 @@ void speex_bits_rewind(SpeexBits *bits); void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); /** Append bytes to the bit-stream + * * @param bits Bit-stream to operate on * @param bytes pointer to the bytes what will be appended * @param len Number of bytes of append */ void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); -/** Write the content of a bit-stream to an area of memory */ +/** Write the content of a bit-stream to an area of memory + * + * @param bits Bit-stream to operate on + * @param bytes Memory location where to write the bits + * @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer) + * @return Number of bytes written to the "bytes" buffer +*/ int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); /** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ @@ -114,13 +129,19 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); */ int speex_bits_nbytes(SpeexBits *bits); -/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */ +/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to look for + * @return Value of the bits peeked, interpreted as unsigned + */ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); /** Get the value of the next bit in the stream, without modifying the * "cursor" position * * @param bits Bit-stream to operate on + * @return Value of the bit peeked (one bit only) */ int speex_bits_peek(SpeexBits *bits); @@ -134,6 +155,7 @@ void speex_bits_advance(SpeexBits *bits, int n); /** Returns the number of bits remaining to be read in a stream * * @param bits Bit-stream to operate on + * @return Number of bits that can still be read from the stream */ int speex_bits_remaining(SpeexBits *bits); @@ -148,4 +170,5 @@ void speex_bits_insert_terminator(SpeexBits *bits); } #endif +/* @} */ #endif diff --git a/libs/speex/include/speex/speex_buffer.h b/libs/speex/include/speex/speex_buffer.h new file mode 100644 index 0000000000..df56f5f18b --- /dev/null +++ b/libs/speex/include/speex/speex_buffer.h @@ -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 + + + + diff --git a/libs/speex/include/speex/speex_callbacks.h b/libs/speex/include/speex/speex_callbacks.h index f6334f22a7..6f450b3a3a 100644 --- a/libs/speex/include/speex/speex_callbacks.h +++ b/libs/speex/include/speex/speex_callbacks.h @@ -35,6 +35,9 @@ #ifndef SPEEX_CALLBACKS_H #define SPEEX_CALLBACKS_H +/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder. + * @{ + */ #include "speex.h" @@ -110,13 +113,16 @@ int speex_default_user_handler(SpeexBits *bits, void *state, void *data); - +/** Standard handler for low mode request (change low mode, no questions asked) */ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR request (Set VBR, no questions asked) */ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); @@ -124,5 +130,5 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da } #endif - +/** @} */ #endif diff --git a/libs/speex/include/speex/speex_echo.h b/libs/speex/include/speex/speex_echo.h index 4813b5a007..53bcd28a1a 100644 --- a/libs/speex/include/speex/speex_echo.h +++ b/libs/speex/include/speex/speex_echo.h @@ -33,7 +33,10 @@ #ifndef SPEEX_ECHO_H #define SPEEX_ECHO_H - +/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller + * This is the acoustic echo canceller module. + * @{ + */ #include "speex/speex_types.h" #ifdef __cplusplus @@ -48,41 +51,120 @@ extern "C" { /** Get sampling rate */ #define SPEEX_ECHO_GET_SAMPLING_RATE 25 +/* Can't set window sizes */ +/** Get size of impulse response (int32) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27 -/*struct drft_lookup;*/ +/* Can't set window content */ +/** Get impulse response (int32[]) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29 + +/** Internal echo canceller state. Should never be accessed directly. */ struct SpeexEchoState_; +/** @class SpeexEchoState + * This holds the state of the echo canceller. You need one per channel. +*/ + +/** Internal echo canceller state. Should never be accessed directly. */ typedef struct SpeexEchoState_ SpeexEchoState; -/** Creates a new echo canceller state */ +/** Creates a new echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @return Newly-created echo canceller state + */ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length); -/** Destroys an echo canceller state */ +/** Creates a new multi-channel echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @param nb_mic Number of microphone channels + * @param nb_speakers Number of speaker channels + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers); + +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ void speex_echo_state_destroy(SpeexEchoState *st); -/** Performs echo cancellation a frame */ +/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added + * to playback in this form) + * + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param play Signal played to the speaker (received from far end) + * @param out Returns near-end signal with echo removed + */ +void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); + +/** Performs echo cancellation a frame (deprecated) */ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); -/** Perform echo cancellation using internal playback buffer */ -void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out, spx_int32_t *Yout); +/** Perform echo cancellation using internal playback buffer, which is delayed by two frames + * to account for the delay introduced by most soundcards (but it could be off!) + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param out Returns near-end signal with echo removed +*/ +void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); -/** Let the echo canceller know that a frame was just played */ +/** Let the echo canceller know that a frame was just queued to the soundcard + * @param st Echo canceller state + * @param play Signal played to the speaker (received from far end) +*/ void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play); -/** Reset the echo canceller state */ +/** Reset the echo canceller to its original state + * @param st Echo canceller state + */ void speex_echo_state_reset(SpeexEchoState *st); /** Used like the ioctl function to control the echo canceller parameters * - * @param state Encoder state + * @param st Echo canceller state * @param request ioctl-type request (one of the SPEEX_ECHO_* macros) * @param ptr Data exchanged to-from function * @return 0 if no error, -1 if request in unknown */ int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); + + +struct SpeexDecorrState_; + +typedef struct SpeexDecorrState_ SpeexDecorrState; + + +/** Create a state for the channel decorrelation algorithm + This is useful for multi-channel echo cancellation only + * @param rate Sampling rate + * @param channels Number of channels (it's a bit pointless if you don't have at least 2) + * @param frame_size Size of the frame to process at ones (counting samples *per* channel) +*/ +SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size); + +/** Remove correlation between the channels by modifying the phase and possibly + adding noise in a way that is not (or little) perceptible. + * @param st Decorrelator state + * @param in Input audio in interleaved format + * @param out Result of the decorrelation (out *may* alias in) + * @param strength How much alteration of the audio to apply from 0 to 100. +*/ +void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength); + +/** Destroy a Decorrelation state + * @param st State to destroy +*/ +void speex_decorrelate_destroy(SpeexDecorrState *st); + + #ifdef __cplusplus } #endif + +/** @}*/ #endif diff --git a/libs/speex/include/speex/speex_header.h b/libs/speex/include/speex/speex_header.h index 32fb81f64d..f85b2496ae 100644 --- a/libs/speex/include/speex/speex_header.h +++ b/libs/speex/include/speex/speex_header.h @@ -36,6 +36,10 @@ #ifndef SPEEX_HEADER_H #define SPEEX_HEADER_H +/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header + * This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP. + * @{ + */ #include "speex/speex_types.h" @@ -45,6 +49,7 @@ extern "C" { struct SpeexMode; +/** Length of the Speex header identifier */ #define SPEEX_HEADER_STRING_LENGTH 8 /** Maximum number of characters for encoding the Speex version number in the header */ @@ -78,9 +83,12 @@ char *speex_header_to_packet(SpeexHeader *header, int *size); /** Creates a SpeexHeader from a packet */ SpeexHeader *speex_packet_to_header(char *packet, int size); +/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */ +void speex_header_free(void *ptr); + #ifdef __cplusplus } #endif - +/** @} */ #endif diff --git a/libs/speex/include/speex/speex_jitter.h b/libs/speex/include/speex/speex_jitter.h index 22f5e14f9a..d68674b13a 100644 --- a/libs/speex/include/speex/speex_jitter.h +++ b/libs/speex/include/speex/speex_jitter.h @@ -35,83 +35,163 @@ #ifndef SPEEX_JITTER_H #define SPEEX_JITTER_H +/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. + * @{ + */ -#include "speex.h" -#include "speex_bits.h" +#include "speex/speex_types.h" #ifdef __cplusplus extern "C" { #endif +/** Generic adaptive jitter buffer state */ struct JitterBuffer_; +/** Generic adaptive jitter buffer state */ typedef struct JitterBuffer_ JitterBuffer; +/** Definition of an incoming packet */ typedef struct _JitterBufferPacket JitterBufferPacket; +/** Definition of an incoming packet */ struct _JitterBufferPacket { - char *data; - spx_uint32_t len; - spx_uint32_t timestamp; - spx_uint32_t span; + char *data; /**< Data bytes contained in the packet */ + spx_uint32_t len; /**< Length of the packet in bytes */ + spx_uint32_t timestamp; /**< Timestamp for the packet */ + spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ + spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ }; - +/** Packet has been retrieved */ #define JITTER_BUFFER_OK 0 +/** Packet is lost or is late */ #define JITTER_BUFFER_MISSING 1 -#define JITTER_BUFFER_INCOMPLETE 2 +/** A "fake" packet is meant to be inserted here to increase buffering */ +#define JITTER_BUFFER_INSERTION 2 +/** There was an error in the jitter buffer */ #define JITTER_BUFFER_INTERNAL_ERROR -1 +/** Invalid argument */ #define JITTER_BUFFER_BAD_ARGUMENT -2 -/** Initialise jitter buffer */ -JitterBuffer *jitter_buffer_init(int tick); -/** Reset jitter buffer */ +/** Set minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_SET_MARGIN 0 +/** Get minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_GET_MARGIN 1 +/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + +/** Get the amount of available packets currently buffered */ +#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 +/** Included because of an early misspelling (will remove in next release) */ +#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 + +/** Assign a function to destroy unused packet. When setting that, the jitter + buffer no longer copies packet data. */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 + +/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */ +#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8 +#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9 + +/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss + should be half of that or less. */ +#define JITTER_BUFFER_SET_MAX_LATE_RATE 10 +#define JITTER_BUFFER_GET_MAX_LATE_RATE 11 + +/** Equivalent cost of one percent late packet in timestamp units */ +#define JITTER_BUFFER_SET_LATE_COST 12 +#define JITTER_BUFFER_GET_LATE_COST 13 + + +/** Initialises jitter buffer + * + * @param step_size Starting value for the size of concleanment packets and delay + adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP + and JITTER_BUFFER_GET_CONCEALMENT_SIZE. + * @return Newly created jitter buffer state + */ +JitterBuffer *jitter_buffer_init(int step_size); + +/** Restores jitter buffer to its original state + * + * @param jitter Jitter buffer state + */ void jitter_buffer_reset(JitterBuffer *jitter); -/** Destroy jitter buffer */ +/** Destroys jitter buffer + * + * @param jitter Jitter buffer state + */ void jitter_buffer_destroy(JitterBuffer *jitter); -/** Put one packet into the jitter buffer */ +/** Put one packet into the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Incoming packet +*/ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); -/** Get one packet from the jitter buffer */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *current_timestamp); +/** Get one packet from the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) + * @param current_timestamp Timestamp for the returned packet +*/ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); -/** Get pointer timestamp of jitter buffer */ +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); + +/** Get pointer timestamp of jitter buffer + * + * @param jitter Jitter buffer state +*/ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); -/** Advance by one tick */ +/** Advance by one tick + * + * @param jitter Jitter buffer state +*/ void jitter_buffer_tick(JitterBuffer *jitter); +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); -/** Speex jitter-buffer state. */ -typedef struct SpeexJitter { - SpeexBits current_packet; /**< Current Speex packet */ - int valid_bits; /**< True if Speex bits are valid */ - JitterBuffer *packets; - void *dec; /**< Pointer to Speex decoder */ - spx_int32_t frame_size; /**< Frame size of Speex decoder */ -} SpeexJitter; +/** Used like the ioctl function to control the jitter buffer parameters + * + * @param jitter Jitter buffer state + * @param request ioctl-type request (one of the JITTER_BUFFER_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr); -/** Initialise jitter buffer */ -void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); +int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); -/** Destroy jitter buffer */ -void speex_jitter_destroy(SpeexJitter *jitter); - -/** Put one packet into the jitter buffer */ -void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); - -/** Get one packet from the jitter buffer */ -void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); - -/** Get pointer timestamp of jitter buffer */ -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); +/* @} */ #ifdef __cplusplus } #endif - #endif diff --git a/libs/speex/include/speex/speex_preprocess.h b/libs/speex/include/speex/speex_preprocess.h index 5bb3a2c424..f8eef2cd91 100644 --- a/libs/speex/include/speex/speex_preprocess.h +++ b/libs/speex/include/speex/speex_preprocess.h @@ -1,8 +1,10 @@ /* Copyright (C) 2003 Epic Games Written by Jean-Marc Valin */ /** - @file speex_preprocess.h - @brief Speex preprocessor + * @file speex_preprocess.h + * @brief Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). */ /* Redistribution and use in source and binary forms, with or without @@ -34,91 +36,61 @@ #ifndef SPEEX_PREPROCESS_H #define SPEEX_PREPROCESS_H +/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor + * This is the Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). + * @{ + */ #include "speex/speex_types.h" #ifdef __cplusplus extern "C" { #endif - -struct drft_lookup; - -/** Speex pre-processor state. */ -typedef struct SpeexPreprocessState { - int frame_size; /**< Number of samples processed each time */ - int ps_size; /**< Number of points in the power spectrum */ - int sampling_rate; /**< Sampling rate of the input/output */ - /* parameters */ - int denoise_enabled; - int agc_enabled; - float agc_level; - int vad_enabled; - int dereverb_enabled; - float reverb_decay; - float reverb_level; - float speech_prob_start; - float speech_prob_continue; - - float *frame; /**< Processing frame (2*ps_size) */ - float *ps; /**< Current power spectrum */ - float *gain2; /**< Adjusted gains */ - float *window; /**< Analysis/Synthesis window */ - float *noise; /**< Noise estimate */ - float *reverb_estimate; /**< Estimate of reverb energy */ - float *old_ps; /**< Power spectrum for last frame */ - float *gain; /**< Ephraim Malah gain */ - float *prior; /**< A-priori SNR */ - float *post; /**< A-posteriori SNR */ +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +struct SpeexPreprocessState_; - float *S; /**< Smoothed power spectrum */ - float *Smin; /**< See Cohen paper */ - float *Stmp; /**< See Cohen paper */ - float *update_prob; /**< Propability of speech presence for noise update */ +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +typedef struct SpeexPreprocessState_ SpeexPreprocessState; - float *zeta; /**< Smoothed a priori SNR */ - float Zpeak; - float Zlast; - float *loudness_weight; /**< Perceptual loudness curve */ - - float *echo_noise; - - float *noise_bands; - float *noise_bands2; - int noise_bandsN; - float *speech_bands; - float *speech_bands2; - int speech_bandsN; - - float *inbuf; /**< Input buffer (overlapped analysis) */ - float *outbuf; /**< Output buffer (for overlap and add) */ - - float speech_prob; - int last_speech; - float loudness; /**< loudness estimate */ - float loudness2; /**< loudness estimate */ - int nb_adapt; /**< Number of frames used for adaptation so far */ - int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */ - int consec_noise; /**< Number of consecutive noise frames */ - int nb_preprocess; /**< Number of frames processed so far */ - struct drft_lookup *fft_lookup; /**< Lookup table for the FFT */ - -} SpeexPreprocessState; - -/** Creates a new preprocessing state */ +/** Creates a new preprocessing state. You MUST create one state per channel processed. + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be + * the same value as that used for the echo canceller for residual echo cancellation to work. + * @param sampling_rate Sampling rate used for the input. + * @return Newly created preprocessor state +*/ SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate); -/** Destroys a denoising state */ +/** Destroys a preprocessor state + * @param st Preprocessor state to destroy +*/ void speex_preprocess_state_destroy(SpeexPreprocessState *st); -/** Preprocess a frame */ +/** Preprocess a frame + * @param st Preprocessor state + * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init(). + * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on. +*/ +int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x); + +/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/ int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); -/** Preprocess a frame */ -void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); +/** Update preprocessor state, but do not compute the output + * @param st Preprocessor state + * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init(). +*/ +void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x); -/** Used like the ioctl function to control the preprocessor parameters */ +/** Used like the ioctl function to control the preprocessor parameters + * @param st Preprocessor state + * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); @@ -138,9 +110,9 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** Get preprocessor Voice Activity Detection state */ #define SPEEX_PREPROCESS_GET_VAD 5 -/** Set preprocessor Automatic Gain Control level */ +/** Set preprocessor Automatic Gain Control level (float) */ #define SPEEX_PREPROCESS_SET_AGC_LEVEL 6 -/** Get preprocessor Automatic Gain Control level */ +/** Get preprocessor Automatic Gain Control level (float) */ #define SPEEX_PREPROCESS_GET_AGC_LEVEL 7 /** Set preprocessor dereverb state */ @@ -158,14 +130,90 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** Get preprocessor dereverb decay */ #define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13 +/** Set probability required for the VAD to go from silence to voice */ #define SPEEX_PREPROCESS_SET_PROB_START 14 +/** Get probability required for the VAD to go from silence to voice */ #define SPEEX_PREPROCESS_GET_PROB_START 15 +/** Set probability required for the VAD to stay in the voice state (integer percent) */ #define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16 +/** Get probability required for the VAD to stay in the voice state (integer percent) */ #define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17 +/** Set maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18 +/** Get maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19 + +/** Set maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20 +/** Get maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21 + +/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22 +/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23 + +/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */ +#define SPEEX_PREPROCESS_SET_ECHO_STATE 24 +/** Get the corresponding echo canceller state */ +#define SPEEX_PREPROCESS_GET_ECHO_STATE 25 + +/** Set maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26 + +/** Get maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27 + +/** Set maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28 + +/** Get maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29 + +/** Set maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30 + +/** Get maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 + +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + +/* Can't set gain */ +/** Get current gain (int32 percent) */ +#define SPEEX_PREPROCESS_GET_AGC_GAIN 35 + +/* Can't set spectrum size */ +/** Get spectrum size for power spectrum (int32) */ +#define SPEEX_PREPROCESS_GET_PSD_SIZE 37 + +/* Can't set power spectrum */ +/** Get power spectrum (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_PSD 39 + +/* Can't set noise size */ +/** Get spectrum size for noise estimate (int32) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41 + +/* Can't set noise estimate */ +/** Get noise estimate (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD 43 + +/* Can't set speech probability */ +/** Get speech probability in last frame (int32). */ +#define SPEEX_PREPROCESS_GET_PROB 45 + +/** Set preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_TARGET 46 +/** Get preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_TARGET 47 + #ifdef __cplusplus } #endif +/** @}*/ #endif diff --git a/libs/speex/include/speex/speex_resampler.h b/libs/speex/include/speex/speex_resampler.h new file mode 100644 index 0000000000..54eef8d7b8 --- /dev/null +++ b/libs/speex/include/speex/speex_resampler.h @@ -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 diff --git a/libs/speex/include/speex/speex_stereo.h b/libs/speex/include/speex/speex_stereo.h index 6ccaa318f9..a259713b82 100644 --- a/libs/speex/include/speex/speex_stereo.h +++ b/libs/speex/include/speex/speex_stereo.h @@ -34,6 +34,10 @@ #ifndef STEREO_H #define STEREO_H +/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files + * This describes the Speex intensity stereo encoding/decoding + * @{ + */ #include "speex/speex_types.h" #include "speex/speex_bits.h" @@ -42,7 +46,7 @@ extern "C" { #endif -/** State used for decoding (intensity) stereo information */ +/** If you access any of these fields directly, I'll personally come and bite you */ typedef struct SpeexStereoState { float balance; /**< Left/right balance info */ float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ @@ -52,9 +56,18 @@ typedef struct SpeexStereoState { float reserved2; /**< Reserved for future use */ } SpeexStereoState; -/** Initialization value for a stereo state */ +/** Deprecated. Use speex_stereo_state_init() instead. */ #define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} +/** Initialise/create a stereo stereo state */ +SpeexStereoState *speex_stereo_state_init(); + +/** Reset/re-initialise an already allocated stereo state */ +void speex_stereo_state_reset(SpeexStereoState *stereo); + +/** Destroy a stereo stereo state */ +void speex_stereo_state_destroy(SpeexStereoState *stereo); + /** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); @@ -74,5 +87,5 @@ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); } #endif - +/** @} */ #endif diff --git a/libs/speex/include/speex/speex_types.h b/libs/speex/include/speex/speex_types.h index c746d4f6f6..852fed801d 100644 --- a/libs/speex/include/speex/speex_types.h +++ b/libs/speex/include/speex/speex_types.h @@ -31,10 +31,10 @@ typedef _G_int16_t spx_int16_t; typedef _G_uint16_t spx_uint16_t; # elif defined(__MINGW32__) - typedef short spx_int16_t; - typedef unsigned short spx_uint16_t; - typedef int spx_int32_t; - typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; # elif defined(__MWERKS__) typedef int spx_int32_t; typedef unsigned int spx_uint32_t; @@ -56,7 +56,7 @@ typedef SInt32 spx_int32_t; typedef UInt32 spx_uint32_t; -#elif defined(__MACOSX__) /* MacOS X Framework build */ +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ # include typedef int16_t spx_int16_t; diff --git a/libs/speex/libspeex/Makefile.am b/libs/speex/libspeex/Makefile.am index 0972172e65..3d4e03f9a6 100644 --- a/libs/speex/libspeex/Makefile.am +++ b/libs/speex/libspeex/Makefile.am @@ -2,41 +2,54 @@ #AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST=testenc.c testenc_wb.c testenc_uwb.c testdenoise.c testecho.c +EXTRA_DIST=echo_diagnostic.m -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) +INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@ @FFT_CFLAGS@ -lib_LTLIBRARIES = libspeex.la +lib_LTLIBRARIES = libspeex.la libspeexdsp.la # Sources for compilation in the library -libspeex_la_SOURCES = nb_celp.c sb_celp.c lpc.c ltp.c lsp.c quant_lsp.c \ - lsp_tables_nb.c gain_table.c gain_table_lbr.c cb_search.c filters.c bits.c \ - modes.c speex.c vq.c high_lsp_tables.c vbr.c hexc_table.c \ - exc_5_256_table.c exc_5_64_table.c exc_8_128_table.c exc_10_32_table.c \ - exc_10_16_table.c exc_20_32_table.c hexc_10_32_table.c misc.c speex_header.c \ - speex_callbacks.c math_approx.c stereo.c preprocess.c smallft.c lbr_48k_tables.c \ - jitter.c mdf.c vorbis_psy.c fftwrap.c kiss_fft.c _kiss_fft_guts.h kiss_fft.h \ - kiss_fftr.c kiss_fftr.h window.c +libspeex_la_SOURCES = cb_search.c exc_10_32_table.c exc_8_128_table.c \ + filters.c gain_table.c hexc_table.c high_lsp_tables.c lsp.c \ + ltp.c speex.c stereo.c vbr.c vq.c bits.c exc_10_16_table.c \ + exc_20_32_table.c exc_5_256_table.c exc_5_64_table.c gain_table_lbr.c hexc_10_32_table.c \ + lpc.c lsp_tables_nb.c modes.c modes_wb.c nb_celp.c quant_lsp.c sb_celp.c \ + speex_callbacks.c speex_header.c window.c -noinst_HEADERS = lsp.h nb_celp.h lpc.h lpc_bfin.h ltp.h quant_lsp.h \ - cb_search.h filters.h stack_alloc.h vq.h vq_sse.h vq_arm4.h vq_bfin.h \ - modes.h sb_celp.h vbr.h misc.h misc_bfin.h ltp_sse.h ltp_arm4.h \ - ltp_bfin.h filters_sse.h filters_arm4.h filters_bfin.h math_approx.h \ - smallft.h arch.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h \ - fixed_generic.h cb_search_sse.h cb_search_arm4.h cb_search_bfin.h vorbis_psy.h \ - fftwrap.h pseudofloat.h lsp_bfin.h quant_lsp_bfin.h +if BUILD_KISS_FFT + FFTSRC=kiss_fft.c _kiss_fft_guts.h kiss_fft.h kiss_fftr.c kiss_fftr.h +else +if BUILD_SMALLFT + FFTSRC=smallft.c +else + FFTSRC= +endif +endif + +libspeexdsp_la_SOURCES = preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c buffer.c scal.c $(FFTSRC) + +noinst_HEADERS = arch.h cb_search_arm4.h cb_search_bfin.h cb_search_sse.h \ + filters.h filters_arm4.h filters_bfin.h filters_sse.h fixed_arm4.h \ + fixed_arm5e.h fixed_bfin.h fixed_debug.h lpc.h lpc_bfin.h ltp.h ltp_arm4.h \ + ltp_sse.h math_approx.h misc_bfin.h nb_celp.h quant_lsp.h sb_celp.h \ + stack_alloc.h vbr.h vq.h vq_arm4.h vq_bfin.h vq_sse.h cb_search.h fftwrap.h \ + filterbank.h fixed_generic.h lsp.h lsp_bfin.h ltp_bfin.h modes.h os_support.h \ + pseudofloat.h quant_lsp_bfin.h smallft.h vorbis_psy.h resample_sse.h libspeex_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ +libspeexdsp_la_LDFLAGS = -no-undefined -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ -noinst_PROGRAMS = testenc testenc_wb testenc_uwb testdenoise testecho +noinst_PROGRAMS = testenc testenc_wb testenc_uwb testdenoise testecho testjitter testenc_SOURCES = testenc.c -testenc_LDADD = $(top_builddir)/libspeex/libspeex.la +testenc_LDADD = libspeex.la testenc_wb_SOURCES = testenc_wb.c -testenc_wb_LDADD = $(top_builddir)/libspeex/libspeex.la +testenc_wb_LDADD = libspeex.la testenc_uwb_SOURCES = testenc_uwb.c -testenc_uwb_LDADD = $(top_builddir)/libspeex/libspeex.la +testenc_uwb_LDADD = libspeex.la testdenoise_SOURCES = testdenoise.c -testdenoise_LDADD = $(top_builddir)/libspeex/libspeex.la +testdenoise_LDADD = libspeexdsp.la @FFT_LIBS@ testecho_SOURCES = testecho.c -testecho_LDADD = $(top_builddir)/libspeex/libspeex.la +testecho_LDADD = libspeexdsp.la @FFT_LIBS@ +testjitter_SOURCES = testjitter.c +testjitter_LDADD = libspeexdsp.la @FFT_LIBS@ diff --git a/libs/speex/libspeex/_kiss_fft_guts.h b/libs/speex/libspeex/_kiss_fft_guts.h index 72acee184a..6571e79c0c 100644 --- a/libs/speex/libspeex/_kiss_fft_guts.h +++ b/libs/speex/libspeex/_kiss_fft_guts.h @@ -20,6 +20,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND and defines typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ #include "kiss_fft.h" +#include "math_approx.h" #define MAXFACTORS 32 /* e.g. an fft of length 128 has 4 factors @@ -44,7 +45,7 @@ struct kiss_fft_state{ C_ADDTO( res , a) : res += a * */ #ifdef FIXED_POINT -#include "misc.h" +#include "arch.h" # define FRACBITS 15 # define SAMPPROD spx_int32_t #define SAMP_MAX 32767 @@ -67,6 +68,10 @@ struct kiss_fft_state{ do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) +# define C_MUL4(m,a,b) \ + do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \ + (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0) + # define DIVSCALAR(x,k) \ (x) = sround( smul( x, SAMP_MAX/k ) ) @@ -84,6 +89,9 @@ struct kiss_fft_state{ #define C_MUL(m,a,b) \ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) + +#define C_MUL4(m,a,b) C_MUL(m,a,b) + # define C_FIXDIV(c,div) /* NOOP */ # define C_MULBYSCALAR( c, s ) \ do{ (c).r *= (s);\ @@ -140,6 +148,11 @@ struct kiss_fft_state{ (x)->r = KISS_FFT_COS(phase);\ (x)->i = KISS_FFT_SIN(phase);\ }while(0) +#define kf_cexp2(x,phase) \ + do{ \ + (x)->r = spx_cos_norm((phase));\ + (x)->i = spx_cos_norm((phase)-32768);\ +}while(0) /* a debugging function */ diff --git a/libs/speex/libspeex/arch.h b/libs/speex/libspeex/arch.h index 0500437395..d38c36ce7c 100644 --- a/libs/speex/libspeex/arch.h +++ b/libs/speex/libspeex/arch.h @@ -35,12 +35,55 @@ #ifndef ARCH_H #define ARCH_H +#ifndef SPEEX_VERSION +#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ +#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ +#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ +#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ +#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ +#endif + +/* A couple test to catch stupid option combinations */ +#ifdef FIXED_POINT + +#ifdef FLOATING_POINT +#error You cannot compile as floating point and fixed point at the same time +#endif +#ifdef _USE_SSE +#error SSE is only for floating-point +#endif +#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#error Make up your mind. What CPU do you have? +#endif +#ifdef VORBIS_PSYCHO +#error Vorbis-psy model currently not implemented in fixed-point +#endif + +#else + +#ifndef FLOATING_POINT +#error You now need to define either FIXED_POINT or FLOATING_POINT +#endif +#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? +#endif +#ifdef FIXED_POINT_DEBUG +#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" +#endif + + +#endif + +#ifndef OUTSIDE_SPEEX #include "speex/speex_types.h" +#endif #define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ #define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ #define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ #define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ #define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ #ifdef FIXED_POINT @@ -64,10 +107,12 @@ typedef spx_word32_t spx_sig_t; #define LPC_SHIFT 13 #define LSP_SHIFT 13 #define SIG_SHIFT 14 +#define GAIN_SHIFT 6 #define VERY_SMALL 0 #define VERY_LARGE32 ((spx_word32_t)2147483647) #define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) #ifdef FIXED_DEBUG @@ -80,8 +125,6 @@ typedef spx_word32_t spx_sig_t; #include "fixed_arm5e.h" #elif defined (ARM4_ASM) #include "fixed_arm4.h" -#elif defined (ARM5E_ASM) -#include "fixed_arm5e.h" #elif defined (BFIN_ASM) #include "fixed_bfin.h" #endif @@ -106,13 +149,11 @@ typedef float spx_word32_t; #define GAIN_SCALING 1.f #define GAIN_SCALING_1 1.f -#define LPC_SHIFT 0 -#define LSP_SHIFT 0 -#define SIG_SHIFT 0 #define VERY_SMALL 1e-15f #define VERY_LARGE32 1e15f #define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) #define QCONST16(x,bits) (x) #define QCONST32(x,bits) (x) @@ -127,6 +168,7 @@ typedef float spx_word32_t; #define SHL32(a,shift) (a) #define PSHR16(a,shift) (a) #define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) #define SATURATE16(x,a) (x) #define SATURATE32(x,a) (x) @@ -147,6 +189,7 @@ typedef float spx_word32_t; #define MULT16_32_Q13(a,b) ((a)*(b)) #define MULT16_32_Q14(a,b) ((a)*(b)) #define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_P15(a,b) ((a)*(b)) #define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) #define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) @@ -186,4 +229,11 @@ typedef float spx_word32_t; #endif + + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + + #endif diff --git a/libs/speex/libspeex/bits.c b/libs/speex/libspeex/bits.c index 376e804f92..3ef7c6c1b5 100644 --- a/libs/speex/libspeex/bits.c +++ b/libs/speex/libspeex/bits.c @@ -37,14 +37,15 @@ #endif #include -#include "misc.h" +#include "arch.h" +#include "os_support.h" /* Maximum size of the bit-stream (for fixed-size allocation) */ #ifndef MAX_CHARS_PER_FRAME #define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR) #endif -void speex_bits_init(SpeexBits *bits) +EXPORT void speex_bits_init(SpeexBits *bits) { bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME); if (!bits->chars) @@ -57,7 +58,7 @@ void speex_bits_init(SpeexBits *bits) speex_bits_reset(bits); } -void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) +EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) { bits->chars = (char*)buff; bits->buf_size = buf_size; @@ -67,15 +68,30 @@ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) speex_bits_reset(bits); } -void speex_bits_destroy(SpeexBits *bits) +EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size) +{ + bits->chars = (char*)buff; + bits->buf_size = buf_size; + + bits->owner=0; + + bits->nbBits=buf_size<charPtr=0; + bits->bitPtr=0; + bits->overflow=0; + +} + +EXPORT void speex_bits_destroy(SpeexBits *bits) { if (bits->owner) speex_free(bits->chars); /* Will do something once the allocation is dynamic */ } -void speex_bits_reset(SpeexBits *bits) +EXPORT void speex_bits_reset(SpeexBits *bits) { + /* We only need to clear the first byte now */ bits->chars[0]=0; bits->nbBits=0; bits->charPtr=0; @@ -83,20 +99,20 @@ void speex_bits_reset(SpeexBits *bits) bits->overflow=0; } -void speex_bits_rewind(SpeexBits *bits) +EXPORT void speex_bits_rewind(SpeexBits *bits) { bits->charPtr=0; bits->bitPtr=0; bits->overflow=0; } -void speex_bits_read_from(SpeexBits *bits, char *chars, int len) +EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len) { int i; int nchars = len / BYTES_PER_CHAR; if (nchars > bits->buf_size) { - speex_warning_int("Packet is larger than allocated buffer: ", len); + speex_notify("Packet is larger than allocated buffer"); if (bits->owner) { char *tmp = (char*)speex_realloc(bits->chars, nchars); @@ -109,7 +125,7 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len) speex_warning("Could not resize input buffer: truncating input"); } } else { - speex_warning("Do not own input buffer: truncating input"); + speex_warning("Do not own input buffer: truncating oversize input"); nchars=bits->buf_size; } } @@ -130,18 +146,14 @@ void speex_bits_read_from(SpeexBits *bits, char *chars, int len) static void speex_bits_flush(SpeexBits *bits) { - int i; int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR); if (bits->charPtr>0) - { - for (i=bits->charPtr;ichars[i-bits->charPtr]=bits->chars[i]; - } + SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr); bits->nbBits -= bits->charPtr<charPtr=0; } -void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes) +EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes) { int i,pos; int nchars = nbytes/BYTES_PER_CHAR; @@ -158,10 +170,10 @@ void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes) bits->chars=tmp; } else { nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1; - speex_warning("Could not resize input buffer: truncating input"); + speex_warning("Could not resize input buffer: truncating oversize input"); } } else { - speex_warning("Do not own input buffer: truncating input"); + speex_warning("Do not own input buffer: truncating oversize input"); nchars=bits->buf_size; } } @@ -173,7 +185,7 @@ void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes) bits->nbBits+=nchars<chars[0]=bits->chars[max_nchars]; else bits->chars[0]=0; - for (i=1;i<((bits->nbBits)>>LOG2_BITS_PER_CHAR)+1;i++) - bits->chars[i]=0; bits->charPtr=0; bits->nbBits &= (BITS_PER_CHAR-1); return max_nchars*BYTES_PER_CHAR; } -void speex_bits_pack(SpeexBits *bits, int data, int nbBits) +EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits) { unsigned int d=data; if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size) { - speex_warning("Buffer too small to pack bits"); + speex_notify("Buffer too small to pack bits"); if (bits->owner) { - int new_nchars = ((bits->buf_size+5)*3)>>1; + int new_nchars = ((bits->buf_size+5)*3)>>1; char *tmp = (char*)speex_realloc(bits->chars, new_nchars); if (tmp) { - speex_memset_bytes(tmp, 0, new_nchars); bits->buf_size=new_nchars; bits->chars=tmp; } else { @@ -260,7 +269,7 @@ void speex_bits_pack(SpeexBits *bits, int data, int nbBits) } } -int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) +EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) { unsigned int d=speex_bits_unpack_unsigned(bits,nbBits); /* If number is negative */ @@ -271,7 +280,7 @@ int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) return d; } -unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits) +EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits) { unsigned int d=0; if ((bits->charPtr<bitPtr+nbBits>bits->nbBits) @@ -293,7 +302,7 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits) return d; } -unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) +EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) { unsigned int d=0; int bitPtr, charPtr; @@ -322,7 +331,7 @@ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) return d; } -int speex_bits_peek(SpeexBits *bits) +EXPORT int speex_bits_peek(SpeexBits *bits) { if ((bits->charPtr<bitPtr+1>bits->nbBits) bits->overflow=1; @@ -331,7 +340,7 @@ int speex_bits_peek(SpeexBits *bits) return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1; } -void speex_bits_advance(SpeexBits *bits, int n) +EXPORT void speex_bits_advance(SpeexBits *bits, int n) { if (((bits->charPtr<bitPtr+n>bits->nbBits) || bits->overflow){ bits->overflow=1; @@ -341,7 +350,7 @@ void speex_bits_advance(SpeexBits *bits, int n) bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */ } -int speex_bits_remaining(SpeexBits *bits) +EXPORT int speex_bits_remaining(SpeexBits *bits) { if (bits->overflow) return -1; @@ -349,12 +358,12 @@ int speex_bits_remaining(SpeexBits *bits) return bits->nbBits-((bits->charPtr<bitPtr); } -int speex_bits_nbytes(SpeexBits *bits) +EXPORT int speex_bits_nbytes(SpeexBits *bits) { return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR); } -void speex_bits_insert_terminator(SpeexBits *bits) +EXPORT void speex_bits_insert_terminator(SpeexBits *bits) { if (bits->bitPtr) speex_bits_pack(bits, 0, 1); diff --git a/libs/speex/libspeex/buffer.c b/libs/speex/libspeex/buffer.c new file mode 100644 index 0000000000..6cfd5a3413 --- /dev/null +++ b/libs/speex/libspeex/buffer.c @@ -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 + +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; +} diff --git a/libs/speex/libspeex/cb_search.c b/libs/speex/libspeex/cb_search.c index 5c68826095..63f4c6a4bd 100644 --- a/libs/speex/libspeex/cb_search.c +++ b/libs/speex/libspeex/cb_search.c @@ -37,7 +37,9 @@ #include "filters.h" #include "stack_alloc.h" #include "vq.h" -#include "misc.h" +#include "arch.h" +#include "math_approx.h" +#include "os_support.h" #ifdef _USE_SSE #include "cb_search_sse.h" @@ -146,8 +148,7 @@ int update_target ALLOC(e, nsf, spx_sig_t); /* FIXME: Do we still need to copy the target? */ - for (i=0;i -#include "misc.h" +#include "arch.h" /** Split codebook parameters. */ typedef struct split_cb_params { diff --git a/libs/speex/libspeex/cb_search_bfin.h b/libs/speex/libspeex/cb_search_bfin.h index 52cc4b3bae..ae9cf8343d 100644 --- a/libs/speex/libspeex/cb_search_bfin.h +++ b/libs/speex/libspeex/cb_search_bfin.h @@ -73,7 +73,10 @@ void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t * : : "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E) : "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0", - "L1", "A0", "A1", "memory", "LC0", "LC1" + "L1", "A0", "A1", "memory" +#if !(__GNUC__ == 3) + , "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */ +#endif ); shape_cb += subvect_size; resp += subvect_size; diff --git a/libs/speex/libspeex/echo_diagnostic.m b/libs/speex/libspeex/echo_diagnostic.m new file mode 100644 index 0000000000..aebf390672 --- /dev/null +++ b/libs/speex/libspeex/echo_diagnostic.m @@ -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); diff --git a/libs/speex/libspeex/fftwrap.c b/libs/speex/libspeex/fftwrap.c index 43a9b18b8b..4f37e1b3fb 100644 --- a/libs/speex/libspeex/fftwrap.c +++ b/libs/speex/libspeex/fftwrap.c @@ -36,11 +36,8 @@ #include "config.h" #endif -/*#define USE_SMALLFT*/ -#define USE_KISS_FFT - - -#include "misc.h" +#include "arch.h" +#include "os_support.h" #define MAX_FFT_SIZE 2048 @@ -64,7 +61,7 @@ static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t boun } for (i=0;i> shift; + out[i] = PSHR16(in[i], shift); } } #endif @@ -103,8 +100,8 @@ void spx_fft(void *table, float *in, float *out) if (in==out) { int i; - speex_warning("FFT should not be done in-place"); float scale = 1./((struct drft_lookup *)table)->n; + speex_warning("FFT should not be done in-place"); for (i=0;i<((struct drft_lookup *)table)->n;i++) out[i] = scale*in[i]; } else { @@ -120,7 +117,6 @@ void spx_ifft(void *table, float *in, float *out) { if (in==out) { - int i; speex_warning("FFT should not be done in-place"); } else { int i; @@ -130,6 +126,119 @@ void spx_ifft(void *table, float *in, float *out) spx_drft_backward((struct drft_lookup *)table, out); } +#elif defined(USE_INTEL_MKL) +#include + +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 + +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;ifft); + + out[0] = optr[0]; + for(i=1;iN; + float *iptr = t->in; + float *optr = t->out; + + iptr[0] = in[0]; + iptr[1] = 0.0f; + for(i=1;iifft); + + for(i=0;ifreq_data = (kiss_fft_cpx*)speex_alloc(sizeof(kiss_fft_cpx)*((size>>1)+1)); table->forward = kiss_fftr_alloc(size,0,NULL,NULL); table->backward = kiss_fftr_alloc(size,1,NULL,NULL); table->N = size; @@ -158,7 +265,6 @@ void spx_fft_destroy(void *table) struct kiss_config *t = (struct kiss_config *)table; kiss_fftr_free(t->forward); kiss_fftr_free(t->backward); - speex_free(t->freq_data); speex_free(table); } @@ -166,18 +272,10 @@ void spx_fft_destroy(void *table) void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) { - int i; int shift; struct kiss_config *t = (struct kiss_config *)table; shift = maximize_range(in, in, 32000, t->N); - kiss_fftr(t->forward, in, t->freq_data); - out[0] = t->freq_data[0].r; - for (i=1;iN>>1;i++) - { - out[(i<<1)-1] = t->freq_data[i].r; - out[(i<<1)] = t->freq_data[i].i; - } - out[(i<<1)-1] = t->freq_data[i].r; + kiss_fftr2(t->forward, in, out); renorm_range(in, in, shift, t->N); renorm_range(out, out, shift, t->N); } @@ -190,32 +288,16 @@ void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) float scale; struct kiss_config *t = (struct kiss_config *)table; scale = 1./t->N; - kiss_fftr(t->forward, in, t->freq_data); - out[0] = scale*t->freq_data[0].r; - for (i=1;iN>>1;i++) - { - out[(i<<1)-1] = scale*t->freq_data[i].r; - out[(i<<1)] = scale*t->freq_data[i].i; - } - out[(i<<1)-1] = scale*t->freq_data[i].r; + kiss_fftr2(t->forward, in, out); + for (i=0;iN;i++) + out[i] *= scale; } #endif void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) { - int i; struct kiss_config *t = (struct kiss_config *)table; - t->freq_data[0].r = in[0]; - t->freq_data[0].i = 0; - for (i=1;iN>>1;i++) - { - t->freq_data[i].r = in[(i<<1)-1]; - t->freq_data[i].i = in[(i<<1)]; - } - t->freq_data[i].r = in[(i<<1)-1]; - t->freq_data[i].i = 0; - - kiss_fftri(t->backward, t->freq_data, out); + kiss_fftri2(t->backward, in, out); } diff --git a/libs/speex/libspeex/fftwrap.h b/libs/speex/libspeex/fftwrap.h index 826b38e979..dfaf489441 100644 --- a/libs/speex/libspeex/fftwrap.h +++ b/libs/speex/libspeex/fftwrap.h @@ -35,7 +35,7 @@ #ifndef FFTWRAP_H #define FFTWRAP_H -#include "misc.h" +#include "arch.h" /** Compute tables for an FFT */ void *spx_fft_init(int size); diff --git a/libs/speex/libspeex/filterbank.c b/libs/speex/libspeex/filterbank.c new file mode 100644 index 0000000000..e2fb71d4ba --- /dev/null +++ b/libs/speex/libspeex/filterbank.c @@ -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 +#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 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;inb_banks;i++) + bank->scaling[i] = 0; + for (i=0;ilen;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;inb_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;inb_banks;i++) + mel[i] = 0; + + for (i=0;ilen;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;inb_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;ilen;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;inb_banks;i++) + mel[i] = 0; + + for (i=0;ilen;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;inb_banks;i++) + mel[i] *= bank->scaling[i]; +} + +void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps) +{ + int i; + for (i=0;ilen;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;inb_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 diff --git a/libs/speex/libspeex/filterbank.h b/libs/speex/libspeex/filterbank.h new file mode 100644 index 0000000000..3e889a22f7 --- /dev/null +++ b/libs/speex/libspeex/filterbank.h @@ -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 diff --git a/libs/speex/libspeex/filters.c b/libs/speex/libspeex/filters.c index a1111ee812..36ef4f697e 100644 --- a/libs/speex/libspeex/filters.c +++ b/libs/speex/libspeex/filters.c @@ -36,7 +36,7 @@ #include "filters.h" #include "stack_alloc.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" #include "ltp.h" #include @@ -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=min_val && vec[i] <= max_val)) + { + if (vec[i] < min_val) + vec[i] = min_val; + else if (vec[i] > max_val) + vec[i] = max_val; + else /* Has to be NaN */ + vec[i] = 0; + } + } +} + void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem) { int i; @@ -83,8 +101,8 @@ void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_m spx_word16_t yi; spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]); yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767)); - mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), MULT16_32_Q14(-den[1],vout)); - mem[1] = ADD32(MULT16_16(num[2],x[i]), MULT16_32_Q14(-den[2],vout)); + mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1)); + mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1)); y[i] = yi; } } @@ -218,10 +236,10 @@ spx_word16_t compute_rms16(const spx_word16_t *x, int len) for (i=0;i>1; for (i=0;i>1; + N2 = N>>1; + ALLOC(xx1, M2+N2, spx_word16_t); + ALLOC(xx2, M2+N2, spx_word16_t); - for (i = 0; i < N/2; i++) - xx[2*i] = PSHR32(x[N/2-1-i],SIG_SHIFT); - for (i = 0; i < M - 1; i += 2) - xx[N+i] = mem[i+1]; + for (i = 0; i < N2; i++) + xx1[i] = x1[N2-1-i]; + for (i = 0; i < M2; i++) + xx1[N2+i] = mem1[2*i+1]; + for (i = 0; i < N2; i++) + xx2[i] = x2[N2-1-i]; + for (i = 0; i < M2; i++) + xx2[N2+i] = mem2[2*i+1]; - for (i = 0; i < N; i += 4) { + for (i = 0; i < N2; i += 2) { spx_sig_t y0, y1, y2, y3; - spx_word16_t x0; + spx_word16_t x10, x20; y0 = y1 = y2 = y3 = 0; - x0 = xx[N-4-i]; + x10 = xx1[N2-2-i]; + x20 = xx2[N2-2-i]; - for (j = 0; j < M; j += 4) { - spx_word16_t x1; + for (j = 0; j < M2; j += 2) { + spx_word16_t x11, x21; spx_word16_t a0, a1; - a0 = a[j]; - a1 = a[j+1]; - x1 = xx[N-2+j-i]; + a0 = a[2*j]; + a1 = a[2*j+1]; + x11 = xx1[N2-1+j-i]; + x21 = xx2[N2-1+j-i]; - y0 = ADD32(y0,SHR(MULT16_16(a0, x1),2)); - y1 = ADD32(y1,SHR(MULT16_16(a1, x1),2)); - y2 = ADD32(y2,SHR(MULT16_16(a0, x0),2)); - y3 = ADD32(y3,SHR(MULT16_16(a1, x0),2)); +#ifdef FIXED_POINT + /* We multiply twice by the same coef to avoid overflows */ + y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21); + y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21); + y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20); + y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20); +#else + y0 = ADD32(y0,MULT16_16(a0, x11-x21)); + y1 = ADD32(y1,MULT16_16(a1, x11+x21)); + y2 = ADD32(y2,MULT16_16(a0, x10-x20)); + y3 = ADD32(y3,MULT16_16(a1, x10+x20)); +#endif + a0 = a[2*j+2]; + a1 = a[2*j+3]; + x10 = xx1[N2+j-i]; + x20 = xx2[N2+j-i]; - a0 = a[j+2]; - a1 = a[j+3]; - x0 = xx[N+j-i]; - - y0 = ADD32(y0,SHR(MULT16_16(a0, x0),2)); - y1 = ADD32(y1,SHR(MULT16_16(a1, x0),2)); - y2 = ADD32(y2,SHR(MULT16_16(a0, x1),2)); - y3 = ADD32(y3,SHR(MULT16_16(a1, x1),2)); +#ifdef FIXED_POINT + /* We multiply twice by the same coef to avoid overflows */ + y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20); + y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20); + y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21); + y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21); +#else + y0 = ADD32(y0,MULT16_16(a0, x10-x20)); + y1 = ADD32(y1,MULT16_16(a1, x10+x20)); + y2 = ADD32(y2,MULT16_16(a0, x11-x21)); + y3 = ADD32(y3,MULT16_16(a1, x11+x21)); +#endif } - y[i] = y0; - y[i+1] = y1; - y[i+2] = y2; - y[i+3] = y3; +#ifdef FIXED_POINT + y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767)); + y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767)); + y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767)); + y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767)); +#else + /* Normalize up explicitly if we're in float */ + y[2*i] = 2.f*y0; + y[2*i+1] = 2.f*y1; + y[2*i+2] = 2.f*y2; + y[2*i+3] = 2.f*y3; +#endif } - for (i = 0; i < M - 1; i += 2) - mem[i+1] = xx[i]; + for (i = 0; i < M2; i++) + mem1[2*i+1] = xx1[i]; + for (i = 0; i < M2; i++) + mem2[2*i+1] = xx2[i]; } #ifdef FIXED_POINT #if 0 -spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043}, +const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043}, {-98, 1133, -4425, 29179, 8895, -2328, 444}, {444, -2328, 8895, 29179, -4425, 1133, -98}}; #else -spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540}, +const spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540}, {-1064, 2817, -6694, 31589, 6837, -990, -209}, {-209, -990, 6837, 31589, -6694, 2817, -1064}}; #endif #else #if 0 -float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02}, +const float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02}, {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403}, {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}}; #else -float shift_filt[3][7] = {{-0.011915, 0.046995, -0.152373, 0.614108, 0.614108, -0.152373, 0.046995}, - {-0.0324855, 0.0859768, -0.2042986, 0.9640297, 0.2086420, -0.0302054, -0.0063646}, - {-0.0063646, -0.0302054, 0.2086420, 0.9640297, -0.2042986, 0.0859768, -0.0324855}}; +const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f}, + {-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f}, + {-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}}; #endif #endif @@ -784,7 +675,9 @@ char *stack spx_word16_t g1, g2; spx_word16_t ngain; spx_word16_t gg1, gg2; - +#ifdef FIXED_POINT + int scaledown=0; +#endif #if 0 /* Set to 1 to enable full pitch search */ int nol_pitch[6]; spx_word16_t nol_pitch_coef[6]; @@ -819,6 +712,23 @@ char *stack else interp_pitch(exc, iexc+nsf, -corr_pitch, 80); +#ifdef FIXED_POINT + for (i=0;i16383) + { + scaledown = 1; + break; + } + } + if (scaledown) + { + for (i=0;i>2), "3" (sig_shift) @@ -95,295 +94,3 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len) return sig_shift; } -#define OVERRIDE_FILTER_MEM2 -void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem) -{ - int i,j; - spx_sig_t xi,yi,nyi; - - for (i=0;i -void filter_mem2_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) +void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) { __m128 num[3], den[3], mem[3]; @@ -87,7 +87,7 @@ void filter_mem2_10(const float *x, const float *_num, const float *_den, float _mm_store_ss(_mem+9, mem[2]); } -void filter_mem2_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) +void filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) { __m128 num[2], den[2], mem[2]; @@ -130,18 +130,18 @@ void filter_mem2_8(const float *x, const float *_num, const float *_den, float * } -#define OVERRIDE_FILTER_MEM2 -void filter_mem2(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) +#define OVERRIDE_FILTER_MEM16 +void filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack) { if(ord==10) - filter_mem2_10(x, _num, _den, y, N, ord, _mem); + filter_mem16_10(x, _num, _den, y, N, ord, _mem); else if (ord==8) - filter_mem2_8(x, _num, _den, y, N, ord, _mem); + filter_mem16_8(x, _num, _den, y, N, ord, _mem); } -void iir_mem2_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem) +void iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem) { __m128 den[3], mem[3]; @@ -190,7 +190,7 @@ void iir_mem2_10(const float *x, const float *_den, float *y, int N, int ord, fl } -void iir_mem2_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem) +void iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem) { __m128 den[2], mem[2]; @@ -229,17 +229,17 @@ void iir_mem2_8(const float *x, const float *_den, float *y, int N, int ord, flo _mm_storeu_ps(_mem+4, mem[1]); } -#define OVERRIDE_IIR_MEM2 -void iir_mem2(const float *x, const float *_den, float *y, int N, int ord, float *_mem) +#define OVERRIDE_IIR_MEM16 +void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack) { if(ord==10) - iir_mem2_10(x, _den, y, N, ord, _mem); + iir_mem16_10(x, _den, y, N, ord, _mem); else if (ord==8) - iir_mem2_8(x, _den, y, N, ord, _mem); + iir_mem16_8(x, _den, y, N, ord, _mem); } -void fir_mem2_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem) +void fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem) { __m128 num[3], mem[3]; @@ -287,7 +287,7 @@ void fir_mem2_10(const float *x, const float *_num, float *y, int N, int ord, fl _mm_store_ss(_mem+9, mem[2]); } -void fir_mem2_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem) +void fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem) { __m128 num[2], mem[2]; @@ -326,11 +326,11 @@ void fir_mem2_8(const float *x, const float *_num, float *y, int N, int ord, flo _mm_storeu_ps(_mem+4, mem[1]); } -#define OVERRIDE_FIR_MEM2 -void fir_mem2(const float *x, const float *_num, float *y, int N, int ord, float *_mem) +#define OVERRIDE_FIR_MEM16 +void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack) { if(ord==10) - fir_mem2_10(x, _num, y, N, ord, _mem); + fir_mem16_10(x, _num, y, N, ord, _mem); else if (ord==8) - fir_mem2_8(x, _num, y, N, ord, _mem); + fir_mem16_8(x, _num, y, N, ord, _mem); } diff --git a/libs/speex/libspeex/fixed_debug.h b/libs/speex/libspeex/fixed_debug.h index 65c5712d32..54f3866e8f 100644 --- a/libs/speex/libspeex/fixed_debug.h +++ b/libs/speex/libspeex/fixed_debug.h @@ -74,53 +74,57 @@ static inline int NEG32(long long x) return res; } -static inline short EXTRACT16(int x) +#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__) +static inline short _EXTRACT16(int x, char *file, int line) { int res; if (!VERIFY_SHORT(x)) { - fprintf (stderr, "EXTRACT16: input is not short: %d\n", x); + fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); } res = x; spx_mips++; return res; } -static inline int EXTEND32(int x) +#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__) +static inline int _EXTEND32(int x, char *file, int line) { int res; if (!VERIFY_SHORT(x)) { - fprintf (stderr, "EXTRACT16: input is not short: %d\n", x); + fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); } res = x; spx_mips++; return res; } -static inline short SHR16(int a, int shift) +#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__) +static inline short _SHR16(int a, int shift, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { - fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift); + fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); } res = a>>shift; if (!VERIFY_SHORT(res)) - fprintf (stderr, "SHR16: output is not short: %d\n", res); + fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); spx_mips++; return res; } -static inline short SHL16(int a, int shift) +#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__) +static inline short _SHL16(int a, int shift, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { - fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift); + fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); } res = a<>shift; if (!VERIFY_INT(res)) + { fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); + } spx_mips++; return res; } @@ -143,62 +149,71 @@ static inline int SHL32(long long a, int shift) long long res; if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) { - fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); + fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); } res = a<>1))),shift)) +#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) -#define PSHR16(a,shift) (SHR16(ADD16(a,(1<<((shift)-1))),shift)) -#define PSHR32(a,shift) (SHR32(ADD32(a,(1<<((shift)-1))),shift)) #define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) #define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) -#define SHR(a,shift) ((a) >> (shift)) -#define SHL(a,shift) ((a) << (shift)) +//#define SHR(a,shift) ((a) >> (shift)) +//#define SHL(a,shift) ((a) << (shift)) -static inline short ADD16(int a, int b) +#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__) +static inline short _ADD16(int a, int b, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { - fprintf (stderr, "ADD16: inputs are not short: %d %d\n", a, b); + fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); } res = a+b; if (!VERIFY_SHORT(res)) - fprintf (stderr, "ADD16: output is not short: %d+%d=%d\n", a,b,res); - spx_mips++; - return res; -} -static inline short SUB16(int a, int b) -{ - int res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { - fprintf (stderr, "SUB16: inputs are not short: %d %d\n", a, b); + fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); } - res = a-b; - if (!VERIFY_SHORT(res)) - fprintf (stderr, "SUB16: output is not short: %d\n", res); spx_mips++; return res; } -static inline int ADD32(long long a, long long b) +#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__) +static inline short _SUB16(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = a-b; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} + +#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__) +static inline int _ADD32(long long a, long long b, char *file, int line) { long long res; if (!VERIFY_INT(a) || !VERIFY_INT(b)) { - fprintf (stderr, "ADD32: inputs are not int: %d %d\n", (int)a, (int)b); + fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); } res = a+b; if (!VERIFY_INT(res)) { - fprintf (stderr, "ADD32: output is not int: %d\n", (int)res); + fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); } spx_mips++; return res; @@ -220,8 +235,6 @@ static inline int SUB32(long long a, long long b) #define ADD64(a,b) (MIPS_INC(a)+(b)) -#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift)) - /* result fits in 16 bits */ static inline short MULT16_16_16(int a, int b) { @@ -237,36 +250,56 @@ static inline short MULT16_16_16(int a, int b) return res; } -static inline int MULT16_16(int a, int b) +#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__) +static inline int _MULT16_16(int a, int b, char *file, int line) { long long res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { - fprintf (stderr, "MULT16_16: inputs are not short: %d %d\n", a, b); + fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); } res = ((long long)a)*b; if (!VERIFY_INT(res)) - fprintf (stderr, "MULT16_16: output is not int: %d\n", (int)res); + fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); spx_mips++; return res; } #define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b)))) -#define MAC16_16_Q11(c,a,b) (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))) -#define MAC16_16_Q13(c,a,b) (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))) -#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) +#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))) +#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))) +#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13)))) -static inline int MULT16_32_QX(int a, long long b, int Q) +#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__) +static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line) { long long res; if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) { - fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); + fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); res = (((long long)a)*(long long)b) >> Q; if (!VERIFY_INT(res)) - fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); + fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); + spx_mips+=5; + return res; +} + +static inline int MULT16_32_PX(int a, long long b, int Q) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); + } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b); + res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<>1))>> Q; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); spx_mips+=5; return res; } @@ -278,6 +311,7 @@ static inline int MULT16_32_QX(int a, long long b, int Q) #define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13) #define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14) #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) +#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15) #define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b))) static inline int SATURATE(int a, int b) @@ -341,7 +375,9 @@ static inline short MULT16_16_Q15(int a, int b) res = ((long long)a)*b; res >>= 15; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res); + } spx_mips+=3; return res; } @@ -398,23 +434,24 @@ static inline short MULT16_16_P15(int a, int b) return res; } +#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__) -static inline int DIV32_16(long long a, long long b) +static inline int _DIV32_16(long long a, long long b, char *file, int line) { long long res; if (b==0) { - fprintf(stderr, "DIV32_16: divide by zero: %d/%d\n", (int)a, (int)b); + fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); return 0; } if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) { - fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d\n", (int)a, (int)b); + fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); } res = a/b; if (!VERIFY_SHORT(res)) { - fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d\n", (int)a,(int)b,(int)res); + fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); if (res>32767) res = 32767; if (res<-32768) @@ -423,22 +460,24 @@ static inline int DIV32_16(long long a, long long b) spx_mips+=20; return res; } -static inline int DIV32(long long a, long long b) + +#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__) +static inline int _DIV32(long long a, long long b, char *file, int line) { long long res; if (b==0) { - fprintf(stderr, "DIV32: divide by zero: %d/%d\n", (int)a, (int)b); + fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); return 0; } if (!VERIFY_INT(a) || !VERIFY_INT(b)) { - fprintf (stderr, "DIV32: inputs are not int/short: %d %d\n", (int)a, (int)b); + fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); } res = a/b; if (!VERIFY_INT(res)) - fprintf (stderr, "DIV32: output is not int: %d\n", (int)res); + fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); spx_mips+=36; return res; } diff --git a/libs/speex/libspeex/fixed_generic.h b/libs/speex/libspeex/fixed_generic.h index 375050c353..3fb096ed90 100644 --- a/libs/speex/libspeex/fixed_generic.h +++ b/libs/speex/libspeex/fixed_generic.h @@ -46,14 +46,15 @@ #define SHL16(a,shift) ((a) << (shift)) #define SHR32(a,shift) ((a) >> (shift)) #define SHL32(a,shift) ((a) << (shift)) -#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift)) -#define PSHR32(a,shift) (SHR32((a)+(1<<((shift)-1)),shift)) +#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift)) +#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) #define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) #define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) #define SHR(a,shift) ((a) >> (shift)) #define SHL(a,shift) ((spx_word32_t)(a) << (shift)) -#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift)) +#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) #define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) @@ -77,6 +78,7 @@ #define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) #define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) +#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) #define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) #define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) diff --git a/libs/speex/libspeex/jitter.c b/libs/speex/libspeex/jitter.c index 6d5f2adaee..17bd044fc3 100644 --- a/libs/speex/libspeex/jitter.c +++ b/libs/speex/libspeex/jitter.c @@ -32,283 +32,490 @@ */ +/* +TODO: +- Add short-term estimate +- Defensive programming + + warn when last returned < last desired (begative buffering) + + warn if update_delay not called between get() and tick() or is called twice in a row +- Linked list structure for holding the packets instead of the current fixed-size array + + return memory to a pool + + allow pre-allocation of the pool + + optional max number of elements +- Statistics + + drift + + loss + + late + + jitter + + buffering delay +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "misc.h" +#include "arch.h" #include #include #include -#include +#include "os_support.h" -#define LATE_BINS 10 -#define MAX_MARGIN 30 /**< Number of bins in margin histogram */ +#ifndef NULL +#define NULL 0 +#endif #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ - +#define TSUB(a,b) ((spx_int32_t)((a)-(b))) #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) -/** Jitter buffer structure */ -struct JitterBuffer_ { - spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ - spx_uint32_t current_timestamp; /**< Timestamp of the local clock (what we will *play* next) */ +#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) - char *buf[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Buffer of packets (NULL if slot is free) */ - spx_uint32_t timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ - int span[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ - int len[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Number of bytes in packet */ +#define MAX_TIMINGS 40 +#define MAX_BUFFERS 3 +#define TOP_DELAY 40 - int tick_size; /**< Output granularity */ - int reset_state; /**< True if state was just reset */ - int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ - - int lost_count; /**< Number of consecutive lost packets */ - float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ - float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ - float loss_rate; /**< Average loss rate */ +/** Buffer that keeps the time of arrival of the latest packets */ +struct TimingBuffer { + int filled; /**< Number of entries occupied in "timing" and "counts"*/ + int curr_count; /**< Number of packet timings we got (including those we discarded) */ + spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ + spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ }; +static void tb_init(struct TimingBuffer *tb) +{ + tb->filled = 0; + tb->curr_count = 0; +} + +/* Add the timing of a new packet to the TimingBuffer */ +static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) +{ + int pos; + /* Discard packet that won't make it into the list because they're too early */ + if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) + { + tb->curr_count++; + return; + } + + /* Find where the timing info goes in the sorted list */ + pos = 0; + /* FIXME: Do bisection instead of linear search */ + while (posfilled && timing >= tb->timing[pos]) + { + pos++; + } + + speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); + + /* Shift everything so we can perform the insertion */ + if (pos < tb->filled) + { + int move_size = tb->filled-pos; + if (tb->filled == MAX_TIMINGS) + move_size -= 1; + SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size); + SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size); + } + /* Insert */ + tb->timing[pos] = timing; + tb->counts[pos] = tb->curr_count; + + tb->curr_count++; + if (tb->filledfilled++; +} + + + +/** Jitter buffer structure */ +struct JitterBuffer_ { + spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ + spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ + spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ + + spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ + + JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ + spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ + + void (*destroy) (void *); /**< Callback for destroying a packet */ + + spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ + spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */ + int reset_state; /**< True if state was just reset */ + int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ + int late_cutoff; /**< How late must a packet be for it not to be considered at all */ + int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ + int auto_adjust; /**< Whether to automatically adjust the delay at any time */ + + struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ + struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ + int window_size; /**< Total window over which the late frames are counted */ + int subwindow_size; /**< Sub-window size for faster computation */ + int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ + int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ + int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ + + int lost_count; /**< Number of consecutive lost packets */ +}; + +/** Based on available data, this computes the optimal delay for the jitter buffer. + The optimised function is in timestamp units and is: + cost = delay + late_factor*[number of frames that would be late if we used that delay] + @param tb Array of buffers + @param late_factor Equivalent cost of a late frame (in timestamp units) + */ +static spx_int16_t compute_opt_delay(JitterBuffer *jitter) +{ + int i; + spx_int16_t opt=0; + spx_int32_t best_cost=0x7fffffff; + int late = 0; + int pos[MAX_BUFFERS]; + int tot_count; + float late_factor; + int penalty_taken = 0; + int best = 0; + int worst = 0; + spx_int32_t deltaT; + struct TimingBuffer *tb; + + tb = jitter->_tb; + + /* Number of packet timings we have received (including those we didn't keep) */ + tot_count = 0; + for (i=0;ilatency_tradeoff != 0) + late_factor = jitter->latency_tradeoff * 100.0f / tot_count; + else + late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; + + /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ + for (i=0;idelay_step); + pos[next]++; + + /* Actual cost function that tells us how bad using this delay would be */ + cost = -latest + late_factor*late; + /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ + if (cost < best_cost) + { + best_cost = cost; + opt = latest; + } + } else { + break; + } + + /* For the next timing we will consider, there will be one more late packet to count */ + late++; + /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ + if (latest >= 0 && !penalty_taken) + { + penalty_taken = 1; + late+=4; + } + } + + deltaT = best-worst; + /* This is a default "automatic latency tradeoff" when none is provided */ + jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; + /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ + + /* FIXME: Compute a short-term estimate too and combine with the long-term one */ + + /* Prevents reducing the buffer size when we haven't really had much data */ + if (tot_count < TOP_DELAY && opt > 0) + return 0; + return opt; +} + + /** Initialise jitter buffer */ -JitterBuffer *jitter_buffer_init(int tick) +EXPORT JitterBuffer *jitter_buffer_init(int step_size) { JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); if (jitter) { int i; + spx_int32_t tmp; for (i=0;ibuf[i]=NULL; - jitter->tick_size = tick; - jitter->buffer_margin = 1; + jitter->packets[i].data=NULL; + jitter->delay_step = step_size; + jitter->concealment_size = step_size; + /*FIXME: Should this be 0 or 1?*/ + jitter->buffer_margin = 0; + jitter->late_cutoff = 50; + jitter->destroy = NULL; + jitter->latency_tradeoff = 0; + jitter->auto_adjust = 1; + tmp = 4; + jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); jitter_buffer_reset(jitter); } return jitter; } /** Reset jitter buffer */ -void jitter_buffer_reset(JitterBuffer *jitter) +EXPORT void jitter_buffer_reset(JitterBuffer *jitter) { int i; for (i=0;ibuf[i]) + if (jitter->packets[i].data) { - speex_free(jitter->buf[i]); - jitter->buf[i] = NULL; + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; } } /* Timestamp is actually undefined at this point */ jitter->pointer_timestamp = 0; - jitter->current_timestamp = 0; + jitter->next_stop = 0; jitter->reset_state = 1; jitter->lost_count = 0; - jitter->loss_rate = 0; - for (i=0;ibuffered = 0; + jitter->auto_tradeoff = 32000; + + for (i=0;ishortterm_margin[i] = 0; - jitter->longterm_margin[i] = 0; + tb_init(&jitter->_tb[i]); + jitter->timeBuffers[i] = &jitter->_tb[i]; } /*fprintf (stderr, "reset\n");*/ } /** Destroy jitter buffer */ -void jitter_buffer_destroy(JitterBuffer *jitter) +EXPORT void jitter_buffer_destroy(JitterBuffer *jitter) { jitter_buffer_reset(jitter); speex_free(jitter); } +/** Take the following timing into consideration for future calculations */ +static void update_timings(JitterBuffer *jitter, spx_int32_t timing) +{ + if (timing < -32767) + timing = -32767; + if (timing > 32767) + timing = 32767; + /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */ + if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size) + { + int i; + /*fprintf(stderr, "Rotate buffer\n");*/ + struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; + for (i=MAX_BUFFERS-1;i>=1;i--) + jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; + jitter->timeBuffers[0] = tmp; + tb_init(jitter->timeBuffers[0]); + } + tb_add(jitter->timeBuffers[0], timing); +} + +/** Compensate all timings when we do an adjustment of the buffering */ +static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) +{ + int i, j; + for (i=0;itimeBuffers[i]->filled;j++) + jitter->timeBuffers[i]->timing[j] += amount; + } +} + + /** Put one packet into the jitter buffer */ -void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) +EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) { int i,j; - spx_int32_t arrival_margin; + int late; /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ - if (jitter->reset_state) - { - jitter->reset_state=0; - jitter->pointer_timestamp = packet->timestamp; - jitter->current_timestamp = packet->timestamp; - /*fprintf(stderr, "reset to %d\n", timestamp);*/ - } /* Cleanup buffer (remove old packets that weren't played) */ - for (i=0;ireset_state) { - if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp)) + for (i=0;ibuf[i]); - jitter->buf[i] = NULL; - } - } - - /*Find an empty slot in the buffer*/ - for (i=0;ibuf[i]==NULL) - break; - } - - /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/ - /*No place left in the buffer*/ - if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) - { - int earliest=jitter->timestamp[0]; - i=0; - for (j=1;jbuf[i] || LT32(jitter->timestamp[j],earliest)) + /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) { - earliest = jitter->timestamp[j]; - i=j; + /*fprintf (stderr, "cleaned (not played)\n");*/ + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; } } - speex_free(jitter->buf[i]); - jitter->buf[i]=NULL; - if (jitter->lost_count>20) - { - jitter_buffer_reset(jitter); - } - /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ } - /* Copy packet in buffer */ - jitter->buf[i]=(char*)speex_alloc(packet->len); - for (j=0;jlen;j++) - jitter->buf[i][j]=packet->data[j]; - jitter->timestamp[i]=packet->timestamp; - jitter->span[i]=packet->span; - jitter->len[i]=packet->len; - - /* Adjust the buffer size depending on network conditions */ - arrival_margin = (packet->timestamp - jitter->current_timestamp) - jitter->buffer_margin*jitter->tick_size; - - if (arrival_margin >= -LATE_BINS*jitter->tick_size) + /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ + /* Check if packet is late (could still be useful though) */ + if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) { - spx_int32_t int_margin; - for (i=0;ishortterm_margin[i] *= .98; - jitter->longterm_margin[i] *= .995; - } - int_margin = LATE_BINS + arrival_margin/jitter->tick_size; - if (int_margin>MAX_MARGIN-1) - int_margin = MAX_MARGIN-1; - if (int_margin>=0) - { - jitter->shortterm_margin[int_margin] += .02; - jitter->longterm_margin[int_margin] += .005; - } + update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); + late = 1; } else { - - /*fprintf (stderr, "way too late = %d\n", arrival_margin);*/ - if (jitter->lost_count>20) - { - jitter_buffer_reset(jitter); - } + late = 0; } -#if 0 /* Enable to check how much is being buffered */ - if (rand()%1000==0) + + /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is + * used to resync. */ + if (jitter->lost_count>20) { - int count = 0; - for (j=0;jbuf[j]) - count++; - } - fprintf (stderr, "buffer_size = %d\n", count); + jitter_buffer_reset(jitter); } -#endif + + /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ + if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) + { + + /*Find an empty slot in the buffer*/ + for (i=0;ipackets[i].data==NULL) + break; + } + + /*No place left in the buffer, need to make room for it by discarding the oldest packet */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int earliest=jitter->packets[0].timestamp; + i=0; + for (j=1;jpackets[i].data || LT32(jitter->packets[j].timestamp,earliest)) + { + earliest = jitter->packets[j].timestamp; + i=j; + } + } + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data=NULL; + /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ + } + + /* Copy packet in buffer */ + if (jitter->destroy) + { + jitter->packets[i].data = packet->data; + } else { + jitter->packets[i].data=(char*)speex_alloc(packet->len); + for (j=0;jlen;j++) + jitter->packets[i].data[j]=packet->data[j]; + } + jitter->packets[i].timestamp=packet->timestamp; + jitter->packets[i].span=packet->span; + jitter->packets[i].len=packet->len; + jitter->packets[i].sequence=packet->sequence; + jitter->packets[i].user_data=packet->user_data; + if (jitter->reset_state || late) + jitter->arrival[i] = 0; + else + jitter->arrival[i] = jitter->next_stop; + } + + } /** Get one packet from the jitter buffer */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *start_offset) +EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) { - int i, j; - float late_ratio_short; - float late_ratio_long; - float ontime_ratio_short; - float ontime_ratio_long; - float early_ratio_short; - float early_ratio_long; - int chunk_size; + int i; + unsigned int j; int incomplete = 0; + spx_int16_t opt; - if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) - { - jitter->current_timestamp = jitter->pointer_timestamp; - speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); - } - /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ + if (start_offset != NULL) + *start_offset = 0; - /* FIXME: This should be only what remaining of the current tick */ - chunk_size = jitter->tick_size; - - /* Compiling arrival statistics */ - - late_ratio_short = 0; - late_ratio_long = 0; - for (i=0;ireset_state) { - late_ratio_short += jitter->shortterm_margin[i]; - late_ratio_long += jitter->longterm_margin[i]; - } - ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; - ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; - early_ratio_short = early_ratio_long = 0; - for (i=LATE_BINS+1;ishortterm_margin[i]; - early_ratio_long += jitter->longterm_margin[i]; - } - if (0&&jitter->pointer_timestamp%1000==0) - { - /*fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);*/ - /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/ - } - - /* Adjusting the buffering */ - - if (late_ratio_short > .1 || late_ratio_long > .03) - { - /* If too many packets are arriving late */ - jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; - jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; - for (i=MAX_MARGIN-3;i>=0;i--) + int found = 0; + /* Find the oldest packet */ + spx_uint32_t oldest=0; + for (i=0;ishortterm_margin[i+1] = jitter->shortterm_margin[i]; - jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; + if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest))) + { + oldest = jitter->packets[i].timestamp; + found = 1; + } } - jitter->shortterm_margin[0] = 0; - jitter->longterm_margin[0] = 0; - jitter->pointer_timestamp -= jitter->tick_size; - jitter->current_timestamp -= jitter->tick_size; - /*fprintf (stderr, "i");*/ - /*fprintf (stderr, "interpolate (getting some slack)\n");*/ - } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8) - { - /* Many frames arriving early */ - jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; - jitter->longterm_margin[0] += jitter->longterm_margin[1]; - for (i=1;ishortterm_margin[i] = jitter->shortterm_margin[i+1]; - jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; + jitter->reset_state=0; + jitter->pointer_timestamp = oldest; + jitter->next_stop = oldest; + } else { + packet->timestamp = 0; + packet->span = jitter->interp_requested; + return JITTER_BUFFER_MISSING; } - jitter->shortterm_margin[MAX_MARGIN-1] = 0; - jitter->longterm_margin[MAX_MARGIN-1] = 0; - /*fprintf (stderr, "drop frame\n");*/ - /*fprintf (stderr, "d");*/ - jitter->pointer_timestamp += jitter->tick_size; - jitter->current_timestamp += jitter->tick_size; - /*fprintf (stderr, "dropping packet (getting more aggressive)\n");*/ + } + + + jitter->last_returned_timestamp = jitter->pointer_timestamp; + + if (jitter->interp_requested != 0) + { + packet->timestamp = jitter->pointer_timestamp; + packet->span = jitter->interp_requested; + + /* Increment the pointer because it got decremented in the delay update */ + jitter->pointer_timestamp += jitter->interp_requested; + packet->len = 0; + /*fprintf (stderr, "Deferred interpolate\n");*/ + + jitter->interp_requested = 0; + + jitter->buffered = packet->span - desired_span; + + return JITTER_BUFFER_INSERTION; } /* Searching for the packet that fits best */ @@ -316,7 +523,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ for (i=0;ibuf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) break; } @@ -325,7 +532,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint { for (i=0;ibuf[i] && jitter->timestamp[i]<=jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) break; } } @@ -335,7 +542,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint { for (i=0;ibuf[i] && jitter->timestamp[i]<=jitter->pointer_timestamp && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp)) + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp)) break; } } @@ -350,12 +557,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint for (i=0;ibuf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp)) + if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) { - if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span))) + if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) { - best_time = jitter->timestamp[i]; - best_span = jitter->span[i]; + best_time = jitter->packets[i].timestamp; + best_span = jitter->packets[i].span; besti = i; found = 1; } @@ -365,144 +572,272 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint { i=besti; incomplete = 1; - /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/ + /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ } } /* If we find something */ if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) { + spx_int32_t offset; + /* We (obviously) haven't lost this packet */ jitter->lost_count = 0; - jitter->loss_rate = .999*jitter->loss_rate; - /* Check for potential overflow */ - packet->len = jitter->len[i]; + + /* In this case, 0 isn't as a valid timestamp */ + if (jitter->arrival[i] != 0) + { + update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); + } + + /* Copy packet */ - for (j=0;jlen;j++) - packet->data[j] = jitter->buf[i][j]; - /* Remove packet */ - speex_free(jitter->buf[i]); - jitter->buf[i] = NULL; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + packet->len = jitter->packets[i].len; + } else { + if (jitter->packets[i].len > packet->len) + { + speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); + } else { + packet->len = jitter->packets[i].len; + } + for (j=0;jlen;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; /* Set timestamp and span (if requested) */ - if (start_offset) - *start_offset = jitter->timestamp[i]-jitter->pointer_timestamp; - packet->timestamp = jitter->timestamp[i]; - packet->span = jitter->span[i]; - /* Point at the end of the current packet */ - jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i]; - if (incomplete) - return JITTER_BUFFER_INCOMPLETE; - else - return JITTER_BUFFER_OK; + offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; + if (start_offset != NULL) + *start_offset = offset; + else if (offset != 0) + speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); + + packet->timestamp = jitter->packets[i].timestamp; + jitter->last_returned_timestamp = packet->timestamp; + + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + /* Point to the end of the current packet */ + jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; + + jitter->buffered = packet->span - desired_span; + + if (start_offset != NULL) + jitter->buffered += *start_offset; + + return JITTER_BUFFER_OK; } /* If we haven't found anything worth returning */ + /*fprintf (stderr, "not found\n");*/ jitter->lost_count++; /*fprintf (stderr, "m");*/ /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ - jitter->loss_rate = .999*jitter->loss_rate + .001; - if (start_offset) - *start_offset = 0; - packet->timestamp = jitter->pointer_timestamp; - packet->span = jitter->tick_size; - jitter->pointer_timestamp += chunk_size; - packet->len = 0; - return JITTER_BUFFER_MISSING; + + opt = compute_opt_delay(jitter); + + /* Should we force an increase in the buffer or just do normal interpolation? */ + if (opt < 0) + { + /* Need to increase buffering */ + + /* Shift histogram to compensate */ + shift_timings(jitter, -opt); + + packet->timestamp = jitter->pointer_timestamp; + packet->span = -opt; + /* Don't move the pointer_timestamp forward */ + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_INSERTION; + /*jitter->pointer_timestamp -= jitter->delay_step;*/ + /*fprintf (stderr, "Forced to interpolate\n");*/ + } else { + /* Normal packet loss */ + packet->timestamp = jitter->pointer_timestamp; + + desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); + packet->span = desired_span; + jitter->pointer_timestamp += desired_span; + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_MISSING; + /*fprintf (stderr, "Normal loss\n");*/ + } + } +EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) +{ + int i, j; + for (i=0;ipackets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) + break; + } + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + /* Copy packet */ + packet->len = jitter->packets[i].len; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + } else { + for (j=0;jlen;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + packet->timestamp = jitter->packets[i].timestamp; + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + return JITTER_BUFFER_OK; + } else { + packet->data = NULL; + packet->len = 0; + packet->span = 0; + return JITTER_BUFFER_MISSING; + } +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + spx_int16_t opt = compute_opt_delay(jitter); + /*fprintf(stderr, "opt adjustment is %d ", opt);*/ + + if (opt < 0) + { + shift_timings(jitter, -opt); + + jitter->pointer_timestamp += opt; + jitter->interp_requested = -opt; + /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ + } else if (opt > 0) + { + shift_timings(jitter, -opt); + jitter->pointer_timestamp += opt; + /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ + } + + return opt; +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + /* If the programmer calls jitter_buffer_update_delay() directly, + automatically disable auto-adjustment */ + jitter->auto_adjust = 0; + + return _jitter_buffer_update_delay(jitter, packet, start_offset); +} + /** Get pointer timestamp of jitter buffer */ -int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) +EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) { return jitter->pointer_timestamp; } -void jitter_buffer_tick(JitterBuffer *jitter) +EXPORT void jitter_buffer_tick(JitterBuffer *jitter) { - jitter->current_timestamp += jitter->tick_size; -} - - - - - -void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate) -{ - jitter->dec = decoder; - speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size); - - jitter->packets = jitter_buffer_init(jitter->frame_size); - - speex_bits_init(&jitter->current_packet); - jitter->valid_bits = 0; - -} - -void speex_jitter_destroy(SpeexJitter *jitter) -{ - jitter_buffer_destroy(jitter->packets); - speex_bits_destroy(&jitter->current_packet); -} - -void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp) -{ - JitterBufferPacket p; - p.data = packet; - p.len = len; - p.timestamp = timestamp; - p.span = jitter->frame_size; - jitter_buffer_put(jitter->packets, &p); -} - -void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp) -{ - int i; - int ret; - char data[2048]; - JitterBufferPacket packet; - packet.data = data; + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); - if (jitter->valid_bits) + if (jitter->buffered >= 0) { - /* Try decoding last received packet */ - ret = speex_decode_int(jitter->dec, &jitter->current_packet, out); - if (ret == 0) - { - jitter_buffer_tick(jitter->packets); - return; - } else { - jitter->valid_bits = 0; - } - } - - ret = jitter_buffer_get(jitter->packets, &packet, NULL); - - if (ret != JITTER_BUFFER_OK) - { - /* No packet found */ - - /*fprintf (stderr, "lost/late frame\n");*/ - /*Packet is late or lost*/ - speex_decode_int(jitter->dec, NULL, out); + jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; } else { - speex_bits_read_from(&jitter->current_packet, packet.data, packet.len); - /* Decode packet */ - ret = speex_decode_int(jitter->dec, &jitter->current_packet, out); - if (ret == 0) - { - jitter->valid_bits = 1; - } else { - /* Error while decoding */ - for (i=0;iframe_size;i++) - out[i]=0; - } + jitter->next_stop = jitter->pointer_timestamp; + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); } - jitter_buffer_tick(jitter->packets); + jitter->buffered = 0; } -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter) +EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) { - return jitter_buffer_get_pointer_timestamp(jitter->packets); + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); + + if (jitter->buffered < 0) + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); + jitter->next_stop = jitter->pointer_timestamp - rem; } + + +/* Used like the ioctl function to control the jitter buffer parameters */ +EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) +{ + int count, i; + switch(request) + { + case JITTER_BUFFER_SET_MARGIN: + jitter->buffer_margin = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_MARGIN: + *(spx_int32_t*)ptr = jitter->buffer_margin; + break; + case JITTER_BUFFER_GET_AVALIABLE_COUNT: + count = 0; + for (i=0;ipackets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) + { + count++; + } + } + *(spx_int32_t*)ptr = count; + break; + case JITTER_BUFFER_SET_DESTROY_CALLBACK: + jitter->destroy = (void (*) (void *))ptr; + break; + case JITTER_BUFFER_GET_DESTROY_CALLBACK: + *(void (**) (void *))ptr = jitter->destroy; + break; + case JITTER_BUFFER_SET_DELAY_STEP: + jitter->delay_step = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_DELAY_STEP: + *(spx_int32_t*)ptr = jitter->delay_step; + break; + case JITTER_BUFFER_SET_CONCEALMENT_SIZE: + jitter->concealment_size = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_CONCEALMENT_SIZE: + *(spx_int32_t*)ptr = jitter->concealment_size; + break; + case JITTER_BUFFER_SET_MAX_LATE_RATE: + jitter->max_late_rate = *(spx_int32_t*)ptr; + jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate; + jitter->subwindow_size = jitter->window_size/MAX_BUFFERS; + break; + case JITTER_BUFFER_GET_MAX_LATE_RATE: + *(spx_int32_t*)ptr = jitter->max_late_rate; + break; + case JITTER_BUFFER_SET_LATE_COST: + jitter->latency_tradeoff = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_LATE_COST: + *(spx_int32_t*)ptr = jitter->latency_tradeoff; + break; + default: + speex_warning_int("Unknown jitter_buffer_ctl request: ", request); + return -1; + } + return 0; +} + diff --git a/libs/speex/libspeex/kiss_fft.c b/libs/speex/libspeex/kiss_fft.c index a0b3724be0..67782810fe 100644 --- a/libs/speex/libspeex/kiss_fft.c +++ b/libs/speex/libspeex/kiss_fft.c @@ -1,5 +1,6 @@ /* Copyright (c) 2003-2004, Mark Borgerding +Copyright (c) 2005-2007, Jean-Marc Valin All rights reserved. @@ -18,127 +19,149 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #endif #include "_kiss_fft_guts.h" -#include "misc.h" +#include "arch.h" +#include "os_support.h" /* The guts header contains all the multiplication and addition macros that are defined for fixed or floating point complex numbers. It also delares the kf_ internal functions. */ -static kiss_fft_cpx *scratchbuf=NULL; -static size_t nscratchbuf=0; -static kiss_fft_cpx *tmpbuf=NULL; -static size_t ntmpbuf=0; - -#define CHECKBUF(buf,nbuf,n) \ - do { \ - if ( nbuf < (size_t)(n) ) {\ - speex_free(buf); \ - buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(sizeof(kiss_fft_cpx)*(n)); \ - nbuf = (size_t)(n); \ - } \ - }while(0) - static void kf_bfly2( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, - int m + int m, + int N, + int mm ) { kiss_fft_cpx * Fout2; - kiss_fft_cpx * tw1 = st->twiddles; + kiss_fft_cpx * tw1; kiss_fft_cpx t; - Fout2 = Fout + m; if (!st->inverse) { - int i; - kiss_fft_cpx *x=Fout; - for (i=0;i<2*m;i++) + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;itwiddles; + for(j=0;jr , 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;itwiddles; + for(j=0;jtwiddles; - - if (!st->inverse) { - int i; - kiss_fft_cpx *x=Fout; - for (i=0;i<4*m;i++) - { - x[i].r = PSHR16(x[i].r,2); - x[i].i = PSHR16(x[i].i,2); - } - } if (st->inverse) { - do { - C_MUL(scratch[0],Fout[m] , *tw1 ); - C_MUL(scratch[1],Fout[m2] , *tw2 ); - C_MUL(scratch[2],Fout[m3] , *tw3 ); - - C_SUB( scratch[5] , *Fout, scratch[1] ); - C_ADDTO(*Fout, scratch[1]); - C_ADD( scratch[3] , scratch[0] , scratch[2] ); - C_SUB( scratch[4] , scratch[0] , scratch[2] ); - C_SUB( Fout[m2], *Fout, scratch[3] ); - tw1 += fstride; - tw2 += fstride*2; - tw3 += fstride*3; - C_ADDTO( *Fout , scratch[3] ); - - Fout[m].r = scratch[5].r - scratch[4].i; - Fout[m].i = scratch[5].i + scratch[4].r; - Fout[m3].r = scratch[5].r + scratch[4].i; - Fout[m3].i = scratch[5].i - scratch[4].r; - ++Fout; - } while(--k); + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;itwiddles; + for (j=0;jtwiddles; + for (j=0;jr = PSHR16(Fout->r, 2); + Fout->i = PSHR16(Fout->i, 2); + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + Fout[m2].r = PSHR16(Fout[m2].r, 2); + Fout[m2].i = PSHR16(Fout[m2].i, 2); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + ++Fout; + } + } } } @@ -263,10 +286,13 @@ static void kf_bfly_generic( int u,k,q1,q; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx t; + kiss_fft_cpx scratchbuf[17]; int Norig = st->nfft; - CHECKBUF(scratchbuf,nscratchbuf,p); - + /*CHECKBUF(scratchbuf,nscratchbuf,p);*/ + if (p>17) + speex_fatal("KissFFT: max radix supported is 17"); + for ( u=0; u floor_sqrt) + if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n) p = n; /* no more factors, skip to end */ } n /= p; @@ -357,7 +454,6 @@ void kf_factor(int n,int * facbuf) *facbuf++ = n; } while (n > 1); } - /* * * User-callable function to allocate all necessary storage space for the fft. @@ -382,15 +478,22 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem int i; st->nfft=nfft; st->inverse = inverse_fft; - +#ifdef FIXED_POINT for (i=0;iinverse) - phase *= -1; - kf_cexp(st->twiddles+i, phase ); + spx_word32_t phase = i; + if (!st->inverse) + phase = -phase; + kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft)); } - +#else + for (i=0;iinverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } +#endif kf_factor(nfft,st->factors); } return st; @@ -401,12 +504,15 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { - if (fin == fout) { - CHECKBUF(tmpbuf,ntmpbuf,st->nfft); - kf_work(tmpbuf,fin,1,in_stride, st->factors,st); - speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); - }else{ - kf_work( fout, fin, 1,in_stride, st->factors,st ); + if (fin == fout) + { + speex_fatal("In-place FFT not supported"); + /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + SPEEX_MOVE(fout,tmpbuf,st->nfft);*/ + } else { + kf_shuffle( fout, fin, 1,in_stride, st->factors,st); + kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); } } @@ -415,16 +521,3 @@ void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) kiss_fft_stride(cfg,fin,fout,1); } - -/* not really necessary to call, but if someone is doing in-place ffts, they may want to free the - buffers from CHECKBUF - */ -void kiss_fft_cleanup(void) -{ - speex_free(scratchbuf); - scratchbuf = NULL; - nscratchbuf=0; - speex_free(tmpbuf); - tmpbuf=NULL; - ntmpbuf=0; -} diff --git a/libs/speex/libspeex/kiss_fft.h b/libs/speex/libspeex/kiss_fft.h index 54627e7da0..fa3f2c6042 100644 --- a/libs/speex/libspeex/kiss_fft.h +++ b/libs/speex/libspeex/kiss_fft.h @@ -3,7 +3,7 @@ #include #include -#include "misc.h" +#include "arch.h" #ifdef __cplusplus extern "C" { @@ -32,7 +32,7 @@ extern "C" { #ifdef FIXED_POINT -#include "misc.h" +#include "arch.h" # define kiss_fft_scalar spx_int16_t #else # ifndef kiss_fft_scalar diff --git a/libs/speex/libspeex/kiss_fftr.c b/libs/speex/libspeex/kiss_fftr.c index b90b7254ce..f6275b8794 100644 --- a/libs/speex/libspeex/kiss_fftr.c +++ b/libs/speex/libspeex/kiss_fftr.c @@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #include "config.h" #endif +#include "os_support.h" #include "kiss_fftr.h" #include "_kiss_fft_guts.h" @@ -58,13 +59,22 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme st->super_twiddles = st->tmpbuf + nfft; kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); - for (i = 0; i < nfft; ++i) { - double phase = - -3.14159265358979323846264338327 * ((double) i / nfft + .5); - if (inverse_fft) - phase *= -1; - kf_cexp (st->super_twiddles+i,phase); +#ifdef FIXED_POINT + for (i=0;i>1); + if (!inverse_fft) + phase = -phase; + kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft)); } +#else + for (i=0;isuper_twiddles+i, phase ); + } +#endif return st; } @@ -75,8 +85,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; if ( st->substate->inverse) { - speex_warning("kiss fft usage error: improper alloc\n"); - exit(1); + speex_fatal("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; @@ -124,14 +133,13 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr } } -void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata) { /* input buffer timedata is stored row-wise */ int k, ncfft; if (st->substate->inverse == 0) { - speex_warning ("kiss fft usage error: improper alloc\n"); - exit (1); + speex_fatal("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; @@ -161,3 +169,129 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t } kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); } + +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx f2k,tdc; + spx_word32_t f1kr, f1ki, twr, twi; + + if ( st->substate->inverse) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0] = tdc.r + tdc.i; + freqdata[2*ncfft-1] = tdc.r - tdc.i; + + for ( k=1;k <= ncfft/2 ; ++k ) + { + /*fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + + /*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13); + f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13); + + twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1); + twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1); + +#ifdef FIXED_POINT + freqdata[2*k-1] = PSHR32(f1kr + twr, 15); + freqdata[2*k] = PSHR32(f1ki + twi, 15); + freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15); + freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15); +#else + freqdata[2*k-1] = .5f*(f1kr + twr); + freqdata[2*k] = .5f*(f1ki + twi); + freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr); + freqdata[2*(ncfft-k)] = .5f*(twi - f1ki); + +#endif + } +} + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + speex_fatal ("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1]; + st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1]; + /*C_FIXDIV(st->tmpbuf[0],2);*/ + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk.r = freqdata[2*k-1]; + fk.i = freqdata[2*k]; + fnkc.r = freqdata[2*(ncfft - k)-1]; + fnkc.i = -freqdata[2*(ncfft - k)]; + /*C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 );*/ + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} diff --git a/libs/speex/libspeex/kiss_fftr.h b/libs/speex/libspeex/kiss_fftr.h index 2e8351a640..7bfb423340 100644 --- a/libs/speex/libspeex/kiss_fftr.h +++ b/libs/speex/libspeex/kiss_fftr.h @@ -32,7 +32,12 @@ void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *f output freqdata has nfft/2+1 complex points */ +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata); + void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata); + /* input freqdata has nfft/2+1 complex points output timedata has nfft scalar points diff --git a/libs/speex/libspeex/lpc.h b/libs/speex/libspeex/lpc.h index d64df96741..952ecdd933 100644 --- a/libs/speex/libspeex/lpc.h +++ b/libs/speex/libspeex/lpc.h @@ -35,7 +35,7 @@ #ifndef LPC_H #define LPC_H -#include "misc.h" +#include "arch.h" void _spx_autocorr( const spx_word16_t * x, /* in: [0...n-1] samples x */ diff --git a/libs/speex/libspeex/lsp.c b/libs/speex/libspeex/lsp.c index 3fdc08aab3..a73d8835f0 100644 --- a/libs/speex/libspeex/lsp.c +++ b/libs/speex/libspeex/lsp.c @@ -509,7 +509,7 @@ void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack) /* hard limit ak's to +/- 32767 */ - if (a < -32767) a = 32767; + if (a < -32767) a = -32767; if (a > 32767) a = 32767; ak[j-1] = (short)a; diff --git a/libs/speex/libspeex/lsp.h b/libs/speex/libspeex/lsp.h index 6266f42fb5..b55bd42f2c 100644 --- a/libs/speex/libspeex/lsp.h +++ b/libs/speex/libspeex/lsp.h @@ -51,7 +51,7 @@ Modified by Jean-Marc Valin #ifndef __AK2LSPD__ #define __AK2LSPD__ -#include "misc.h" +#include "arch.h" int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); diff --git a/libs/speex/libspeex/ltp.c b/libs/speex/libspeex/ltp.c index 27e4f4de2d..0129c95f15 100644 --- a/libs/speex/libspeex/ltp.c +++ b/libs/speex/libspeex/ltp.c @@ -40,6 +40,7 @@ #include "filters.h" #include #include "math_approx.h" +#include "os_support.h" #ifndef NULL #define NULL 0 @@ -176,20 +177,56 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p VARDECL(spx_word32_t *best_ener); spx_word32_t e0; VARDECL(spx_word32_t *corr); +#ifdef FIXED_POINT + /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) + arrays for (normalized) 16-bit values */ + VARDECL(spx_word16_t *corr16); + VARDECL(spx_word16_t *ener16); + spx_word32_t *energy; + int cshift=0, eshift=0; + int scaledown = 0; + ALLOC(corr16, end-start+1, spx_word16_t); + ALLOC(ener16, end-start+1, spx_word16_t); + ALLOC(corr, end-start+1, spx_word32_t); + energy = corr; +#else + /* In floating-point, we need to float arrays and no normalized copies */ VARDECL(spx_word32_t *energy); - + spx_word16_t *corr16; + spx_word16_t *ener16; + ALLOC(energy, end-start+2, spx_word32_t); + ALLOC(corr, end-start+1, spx_word32_t); + corr16 = corr; + ener16 = energy; +#endif + ALLOC(best_score, N, spx_word32_t); ALLOC(best_ener, N, spx_word32_t); - ALLOC(corr, end-start+1, spx_word32_t); - ALLOC(energy, end-start+2, spx_word32_t); - for (i=0;i16383) + { + scaledown=1; + break; + } + } + /* If the weighted input is close to saturation, then we scale it down */ + if (scaledown) + { + for (i=-end;iMULT16_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;jMULT16_16(best_score[j],ADD16(1,ener16[i-start]))) - { - for (k=N-1;k>j;k--) - { - best_score[k]=best_score[k-1]; - best_ener[k]=best_ener[k-1]; - pitch[k]=pitch[k-1]; - } - best_score[j]=tmp; - best_ener[j]=ener16[i-start]+1; - pitch[j]=i; - break; - } - } - } + sw[i]=SHL16(sw[i],1); } - } -#else + } +#endif + + /* Search for the best pitch prediction gain */ for (i=start;i<=end;i++) { - float tmp = corr[i-start]*corr[i-start]; - if (tmp*best_ener[N-1]>best_score[N-1]*(1+energy[i-start])) + spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); + /* Instead of dividing the tmp by the energy, we multiply on the other side */ + if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) { - for (j=0;jbest_score[j]*(1+energy[i-start])) + if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) { for (k=N-1;k>j;k--) { @@ -260,29 +280,30 @@ void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *p pitch[k]=pitch[k-1]; } best_score[j]=tmp; - best_ener[j]=energy[i-start]+1; + best_ener[j]=ener16[i-start]+1; pitch[j]=i; break; } } } } -#endif - - /* Compute open-loop gain */ + + /* Compute open-loop gain if necessary */ if (gain) { - for (j=0;j=0;i--) { spx_word16_t e0=exc2[-pitch-1+i]; +#ifdef FIXED_POINT + /* Scale excitation down if needed (avoiding overflow) */ + if (scaledown) + e0 = SHR16(e0,1); +#endif x[i][0]=MULT16_16_Q14(r[0], e0); for (j=0;jpitch_bits); speex_bits_pack(bits, 0, params->gain_bits); - for (i=0;i16383) + { + scaledown=1; + break; + } + } + for (i=-end;i16383) + { + scaledown=1; + break; + } + } +#endif if (N>end-start+1) N=end-start+1; if (end != start) @@ -559,16 +617,13 @@ spx_word32_t *cumul_gain for (i=0;i63) pitch_coef=63; @@ -734,9 +793,11 @@ spx_word32_t *cumul_gain { exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); } - syn_percep_zero(exc, ak, awk1, awk2, res, nsf, p, stack); for (i=0;i -#include "misc.h" +#include "arch.h" /** LTP parameters. */ typedef struct { diff --git a/libs/speex/libspeex/ltp_arm4.h b/libs/speex/libspeex/ltp_arm4.h index 7479e8bfd0..cdb94e603a 100644 --- a/libs/speex/libspeex/ltp_arm4.h +++ b/libs/speex/libspeex/ltp_arm4.h @@ -75,9 +75,10 @@ spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) "\tadd %2, %2, %7, asr #5\n" "\tadd %3, %3, %10, asr #5\n" "\tbne .inner_prod_loop%=\n" - : "=r" (deadx), "=r" (deady), "=r" (sum1), "=r" (sum2), "=r" (deadlen), - "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6) - : "0" (x), "1" (y), "2" (sum1), "3" (sum2), "4" (len>>3) + : "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2), + "=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3), + "=r" (dead4), "=r" (dead5), "=r" (dead6) + : "0" (x), "1" (y), "4" (len>>3) : "cc" ); return (sum1+sum2)>>1; @@ -169,13 +170,11 @@ void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *c "\tstr %6, %13 \n" "\tstr %7, %14 \n" - : "=r" (y0), "=r" (y1), "=r" (y2), "=r" (y3), + : "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3), "=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4), - "=r" (x), "=r" (y), "=r" (x0), - "=m" (sum1), "=m" (sum2), "=m" (sum3), "=m" (sum4), "=r" (dead1) - : "0" (y0), "1" (y1), "2" (y2), "3" (y3), - "8" (x), "9" (y), - "11" (sum1), "12" (sum2), "13" (sum3), "14" (sum4) + "+r" (x), "+r" (y), "=r" (x0), "+m" (sum1), + "+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1) + : : "cc", "memory" ); } diff --git a/libs/speex/libspeex/ltp_bfin.h b/libs/speex/libspeex/ltp_bfin.h index c4669022f1..b530f85986 100644 --- a/libs/speex/libspeex/ltp_bfin.h +++ b/libs/speex/libspeex/ltp_bfin.h @@ -330,7 +330,6 @@ static int pitch_gain_search_3tap_vq( " %0 = 0;\n\t" /* %0: best_sum */ " %1 = 0;\n\t" /* %1: best_cbdk */ " P1 = 0;\n\t" /* P1: loop counter */ -" R5 = 64;\n\t" /* R5: pitch_control */ " LSETUP (pgs1, pgs2) LC1 = %4;\n\t" "pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */ @@ -339,6 +338,7 @@ static int pitch_gain_search_3tap_vq( " R2 += 32;\n\t" " R3 += 32;\n\t" " R4 += 32;\n\t" +" R4.H = 64;\n\t" /* R4.H: pitch_control */ " R0 = B [P0++] (X);\n\t" " B0 = R0;\n\t" /* BO: gain_sum */ @@ -349,13 +349,13 @@ static int pitch_gain_search_3tap_vq( " A0 = 0;\n\t" " R0.L = W[I1++];\n\t" -" R1.L = R2.L*R5.L (IS);\n\t" +" R1.L = R2.L*R4.H (IS);\n\t" " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" -" R1.L = R3.L*R5.L (IS);\n\t" +" R1.L = R3.L*R4.H (IS);\n\t" " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" -" R1.L = R4.L*R5.L (IS);\n\t" +" R1.L = R4.L*R4.H (IS);\n\t" " A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" " R1.L = R2.L*R3.L (IS);\n\t" @@ -406,7 +406,7 @@ static int pitch_gain_search_3tap_vq( : "=&d" (best_sum), "=&d" (best_cdbk) : "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain), "b" (-VERY_LARGE32) - : "R0", "R1", "R2", "R3", "R4", "R5", "P0", + : "R0", "R1", "R2", "R3", "R4", "P0", "P1", "I1", "L1", "A0", "B0" #if (__GNUC__ == 4) , "LC1" diff --git a/libs/speex/libspeex/math_approx.h b/libs/speex/libspeex/math_approx.h index 377bf1acc4..9ca830755d 100644 --- a/libs/speex/libspeex/math_approx.h +++ b/libs/speex/libspeex/math_approx.h @@ -35,16 +35,298 @@ #ifndef MATH_APPROX_H #define MATH_APPROX_H -#include "misc.h" +#include "arch.h" -spx_word16_t spx_cos(spx_word16_t x); +#ifndef FIXED_POINT -#ifdef FIXED_POINT -spx_word16_t spx_sqrt(spx_word32_t x); -spx_word16_t spx_acos(spx_word16_t x); -#else #define spx_sqrt sqrt #define spx_acos acos -#endif +#define spx_exp exp +#define spx_cos_norm(x) (cos((.5f*M_PI)*(x))) +#define spx_atan atan + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 3.4642*std*ran.f; +} + + +#endif + + +static inline spx_int16_t spx_ilog2(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 16; + } + if (x>=256) + { + x >>= 8; + r += 8; + } + if (x>=16) + { + x >>= 4; + r += 4; + } + if (x>=4) + { + x >>= 2; + r += 2; + } + if (x>=2) + { + r += 1; + } + return r; +} + +static inline spx_int16_t spx_ilog4(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 8; + } + if (x>=256) + { + x >>= 8; + r += 4; + } + if (x>=16) + { + x >>= 4; + r += 2; + } + if (x>=4) + { + r += 1; + } + return r; +} + +#ifdef FIXED_POINT + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + spx_word32_t res; + *seed = 1664525 * *seed + 1013904223; + res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std); + return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14)); +} + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */ +/*#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4215*/ + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */ +#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4204 + +static inline spx_word16_t spx_sqrt(spx_word32_t x) +{ + int k; + spx_word32_t rt; + k = spx_ilog4(x)-6; + x = VSHR32(x, (k<<1)); + rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3))))))); + rt = VSHR32(rt,7-k); + return rt; +} + +/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */ + + +#define A1 16469 +#define A2 2242 +#define A3 1486 + +static inline spx_word16_t spx_acos(spx_word16_t x) +{ + int s=0; + spx_word16_t ret; + spx_word16_t sq; + if (x<0) + { + s=1; + x = NEG16(x); + } + x = SUB16(16384,x); + + x = x >> 1; + sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3)))))); + ret = spx_sqrt(SHL32(EXTEND32(sq),13)); + + /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/ + if (s) + ret = SUB16(25736,ret); + return ret; +} + + +#define K1 8192 +#define K2 -4096 +#define K3 340 +#define K4 -10 + +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + spx_word16_t x2; + + if (x<12868) + { + x2 = MULT16_16_P13(x,x); + return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } else { + x = SUB16(25736,x); + x2 = MULT16_16_P13(x,x); + return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x) +{ + spx_word16_t x2; + + x2 = MULT16_16_P15(x,x); + return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2)))))))); +} + +static inline spx_word16_t spx_cos_norm(spx_word32_t x) +{ + x = x&0x0001ffff; + if (x>SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17),x); + if (x&0x00007fff) + { + if (x14) + 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(b) ? (a) : (b)) - #ifdef FIXED_POINT #define WEIGHT_SHIFT 11 #define NORMALIZE_SCALEDOWN 5 @@ -90,19 +88,46 @@ #define WEIGHT_SHIFT 0 #endif -/* If enabled, the transition between blocks is smooth, so there isn't any blocking -aftifact when adapting. The cost is an extra FFT and a matrix-vector multiply */ -#define SMOOTH_BLOCKS +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk + and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */ +#define TWO_PATH #ifdef FIXED_POINT -static const spx_float_t MIN_LEAK = {16777, -19}; +static const spx_float_t MIN_LEAK = {20972, -22}; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = {23593, -16}; +static const spx_float_t VAR2_SMOOTH = {23675, -15}; +static const spx_float_t VAR1_UPDATE = {16384, -15}; +static const spx_float_t VAR2_UPDATE = {16384, -16}; +static const spx_float_t VAR_BACKTRACK = {16384, -12}; #define TOP16(x) ((x)>>16) + #else -static const spx_float_t MIN_LEAK = .032f; + +static const spx_float_t MIN_LEAK = .005f; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = .36f; +static const spx_float_t VAR2_SMOOTH = .7225f; +static const spx_float_t VAR1_UPDATE = .5f; +static const spx_float_t VAR2_UPDATE = .25f; +static const spx_float_t VAR_BACKTRACK = 4.f; #define TOP16(x) (x) #endif +#define PLAYBACK_DELAY 2 + +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + + /** Speex echo cancellation state. */ struct SpeexEchoState_ { int frame_size; /**< Number of samples processed each time */ @@ -111,49 +136,61 @@ struct SpeexEchoState_ { int cancel_count; int adapted; int saturated; + int screwed_up; + int C; /** Number of input channels (microphones) */ + int K; /** Number of output channels (loudspeakers) */ spx_int32_t sampling_rate; spx_word16_t spec_average; spx_word16_t beta0; spx_word16_t beta_max; spx_word32_t sum_adapt; - spx_word16_t *e; - spx_word16_t *x; - spx_word16_t *X; - spx_word16_t *d; - spx_word16_t *y; + spx_word16_t leak_estimate; + + spx_word16_t *e; /* scratch */ + spx_word16_t *x; /* Far-end input buffer (2N) */ + spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */ + spx_word16_t *input; /* scratch */ + spx_word16_t *y; /* scratch */ spx_word16_t *last_y; - spx_word32_t *Yps; - spx_word16_t *Y; + spx_word16_t *Y; /* scratch */ spx_word16_t *E; - spx_word32_t *PHI; - spx_word32_t *W; - spx_word32_t *power; - spx_float_t *power_1; - spx_word16_t *wtmp; -#ifdef FIXED_POINT - spx_word16_t *wtmp2; + spx_word32_t *PHI; /* scratch */ + spx_word32_t *W; /* (Background) filter weights */ +#ifdef TWO_PATH + spx_word16_t *foreground; /* Foreground filter weights */ + spx_word32_t Davg1; /* 1st recursive average of the residual power difference */ + spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */ + spx_float_t Dvar1; /* Estimated variance of 1st estimator */ + spx_float_t Dvar2; /* Estimated variance of 2nd estimator */ #endif - spx_word32_t *Rf; - spx_word32_t *Yf; - spx_word32_t *Xf; + spx_word32_t *power; /* Power of the far-end signal */ + spx_float_t *power_1;/* Inverse power of far-end */ + spx_word16_t *wtmp; /* scratch */ +#ifdef FIXED_POINT + spx_word16_t *wtmp2; /* scratch */ +#endif + spx_word32_t *Rf; /* scratch */ + spx_word32_t *Yf; /* scratch */ + spx_word32_t *Xf; /* scratch */ spx_word32_t *Eh; spx_word32_t *Yh; - spx_float_t Pey; - spx_float_t Pyy; + spx_float_t Pey; + spx_float_t Pyy; spx_word16_t *window; spx_word16_t *prop; void *fft_table; - spx_word16_t memX, memD, memE; + spx_word16_t *memX, *memD, *memE; spx_word16_t preemph; spx_word16_t notch_radius; - spx_mem_t notch_mem[2]; + spx_mem_t *notch_mem; /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */ spx_int16_t *play_buf; int play_buf_pos; + int play_buf_started; }; -static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem) +static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride) { int i; spx_word16_t den2; @@ -165,7 +202,7 @@ static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, /*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/ for (i=0;i max_sum) + max_sum = prop[i]; + } + for (i=0;i +static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL; + +static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len) +{ + if (!(rFile && pFile && oFile)) + { + speex_fatal("Dump files not open"); + } + fwrite(rec, sizeof(spx_int16_t), len, rFile); + fwrite(play, sizeof(spx_int16_t), len, pFile); + fwrite(out, sizeof(spx_int16_t), len, oFile); +} +#endif /** Creates a new echo canceller state */ -SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) +EXPORT SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) { - int i,N,M; + return speex_echo_state_init_mc(frame_size, filter_length, 1, 1); +} + +EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers) +{ + int i,N,M, C, K; SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState)); + st->K = nb_speakers; + st->C = nb_mic; + C=st->C; + K=st->K; +#ifdef DUMP_ECHO_CANCEL_DATA + if (rFile || pFile || oFile) + speex_fatal("Opening dump files twice"); + rFile = fopen("aec_rec.sw", "wb"); + pFile = fopen("aec_play.sw", "wb"); + oFile = fopen("aec_out.sw", "wb"); +#endif + st->frame_size = frame_size; st->window_size = 2*frame_size; N = st->window_size; @@ -281,7 +428,8 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) st->cancel_count=0; st->sum_adapt = 0; st->saturated = 0; - /* FIXME: Make that an init option (new API call?) */ + st->screwed_up = 0; + /* This is the default sampling rate */ st->sampling_rate = 8000; st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate); #ifdef FIXED_POINT @@ -291,25 +439,28 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) st->beta0 = (2.0f*st->frame_size)/st->sampling_rate; st->beta_max = (.5f*st->frame_size)/st->sampling_rate; #endif + st->leak_estimate = 0; st->fft_table = spx_fft_init(N); - st->e = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->x = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->d = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->Yps = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); - st->last_y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); + st->e = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->x = (spx_word16_t*)speex_alloc(K*N*sizeof(spx_word16_t)); + st->input = (spx_word16_t*)speex_alloc(C*st->frame_size*sizeof(spx_word16_t)); + st->y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->last_y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); st->Yf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); st->Rf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); st->Xf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); st->Yh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); st->Eh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); - st->X = (spx_word16_t*)speex_alloc((M+1)*N*sizeof(spx_word16_t)); - st->Y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->E = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); - st->W = (spx_word32_t*)speex_alloc(M*N*sizeof(spx_word32_t)); + st->X = (spx_word16_t*)speex_alloc(K*(M+1)*N*sizeof(spx_word16_t)); + st->Y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->E = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->W = (spx_word32_t*)speex_alloc(C*K*M*N*sizeof(spx_word32_t)); +#ifdef TWO_PATH + st->foreground = (spx_word16_t*)speex_alloc(M*N*C*K*sizeof(spx_word16_t)); +#endif st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t)); st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t)); @@ -329,14 +480,12 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) #endif for (i=0;i<=st->frame_size;i++) st->power_1[i] = FLOAT_ONE; - for (i=0;iW[i] = 0; - for (i=0;iPHI[i] = 0; { spx_word32_t sum = 0; /* Ratio of ~10 between adaptation rate of first and last block */ - spx_word16_t decay = QCONST16(exp(-2.4/M),15); + spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1); st->prop[0] = QCONST16(.7, 15); sum = EXTEND32(st->prop[0]); for (i=1;i=0;i--) { - st->prop[i] = DIV32(MULT16_16(QCONST16(.8,15), st->prop[i]),sum); + st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum); } } - st->memX=st->memD=st->memE=0; + st->memX = (spx_word16_t*)speex_alloc(K*sizeof(spx_word16_t)); + st->memD = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); + st->memE = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); st->preemph = QCONST16(.9,15); if (st->sampling_rate<12000) st->notch_radius = QCONST16(.9, 15); @@ -359,52 +510,91 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) else st->notch_radius = QCONST16(.992, 15); - st->notch_mem[0] = st->notch_mem[1] = 0; + st->notch_mem = (spx_mem_t*)speex_alloc(2*C*sizeof(spx_mem_t)); st->adapted = 0; st->Pey = st->Pyy = FLOAT_ONE; - st->play_buf = (spx_int16_t*)speex_alloc(2*st->frame_size*sizeof(spx_int16_t)); - st->play_buf_pos = 0; - +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + + st->play_buf = (spx_int16_t*)speex_alloc(K*(PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t)); + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; + return st; } /** Resets echo canceller state */ -void speex_echo_state_reset(SpeexEchoState *st) +EXPORT void speex_echo_state_reset(SpeexEchoState *st) { - int i, M, N; + int i, M, N, C, K; st->cancel_count=0; + st->screwed_up = 0; N = st->window_size; M = st->M; + C=st->C; + K=st->K; for (i=0;iW[i] = 0; +#ifdef TWO_PATH + for (i=0;iforeground[i] = 0; +#endif for (i=0;iX[i] = 0; for (i=0;i<=st->frame_size;i++) + { st->power[i] = 0; - for (i=0;ipower_1[i] = FLOAT_ONE; + st->Eh[i] = 0; + st->Yh[i] = 0; + } + for (i=0;iframe_size;i++) + { + st->last_y[i] = 0; + } + for (i=0;iE[i] = 0; - st->notch_mem[0] = st->notch_mem[1] = 0; - + } + for (i=0;ix[i] = 0; + } + for (i=0;i<2*C;i++) + st->notch_mem[i] = 0; + for (i=0;imemD[i]=st->memE[i]=0; + for (i=0;imemX[i]=0; + st->saturated = 0; st->adapted = 0; st->sum_adapt = 0; st->Pey = st->Pyy = FLOAT_ONE; - st->play_buf_pos = 0; +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + for (i=0;i<3*st->frame_size;i++) + st->play_buf[i] = 0; + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; } /** Destroys an echo canceller state */ -void speex_echo_state_destroy(SpeexEchoState *st) +EXPORT void speex_echo_state_destroy(SpeexEchoState *st) { spx_fft_destroy(st->fft_table); speex_free(st->e); speex_free(st->x); - speex_free(st->d); + speex_free(st->input); speex_free(st->y); speex_free(st->last_y); - speex_free(st->Yps); speex_free(st->Yf); speex_free(st->Rf); speex_free(st->Xf); @@ -415,6 +605,9 @@ void speex_echo_state_destroy(SpeexEchoState *st) speex_free(st->Y); speex_free(st->E); speex_free(st->W); +#ifdef TWO_PATH + speex_free(st->foreground); +#endif speex_free(st->PHI); speex_free(st->power); speex_free(st->power_1); @@ -424,21 +617,35 @@ void speex_echo_state_destroy(SpeexEchoState *st) #ifdef FIXED_POINT speex_free(st->wtmp2); #endif + speex_free(st->memX); + speex_free(st->memD); + speex_free(st->memE); + speex_free(st->notch_mem); + speex_free(st->play_buf); speex_free(st); + +#ifdef DUMP_ECHO_CANCEL_DATA + fclose(rFile); + fclose(pFile); + fclose(oFile); + rFile = pFile = oFile = NULL; +#endif } -void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out, spx_int32_t *Yout) +EXPORT void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) { int i; + /*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/ + st->play_buf_started = 1; if (st->play_buf_pos>=st->frame_size) { - speex_echo_cancel(st, rec, st->play_buf, out, Yout); + speex_echo_cancellation(st, rec, st->play_buf, out); st->play_buf_pos -= st->frame_size; - for (i=0;iframe_size;i++) + for (i=0;iplay_buf_pos;i++) st->play_buf[i] = st->play_buf[i+st->frame_size]; } else { - speex_warning("no playback frame available"); + speex_warning("No playback frame available (your application is buggy and/or got xruns)"); if (st->play_buf_pos!=0) { speex_warning("internal playback buffer corruption?"); @@ -449,27 +656,49 @@ void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t } } -void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play) +EXPORT void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play) { - if (st->play_buf_pos<=st->frame_size) + /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/ + if (!st->play_buf_started) + { + speex_warning("discarded first playback frame"); + return; + } + if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size) { int i; for (i=0;iframe_size;i++) st->play_buf[st->play_buf_pos+i] = play[i]; st->play_buf_pos += st->frame_size; + if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size) + { + speex_warning("Auto-filling the buffer (your application is buggy and/or got xruns)"); + for (i=0;iframe_size;i++) + st->play_buf[st->play_buf_pos+i] = play[i]; + st->play_buf_pos += st->frame_size; + } } else { - speex_warning("had to discard a playback frame"); + speex_warning("Had to discard a playback frame (your application is buggy and/or got xruns)"); } } -/** Performs echo cancellation on a frame */ -void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int16_t *echo, spx_int16_t *out, spx_int32_t *Yout) +/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ +EXPORT void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout) { - int i,j; - int N,M; - spx_word32_t Syy,See,Sxx; + speex_echo_cancellation(st, in, far_end, out); +} + +/** Performs echo cancellation on a frame */ +EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out) +{ + int i,j, chan, speak; + int N,M, C, K; + spx_word32_t Syy,See,Sxx,Sdd, Sff; +#ifdef TWO_PATH + spx_word32_t Dbf; + int update_foreground; +#endif spx_word32_t Sey; - spx_word16_t leak_estimate; spx_word16_t ss, ss_1; spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE; spx_float_t alpha, alpha_1; @@ -478,6 +707,9 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int N = st->window_size; M = st->M; + C = st->C; + K = st->K; + st->cancel_count++; #ifdef FIXED_POINT ss=DIV32_16(11469,M); @@ -487,187 +719,342 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int ss_1 = 1-ss; #endif - filter_dc_notch16(ref, st->notch_radius, st->d, st->frame_size, st->notch_mem); - /* Copy input data to buffer */ - for (i=0;iframe_size;i++) + for (chan = 0; chan < C; chan++) { - spx_word16_t tmp; - spx_word32_t tmp32; - st->x[i] = st->x[i+st->frame_size]; - tmp32 = SUB32(EXTEND32(echo[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX))); + /* Apply a notch filter to make sure DC doesn't end up causing problems */ + filter_dc_notch16(in+chan, st->notch_radius, st->input+chan*st->frame_size, st->frame_size, st->notch_mem+2*chan, C); + /* Copy input data to buffer and apply pre-emphasis */ + /* Copy input data to buffer */ + for (i=0;iframe_size;i++) + { + spx_word32_t tmp32; + /* FIXME: This core has changed a bit, need to merge properly */ + tmp32 = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD[chan]))); #ifdef FIXED_POINT - /*FIXME: If saturation occurs here, we need to freeze adaptation for M frames (not just one) */ - if (tmp32 > 32767) - { - tmp32 = 32767; - st->saturated = 1; - } - if (tmp32 < -32767) - { - tmp32 = -32767; - st->saturated = 1; - } + if (tmp32 > 32767) + { + tmp32 = 32767; + if (st->saturated == 0) + st->saturated = 1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + if (st->saturated == 0) + st->saturated = 1; + } #endif - st->x[i+st->frame_size] = EXTRACT16(tmp32); - st->memX = echo[i]; - - tmp = st->d[i]; - st->d[i] = st->d[i+st->frame_size]; - tmp32 = SUB32(EXTEND32(tmp), EXTEND32(MULT16_16_P15(st->preemph, st->memD))); -#ifdef FIXED_POINT - if (tmp32 > 32767) - { - tmp32 = 32767; - st->saturated = 1; - } - if (tmp32 < -32767) - { - tmp32 = -32767; - st->saturated = 1; + st->memD[chan] = st->input[chan*st->frame_size+i]; + st->input[chan*st->frame_size+i] = EXTRACT16(tmp32); } -#endif - st->d[i+st->frame_size] = tmp32; - st->memD = tmp; } - /* Shift memory: this could be optimized eventually*/ - for (j=M-1;j>=0;j--) + for (speak = 0; speak < K; speak++) { - for (i=0;iX[(j+1)*N+i] = st->X[j*N+i]; - } - - /* Convert x (echo input) to frequency domain */ - spx_fft(st->fft_table, st->x, &st->X[0]); + for (i=0;iframe_size;i++) + { + spx_word32_t tmp32; + st->x[speak*N+i] = st->x[speak*N+i+st->frame_size]; + tmp32 = SUB32(EXTEND32(far_end[i*K+speak]), EXTEND32(MULT16_16_P15(st->preemph, st->memX[speak]))); +#ifdef FIXED_POINT + /*FIXME: If saturation occurs here, we need to freeze adaptation for M frames (not just one) */ + if (tmp32 > 32767) + { + tmp32 = 32767; + st->saturated = M+1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + st->saturated = M+1; + } +#endif + st->x[speak*N+i+st->frame_size] = EXTRACT16(tmp32); + st->memX[speak] = far_end[i*K+speak]; + } + } -#ifdef SMOOTH_BLOCKS - spectral_mul_accum(st->X, st->W, st->Y, N, M); - spx_ifft(st->fft_table, st->Y, st->e); -#endif - - /* Compute weight gradient */ - if (!st->saturated) + for (speak = 0; speak < K; speak++) { + /* Shift memory: this could be optimized eventually*/ for (j=M-1;j>=0;j--) { - weighted_spectral_mul_conj(st->power_1, &st->X[(j+1)*N], st->E, st->PHI, N); for (i=0;iW[j*N+i] += MULT16_32_Q15(st->prop[j], st->PHI[i]); - - } + st->X[(j+1)*N*K+speak*N+i] = st->X[j*N*K+speak*N+i]; + } + /* Convert x (echo input) to frequency domain */ + spx_fft(st->fft_table, st->x+speak*N, &st->X[speak*N]); } - st->saturated = 0; + Sxx = 0; + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + Sff = 0; + for (chan = 0; chan < C; chan++) + { +#ifdef TWO_PATH + /* Compute foreground filter */ + spectral_mul_accum16(st->X, st->foreground+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->e+chan*N); + for (i=0;iframe_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->e[chan*N+i+st->frame_size]); + Sff += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); +#endif + } + + /* Adjust proportional adaption rate */ + /* FIXME: Adjust that for C, K*/ + if (st->adapted) + mdf_adjust_prop (st->W, N, M, C*K, st->prop); + /* Compute weight gradient */ + if (st->saturated == 0) + { + for (chan = 0; chan < C; chan++) + { + for (speak = 0; speak < K; speak++) + { + for (j=M-1;j>=0;j--) + { + weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N*K+speak*N], st->E+chan*N, st->PHI, N); + for (i=0;iW[chan*N*K*M + j*N*K + speak*N + i] += st->PHI[i]; + } + } + } + } else { + st->saturated--; + } + + /* FIXME: MC conversion required */ /* Update weight to prevent circular convolution (MDF / AUMDF) */ - for (j=0;jcancel_count%(M-1) == j-1) + for (speak = 0; speak < K; speak++) { + for (j=0;jcancel_count%(M-1) == j-1) + { #ifdef FIXED_POINT - for (i=0;iwtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],NORMALIZE_SCALEDOWN+16)); - spx_ifft(st->fft_table, st->wtmp2, st->wtmp); + for (i=0;iwtmp2[i] = EXTRACT16(PSHR32(st->W[chan*N*K*M + j*N*K + speak*N + i],NORMALIZE_SCALEDOWN+16)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); + for (i=0;iframe_size;i++) + { + st->wtmp[i]=0; + } + for (i=st->frame_size;iwtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP); + } + spx_fft(st->fft_table, st->wtmp, st->wtmp2); + /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */ + for (i=0;iW[chan*N*K*M + j*N*K + speak*N + i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); +#else + spx_ifft(st->fft_table, &st->W[chan*N*K*M + j*N*K + speak*N], st->wtmp); + for (i=st->frame_size;iwtmp[i]=0; + } + spx_fft(st->fft_table, st->wtmp, &st->W[chan*N*K*M + j*N*K + speak*N]); +#endif + } + } + } + } + + /* So we can use power_spectrum_accum */ + for (i=0;i<=st->frame_size;i++) + st->Rf[i] = st->Yf[i] = st->Xf[i] = 0; + + Dbf = 0; + See = 0; +#ifdef TWO_PATH + /* Difference in response, this is used to estimate the variance of our residual power estimate */ + for (chan = 0; chan < C; chan++) + { + spectral_mul_accum(st->X, st->W+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->y+chan*N); + for (i=0;iframe_size;i++) + st->e[chan*N+i] = SUB16(st->e[chan*N+i+st->frame_size], st->y[chan*N+i+st->frame_size]); + Dbf += 10+mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + for (i=0;iframe_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + See += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + } +#endif + +#ifndef TWO_PATH + Sff = See; +#endif + +#ifdef TWO_PATH + /* Logic for updating the foreground filter */ + + /* For two time windows, compute the mean of the energy difference, as well as the variance */ + st->Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),st->Davg1), MULT16_32_Q15(QCONST16(.4f,15),SUB32(Sff,See))); + st->Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),st->Davg2), MULT16_32_Q15(QCONST16(.15f,15),SUB32(Sff,See))); + st->Dvar1 = FLOAT_ADD(FLOAT_MULT(VAR1_SMOOTH, st->Dvar1), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), MULT16_32_Q15(QCONST16(.4f,15),Dbf))); + st->Dvar2 = FLOAT_ADD(FLOAT_MULT(VAR2_SMOOTH, st->Dvar2), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), MULT16_32_Q15(QCONST16(.15f,15),Dbf))); + + /* Equivalent float code: + st->Davg1 = .6*st->Davg1 + .4*(Sff-See); + st->Davg2 = .85*st->Davg2 + .15*(Sff-See); + st->Dvar1 = .36*st->Dvar1 + .16*Sff*Dbf; + st->Dvar2 = .7225*st->Dvar2 + .0225*Sff*Dbf; + */ + + update_foreground = 0; + /* Check if we have a statistically significant reduction in the residual echo */ + /* Note that this is *not* Gaussian, so we need to be careful about the longer tail */ + if (FLOAT_GT(FLOAT_MUL32U(SUB32(Sff,See),ABS32(SUB32(Sff,See))), FLOAT_MUL32U(Sff,Dbf))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg1, ABS32(st->Davg1)), FLOAT_MULT(VAR1_UPDATE,(st->Dvar1)))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg2, ABS32(st->Davg2)), FLOAT_MULT(VAR2_UPDATE,(st->Dvar2)))) + update_foreground = 1; + + /* Do we update? */ + if (update_foreground) + { + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + /* Copy background filter to foreground filter */ + for (i=0;iforeground[i] = EXTRACT16(PSHR32(st->W[i],16)); + /* Apply a smooth transition so as to not introduce blocking artifacts */ + for (chan = 0; chan < C; chan++) for (i=0;iframe_size;i++) - { - st->wtmp[i]=0; - } - for (i=st->frame_size;iwtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP); - } - spx_fft(st->fft_table, st->wtmp, st->wtmp2); - /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */ - for (i=0;iW[j*N+i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); -#else - spx_ifft(st->fft_table, &st->W[j*N], st->wtmp); - for (i=st->frame_size;iwtmp[i]=0; - } - spx_fft(st->fft_table, st->wtmp, &st->W[j*N]); -#endif - } - } - - /* Compute filter response Y */ - spectral_mul_accum(st->X, st->W, st->Y, N, M); - spx_ifft(st->fft_table, st->Y, st->y); - - - /* Compute error signal (for the output with de-emphasis) */ - for (i=0;iframe_size;i++) - { - spx_word32_t tmp_out; -#ifdef SMOOTH_BLOCKS - spx_word16_t y = MULT16_16_Q15(st->window[i+st->frame_size],st->e[i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[i+st->frame_size]); - tmp_out = SUB32(EXTEND32(st->d[i+st->frame_size]), EXTEND32(y)); -#else - tmp_out = SUB32(EXTEND32(st->d[i+st->frame_size]), EXTEND32(st->y[i+st->frame_size])); -#endif - - /* Saturation */ - if (tmp_out>32767) - tmp_out = 32767; - else if (tmp_out<-32768) - tmp_out = -32768; - tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE))); - /* This is an arbitrary test for saturation */ - if (ref[i] <= -32000 || ref[i] >= 32000) + st->e[chan*N+i+st->frame_size] = MULT16_16_Q15(st->window[i+st->frame_size],st->e[chan*N+i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[chan*N+i+st->frame_size]); + } else { + int reset_background=0; + /* Otherwise, check if the background filter is significantly worse */ + if (FLOAT_GT(FLOAT_MUL32U(NEG32(SUB32(Sff,See)),ABS32(SUB32(Sff,See))), FLOAT_MULT(VAR_BACKTRACK,FLOAT_MUL32U(Sff,Dbf)))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg1), ABS32(st->Davg1)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar1))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg2), ABS32(st->Davg2)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar2))) + reset_background = 1; + if (reset_background) { - tmp_out = 0; - st->saturated = 1; + /* Copy foreground filter to background filter */ + for (i=0;iW[i] = SHL32(EXTEND32(st->foreground[i]),16); + /* We also need to copy the output so as to get correct adaptation */ + for (chan = 0; chan < C; chan++) + { + for (i=0;iframe_size;i++) + st->y[chan*N+i+st->frame_size] = st->e[chan*N+i+st->frame_size]; + for (i=0;iframe_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + } + See = Sff; + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; } - out[i] = (spx_int16_t)tmp_out; - st->memE = tmp_out; } +#endif - /* Compute error signal (filter update version) */ - for (i=0;iframe_size;i++) - { - st->e[i] = 0; - st->e[i+st->frame_size] = st->d[i+st->frame_size] - st->y[i+st->frame_size]; - } + Sey = Syy = Sdd = 0; + for (chan = 0; chan < C; chan++) + { + /* Compute error signal (for the output with de-emphasis) */ + for (i=0;iframe_size;i++) + { + spx_word32_t tmp_out; +#ifdef TWO_PATH + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size])); +#else + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->y[chan*N+i+st->frame_size])); +#endif + tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan]))); + /* This is an arbitrary test for saturation in the microphone signal */ + if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000) + { + if (st->saturated == 0) + st->saturated = 1; + } + out[i*C+chan] = WORD2INT(tmp_out); + st->memE[chan] = tmp_out; + } - /* Compute a bunch of correlations */ - Sey = mdf_inner_prod(st->e+st->frame_size, st->y+st->frame_size, st->frame_size); - See = mdf_inner_prod(st->e+st->frame_size, st->e+st->frame_size, st->frame_size); - See = ADD32(See, SHR32(MULT16_16(N, 100),6)); - Syy = mdf_inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size); - Sxx = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size); - - /* Convert error to frequency domain */ - spx_fft(st->fft_table, st->e, st->E); - for (i=0;iframe_size;i++) - st->y[i] = 0; - spx_fft(st->fft_table, st->y, st->Y); - - /* Compute power spectrum of echo (X), error (E) and filter response (Y) */ - power_spectrum(st->E, st->Rf, N); - power_spectrum(st->Y, st->Yf, N); - power_spectrum(st->X, st->Xf, N); +#ifdef DUMP_ECHO_CANCEL_DATA + dump_audio(in, far_end, out, st->frame_size); +#endif - /* Smooth echo energy estimate over time */ + /* Compute error signal (filter update version) */ + for (i=0;iframe_size;i++) + { + st->e[chan*N+i+st->frame_size] = st->e[chan*N+i]; + st->e[chan*N+i] = 0; + } + + /* Compute a bunch of correlations */ + /* FIXME: bad merge */ + Sey += mdf_inner_prod(st->e+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Syy += mdf_inner_prod(st->y+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Sdd += mdf_inner_prod(st->input+chan*st->frame_size, st->input+chan*st->frame_size, st->frame_size); + + /* Convert error to frequency domain */ + spx_fft(st->fft_table, st->e+chan*N, st->E+chan*N); + for (i=0;iframe_size;i++) + st->y[i+chan*N] = 0; + spx_fft(st->fft_table, st->y+chan*N, st->Y+chan*N); + + /* Compute power spectrum of echo (X), error (E) and filter response (Y) */ + power_spectrum_accum(st->E+chan*N, st->Rf, N); + power_spectrum_accum(st->Y+chan*N, st->Yf, N); + + } + + /*printf ("%f %f %f %f\n", Sff, See, Syy, Sdd, st->update_cond);*/ + + /* Do some sanity check */ + if (!(Syy>=0 && Sxx>=0 && See >= 0) +#ifndef FIXED_POINT + || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9) +#endif + ) + { + /* Things have gone really bad */ + st->screwed_up += 50; + for (i=0;iframe_size*C;i++) + out[i] = 0; + } else if (SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6))) + { + /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */ + st->screwed_up++; + } else { + /* Everything's fine */ + st->screwed_up=0; + } + if (st->screwed_up>=50) + { + speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now."); + speex_echo_state_reset(st); + return; + } + + /* Add a small noise floor to make sure not to have problems when dividing */ + See = MAX32(See, SHR32(MULT16_16(N, 100),6)); + + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + + + /* Smooth far end energy estimate over time */ for (j=0;j<=st->frame_size;j++) st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]); - - /* Enable this to compute the power based only on the tail (would need to compute more - efficiently to make this really useful */ - if (0) - { - float scale2 = .5f/M; - for (j=0;j<=st->frame_size;j++) - st->power[j] = 100; - for (i=0;iX[i*N], st->Xf, N); - for (j=0;j<=st->frame_size;j++) - st->power[j] += scale2*st->Xf[j]; - } - } /* Compute filtered spectra and (cross-)correlations */ for (j=st->frame_size;j>=0;j--) @@ -706,17 +1093,17 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int if (FLOAT_GT(st->Pey, st->Pyy)) st->Pey = st->Pyy; /* leak_estimate is the linear regression result */ - leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14)); + st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14)); /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */ - if (leak_estimate > 16383) - leak_estimate = 32767; + if (st->leak_estimate > 16383) + st->leak_estimate = 32767; else - leak_estimate = SHL16(leak_estimate,1); - /*printf ("%f\n", leak_estimate);*/ + st->leak_estimate = SHL16(st->leak_estimate,1); + /*printf ("%f\n", st->leak_estimate);*/ /* Compute Residual to Error Ratio */ #ifdef FIXED_POINT - tmp32 = MULT16_32_Q15(leak_estimate,Syy); + tmp32 = MULT16_32_Q15(st->leak_estimate,Syy); tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1))); /* Check for y in e (lower bound on RER) */ { @@ -731,7 +1118,7 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int tmp32 = SHR32(See,1); RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15)); #else - RER = (.0001*Sxx + 3.*MULT16_32_Q15(leak_estimate,Syy)) / See; + RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See; /* Check for y in e (lower bound on RER) */ if (RER < Sey*Sey/(1+See*Syy)) RER = Sey*Sey/(1+See*Syy); @@ -740,18 +1127,19 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int #endif /* We consider that the filter has had minimal adaptation if the following is true*/ - if (!st->adapted && st->sum_adapt > QCONST32(1,15)) + if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy)) { st->adapted = 1; } if (st->adapted) { + /* Normal learning rate calculation once we're past the minimal adaptation phase */ for (i=0;i<=st->frame_size;i++) { spx_word32_t r, e; /* Compute frequency-domain adaptation mask */ - r = MULT16_32_Q15(leak_estimate,SHL32(st->Yf[i],3)); + r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3)); e = SHL32(st->Rf[i],3)+1; #ifdef FIXED_POINT if (r>SHR32(e,1)) @@ -764,20 +1152,22 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int /*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/ st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16); } - } else if (Sxx > SHR32(MULT16_16(N, 1000),6)) { + } else { /* Temporary adaption rate if filter is not yet adapted enough */ spx_word16_t adapt_rate=0; - tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); + if (Sxx > SHR32(MULT16_16(N, 1000),6)) + { + tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); #ifdef FIXED_POINT - if (tmp32 > SHR32(See,2)) - tmp32 = SHR32(See,2); + if (tmp32 > SHR32(See,2)) + tmp32 = SHR32(See,2); #else - if (tmp32 > .25*See) - tmp32 = .25*See; + if (tmp32 > .25*See) + tmp32 = .25*See; #endif - adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); - + adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); + } for (i=0;i<=st->frame_size;i++) st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1); @@ -786,50 +1176,57 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int st->sum_adapt = ADD32(st->sum_adapt,adapt_rate); } - /* Compute spectrum of estimated echo for use in an echo post-filter (if necessary)*/ - if (Yout) + /* FIXME: MC conversion required */ + for (i=0;iframe_size;i++) + st->last_y[i] = st->last_y[st->frame_size+i]; + if (st->adapted) { - spx_word16_t leak2; - if (st->adapted) - { - /* If the filter is adapted, take the filtered echo */ - for (i=0;iframe_size;i++) - st->last_y[i] = st->last_y[st->frame_size+i]; - for (i=0;iframe_size;i++) - st->last_y[st->frame_size+i] = ref[i]-out[i]; - } else { - /* If filter isn't adapted yet, all we can do is take the echo signal directly */ - for (i=0;ilast_y[i] = st->x[i]; - } - - /* Apply hanning window (should pre-compute it)*/ - for (i=0;iy[i] = MULT16_16_Q15(st->window[i],st->last_y[i]); - - /* Compute power spectrum of the echo */ - spx_fft(st->fft_table, st->y, st->Y); - power_spectrum(st->Y, st->Yps, N); - -#ifdef FIXED_POINT - if (leak_estimate > 16383) - leak2 = 32767; - else - leak2 = SHL16(leak_estimate, 1); -#else - if (leak_estimate>.5) - leak2 = 1; - else - leak2 = 2*leak_estimate; -#endif - /* Estimate residual echo */ - for (i=0;i<=st->frame_size;i++) - Yout[i] = (spx_int32_t)MULT16_32_Q15(leak2,st->Yps[i]); + /* If the filter is adapted, take the filtered echo */ + for (i=0;iframe_size;i++) + st->last_y[st->frame_size+i] = in[i]-out[i]; + } else { + /* If filter isn't adapted yet, all we can do is take the far end signal directly */ + /* moved earlier: for (i=0;ilast_y[i] = st->x[i];*/ } + } +/* Compute spectrum of estimated echo for use in an echo post-filter */ +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, int len) +{ + int i; + spx_word16_t leak2; + int N; + + N = st->window_size; -int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) + /* Apply hanning window (should pre-compute it)*/ + for (i=0;iy[i] = MULT16_16_Q15(st->window[i],st->last_y[i]); + + /* Compute power spectrum of the echo */ + spx_fft(st->fft_table, st->y, st->Y); + power_spectrum(st->Y, residual_echo, N); + +#ifdef FIXED_POINT + if (st->leak_estimate > 16383) + leak2 = 32767; + else + leak2 = SHL16(st->leak_estimate, 1); +#else + if (st->leak_estimate>.5) + leak2 = 1; + else + leak2 = 2*st->leak_estimate; +#endif + /* Estimate residual echo */ + for (i=0;i<=st->frame_size;i++) + residual_echo[i] = (spx_int32_t)MULT16_32_Q15(leak2,residual_echo[i]); + +} + +EXPORT int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) { switch(request) { @@ -857,6 +1254,29 @@ int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) case SPEEX_ECHO_GET_SAMPLING_RATE: (*(int*)ptr) = st->sampling_rate; break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE: + /*FIXME: Implement this for multiple channels */ + *((spx_int32_t *)ptr) = st->M * st->frame_size; + break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE: + { + int M = st->M, N = st->window_size, n = st->frame_size, i, j; + spx_int32_t *filt = (spx_int32_t *) ptr; + for(j=0;jwtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],16+NORMALIZE_SCALEDOWN)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); +#else + spx_ifft(st->fft_table, &st->W[j*N], st->wtmp); +#endif + for(i=0;iwtmp[i]), WEIGHT_SHIFT-NORMALIZE_SCALEDOWN); + } + } + break; default: speex_warning_int("Unknown speex_echo_ctl request: ", request); return -1; diff --git a/libs/speex/libspeex/modes.c b/libs/speex/libspeex/modes.c index 97e7d1e3fa..e10a32e8e7 100644 --- a/libs/speex/libspeex/modes.c +++ b/libs/speex/libspeex/modes.c @@ -43,28 +43,23 @@ #include "sb_celp.h" #include "nb_celp.h" #include "vbr.h" -#include "misc.h" +#include "arch.h" #include #ifndef NULL #define NULL 0 #endif -#define MAX_IN_SAMPLES 640 - -const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; /* Extern declarations for all codebooks we use here */ extern const signed char gain_cdbk_nb[]; extern const signed char gain_cdbk_lbr[]; -extern const signed char hexc_table[]; extern const signed char exc_5_256_table[]; extern const signed char exc_5_64_table[]; extern const signed char exc_8_128_table[]; extern const signed char exc_10_32_table[]; extern const signed char exc_10_16_table[]; extern const signed char exc_20_32_table[]; -extern const signed char hexc_10_32_table[]; /* Parameters for Long-Term Prediction (LTP)*/ @@ -150,28 +145,7 @@ static const split_cb_params split_cb_sb = { 0, }; -#ifndef DISABLE_WIDEBAND -/* Split-VQ innovation for high-band wideband */ -static const split_cb_params split_cb_high = { - 8, /*subvect_size*/ - 5, /*nb_subvect*/ - hexc_table, /*shape_cb*/ - 7, /*shape_bits*/ - 1, -}; - - -/* Split-VQ innovation for high-band wideband */ -static const split_cb_params split_cb_high_lbr = { - 10, /*subvect_size*/ - 4, /*nb_subvect*/ - hexc_10_32_table, /*shape_cb*/ - 5, /*shape_bits*/ - 0, -}; - -#endif /* 2150 bps "vocoder-like" mode for comfort noise */ static const SpeexSubmode nb_submode1 = { @@ -354,11 +328,7 @@ static const SpeexNBMode nb_mode = { #else 0.9, 0.6, /* gamma1, gamma2 */ #endif - .012, /*lag_factor*/ QCONST16(.0002,15), /*lpc_floor*/ -#ifdef EPIC_48K - 0, -#endif {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7, &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 5, @@ -367,7 +337,7 @@ static const SpeexNBMode nb_mode = { /* Default mode for narrowband */ -const SpeexMode speex_nb_mode = { +EXPORT const SpeexMode speex_nb_mode = { &nb_mode, nb_mode_query, "narrowband", @@ -384,290 +354,13 @@ const SpeexMode speex_nb_mode = { }; -/* Wideband part */ -static const SpeexSubmode wb_submode1 = { - 0, - 0, - 1, - 0, - /*LSP quantization*/ - lsp_quant_high, - lsp_unquant_high, - /*Pitch quantization*/ - NULL, - NULL, - NULL, - /*No innovation quantization*/ - NULL, - NULL, - NULL, - -1, - 36 -}; - - -static const SpeexSubmode wb_submode2 = { - 0, - 0, - 1, - 0, - /*LSP quantization*/ - lsp_quant_high, - lsp_unquant_high, - /*Pitch quantization*/ - NULL, - NULL, - NULL, - /*Innovation quantization*/ - split_cb_search_shape_sign, - split_cb_shape_sign_unquant, -#ifdef DISABLE_WIDEBAND - NULL, -#else - &split_cb_high_lbr, -#endif - -1, - 112 -}; - - -static const SpeexSubmode wb_submode3 = { - 0, - 0, - 1, - 0, - /*LSP quantization*/ - lsp_quant_high, - lsp_unquant_high, - /*Pitch quantization*/ - NULL, - NULL, - NULL, - /*Innovation quantization*/ - split_cb_search_shape_sign, - split_cb_shape_sign_unquant, -#ifdef DISABLE_WIDEBAND - NULL, -#else - &split_cb_high, -#endif - -1, - 192 -}; - -static const SpeexSubmode wb_submode4 = { - 0, - 0, - 1, - 1, - /*LSP quantization*/ - lsp_quant_high, - lsp_unquant_high, - /*Pitch quantization*/ - NULL, - NULL, - NULL, - /*Innovation quantization*/ - split_cb_search_shape_sign, - split_cb_shape_sign_unquant, -#ifdef DISABLE_WIDEBAND - NULL, -#else - &split_cb_high, -#endif - -1, - 352 -}; - - -/* Split-band wideband CELP mode*/ -static const SpeexSBMode sb_wb_mode = { - &speex_nb_mode, - 160, /*frameSize*/ - 40, /*subframeSize*/ - 8, /*lpcSize*/ - 640, /*bufSize*/ -#ifdef FIXED_POINT - 29491, 19661, /* gamma1, gamma2 */ -#else - 0.9, 0.6, /* gamma1, gamma2 */ -#endif - .012, /*lag_factor*/ - QCONST16(.0002,15), /*lpc_floor*/ - 0.9, - {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, - 3, - {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7}, - {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4}, - vbr_hb_thresh, - 5 -}; - - -const SpeexMode speex_wb_mode = { - &sb_wb_mode, - wb_mode_query, - "wideband (sub-band CELP)", - 1, - 4, - &sb_encoder_init, - &sb_encoder_destroy, - &sb_encode, - &sb_decoder_init, - &sb_decoder_destroy, - &sb_decode, - &sb_encoder_ctl, - &sb_decoder_ctl, -}; - - - -/* "Ultra-wideband" mode stuff */ - - - -/* Split-band "ultra-wideband" (32 kbps) CELP mode*/ -static const SpeexSBMode sb_uwb_mode = { - &speex_wb_mode, - 320, /*frameSize*/ - 80, /*subframeSize*/ - 8, /*lpcSize*/ - 1280, /*bufSize*/ -#ifdef FIXED_POINT - 29491, 19661, /* gamma1, gamma2 */ -#else - 0.9, 0.6, /* gamma1, gamma2 */ -#endif - .012, /*lag_factor*/ - QCONST16(.0002,15), /*lpc_floor*/ - 0.7, - {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, - 1, - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, - {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - vbr_uhb_thresh, - 2 -}; - - -const SpeexMode speex_uwb_mode = { - &sb_uwb_mode, - wb_mode_query, - "ultra-wideband (sub-band CELP)", - 2, - 4, - &sb_encoder_init, - &sb_encoder_destroy, - &sb_encode, - &sb_decoder_init, - &sb_decoder_destroy, - &sb_decode, - &sb_encoder_ctl, - &sb_decoder_ctl, -}; - - - - -#ifdef EPIC_48K - -extern const signed char gain_cdbk_ulbr[]; -extern const signed char exc_12_32_table[]; - -/* Parameters for Long-Term Prediction (LTP)*/ -static const ltp_params ltp_params_48k = { - gain_cdbk_ulbr, - 3, - 0 -}; - -static const split_cb_params split_cb_nb_48k = { - 12, /*subvect_size*/ - 4, /*nb_subvect*/ - exc_12_32_table, /*shape_cb*/ - 5, /*shape_bits*/ - 0, -}; - - -/* 4.8 kbps very low bit-rate mode */ -static const SpeexSubmode nb_48k_submode = { - 0, - 0, - 0, - 0, - /*LSP quantization*/ - lsp_quant_48k, - lsp_unquant_48k, - /*No pitch quantization*/ - pitch_search_3tap, - pitch_unquant_3tap, - <p_params_48k, - /*Innovation quantization*/ - split_cb_search_shape_sign, - split_cb_shape_sign_unquant, - &split_cb_nb_48k, -#ifdef FIXED_POINT - 22938, 16384, 11796, 18022, -#else - 0.7, 0.5, .36, .55, -#endif - 144 -}; - - -/* Special, non-standard 4.8 kbps mode */ -static const SpeexNBMode nb_48k_mode = { - 240, /*frameSize*/ - 48, /*subframeSize*/ - 10, /*lpcSize*/ - 640, /*bufSize*/ - 17, /*pitchStart*/ - 144, /*pitchEnd*/ - 0.9, /*gamma1*/ - 0.6, /*gamma2*/ - .01, /*lag_factor*/ - QCONST16(.0003,15), /*lpc_floor*/ - 1, - {NULL, NULL, &nb_48k_submode, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, - 2, - {2,2,2,2,2,2,2,2,2,2,2} -}; - - -/* Default mode for narrowband */ -const SpeexMode speex_nb_48k_mode = { - &nb_48k_mode, - nb_mode_query, - "narrowband 4.8 kbps", - 1000, - 4, - &nb_encoder_init, - &nb_encoder_destroy, - &nb_encode, - &nb_decoder_init, - &nb_decoder_destroy, - &nb_decode, - &nb_encoder_ctl, - &nb_decoder_ctl, -}; - - -#endif - -int speex_mode_query(const SpeexMode *mode, int request, void *ptr) +EXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr) { return mode->query(mode->mode, request, ptr); } -const SpeexMode * speex_lib_get_mode (int mode) -{ -#ifdef EPIC_48K - if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode; +#ifdef FIXED_DEBUG +long long spx_mips=0; #endif - if (mode < 0 || mode > SPEEX_NB_MODES) return NULL; - - return speex_mode_list[mode]; -} diff --git a/libs/speex/libspeex/modes.h b/libs/speex/libspeex/modes.h index 6a632402f7..26e2d86180 100644 --- a/libs/speex/libspeex/modes.h +++ b/libs/speex/libspeex/modes.h @@ -38,7 +38,7 @@ #include #include -#include "misc.h" +#include "arch.h" #define NB_SUBMODES 16 #define NB_SUBMODE_BITS 4 @@ -46,6 +46,23 @@ #define SB_SUBMODES 8 #define SB_SUBMODE_BITS 3 +/* Used internally, NOT TO BE USED in applications */ +/** Used internally*/ +#define SPEEX_GET_PI_GAIN 100 +/** Used internally*/ +#define SPEEX_GET_EXC 101 +/** Used internally*/ +#define SPEEX_GET_INNOV 102 +/** Used internally*/ +#define SPEEX_GET_DTX_STATUS 103 +/** Used internally*/ +#define SPEEX_SET_INNOVATION_SAVE 104 +/** Used internally*/ +#define SPEEX_SET_WIDEBAND 105 + +/** Used internally*/ +#define SPEEX_GET_STACK 106 + /** Quantizes LSPs */ typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *); @@ -81,7 +98,7 @@ typedef struct SpeexSubmode { lsp_quant_func lsp_quant; /**< LSP quantization function */ lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ - /*Lont-term predictor functions*/ + /*Long-term predictor functions*/ ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ const void *ltp_params; /**< Pitch parameters (options) */ @@ -106,13 +123,8 @@ typedef struct SpeexNBMode { spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ spx_word16_t gamma2; /**< Perceptual filter parameter #2 */ - float lag_factor; /**< Lag-windowing parameter */ spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ -#ifdef EPIC_48K - int lbr48k; /**< 1 for the special 4.8 kbps mode */ -#endif - const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ int defaultSubmode; /**< Default sub-mode to use when encoding */ int quality_map[11]; /**< Mode corresponding to each quality setting */ @@ -125,18 +137,18 @@ typedef struct SpeexSBMode { int frameSize; /**< Size of frames used for encoding */ int subframeSize; /**< Size of sub-frames used for encoding */ int lpcSize; /**< Order of LPC filter */ - int bufSize; /**< Signal buffer size in encoder */ spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ spx_word16_t gamma2; /**< Perceptual filter parameter #1 */ - float lag_factor; /**< Lag-windowing parameter */ spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ - float folding_gain; + spx_word16_t folding_gain; const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */ int defaultSubmode; /**< Default sub-mode to use when encoding */ int low_quality_map[11]; /**< Mode corresponding to each quality setting */ int quality_map[11]; /**< Mode corresponding to each quality setting */ +#ifndef DISABLE_VBR const float (*vbr_thresh)[11]; +#endif int nb_modes; } SpeexSBMode; diff --git a/libs/speex/libspeex/modes_wb.c b/libs/speex/libspeex/modes_wb.c new file mode 100644 index 0000000000..e3b484223e --- /dev/null +++ b/libs/speex/libspeex/modes_wb.c @@ -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 +#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]; +} + + + diff --git a/libs/speex/libspeex/nb_celp.c b/libs/speex/libspeex/nb_celp.c index 234ac2d529..9dd726a0cf 100644 --- a/libs/speex/libspeex/nb_celp.c +++ b/libs/speex/libspeex/nb_celp.c @@ -45,8 +45,9 @@ #include "vq.h" #include #include "vbr.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" +#include "os_support.h" #include #ifdef VORBIS_PSYCHO @@ -87,14 +88,14 @@ const spx_word16_t exc_gain_quant_scal1[2]={11546, 17224}; #else -const float exc_gain_quant_scal3_bound[7]={0.112338, 0.236980, 0.369316, 0.492054, 0.637471, 0.828874, 1.132784}; -const float exc_gain_quant_scal3[8]={0.061130, 0.163546, 0.310413, 0.428220, 0.555887, 0.719055, 0.938694, 1.326874}; -const float exc_gain_quant_scal1_bound[1]={0.87798}; -const float exc_gain_quant_scal1[2]={0.70469, 1.05127}; +const float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f}; +const float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f}; +const float exc_gain_quant_scal1_bound[1]={0.87798f}; +const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f}; -#define LSP_MARGIN .002 -#define LSP_DELTA1 .2 -#define LSP_DELTA2 .05 +#define LSP_MARGIN .002f +#define LSP_DELTA1 .2f +#define LSP_DELTA2 .05f #endif @@ -107,6 +108,7 @@ const float exc_gain_quant_scal1[2]={0.70469, 1.05127}; #define sqr(x) ((x)*(x)) +extern const spx_word16_t lag_window[]; extern const spx_word16_t lpc_window[]; void *nb_encoder_init(const SpeexMode *m) @@ -136,7 +138,6 @@ void *nb_encoder_init(const SpeexMode *m) st->gamma2=mode->gamma2; st->min_pitch=mode->pitchStart; st->max_pitch=mode->pitchEnd; - st->lag_factor=mode->lag_factor; st->lpc_floor = mode->lpc_floor; st->submodes=mode->submodes; @@ -144,9 +145,6 @@ void *nb_encoder_init(const SpeexMode *m) st->bounded_pitch = 1; st->encode_submode = 1; -#ifdef EPIC_48K - st->lbr_48k=mode->lbr48k; -#endif #ifdef VORBIS_PSYCHO st->psy = vorbis_psy_init(8000, 256); @@ -168,17 +166,13 @@ void *nb_encoder_init(const SpeexMode *m) st->window= lpc_window; /* Create the window for autocorrelation (lag-windowing) */ - st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + st->lagWindow = lag_window; st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); st->first = 1; for (i=0;ilpcSize;i++) - { - st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1); - } + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); @@ -187,10 +181,11 @@ void *nb_encoder_init(const SpeexMode *m) st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); - st->innov_save = NULL; + st->innov_rms_save = NULL; st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int)); +#ifndef DISABLE_VBR st->vbr = (VBRState*)speex_alloc(sizeof(VBRState)); vbr_init(st->vbr); st->vbr_quality = 8; @@ -198,18 +193,20 @@ void *nb_encoder_init(const SpeexMode *m) st->vbr_max = 0; st->vad_enabled = 0; st->dtx_enabled = 0; + st->dtx_count=0; st->abr_enabled = 0; st->abr_drift = 0; + st->abr_drift2 = 0; +#endif /* #ifndef DISABLE_VBR */ st->plc_tuning = 2; st->complexity=2; st->sampling_rate=8000; - st->dtx_count=0; st->isWideband = 0; st->highpass_enabled = 1; #ifdef ENABLE_VALGRIND - VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); + VALGRIND_MAKE_READABLE(st, NB_ENC_STACK); #endif return st; } @@ -227,8 +224,6 @@ void nb_encoder_destroy(void *state) speex_free (st->old_qlsp); speex_free (st->swBuf); - speex_free (st->lagWindow); - speex_free (st->old_lsp); speex_free (st->mem_sp); speex_free (st->mem_sw); @@ -238,8 +233,10 @@ void nb_encoder_destroy(void *state) speex_free (st->pi_gain); speex_free (st->pitch); +#ifndef DISABLE_VBR vbr_destroy(st->vbr); speex_free (st->vbr); +#endif /* #ifndef DISABLE_VBR */ #ifdef VORBIS_PSYCHO vorbis_psy_destroy(st->psy); @@ -276,10 +273,9 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) char *stack; VARDECL(spx_word16_t *syn_resp); VARDECL(spx_word16_t *real_exc); -#ifdef EPIC_48K - int pitch_half[2]; - int ol_pitch_id=0; -#endif + + spx_word32_t ener=0; + spx_word16_t fine_gain; spx_word16_t *in = (spx_word16_t*)vin; st=(EncState *)state; @@ -296,8 +292,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) ALLOC(interp_qlpc, st->lpcSize, spx_coef_t); /* Move signals 1 frame towards the past */ - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch+2)*sizeof(spx_word16_t)); - speex_move(st->swBuf, st->swBuf+st->frameSize, (st->max_pitch+2)*sizeof(spx_word16_t)); + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2); + SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2); if (st->highpass_enabled) highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp); @@ -340,6 +336,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */ { + int diff = st->windowSize-st->frameSize; if (st->first) for (i=0;ilpcSize;i++) interp_lsp[i] = lsp[i]; @@ -353,19 +350,20 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) /*Open-loop pitch*/ - if (st->complexity>2 || !st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) || - SUBMODE(lbr_pitch) != -1) + if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1 +#ifndef DISABLE_VBR + || st->vbr_enabled || st->vad_enabled +#endif + ) { int nol_pitch[6]; spx_word16_t nol_pitch_coef[6]; bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); - - for (i=0;iwindowSize-st->frameSize;i++) - st->sw[i] = st->winBuf[i]; - for (;iframeSize;i++) - st->sw[i] = in[i-st->windowSize+st->frameSize]; + + SPEEX_COPY(st->sw, st->winBuf, diff); + SPEEX_COPY(st->sw+diff, in, st->frameSize-diff); filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack); open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, @@ -391,54 +389,20 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) ol_pitch/=2;*/ /*ol_pitch_coef = sqrt(ol_pitch_coef);*/ -#ifdef EPIC_48K - if (st->lbr_48k) - { - if (ol_pitch < st->min_pitch+2) - ol_pitch = st->min_pitch+2; - if (ol_pitch > st->max_pitch-2) - ol_pitch = st->max_pitch-2; - open_loop_nbest_pitch(st->sw, ol_pitch-2, ol_pitch+2, st->frameSize>>1, - &pitch_half[0], nol_pitch_coef, 1, stack); - open_loop_nbest_pitch(st->sw+(st->frameSize>>1), pitch_half[0]-1, pitch_half[0]+2, st->frameSize>>1, - &pitch_half[1], nol_pitch_coef, 1, stack); - } -#endif } else { ol_pitch=0; ol_pitch_coef=0; } /*Compute "real" excitation*/ - for (i=0;iwindowSize-st->frameSize;i++) - st->exc[i] = st->winBuf[i]; - for (;iframeSize;i++) - st->exc[i] = in[i-st->windowSize+st->frameSize]; + SPEEX_COPY(st->exc, st->winBuf, diff); + SPEEX_COPY(st->exc+diff, in, st->frameSize-diff); fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack); /* Compute open-loop excitation gain */ -#ifdef EPIC_48K - if (st->lbr_48k) - { - float ol1=0,ol2=0; - float ol_gain2; - ol1 = compute_rms16(st->exc, st->frameSize>>1); - ol2 = compute_rms16(st->exc+(st->frameSize>>1), st->frameSize>>1); - ol1 *= ol1*(st->frameSize>>1); - ol2 *= ol2*(st->frameSize>>1); - - ol_gain2=ol1; - if (ol2>ol1) - ol_gain2=ol2; - ol_gain2 = sqrt(2*ol_gain2*(ol1+ol2))*1.3*(1-.5*GAIN_SCALING_1*GAIN_SCALING_1*ol_pitch_coef*ol_pitch_coef); - - ol_gain=SHR(sqrt(1+ol_gain2/st->frameSize),SIG_SHIFT); - - } else -#endif { spx_word16_t g = compute_rms16(st->exc, st->frameSize); - if (ol_pitch>0) + if (st->submodeID!=1 && ol_pitch>0) ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14), spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16))))); else @@ -447,18 +411,16 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) } #ifdef VORBIS_PSYCHO - for(i=0;i<256-st->frameSize;i++) - st->psy_window[i] = st->psy_window[i+st->frameSize]; - for(i=0;iframeSize;i++) - st->psy_window[256-st->frameSize+i] = in[i]; + SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize); + SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize); compute_curve(st->psy, st->psy_window, st->curve); /*print_vec(st->curve, 128, "curve");*/ if (st->first) - for (i=0;i<128;i++) - st->old_curve[i] = st->curve[i]; + SPEEX_COPY(st->old_curve, st->curve, 128); #endif /*VBR stuff*/ +#ifndef DISABLE_VBR if (st->vbr && (st->vbr_enabled||st->vad_enabled)) { float lsp_dist=0; @@ -570,22 +532,16 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) } else { st->relative_quality = -1; } +#endif /* #ifndef DISABLE_VBR */ if (st->encode_submode) { -#ifdef EPIC_48K - if (!st->lbr_48k) { -#endif + /* First, transmit a zero for narrowband */ + speex_bits_pack(bits, 0, 1); - /* First, transmit a zero for narrowband */ - speex_bits_pack(bits, 0, 1); + /* Transmit the sub-mode we use for this frame */ + speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS); - /* Transmit the sub-mode we use for this frame */ - speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS); - -#ifdef EPIC_48K - } -#endif } /* If null mode (no transmission), just set a couple things to zero*/ @@ -599,7 +555,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) st->first=1; st->bounded_pitch = 1; - speex_move(st->winBuf, in+2*st->frameSize-st->windowSize, (st->windowSize-st->frameSize)*sizeof(spx_word16_t)); + SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize); /* Clear memory (no need to really compute it) */ for (i=0;ilpcSize;i++) @@ -624,35 +580,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) qlsp[i]=lsp[i]; #endif -#ifdef EPIC_48K - if (st->lbr_48k) { - speex_bits_pack(bits, pitch_half[0]-st->min_pitch, 7); - speex_bits_pack(bits, pitch_half[1]-pitch_half[0]+1, 2); - - { - int quant = (int)floor(.5+7.4*GAIN_SCALING_1*ol_pitch_coef); - if (quant>7) - quant=7; - if (quant<0) - quant=0; - ol_pitch_id=quant; - speex_bits_pack(bits, quant, 3); - ol_pitch_coef=GAIN_SCALING*0.13514*quant; - - } - { - int qe = (int)(floor(.5+2.1*log(ol_gain*1.0/SIG_SCALING)))-2; - if (qe<0) - qe=0; - if (qe>15) - qe=15; - ol_gain = exp((qe+2)/2.1)*SIG_SCALING; - speex_bits_pack(bits, qe, 4); - } - - } else { -#endif - /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ if (SUBMODE(lbr_pitch)!=-1) { @@ -662,13 +589,19 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) if (SUBMODE(forced_pitch_gain)) { int quant; + /* This just damps the pitch a bit, because it tends to be too aggressive when forced */ + ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef); +#ifdef FIXED_POINT + quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT); +#else quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1); +#endif if (quant>15) quant=15; if (quant<0) quant=0; speex_bits_pack(bits, quant, 4); - ol_pitch_coef=GAIN_SCALING*0.066667*quant; + ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT)); } @@ -693,10 +626,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) #endif -#ifdef EPIC_48K - } -#endif - /* Special case for first frame */ if (st->first) @@ -720,18 +649,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) int offset; spx_word16_t *sw; spx_word16_t *exc; - spx_sig_t *innov_save = NULL; int pitch; int response_bound = st->subframeSize; -#ifdef EPIC_48K - if (st->lbr_48k) - { - if (sub*2 < st->nbSubframes) - ol_pitch = pitch_half[0]; - else - ol_pitch = pitch_half[1]; - } -#endif /* Offset relative to start of frame */ offset = st->subframeSize*sub; @@ -739,9 +658,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) exc=st->exc+offset; /* Weighted signal */ sw=st->sw+offset; - /* Pointer for saving innovation */ - if (st->innov_save) - innov_save = st->innov_save+offset; /* LSP interpolation (quantized and unquantized) */ lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes); @@ -782,25 +698,21 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); else { - bw_lpc2[0]=1; - for (i=1;i<=st->lpcSize;i++) + for (i=0;ilpcSize;i++) bw_lpc2[i]=0; } /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/ #endif + /*FIXME: This will break if we change the window size */ + speex_assert(st->windowSize-st->frameSize == st->subframeSize); + if (sub==0) { - /*FIXME: This will break if we change the window size */ - if (st->windowSize-st->frameSize != st->subframeSize) - speex_error("windowSize-frameSize != subframeSize"); - if (sub==0) - { - for (i=0;isubframeSize;i++) - real_exc[i] = sw[i] = st->winBuf[i]; - } else { - for (i=0;isubframeSize;i++) - real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)]; - } + for (i=0;isubframeSize;i++) + real_exc[i] = sw[i] = st->winBuf[i]; + } else { + for (i=0;isubframeSize;i++) + real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)]; } fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack); @@ -820,8 +732,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) for (i=0;ilpcSize;i++) mem[i]=SHL32(st->mem_sw[i],1); filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack); - for (i=response_bound;isubframeSize;i++) - ringing[i]=0; + SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound); #else iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack); for (i=0;ilpcSize;i++) @@ -838,16 +749,15 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) for (i=0;ilpcSize;i++) st->mem_sw[i]=mem[i]; - /* Compute target signal */ + /* Compute target signal (saturation prevents overflows on clipped input speech) */ for (i=0;isubframeSize;i++) - target[i]=SUB16(sw[i],PSHR32(ringing[i],1)); + target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767)); /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; + SPEEX_MEMSET(exc, 0, st->subframeSize); /* If we have a long-term predictor (otherwise, something's wrong) */ - if (SUBMODE(ltp_quant)) + speex_assert (SUBMODE(ltp_quant)); { int pit_min, pit_max; /* Long-term prediction */ @@ -876,129 +786,98 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) if (st->bounded_pitch && pit_max>offset) pit_max=offset; -#ifdef EPIC_48K - if (st->lbr_48k) - { - pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2, - exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, - st->lpcSize, st->subframeSize, bits, stack, - exc, syn_resp, st->complexity, ol_pitch_id, st->plc_tuning, &st->cumul_gain); - } else { -#endif - /* Perform pitch search */ pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2, exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, st->lpcSize, st->subframeSize, bits, stack, exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain); -#ifdef EPIC_48K - } -#endif st->pitch[sub]=pitch; - } else { - speex_error ("No pitch prediction, what's wrong"); } - /* Quantization of innovation */ - { - spx_word32_t ener=0; - spx_word16_t fine_gain; - - for (i=0;isubframeSize;i++) - innov[i]=0; - - for (i=0;isubframeSize;i++) - real_exc[i] = SUB16(real_exc[i], PSHR32(exc32[i],SIG_SHIFT-1)); - - ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT); - - /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */ + SPEEX_MEMSET(innov, 0, st->subframeSize); + + /* FIXME: Make sure this is save from overflows (so far so good) */ + for (i=0;isubframeSize;i++) + real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1))); + + ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT); + + /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */ #ifdef FIXED_POINT - { - spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT)); - if (f<=32767) - fine_gain = f; - else - fine_gain = 32767; - } + { + spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT)); + if (f<=32767) + fine_gain = f; + else + fine_gain = 32767; + } #else - fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT)); + fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT)); #endif - /* Calculate gain correction for the sub-frame (if any) */ - if (SUBMODE(have_subframe_gain)) + /* Calculate gain correction for the sub-frame (if any) */ + if (SUBMODE(have_subframe_gain)) + { + int qe; + if (SUBMODE(have_subframe_gain)==3) { - int qe; - if (SUBMODE(have_subframe_gain)==3) - { - qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8); - speex_bits_pack(bits, qe, 3); - ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain); - } else { - qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2); - speex_bits_pack(bits, qe, 1); - ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain); - } + qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8); + speex_bits_pack(bits, qe, 3); + ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain); } else { - ener=ol_gain; + qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2); + speex_bits_pack(bits, qe, 1); + ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain); } + } else { + ener=ol_gain; + } + + /*printf ("%f %f\n", ener, ol_gain);*/ + + /* Normalize innovation */ + signal_div(target, target, ener, st->subframeSize); + + /* Quantize innovation */ + speex_assert (SUBMODE(innovation_quant)); + { + /* Codebook search */ + SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); + + /* De-normalize innovation and update excitation */ + signal_mul(innov, innov, ener, st->subframeSize); + + for (i=0;isubframeSize;i++) + exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); - /*printf ("%f %f\n", ener, ol_gain);*/ - - /* Normalize innovation */ - signal_div(target, target, ener, st->subframeSize); - - /* Quantize innovation */ - if (SUBMODE(innovation_quant)) - { - /* Codebook search */ - SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); - - /* De-normalize innovation and update excitation */ - signal_mul(innov, innov, ener, st->subframeSize); - - for (i=0;isubframeSize;i++) - exc[i] = EXTRACT16(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT)); - } else { - speex_error("No fixed codebook"); - } - - if (innov_save) - { - for (i=0;isubframeSize;i++) - innov_save[i] = innov[i]; - } /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ if (SUBMODE(double_codebook)) { char *tmp_stack=stack; VARDECL(spx_sig_t *innov2); ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]=MULT16_16_P13(QCONST16(2.2,13), target[i]); + target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]); SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov2, syn_resp, bits, stack, st->complexity, 0); - signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545,15),ener), st->subframeSize); + signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize); for (i=0;isubframeSize;i++) - exc[i] = ADD32(exc[i],PSHR32(innov2[i],SIG_SHIFT)); - if (innov_save) - { - for (i=0;isubframeSize;i++) - innov_save[i] = ADD32(innov_save[i],innov2[i]); - } + innov[i] = ADD32(innov[i],innov2[i]); stack = tmp_stack; } - + for (i=0;isubframeSize;i++) + exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize); + } } - for (i=0;isubframeSize;i++) - sw[i] = exc[i]; /* Final signal synthesis from excitation */ - iir_mem16(sw, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack); + iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack); /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ if (st->complexity!=0) @@ -1017,23 +896,22 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) #ifdef VORBIS_PSYCHO if (st->submodeID>=1) - { - for (i=0;i<128;i++) - st->old_curve[i] = st->curve[i]; - } + SPEEX_COPY(st->old_curve, st->curve, 128); #endif if (st->submodeID==1) { +#ifndef DISABLE_VBR if (st->dtx_count) speex_bits_pack(bits, 15, 4); else +#endif speex_bits_pack(bits, 0, 4); } /* The next frame will not be the first (Duh!) */ st->first = 0; - speex_move(st->winBuf, in+2*st->frameSize-st->windowSize, (st->windowSize-st->frameSize)*sizeof(spx_word16_t)); + SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize); if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) st->bounded_pitch = 1; @@ -1063,9 +941,6 @@ void *nb_decoder_init(const SpeexMode *m) st->encode_submode = 1; -#ifdef EPIC_48K - st->lbr_48k=mode->lbr48k; -#endif st->first=1; /* Codec parameters, should eventually have several "modes"*/ @@ -1083,8 +958,7 @@ void *nb_decoder_init(const SpeexMode *m) st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6; - for (i=0;iframeSize + st->max_pitch + 1;i++) - st->excBuf[i]=0; + SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch); st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); @@ -1111,7 +985,7 @@ void *nb_decoder_init(const SpeexMode *m) st->highpass_enabled = 1; #ifdef ENABLE_VALGRIND - VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); + VALGRIND_MAKE_READABLE(st, NB_DEC_STACK); #endif return st; } @@ -1166,7 +1040,7 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack) pitch_gain = st->last_pitch_gain; if (pitch_gain>54) pitch_gain = 54; - pitch_gain = SHL(pitch_gain, 9); + pitch_gain = SHL16(pitch_gain, 9); #else pitch_gain = GAIN_SCALING_1*st->last_pitch_gain; if (pitch_gain>.85) @@ -1177,7 +1051,7 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack) innov_gain = compute_rms16(st->exc, st->frameSize); noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain)))); /* Shift all buffers by one frame */ - speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12); pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT); @@ -1191,21 +1065,21 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack) speex_rand(noise_gain, &st->seed); } - for (i=0;iframeSize;i++) - out[i]=st->exc[i-st->subframeSize]; bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize); - iir_mem16(out, st->interp_qlpc, out, st->frameSize, st->lpcSize, - st->mem_sp, stack); + iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize, + st->lpcSize, st->mem_sp, stack); highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp); st->first = 0; st->count_lost++; - st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR(pitch_gain,9); + st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9); if (st->pitch_gain_buf_idx > 2) /* rollover */ st->pitch_gain_buf_idx = 0; } - +/* Just so we don't need to carry the complete wideband mode information */ +static const int wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0}; + int nb_decode(void *state, SpeexBits *bits, void *vout) { DecState *st; @@ -1225,10 +1099,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) VARDECL(spx_coef_t *ak); VARDECL(spx_lsp_t *qlsp); spx_word16_t pitch_average=0; -#ifdef EPIC_48K - int pitch_half[2]; - int ol_pitch_id=0; -#endif + spx_word16_t *out = (spx_word16_t*)vout; VARDECL(spx_lsp_t *interp_qlsp); @@ -1250,9 +1121,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) if (st->encode_submode) { -#ifdef EPIC_48K - if (!st->lbr_48k) { -#endif /* Search for next narrowband block (handle requests, skip wideband blocks) */ do { @@ -1264,10 +1132,11 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) int submode; int advance; advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); + /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/ + advance = wb_skip_table[submode]; if (advance < 0) { - speex_warning ("Invalid wideband mode encountered. Corrupted stream?"); + speex_notify("Invalid mode encountered. The stream is corrupted."); return -2; } advance -= (SB_SUBMODE_BITS+1); @@ -1279,10 +1148,11 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) if (wideband) { advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); + /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/ + advance = wb_skip_table[submode]; if (advance < 0) { - speex_warning ("Invalid wideband mode encountered: corrupted stream?"); + speex_notify("Invalid mode encountered. The stream is corrupted."); return -2; } advance -= (SB_SUBMODE_BITS+1); @@ -1290,7 +1160,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) wideband = speex_bits_unpack_unsigned(bits, 1); if (wideband) { - speex_warning ("More than two wideband layers found: corrupted stream?"); + speex_notify("More than two wideband layers found. The stream is corrupted."); return -2; } @@ -1315,7 +1185,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) return ret; } else if (m>8) /* Invalid mode */ { - speex_warning("Invalid mode encountered: corrupted stream?"); + speex_notify("Invalid mode encountered. The stream is corrupted."); return -2; } @@ -1323,27 +1193,21 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) /* Get the sub-mode that was used */ st->submodeID = m; -#ifdef EPIC_48K - } -#endif } } /* Shift all buffers by one frame */ - speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12); /* If null mode (no transmission), just set a couple things to zero*/ if (st->submodes[st->submodeID] == NULL) { VARDECL(spx_coef_t *lpc); ALLOC(lpc, st->lpcSize, spx_coef_t); - bw_lpc(GAMMA_SCALING*.93, st->interp_qlpc, lpc, st->lpcSize); + bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize); { - float innov_gain=0; - float pgain=GAIN_SCALING_1*st->last_pitch_gain; - if (pgain>.6) - pgain=.6; + spx_word16_t innov_gain=0; /* FIXME: This was innov, not exc */ innov_gain = compute_rms16(st->exc, st->frameSize); for (i=0;iframeSize;i++) @@ -1353,10 +1217,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) st->first=1; - for (i=0;iframeSize;i++) - out[i] = st->exc[i]; /* Final signal synthesis from excitation */ - iir_mem16(out, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack); + iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack); st->count_lost=0; return 0; @@ -1391,23 +1253,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) st->old_qlsp[i] = qlsp[i]; } -#ifdef EPIC_48K - if (st->lbr_48k) { - pitch_half[0] = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); - pitch_half[1] = pitch_half[0]+speex_bits_unpack_unsigned(bits, 2)-1; - - ol_pitch_id = speex_bits_unpack_unsigned(bits, 3); - ol_pitch_coef=GAIN_SCALING*0.13514*ol_pitch_id; - - { - int qe; - qe = speex_bits_unpack_unsigned(bits, 4); - ol_gain = SIG_SCALING*exp((qe+2)/2.1),SIG_SHIFT; - } - - } else { -#endif - /* Get open-loop pitch estimation for low bit-rate pitch coding */ if (SUBMODE(lbr_pitch)!=-1) { @@ -1418,7 +1263,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) { int quant; quant = speex_bits_unpack_unsigned(bits, 4); - ol_pitch_coef=GAIN_SCALING*0.066667*quant; + ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT)); } /* Get global excitation gain */ @@ -1426,14 +1271,12 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) int qe; qe = speex_bits_unpack_unsigned(bits, 5); #ifdef FIXED_POINT + /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */ ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]); #else ol_gain = SIG_SCALING*exp(qe/3.5); #endif } -#ifdef EPIC_48K - } -#endif ALLOC(ak, st->lpcSize, spx_coef_t); ALLOC(innov, st->subframeSize, spx_sig_t); @@ -1458,19 +1301,9 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) int offset; spx_word16_t *exc; spx_word16_t *sp; - spx_sig_t *innov_save = NULL; + spx_word16_t *innov_save = NULL; spx_word16_t tmp; -#ifdef EPIC_48K - if (st->lbr_48k) - { - if (sub*2 < st->nbSubframes) - ol_pitch = pitch_half[0]; - else - ol_pitch = pitch_half[1]; - } -#endif - /* Offset relative to start of frame */ offset = st->subframeSize*sub; /* Excitation */ @@ -1482,11 +1315,10 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; + SPEEX_MEMSET(exc, 0, st->subframeSize); /*Adaptive codebook contribution*/ - if (SUBMODE(ltp_unquant)) + speex_assert (SUBMODE(ltp_unquant)); { int pit_min, pit_max; /* Handle pitch constraints if any */ @@ -1519,23 +1351,16 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) } -#ifdef EPIC_48K - if (st->lbr_48k) - { - SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), - st->subframeSize, &pitch, &pitch_gain[0], bits, stack, - st->count_lost, offset, st->last_pitch_gain, ol_pitch_id); - } else { -#endif - SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), - st->subframeSize, &pitch, &pitch_gain[0], bits, stack, - st->count_lost, offset, st->last_pitch_gain, 0); - -#ifdef EPIC_48K - } -#endif + SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), + st->subframeSize, &pitch, &pitch_gain[0], bits, stack, + st->count_lost, offset, st->last_pitch_gain, 0); + /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is + crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat). + We can probably be even more aggressive and limit to 15000 or so. */ + sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize); + tmp = gain_3tap_to_1tap(pitch_gain); pitch_average += tmp; @@ -1547,8 +1372,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) if (tmp > best_pitch_gain) best_pitch_gain = tmp; } - } else { - speex_error("No pitch prediction, what's wrong"); } /* Unquantize the innovation */ @@ -1556,8 +1379,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) int q_energy; spx_word32_t ener; - for (i=0;isubframeSize;i++) - innov[i]=0; + SPEEX_MEMSET(innov, 0, st->subframeSize); /* Decode sub-frame gain correction */ if (SUBMODE(have_subframe_gain)==3) @@ -1572,80 +1394,72 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) ener = ol_gain; } - if (SUBMODE(innovation_unquant)) + speex_assert (SUBMODE(innovation_unquant)); { /*Fixed codebook contribution*/ SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); - } else { - speex_error("No fixed codebook"); - } + /* De-normalize innovation and update excitation */ - /* De-normalize innovation and update excitation */ -#ifdef FIXED_POINT - signal_mul(innov, innov, ener, st->subframeSize); -#else - signal_mul(innov, innov, ener, st->subframeSize); -#endif - /*Vocoder mode*/ - if (st->submodeID==1) - { - float g=ol_pitch_coef*GAIN_SCALING_1; + signal_mul(innov, innov, ener, st->subframeSize); - - for (i=0;isubframeSize;i++) - exc[i]=0; - while (st->voc_offsetsubframeSize) + /* Decode second codebook (only for some modes) */ + if (SUBMODE(double_codebook)) { - if (st->voc_offset>=0) - exc[st->voc_offset]=sqrt(1.0*ol_pitch); - st->voc_offset+=ol_pitch; + char *tmp_stack=stack; + VARDECL(spx_sig_t *innov2); + ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); + SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); + signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize); + for (i=0;isubframeSize;i++) + innov[i] = ADD32(innov[i], innov2[i]); + stack = tmp_stack; } - st->voc_offset -= st->subframeSize; - - g=.5+2*(g-.6); - if (g<0) - g=0; - if (g>1) - g=1; for (i=0;isubframeSize;i++) - { - spx_word16_t exci=exc[i]; - /* FIXME: cleanup the innov[i]/SIG_SCALING */ - exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT); - st->voc_m1 = exci; - st->voc_m2=innov[i]; - st->voc_mean = .95*st->voc_mean + .05*exc[i]; - exc[i]-=st->voc_mean; - } - } else { - for (i=0;isubframeSize;i++) - exc[i]=PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT); + exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); /*print_vec(exc, 40, "innov");*/ - } - if (innov_save) - { - for (i=0;isubframeSize;i++) - innov_save[i] = innov[i]; - } - /* Decode second codebook (only for some modes) */ - if (SUBMODE(double_codebook)) - { - char *tmp_stack=stack; - VARDECL(spx_sig_t *innov2); - ALLOC(innov2, st->subframeSize, spx_sig_t); - for (i=0;isubframeSize;i++) - innov2[i]=0; - SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); - signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545,15),ener), st->subframeSize); - for (i=0;isubframeSize;i++) - exc[i] = ADD16(exc[i],PSHR32(innov2[i],SIG_SHIFT)); if (innov_save) { for (i=0;isubframeSize;i++) - innov_save[i] = ADD32(innov_save[i],innov2[i]); + innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT)); } - stack = tmp_stack; } + + /*Vocoder mode*/ + if (st->submodeID==1) + { + spx_word16_t g=ol_pitch_coef; + g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6))); + if (g<0) + g=0; + if (g>GAIN_SCALING) + g=GAIN_SCALING; + + SPEEX_MEMSET(exc, 0, st->subframeSize); + while (st->voc_offsetsubframeSize) + { + /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain; + Not quite sure why we need the factor of two in the sqrt */ + if (st->voc_offset>=0) + exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6))); + st->voc_offset+=ol_pitch; + } + st->voc_offset -= st->subframeSize; + + for (i=0;isubframeSize;i++) + { + spx_word16_t exci=exc[i]; + exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)), + SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))), + MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT))) + )); + st->voc_m1 = exci; + st->voc_m2=innov[i]; + st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15)); + exc[i]-=st->voc_mean; + } + } + } } @@ -1656,8 +1470,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack); multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack); } else { - for (i=0;iframeSize;i++) - out[i]=st->exc[i-st->subframeSize]; + SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize); } /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */ @@ -1712,7 +1525,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) for (i=0;ilpcSize;i+=2) { /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/ - pi_g = ADD32(pi_g, SUB32(EXTEND32(st->interp_qlpc[i+1]),EXTEND32(st->interp_qlpc[i]))); + pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i]))); } st->pi_gain[sub] = pi_g; } @@ -1730,6 +1543,14 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) /*for (i=0;iframeSize;i++) printf ("%d\n", (int)st->frame[i]);*/ + /* Tracking output level */ + st->level = 1+PSHR32(ol_gain,SIG_SHIFT); + st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level); + st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level); + if (st->max_level < st->min_level+1) + st->max_level = st->min_level+1; + /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/ + /* Store the LSPs for interpolation in the next frame */ for (i=0;ilpcSize;i++) st->old_qlsp[i] = qlsp[i]; @@ -1769,7 +1590,8 @@ int nb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_MODE: (*(spx_int32_t*)ptr) = st->submodeID; break; - case SPEEX_SET_VBR: +#ifndef DISABLE_VBR + case SPEEX_SET_VBR: st->vbr_enabled = (*(spx_int32_t*)ptr); break; case SPEEX_GET_VBR: @@ -1817,12 +1639,15 @@ int nb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_ABR: (*(spx_int32_t*)ptr) = st->abr_enabled; break; +#endif /* #ifndef DISABLE_VBR */ +#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) case SPEEX_SET_VBR_QUALITY: st->vbr_quality = (*(float*)ptr); break; case SPEEX_GET_VBR_QUALITY: (*(float*)ptr) = st->vbr_quality; break; +#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */ case SPEEX_SET_QUALITY: { int quality = (*(spx_int32_t*)ptr); @@ -1874,7 +1699,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr) st->bounded_pitch = 1; st->first = 1; for (i=0;ilpcSize;i++) - st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); for (i=0;ilpcSize;i++) st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; for (i=0;iframeSize+st->max_pitch+1;i++) @@ -1900,12 +1725,14 @@ int nb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_PLC_TUNING: (*(spx_int32_t*)ptr)=(st->plc_tuning); break; +#ifndef DISABLE_VBR case SPEEX_SET_VBR_MAX_BITRATE: st->vbr_max = (*(spx_int32_t*)ptr); break; case SPEEX_GET_VBR_MAX_BITRATE: (*(spx_int32_t*)ptr) = st->vbr_max; break; +#endif /* #ifndef DISABLE_VBR */ case SPEEX_SET_HIGHPASS: st->highpass_enabled = (*(spx_int32_t*)ptr); break; @@ -1925,20 +1752,24 @@ int nb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_EXC: { int i; - spx_word16_t *e = (spx_word16_t*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; + for (i=0;inbSubframes;i++) + ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize); } break; +#ifndef DISABLE_VBR case SPEEX_GET_RELATIVE_QUALITY: (*(float*)ptr)=st->relative_quality; break; +#endif /* #ifndef DISABLE_VBR */ case SPEEX_SET_INNOVATION_SAVE: - st->innov_save = (spx_sig_t*)ptr; + st->innov_rms_save = (spx_word16_t*)ptr; break; case SPEEX_SET_WIDEBAND: st->isWideband = *((spx_int32_t*)ptr); break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; default: speex_warning_int("Unknown nb_ctl request: ", request); return -1; @@ -2021,7 +1852,22 @@ int nb_decoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_HIGHPASS: (*(spx_int32_t*)ptr) = st->highpass_enabled; break; - + /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */ +#ifndef DISABLE_FLOAT_API + case SPEEX_GET_ACTIVITY: + { + float ret; + ret = log(st->level/st->min_level)/log(st->max_level/st->min_level); + if (ret>1) + ret = 1; + /* Done in a strange way to catch NaNs as well */ + if (!(ret > 0)) + ret = 0; + /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/ + (*(spx_int32_t*)ptr) = (int)(100*ret); + } + break; +#endif case SPEEX_GET_PI_GAIN: { int i; @@ -2033,20 +1879,22 @@ int nb_decoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_EXC: { int i; - spx_word16_t *e = (spx_word16_t*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; + for (i=0;inbSubframes;i++) + ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize); } break; case SPEEX_GET_DTX_STATUS: *((spx_int32_t*)ptr) = st->dtx_enabled; break; case SPEEX_SET_INNOVATION_SAVE: - st->innov_save = (spx_sig_t*)ptr; + st->innov_save = (spx_word16_t*)ptr; break; case SPEEX_SET_WIDEBAND: st->isWideband = *((spx_int32_t*)ptr); break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; default: speex_warning_int("Unknown nb_ctl request: ", request); return -1; diff --git a/libs/speex/libspeex/nb_celp.h b/libs/speex/libspeex/nb_celp.h index 9a61d68108..14c776ff35 100644 --- a/libs/speex/libspeex/nb_celp.h +++ b/libs/speex/libspeex/nb_celp.h @@ -64,10 +64,6 @@ typedef struct EncState { int ol_voiced; /**< Open-loop voiced/non-voiced decision */ int *pitch; -#ifdef EPIC_48K - int lbr_48k; -#endif - #ifdef VORBIS_PSYCHO VorbisPsy *psy; float *psy_window; @@ -77,7 +73,6 @@ typedef struct EncState { spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */ spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */ - float lag_factor; /**< Lag windowing Gaussian width */ spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ char *stack; /**< Pseudo-stack allocation for temporary memory */ spx_word16_t *winBuf; /**< Input buffer (original signal) */ @@ -86,7 +81,7 @@ typedef struct EncState { spx_word16_t *swBuf; /**< Weighted signal buffer */ spx_word16_t *sw; /**< Start of weighted signal frame */ const spx_word16_t *window; /**< Temporary (Hanning) window */ - spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ + const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ spx_lsp_t *old_lsp; /**< LSPs for previous frame */ spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */ @@ -96,8 +91,9 @@ typedef struct EncState { spx_mem_t *mem_exc2; /**< Filter memory for excitation (whole frame) */ spx_mem_t mem_hp[2]; /**< High-pass filter memory */ spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - spx_sig_t *innov_save; /**< If non-NULL, innovation is copied here */ - + spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */ + +#ifndef DISABLE_VBR VBRState *vbr; /**< State of the VBR data */ float vbr_quality; /**< Quality setting for VBR encoding */ float relative_quality; /**< Relative quality that will be needed by VBR */ @@ -110,6 +106,8 @@ typedef struct EncState { float abr_drift; float abr_drift2; float abr_count; +#endif /* #ifndef DISABLE_VBR */ + int complexity; /**< Complexity setting (0-10 from least complex to most complex) */ spx_int32_t sampling_rate; int plc_tuning; @@ -134,10 +132,6 @@ typedef struct DecState { int max_pitch; /**< Maximum pitch value allowed */ spx_int32_t sampling_rate; -#ifdef EPIC_48K - int lbr_48k; -#endif - spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */ char *stack; /**< Pseudo-stack allocation for temporary memory */ @@ -148,7 +142,11 @@ typedef struct DecState { spx_mem_t *mem_sp; /**< Filter memory for synthesis signal */ spx_mem_t mem_hp[2]; /**< High-pass filter memory */ spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - spx_sig_t *innov_save; /** If non-NULL, innovation is copied here */ + spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */ + + spx_word16_t level; + spx_word16_t max_level; + spx_word16_t min_level; /* This is used in packet loss concealment */ int last_pitch; /**< Pitch of last correctly decoded frame */ @@ -168,7 +166,7 @@ typedef struct DecState { /*Vocoder data*/ spx_word16_t voc_m1; spx_word32_t voc_m2; - float voc_mean; + spx_word16_t voc_mean; int voc_offset; int dtx_enabled; diff --git a/libs/speex/libspeex/os_support.h b/libs/speex/libspeex/os_support.h new file mode 100644 index 0000000000..6b74b0c22f --- /dev/null +++ b/libs/speex/libspeex/os_support.h @@ -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 +#include +#include + +#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 #include "speex/speex_preprocess.h" -#include "misc.h" -#include "smallft.h" - -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) < (b) ? (a) : (b)) +#include "speex/speex_echo.h" +#include "arch.h" +#include "fftwrap.h" +#include "filterbank.h" +#include "math_approx.h" +#include "os_support.h" #ifndef M_PI #define M_PI 3.14159263 #endif -#define SQRT_M_PI_2 0.88623 -#define LOUDNESS_EXP 2.5 +#define LOUDNESS_EXP 5.f +#define AMP_SCALE .001f +#define AMP_SCALE_1 1000.f + +#define NB_BANDS 24 -#define NB_BANDS 8 +#define SPEECH_PROB_START_DEFAULT QCONST16(0.35f,15) +#define SPEECH_PROB_CONTINUE_DEFAULT QCONST16(0.20f,15) +#define NOISE_SUPPRESS_DEFAULT -15 +#define ECHO_SUPPRESS_DEFAULT -40 +#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15 -#define SPEEX_PROB_START_DEFAULT 0.35f -#define SPEEX_PROB_CONTINUE_DEFAULT 0.20f +#ifndef NULL +#define NULL 0 +#endif -#define ZMIN .1 -#define ZMAX .316 -#define ZMIN_1 10 -#define LOG_MIN_MAX_1 0.86859 +#define SQR(x) ((x)*(x)) +#define SQR16(x) (MULT16_16((x),(x))) +#define SQR16_Q15(x) (MULT16_16_Q15((x),(x))) -static void conj_window(float *w, int len) +#ifdef FIXED_POINT +static inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,7) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,8); + return PDIV32_16(a,b); + } + +} +static inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,15) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,15)-a; + return DIV32_16(a,b); + } +} +#define SNR_SCALING 256.f +#define SNR_SCALING_1 0.0039062f +#define SNR_SHIFT 8 + +#define FRAC_SCALING 32767.f +#define FRAC_SCALING_1 3.0518e-05 +#define FRAC_SHIFT 1 + +#define EXPIN_SCALING 2048.f +#define EXPIN_SCALING_1 0.00048828f +#define EXPIN_SHIFT 11 +#define EXPOUT_SCALING_1 1.5259e-05 + +#define NOISE_SHIFT 7 + +#else + +#define DIV32_16_Q8(a,b) ((a)/(b)) +#define DIV32_16_Q15(a,b) ((a)/(b)) +#define SNR_SCALING 1.f +#define SNR_SCALING_1 1.f +#define SNR_SHIFT 0 +#define FRAC_SCALING 1.f +#define FRAC_SCALING_1 1.f +#define FRAC_SHIFT 0 +#define NOISE_SHIFT 0 + +#define EXPIN_SCALING 1.f +#define EXPIN_SCALING_1 1.f +#define EXPOUT_SCALING_1 1.f + +#endif + +/** Speex pre-processor state. */ +struct SpeexPreprocessState_ { + /* Basic info */ + 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 */ + int nbands; + FilterBank *bank; + + /* Parameters */ + int denoise_enabled; + int vad_enabled; + int dereverb_enabled; + spx_word16_t reverb_decay; + spx_word16_t reverb_level; + spx_word16_t speech_prob_start; + spx_word16_t speech_prob_continue; + int noise_suppress; + int echo_suppress; + int echo_suppress_active; + SpeexEchoState *echo_state; + + spx_word16_t speech_prob; /**< Probability last frame was speech */ + + /* DSP-related arrays */ + spx_word16_t *frame; /**< Processing frame (2*ps_size) */ + spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */ + spx_word32_t *ps; /**< Current power spectrum */ + spx_word16_t *gain2; /**< Adjusted gains */ + spx_word16_t *gain_floor; /**< Minimum gain allowed */ + spx_word16_t *window; /**< Analysis/Synthesis window */ + spx_word32_t *noise; /**< Noise estimate */ + spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */ + spx_word32_t *old_ps; /**< Power spectrum for last frame */ + spx_word16_t *gain; /**< Ephraim Malah gain */ + spx_word16_t *prior; /**< A-priori SNR */ + spx_word16_t *post; /**< A-posteriori SNR */ + + spx_word32_t *S; /**< Smoothed power spectrum */ + spx_word32_t *Smin; /**< See Cohen paper */ + spx_word32_t *Stmp; /**< See Cohen paper */ + int *update_prob; /**< Probability of speech presence for noise update */ + + spx_word16_t *zeta; /**< Smoothed a priori SNR */ + spx_word32_t *echo_noise; + spx_word32_t *residual_echo; + + /* Misc */ + spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */ + spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */ + + /* AGC stuff, only for floating point for now */ +#ifndef FIXED_POINT + int agc_enabled; + float agc_level; + float loudness_accum; + float *loudness_weight; /**< Perceptual loudness curve */ + float loudness; /**< Loudness estimate */ + float agc_gain; /**< Current AGC gain */ + float max_gain; /**< Maximum gain allowed */ + float max_increase_step; /**< Maximum increase in gain from one frame to another */ + float max_decrease_step; /**< Maximum decrease in gain from one frame to another */ + float prev_loudness; /**< Loudness of previous frame */ + float init_max; /**< Current gain limit during initialisation */ +#endif + int nb_adapt; /**< Number of frames used for adaptation so far */ + int was_speech; + int min_count; /**< Number of frames processed so far */ + void *fft_lookup; /**< Lookup table for the FFT */ +#ifdef FIXED_POINT + int frame_shift; +#endif +}; + + +static void conj_window(spx_word16_t *w, int len) { int i; for (i=0;i19) + return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT)))); + frac = SHL32(xx-SHL32(ind,10),5); + return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7); +} + +static inline spx_word16_t qcurve(spx_word16_t x) +{ + x = MAX16(x, 1); + return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x)))); +} + +/* Compute the gain floor based on different floors for the background noise and residual echo */ +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) +{ + int i; + + if (noise_suppress > effective_echo_suppress) + { + spx_word16_t noise_gain, gain_ratio; + noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1))); + gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1))); + + /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ + for (i=0;i19) - return 1+.1296/x; - frac = 2*x-integer; - return ((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f); + x = EXPIN_SCALING_1*xx; + integer = floor(2*x); + ind = (int)integer; + if (ind<0) + return FRAC_SCALING; + if (ind>19) + return FRAC_SCALING*(1+.1296/x); + frac = 2*x-integer; + return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f); } -static inline float qcurve(float x) +static inline spx_word16_t qcurve(spx_word16_t x) { - return 1.f/(1.f+.1f/(x*x)); + return 1.f/(1.f+.15f/(SNR_SCALING_1*x)); } -SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate) +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) { int i; - int N, N3, N4; + float echo_floor; + float noise_floor; + + noise_floor = exp(.2302585f*noise_suppress); + echo_floor = exp(.2302585f*effective_echo_suppress); + + /* Compute the gain floor based on different floors for the background noise and residual echo */ + for (i=0;iframe_size = frame_size; @@ -153,49 +428,51 @@ SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_r st->sampling_rate = sampling_rate; st->denoise_enabled = 1; - st->agc_enabled = 0; - st->agc_level = 8000; st->vad_enabled = 0; st->dereverb_enabled = 0; - st->reverb_decay = .5; - st->reverb_level = .2; + st->reverb_decay = 0; + st->reverb_level = 0; + st->noise_suppress = NOISE_SUPPRESS_DEFAULT; + st->echo_suppress = ECHO_SUPPRESS_DEFAULT; + st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT; - st->speech_prob_start = SPEEX_PROB_START_DEFAULT; - st->speech_prob_continue = SPEEX_PROB_CONTINUE_DEFAULT; + st->speech_prob_start = SPEECH_PROB_START_DEFAULT; + st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT; - st->frame = (float*)speex_alloc(2*N*sizeof(float)); - st->ps = (float*)speex_alloc(N*sizeof(float)); - st->gain2 = (float*)speex_alloc(N*sizeof(float)); - st->window = (float*)speex_alloc(2*N*sizeof(float)); - st->noise = (float*)speex_alloc(N*sizeof(float)); - st->reverb_estimate = (float*)speex_alloc(N*sizeof(float)); - st->old_ps = (float*)speex_alloc(N*sizeof(float)); - st->gain = (float*)speex_alloc(N*sizeof(float)); - st->prior = (float*)speex_alloc(N*sizeof(float)); - st->post = (float*)speex_alloc(N*sizeof(float)); - st->loudness_weight = (float*)speex_alloc(N*sizeof(float)); - st->inbuf = (float*)speex_alloc(N3*sizeof(float)); - st->outbuf = (float*)speex_alloc(N3*sizeof(float)); - st->echo_noise = (float*)speex_alloc(N*sizeof(float)); - - st->S = (float*)speex_alloc(N*sizeof(float)); - st->Smin = (float*)speex_alloc(N*sizeof(float)); - st->Stmp = (float*)speex_alloc(N*sizeof(float)); - st->update_prob = (float*)speex_alloc(N*sizeof(float)); - - st->zeta = (float*)speex_alloc(N*sizeof(float)); - st->Zpeak = 0; - st->Zlast = 0; - - st->noise_bands = (float*)speex_alloc(NB_BANDS*sizeof(float)); - st->noise_bands2 = (float*)speex_alloc(NB_BANDS*sizeof(float)); - st->speech_bands = (float*)speex_alloc(NB_BANDS*sizeof(float)); - st->speech_bands2 = (float*)speex_alloc(NB_BANDS*sizeof(float)); - st->noise_bandsN = st->speech_bandsN = 1; + st->echo_state = NULL; + + st->nbands = NB_BANDS; + M = st->nbands; + st->bank = filterbank_new(M, sampling_rate, N, 1); + + st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + + st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + + st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->update_prob = (int*)speex_alloc(N*sizeof(int)); + + st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); + st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); conj_window(st->window, 2*N3); for (i=2*N3;i<2*st->ps_size;i++) - st->window[i]=1; + st->window[i]=Q15_ONE; if (N4>0) { @@ -205,51 +482,61 @@ SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_r st->window[i+N3]=1; } } - for (i=0;inoise[i]=1e4; - st->reverb_estimate[i]=0.; - st->old_ps[i]=1e4; - st->gain[i]=1; - st->post[i]=1; - st->prior[i]=1; + st->noise[i]=QCONST32(1.f,NOISE_SHIFT); + st->reverb_estimate[i]=0; + st->old_ps[i]=1; + st->gain[i]=Q15_ONE; + st->post[i]=SHL16(1, SNR_SHIFT); + st->prior[i]=SHL16(1, SNR_SHIFT); } + for (i=0;iupdate_prob[i] = 1; for (i=0;iinbuf[i]=0; st->outbuf[i]=0; } - +#ifndef FIXED_POINT + st->agc_enabled = 0; + st->agc_level = 8000; + st->loudness_weight = (float*)speex_alloc(N*sizeof(float)); for (i=0;iloudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/ st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f); if (st->loudness_weight[i]<.01f) st->loudness_weight[i]=.01f; st->loudness_weight[i] *= st->loudness_weight[i]; } + /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/ + st->loudness = 1e-15; + st->agc_gain = 1; + st->max_gain = 30; + st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate); + st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate); + st->prev_loudness = 1; + st->init_max = 1; +#endif + st->was_speech = 0; - st->speech_prob = 0; - st->last_speech = 1000; - st->loudness = pow(6000,LOUDNESS_EXP); - st->loudness2 = 6000; - st->nb_loudness_adapt = 0; - - st->fft_lookup = (struct drft_lookup*)speex_alloc(sizeof(struct drft_lookup)); - spx_drft_init(st->fft_lookup,2*N); + st->fft_lookup = spx_fft_init(2*N); st->nb_adapt=0; - st->consec_noise=0; - st->nb_preprocess=0; + st->min_count=0; return st; } -void speex_preprocess_state_destroy(SpeexPreprocessState *st) +EXPORT void speex_preprocess_state_destroy(SpeexPreprocessState *st) { speex_free(st->frame); + speex_free(st->ft); speex_free(st->ps); speex_free(st->gain2); + speex_free(st->gain_floor); speex_free(st->window); speex_free(st->noise); speex_free(st->reverb_estimate); @@ -257,8 +544,11 @@ void speex_preprocess_state_destroy(SpeexPreprocessState *st) speex_free(st->gain); speex_free(st->prior); speex_free(st->post); +#ifndef FIXED_POINT speex_free(st->loudness_weight); +#endif speex_free(st->echo_noise); + speex_free(st->residual_echo); speex_free(st->S); speex_free(st->Smin); @@ -266,298 +556,64 @@ void speex_preprocess_state_destroy(SpeexPreprocessState *st) speex_free(st->update_prob); speex_free(st->zeta); - speex_free(st->noise_bands); - speex_free(st->noise_bands2); - speex_free(st->speech_bands); - speex_free(st->speech_bands2); - speex_free(st->inbuf); speex_free(st->outbuf); - spx_drft_clear(st->fft_lookup); - speex_free(st->fft_lookup); - + spx_fft_destroy(st->fft_lookup); + filterbank_destroy(st->bank); speex_free(st); } -static void update_noise(SpeexPreprocessState *st, float *ps, spx_int32_t *echo) +/* FIXME: The AGC doesn't work yet with fixed-point*/ +#ifndef FIXED_POINT +static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft) { int i; - float beta; - st->nb_adapt++; - beta=1.0f/st->nb_adapt; - if (beta < .05f) - beta=.05f; + int N = st->ps_size; + float target_gain; + float loudness=1.f; + float rate; - if (!echo) + for (i=2;ips_size;i++) - st->noise[i] = (1.f-beta)*st->noise[i] + beta*ps[i]; - } else { - for (i=0;ips_size;i++) - st->noise[i] = (1.f-beta)*st->noise[i] + beta*max(1.f,ps[i]-st->frame_size*st->frame_size*1.0*echo[i]); -#if 0 - for (i=0;ips_size;i++) - st->noise[i] = 0; -#endif + loudness += 2.f*N*st->ps[i]* st->loudness_weight[i]; } -} - -static int speex_compute_vad(SpeexPreprocessState *st, float *ps, float mean_prior, float mean_post) -{ - int i, is_speech=0; - int N = st->ps_size; - float scale=.5f/N; - - /* FIXME: Clean this up a bit */ - { - float bands[NB_BANDS]; - int j; - float p0, p1; - float tot_loudness=0; - float x = sqrt(mean_post); - - for (i=5;ips[i] * st->loudness_weight[i]; - } - - for (i=0;ispeech_prob + .01*(1-st->speech_prob); - p1 *= .01*st->speech_prob + .99*(1-st->speech_prob); - - st->speech_prob = p0/(p1+p0); - */ - - if (st->noise_bandsN < 50 || st->speech_bandsN < 50) - { - if (mean_post > 5.f) - { - float adapt = 1./st->speech_bandsN++; - if (adapt<.005f) - adapt = .005f; - for (i=0;ispeech_bands[i] = (1.f-adapt)*st->speech_bands[i] + adapt*bands[i]; - /*st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*bands[i]*bands[i];*/ - st->speech_bands2[i] = (1.f-adapt)*st->speech_bands2[i] + adapt*(bands[i]-st->speech_bands[i])*(bands[i]-st->speech_bands[i]); - } - } else { - float adapt = 1./st->noise_bandsN++; - if (adapt<.005f) - adapt = .005f; - for (i=0;inoise_bands[i] = (1.f-adapt)*st->noise_bands[i] + adapt*bands[i]; - /*st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*bands[i]*bands[i];*/ - st->noise_bands2[i] = (1.f-adapt)*st->noise_bands2[i] + adapt*(bands[i]-st->noise_bands[i])*(bands[i]-st->noise_bands[i]); - } - } - } - p0=p1=1; - for (i=0;inoise_bands2[i] - st->noise_bands[i]*st->noise_bands[i]; - speech_var = 1.01*st->speech_bands2[i] - st->speech_bands[i]*st->speech_bands[i];*/ - noise_var = st->noise_bands2[i]; - speech_var = st->speech_bands2[i]; - if (noise_var < .1f) - noise_var = .1f; - if (speech_var < .1f) - speech_var = .1f; - - /*speech_var = sqrt(speech_var*noise_var); - noise_var = speech_var;*/ - if (noise_var < .05f*speech_var) - noise_var = .05f*speech_var; - if (speech_var < .05f*noise_var) - speech_var = .05f*noise_var; - - if (bands[i] < st->noise_bands[i]) - speech_var = noise_var; - if (bands[i] > st->speech_bands[i]) - noise_var = speech_var; - - speech_mean = st->speech_bands[i]; - noise_mean = st->noise_bands[i]; - if (noise_mean < speech_mean - 5.f) - noise_mean = speech_mean - 5.f; - - tmp1 = exp(-.5f*(bands[i]-speech_mean)*(bands[i]-speech_mean)/speech_var)/sqrt(2.f*M_PI*speech_var); - tmp2 = exp(-.5f*(bands[i]-noise_mean)*(bands[i]-noise_mean)/noise_var)/sqrt(2.f*M_PI*noise_var); - /*fprintf (stderr, "%f ", (float)(p0/(.01+p0+p1)));*/ - /*fprintf (stderr, "%f ", (float)(bands[i]));*/ - pr = tmp1/(1e-25+tmp1+tmp2); - /*if (bands[i] < st->noise_bands[i]) - pr=.01; - if (bands[i] > st->speech_bands[i] && pr < .995) - pr=.995;*/ - if (pr>.999f) - pr=.999f; - if (pr<.001f) - pr=.001f; - /*fprintf (stderr, "%f ", pr);*/ - p0 *= pr; - p1 *= (1-pr); - } - - p0 = pow(p0,.2); - p1 = pow(p1,.2); - -#if 1 - p0 *= 2.f; - p0=p0/(p1+p0); - if (st->last_speech>20) - { - float tmp = sqrt(tot_loudness)/st->loudness2; - tmp = 1.f-exp(-10.f*tmp); - if (p0>tmp) - p0=tmp; - } - p1=1-p0; -#else - if (sqrt(tot_loudness) < .6f*st->loudness2 && p0>15.f*p1) - p0=15.f*p1; - if (sqrt(tot_loudness) < .45f*st->loudness2 && p0>7.f*p1) - p0=7.f*p1; - if (sqrt(tot_loudness) < .3f*st->loudness2 && p0>3.f*p1) - p0=3.f*p1; - if (sqrt(tot_loudness) < .15f*st->loudness2 && p0>p1) - p0=p1; - /*fprintf (stderr, "%f %f ", (float)(sqrt(tot_loudness) /( .25*st->loudness2)), p0/(p1+p0));*/ -#endif - - p0 *= .99f*st->speech_prob + .01f*(1-st->speech_prob); - p1 *= .01f*st->speech_prob + .99f*(1-st->speech_prob); - - st->speech_prob = p0/(1e-25f+p1+p0); - /*fprintf (stderr, "%f %f %f ", tot_loudness, st->loudness2, st->speech_prob);*/ - - if (st->speech_prob > st->speech_prob_start - || (st->last_speech < 20 && st->speech_prob > st->speech_prob_continue)) - { - is_speech = 1; - st->last_speech = 0; - } else { - st->last_speech++; - if (st->last_speech<20) - is_speech = 1; - } - - if (st->noise_bandsN > 50 && st->speech_bandsN > 50) - { - if (mean_post > 5) - { - float adapt = 1./st->speech_bandsN++; - if (adapt<.005f) - adapt = .005f; - for (i=0;ispeech_bands[i] = (1-adapt)*st->speech_bands[i] + adapt*bands[i]; - /*st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*bands[i]*bands[i];*/ - st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*(bands[i]-st->speech_bands[i])*(bands[i]-st->speech_bands[i]); - } - } else { - float adapt = 1./st->noise_bandsN++; - if (adapt<.005f) - adapt = .005f; - for (i=0;inoise_bands[i] = (1-adapt)*st->noise_bands[i] + adapt*bands[i]; - /*st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*bands[i]*bands[i];*/ - st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*(bands[i]-st->noise_bands[i])*(bands[i]-st->noise_bands[i]); - } - } - } - - - } - - return is_speech; -} - -static void speex_compute_agc(SpeexPreprocessState *st, float mean_prior) -{ - int i; - int N = st->ps_size; - float scale=.5f/N; - float agc_gain; - int freq_start, freq_end; - float active_bands = 0; - - freq_start = (int)(300.0f*2*N/st->sampling_rate); - freq_end = (int)(2000.0f*2*N/st->sampling_rate); - for (i=freq_start;iS[i] > 20.f*st->Smin[i]+1000.f) - active_bands+=1; - } - active_bands /= (freq_end-freq_start+1); - - if (active_bands > .2f) - { - float loudness=0.f; - float rate, rate2=.2f; - st->nb_loudness_adapt++; - rate=2.0f/(1+st->nb_loudness_adapt); - if (rate < .05f) - rate = .05f; - if (rate < .1f && pow(loudness, LOUDNESS_EXP) > st->loudness) - rate = .1f; - if (rate < .2f && pow(loudness, LOUDNESS_EXP) > 3.f*st->loudness) - rate = .2f; - if (rate < .4f && pow(loudness, LOUDNESS_EXP) > 10.f*st->loudness) - rate = .4f; - - for (i=2;ips[i] * st->gain2[i] * st->gain2[i] * st->loudness_weight[i]; - } - loudness=sqrt(loudness); + loudness=sqrt(loudness); /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) && - loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/ - st->loudness = (1-rate)*st->loudness + (rate)*pow(loudness, LOUDNESS_EXP); - - st->loudness2 = (1-rate2)*st->loudness2 + rate2*pow(st->loudness, 1.0f/LOUDNESS_EXP); - - loudness = pow(st->loudness, 1.0f/LOUDNESS_EXP); - - /*fprintf (stderr, "%f %f %f\n", loudness, st->loudness2, rate);*/ + loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/ + if (Pframe>.3f) + { + /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/ + rate = .03*Pframe*Pframe; + st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP); + st->loudness_accum = (1-rate)*st->loudness_accum + rate; + if (st->init_max < st->max_gain && st->nb_adapt > 20) + st->init_max *= 1.f + .1f*Pframe*Pframe; } + /*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/ - agc_gain = st->agc_level/st->loudness2; - /*fprintf (stderr, "%f %f %f %f\n", active_bands, st->loudness, st->loudness2, agc_gain);*/ - if (agc_gain>200) - agc_gain = 200; + target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP); - for (i=0;igain2[i] *= agc_gain; + if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain) + { + if (target_gain > st->max_increase_step*st->agc_gain) + target_gain = st->max_increase_step*st->agc_gain; + if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness) + target_gain = st->max_decrease_step*st->agc_gain; + if (target_gain > st->max_gain) + target_gain = st->max_gain; + if (target_gain > st->init_max) + target_gain = st->init_max; + st->agc_gain = target_gain; + } + /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/ + + for (i=0;i<2*N;i++) + ft[i] *= st->agc_gain; + st->prev_loudness = loudness; } +#endif static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x) { @@ -565,7 +621,7 @@ static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x) int N = st->ps_size; int N3 = 2*N - st->frame_size; int N4 = st->frame_size - N3; - float *ps=st->ps; + spx_word32_t *ps=st->ps; /* 'Build' input frame */ for (i=0;iframe[i] *= st->window[i]; + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); +#ifdef FIXED_POINT + { + spx_word16_t max_val=0; + for (i=0;i<2*N;i++) + max_val = MAX16(max_val, ABS16(st->frame[i])); + st->frame_shift = 14-spx_ilog2(EXTEND32(max_val)); + for (i=0;i<2*N;i++) + st->frame[i] = SHL16(st->frame[i], st->frame_shift); + } +#endif + /* Perform FFT */ - spx_drft_forward(st->fft_lookup, st->frame); - + spx_fft(st->fft_lookup, st->frame, st->ft); + /* Power spectrum */ - ps[0]=1; + ps[0]=MULT16_16(st->ft[0],st->ft[0]); for (i=1;iframe[2*i-1]*st->frame[2*i-1] + st->frame[2*i]*st->frame[2*i]; + ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]); + for (i=0;ips[i] = PSHR32(st->ps[i], 2*st->frame_shift); + filterbank_compute_bank32(st->bank, ps, ps+N); } static void update_noise_prob(SpeexPreprocessState *st) { int i; + int min_range; int N = st->ps_size; for (i=1;iS[i] = 100.f+ .8f*st->S[i] + .05f*st->ps[i-1]+.1f*st->ps[i]+.05f*st->ps[i+1]; + st->S[i] = MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1]) + + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]); + st->S[0] = MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]); + st->S[N-1] = MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]); - if (st->nb_preprocess<1) + if (st->nb_adapt==1) { - for (i=1;iSmin[i] = st->Stmp[i] = st->S[i]+100.f; + for (i=0;iSmin[i] = st->Stmp[i] = 0; } - if (st->nb_preprocess%200==0) + if (st->nb_adapt < 100) + min_range = 15; + else if (st->nb_adapt < 1000) + min_range = 50; + else if (st->nb_adapt < 10000) + min_range = 150; + else + min_range = 300; + if (st->min_count > min_range) { - for (i=1;imin_count = 0; + for (i=0;iSmin[i] = min(st->Stmp[i], st->S[i]); + st->Smin[i] = MIN32(st->Stmp[i], st->S[i]); st->Stmp[i] = st->S[i]; } } else { - for (i=1;iSmin[i] = min(st->Smin[i], st->S[i]); - st->Stmp[i] = min(st->Stmp[i], st->S[i]); + st->Smin[i] = MIN32(st->Smin[i], st->S[i]); + st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]); } } - for (i=1;iupdate_prob[i] *= .2f; - if (st->S[i] > 2.5*st->Smin[i]) - st->update_prob[i] += .8f; + if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > st->Smin[i]) + st->update_prob[i] = 1; + else + st->update_prob[i] = 0; /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/ /*fprintf (stderr, "%f ", st->update_prob[i]);*/ } } -#define NOISE_OVERCOMPENS 1.4 +#define NOISE_OVERCOMPENS 1. -int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + +EXPORT int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) +{ + return speex_preprocess_run(st, x); +} + +EXPORT int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x) { int i; - int is_speech=1; - float mean_post=0; - float mean_prior=0; + int M; int N = st->ps_size; int N3 = 2*N - st->frame_size; int N4 = st->frame_size - N3; - float scale=.5f/N; - float *ps=st->ps; - float Zframe=0, Pframe; - + spx_word32_t *ps=st->ps; + spx_word32_t Zframe; + spx_word16_t Pframe; + spx_word16_t beta, beta_1; + spx_word16_t effective_echo_suppress; + + st->nb_adapt++; + if (st->nb_adapt>20000) + st->nb_adapt = 20000; + st->min_count++; + + beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); + beta_1 = Q15_ONE-beta; + M = st->nbands; + /* Deal with residual echo if provided */ + if (st->echo_state) + { + speex_echo_get_residual(st->echo_state, st->residual_echo, N); +#ifndef FIXED_POINT + /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */ + if (!(st->residual_echo[0] >=0 && st->residual_echo[0]residual_echo[i] = 0; + } +#endif + for (i=0;iecho_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]); + filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N); + } else { + for (i=0;iecho_noise[i] = 0; + } preprocess_analysis(st, x); update_noise_prob(st); - st->nb_preprocess++; - - /* Noise estimation always updated for the 20 first times */ - if (st->nb_adapt<10) + /* Noise estimation always updated for the 10 first frames */ + /*if (st->nb_adapt<10) { - update_noise(st, ps, echo); + for (i=1;iupdate_prob[i] = 0; } - - /* Deal with residual echo if provided */ - if (echo) - for (i=1;iecho_noise[i] = (.3f*st->echo_noise[i] + st->frame_size*st->frame_size*1.0*echo[i]); - - /* Compute a posteriori SNR */ - for (i=1;inoise[i] + st->echo_noise[i] + st->reverb_estimate[i]; - st->post[i] = ps[i]/tot_noise - 1.f; - if (st->post[i]>100.f) - st->post[i]=100.f; - /*if (st->post[i]<0) - st->post[i]=0;*/ - mean_post+=st->post[i]; + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT)) + st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT))); } - mean_post /= N; - if (mean_post<0.f) - mean_post=0.f; + filterbank_compute_bank32(st->bank, st->noise, st->noise+N); /* Special case for first frame */ if (st->nb_adapt==1) - for (i=1;iold_ps[i] = ps[i]; - /* Compute a priori SNR */ + /* Compute a posteriori SNR */ + for (i=0;iprior[i]*st->prior[i]/((1+st->prior[i])*(1+st->prior[i])); - float tot_noise = 1.f+ NOISE_OVERCOMPENS*st->noise[i] + st->echo_noise[i] + st->reverb_estimate[i]; - /* A priori SNR update */ - st->prior[i] = gamma*max(0.0f,st->post[i]) + - (1.f-gamma)* (.8*st->gain[i]*st->gain[i]*st->old_ps[i]/tot_noise + .2*st->prior[i]); - - if (st->prior[i]>100.f) - st->prior[i]=100.f; - - mean_prior+=st->prior[i]; - } + spx_word16_t gamma; + + /* Total noise estimate including residual echo and reverberation */ + spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]); + + /* A posteriori SNR = ps/noise - 1*/ + st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT)); + st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT)); + + /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */ + gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise)))); + + /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */ + st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15)); + st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT)); } - mean_prior /= N; -#if 0 - for (i=0;ipost, N+M, "");*/ + + /* Recursive average of the a priori SNR. A bit smoothed for the psd components */ + st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15); + for (i=1;izeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])), + MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15); + for (i=N-1;izeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15); + + /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */ + Zframe = 0; + for (i=N;izeta[i])); + Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands))); + + effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15)); + + compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M); + + /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale) + Technically this is actually wrong because the EM gaim assumes a slightly different probability + distribution */ + for (i=N;iprior[i]); - } - fprintf (stderr, "\n"); + /* See EM and Cohen papers*/ + spx_word32_t theta; + /* Gain from hypergeometric function */ + spx_word32_t MM; + /* Weiner filter gain */ + spx_word16_t prior_ratio; + /* a priority probability of speech presence based on Bark sub-band alone */ + spx_word16_t P1; + /* Speech absence a priori probability (considering sub-band and frame) */ + spx_word16_t q; +#ifdef FIXED_POINT + spx_word16_t tmp; #endif - /*fprintf (stderr, "%f %f\n", mean_prior,mean_post);*/ - - if (st->nb_preprocess>=20) - { - int do_update = 0; - float noise_ener=0, sig_ener=0; - /* If SNR is low (both a priori and a posteriori), update the noise estimate*/ - /*if (mean_prior<.23 && mean_post < .5)*/ - if (mean_prior<.23f && mean_post < .5f) - do_update = 1; - for (i=1;inoise[i]; - sig_ener += ps[i]; - } - if (noise_ener > 3.f*sig_ener) - do_update = 1; - /*do_update = 0;*/ - if (do_update) - { - st->consec_noise++; - } else { - st->consec_noise=0; - } - } - - if (st->vad_enabled) - is_speech = speex_compute_vad(st, ps, mean_prior, mean_post); - - - if (st->consec_noise>=3) - { - update_noise(st, st->old_ps, echo); - } else { - for (i=1;iupdate_prob[i]<.5f/* || st->ps[i] < st->noise[i]*/) - { - if (echo) - st->noise[i] = .95f*st->noise[i] + .05f*max(1.0f,st->ps[i]-st->frame_size*st->frame_size*1.0*echo[i]); - else - st->noise[i] = .95f*st->noise[i] + .05f*st->ps[i]; - } - } - } - - for (i=1;izeta[i] = .7f*st->zeta[i] + .3f*st->prior[i]; - } - - { - int freq_start = (int)(300.0f*2.f*N/st->sampling_rate); - int freq_end = (int)(2000.0f*2.f*N/st->sampling_rate); - for (i=freq_start;izeta[i]; - } - Zframe /= (freq_end-freq_start); - } - st->Zlast = Zframe; - - Pframe = qcurve(Zframe); - - /*fprintf (stderr, "%f\n", Pframe);*/ - /* Compute gain according to the Ephraim-Malah algorithm */ - for (i=1;iprior[i]/(1.0001f+st->prior[i]); - theta = (1.f+st->post[i])*prior_ratio; - - if (i==1 || i==N-1) - zeta1 = st->zeta[i]; - else - zeta1 = .25f*st->zeta[i-1] + .5f*st->zeta[i] + .25f*st->zeta[i+1]; - P1 = qcurve (zeta1); - /* FIXME: add global prob (P2) */ - q = 1-Pframe*P1; - q = 1-P1; - if (q>.95f) - q=.95f; - p=1.f/(1.f + (q/(1.f-q))*(1.f+st->prior[i])*exp(-theta)); - /*p=1;*/ + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); - /* Optimal estimator for loudness domain */ MM = hypergeom_gain(theta); + /* Gain with bound */ + st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Save old Bark power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); - st->gain[i] = prior_ratio * MM; - /*Put some (very arbitraty) limit on the gain*/ - if (st->gain[i]>2.f) + P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i])); + q = Q15_ONE-MULT16_16_Q15(Pframe,P1); +#ifdef FIXED_POINT + theta = MIN32(theta, EXTEND32(32767)); +/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1)))); + tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/ +/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8)); + st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp)); +#else + st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta)); +#endif + } + /* Convert the EM gains and speech prob to linear frequency */ + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); + filterbank_compute_psd16(st->bank,st->gain+N, st->gain); + + /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */ + if (1) + { + filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor); + + /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */ + for (i=0;igain[i]=2.f; + spx_word32_t MM; + spx_word32_t theta; + spx_word16_t prior_ratio; + spx_word16_t tmp; + spx_word16_t p; + spx_word16_t g; + + /* Wiener filter gain */ + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + /* Optimal estimator for loudness domain */ + MM = hypergeom_gain(theta); + /* EM gain with bound */ + g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Interpolated speech probability of presence */ + p = st->gain2[i]; + + /* Constrain the gain to be close to the Bark scale gain */ + if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i]) + g = MULT16_16(3,st->gain[i]); + st->gain[i] = g; + + /* Save old power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); + + /* Apply gain floor */ + if (st->gain[i] < st->gain_floor[i]) + st->gain[i] = st->gain_floor[i]; + + /* Exponential decay model for reverberation (unused) */ + /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/ + + /* Take into account speech probability of presence (loudness domain MMSE estimator) */ + /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */ + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); + + /* Use this if you want a log-domain MMSE estimator instead */ + /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/ } - - st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i]; - if (st->denoise_enabled) + } else { + for (i=N;igain2[i] = p*p*st->gain[i];*/ - st->gain2[i]=(p*sqrt(st->gain[i])+.2*(1-p)) * (p*sqrt(st->gain[i])+.2*(1-p)); - /*st->gain2[i] = pow(st->gain[i], p) * pow(.1f,1.f-p);*/ - } else { - st->gain2[i]=1.f; + spx_word16_t tmp; + spx_word16_t p = st->gain2[i]; + st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]); + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); } + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); } - st->gain2[0]=st->gain[0]=0.f; - st->gain2[N-1]=st->gain[N-1]=0.f; - /* - for (i=30;idenoise_enabled) { - st->gain[i] = st->gain2[i]*st->gain2[i] + (1-st->gain2[i])*.333*(.6*st->gain2[i-1]+st->gain2[i]+.6*st->gain2[i+1]+.4*st->gain2[i-2]+.4*st->gain2[i+2]); + for (i=0;igain2[i]=Q15_ONE; } - for (i=30;igain2[i] = st->gain[i]; - */ - if (st->agc_enabled) - speex_compute_agc(st, mean_prior); - -#if 0 - if (!is_speech) - { - for (i=0;igain2[i] = 0; - } -#if 0 - else { - for (i=0;igain2[i] = 1; - } -#endif -#endif - + /* Apply computed gain */ for (i=1;iframe[2*i-1] *= st->gain2[i]; - st->frame[2*i] *= st->gain2[i]; + st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]); + st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]); } - - /* Get rid of the DC and very low frequencies */ - st->frame[0]=0; - st->frame[1]=0; - st->frame[2]=0; - /* Nyquist frequency is mostly useless too */ - st->frame[2*N-1]=0; + st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]); + st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]); + + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) + speex_compute_agc(st, Pframe, st->ft); +#endif /* Inverse FFT with 1/N scaling */ - spx_drft_backward(st->fft_lookup, st->frame); - + spx_ifft(st->fft_lookup, st->ft, st->frame); + /* Scale back to original (lower) amplitude */ for (i=0;i<2*N;i++) - st->frame[i] *= scale; + st->frame[i] = PSHR16(st->frame[i], st->frame_shift); + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) { float max_sample=0; for (i=0;i<2*N;i++) @@ -880,9 +976,11 @@ int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo st->frame[i] *= damp; } } - +#endif + + /* Synthesis window (for WOLA) */ for (i=0;i<2*N;i++) - st->frame[i] *= st->window[i]; + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); /* Perform overlap and add */ for (i=0;ioutbuf[i] = st->frame[st->frame_size+i]; - /* Save old power spectrum */ - for (i=1;iold_ps[i] = ps[i]; - - return is_speech; + /* FIXME: This VAD is a kludge */ + st->speech_prob = Pframe; + if (st->vad_enabled) + { + if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue)) + { + st->was_speech=1; + return 1; + } else + { + st->was_speech=0; + return 0; + } + } else { + return 1; + } } -void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) +EXPORT void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x) { int i; int N = st->ps_size; int N3 = 2*N - st->frame_size; + int M; + spx_word32_t *ps=st->ps; - float *ps=st->ps; - + M = st->nbands; + st->min_count++; + preprocess_analysis(st, x); update_noise_prob(st); - - st->nb_preprocess++; for (i=1;iupdate_prob[i]<.5f || st->ps[i] < st->noise[i]) + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT)) { - if (echo) - st->noise[i] = .95f*st->noise[i] + .1f*max(1.0f,st->ps[i]-st->frame_size*st->frame_size*1.0*echo[i]); - else - st->noise[i] = .95f*st->noise[i] + .1f*st->ps[i]; + st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT)); } } for (i=0;ioutbuf[i] = x[st->frame_size-N3+i]*st->window[st->frame_size+i]; + st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]); /* Save old power spectrum */ - for (i=1;iold_ps[i] = ps[i]; - for (i=1;ireverb_estimate[i] *= st->reverb_decay; + for (i=0;ireverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]); } -int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) +EXPORT int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) { int i; SpeexPreprocessState *st; @@ -946,19 +1053,19 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) switch(request) { case SPEEX_PREPROCESS_SET_DENOISE: - st->denoise_enabled = (*(int*)ptr); + st->denoise_enabled = (*(spx_int32_t*)ptr); break; case SPEEX_PREPROCESS_GET_DENOISE: - (*(int*)ptr) = st->denoise_enabled; + (*(spx_int32_t*)ptr) = st->denoise_enabled; break; - +#ifndef FIXED_POINT case SPEEX_PREPROCESS_SET_AGC: - st->agc_enabled = (*(int*)ptr); + st->agc_enabled = (*(spx_int32_t*)ptr); break; case SPEEX_PREPROCESS_GET_AGC: - (*(int*)ptr) = st->agc_enabled; + (*(spx_int32_t*)ptr) = st->agc_enabled; break; - +#ifndef DISABLE_FLOAT_API case SPEEX_PREPROCESS_SET_AGC_LEVEL: st->agc_level = (*(float*)ptr); if (st->agc_level<1) @@ -969,58 +1076,144 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) case SPEEX_PREPROCESS_GET_AGC_LEVEL: (*(float*)ptr) = st->agc_level; break; - +#endif /* #ifndef DISABLE_FLOAT_API */ + case SPEEX_PREPROCESS_SET_AGC_INCREMENT: + st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_INCREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_DECREMENT: + st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_DECREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN: + st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr)); + break; + case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain)); + break; +#endif case SPEEX_PREPROCESS_SET_VAD: - st->vad_enabled = (*(int*)ptr); + speex_warning("The VAD has been replaced by a hack pending a complete rewrite"); + st->vad_enabled = (*(spx_int32_t*)ptr); break; case SPEEX_PREPROCESS_GET_VAD: - (*(int*)ptr) = st->vad_enabled; + (*(spx_int32_t*)ptr) = st->vad_enabled; break; case SPEEX_PREPROCESS_SET_DEREVERB: - st->dereverb_enabled = (*(int*)ptr); + st->dereverb_enabled = (*(spx_int32_t*)ptr); for (i=0;ips_size;i++) st->reverb_estimate[i]=0; break; case SPEEX_PREPROCESS_GET_DEREVERB: - (*(int*)ptr) = st->dereverb_enabled; + (*(spx_int32_t*)ptr) = st->dereverb_enabled; break; case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL: - st->reverb_level = (*(float*)ptr); + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_level = (*(float*)ptr);*/ break; case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL: - (*(float*)ptr) = st->reverb_level; + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_level;*/ break; case SPEEX_PREPROCESS_SET_DEREVERB_DECAY: - st->reverb_decay = (*(float*)ptr); + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_decay = (*(float*)ptr);*/ break; case SPEEX_PREPROCESS_GET_DEREVERB_DECAY: - (*(float*)ptr) = st->reverb_decay; + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_decay;*/ break; case SPEEX_PREPROCESS_SET_PROB_START: - st->speech_prob_start = (*(int*)ptr) / 100.0; - if ( st->speech_prob_start > 1 || st->speech_prob_start < 0 ) - st->speech_prob_start = SPEEX_PROB_START_DEFAULT; + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); break; case SPEEX_PREPROCESS_GET_PROB_START: - (*(int*)ptr) = st->speech_prob_start * 100; + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); break; case SPEEX_PREPROCESS_SET_PROB_CONTINUE: - st->speech_prob_continue = (*(int*)ptr) / 100.0; - if ( st->speech_prob_continue > 1 || st->speech_prob_continue < 0 ) - st->speech_prob_continue = SPEEX_PROB_CONTINUE_DEFAULT; + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); break; case SPEEX_PREPROCESS_GET_PROB_CONTINUE: - (*(int*)ptr) = st->speech_prob_continue * 100; + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); break; - default: + case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS: + st->noise_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: + (*(spx_int32_t*)ptr) = st->noise_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS: + st->echo_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: + (*(spx_int32_t*)ptr) = st->echo_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE: + st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: + (*(spx_int32_t*)ptr) = st->echo_suppress_active; + break; + case SPEEX_PREPROCESS_SET_ECHO_STATE: + st->echo_state = (SpeexEchoState*)ptr; + break; + case SPEEX_PREPROCESS_GET_ECHO_STATE: + (*(SpeexEchoState**)ptr) = (SpeexEchoState*)st->echo_state; + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: + (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); + break; + case SPEEX_PREPROCESS_GET_AGC_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->agc_gain)); + break; +#endif + case SPEEX_PREPROCESS_GET_PSD_SIZE: + case SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE: + (*(spx_int32_t*)ptr) = st->ps_size; + break; + case SPEEX_PREPROCESS_GET_PSD: + for(i=0;ips_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i]; + break; + case SPEEX_PREPROCESS_GET_NOISE_PSD: + for(i=0;ips_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT); + break; + case SPEEX_PREPROCESS_GET_PROB: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob, 100); + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_SET_AGC_TARGET: + st->agc_level = (*(spx_int32_t*)ptr); + if (st->agc_level<1) + st->agc_level=1; + if (st->agc_level>32768) + st->agc_level=32768; + break; + case SPEEX_PREPROCESS_GET_AGC_TARGET: + (*(spx_int32_t*)ptr) = st->agc_level; + break; +#endif + default: speex_warning_int("Unknown speex_preprocess_ctl request: ", request); return -1; } return 0; } + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + diff --git a/libs/speex/libspeex/pseudofloat.h b/libs/speex/libspeex/pseudofloat.h index 84b3ac8eb6..fa841a0101 100644 --- a/libs/speex/libspeex/pseudofloat.h +++ b/libs/speex/libspeex/pseudofloat.h @@ -2,6 +2,15 @@ /** @file pseudofloat.h @brief Pseudo-floating point + * This header file provides a lightweight floating point type for + * use on fixed-point platforms when a large dynamic range is + * required. The new type is not compatible with the 32-bit IEEE format, + * it is not even remotely as accurate as 32-bit floats, and is not + * even guaranteed to produce even remotely correct results for code + * other than Speex. It makes all kinds of shortcuts that are acceptable + * for Speex, but may not be acceptable for your application. You're + * quite welcome to reuse this code and improve it, but don't assume + * it works out of the box. Most likely, it doesn't. */ /* Redistribution and use in source and binary forms, with or without @@ -35,7 +44,8 @@ #ifndef PSEUDOFLOAT_H #define PSEUDOFLOAT_H -#include "misc.h" +#include "arch.h" +#include "os_support.h" #include "math_approx.h" #include @@ -65,18 +75,8 @@ static inline spx_float_t PSEUDOFLOAT(spx_int32_t x) spx_float_t r = {0,0}; return r; } - while (x>32767) - { - x >>= 1; - /*x *= .5;*/ - e++; - } - while (x<16383) - { - x <<= 1; - /*x *= 2;*/ - e--; - } + e = spx_ilog2(ABS32(x))-14; + x = VSHR32(x, e); if (sign) { spx_float_t r; @@ -205,6 +205,14 @@ static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b) return r; } +static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15); + r.e = (a).e+(b).e+15; + return r; +} + static inline spx_float_t FLOAT_SHL(spx_float_t a, int b) { @@ -232,61 +240,38 @@ static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a) static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b) { - if (a.e<-15) - return SHR32(MULT16_32_Q15(a.m, b),-a.e-15); - else - return SHL32(MULT16_32_Q15(a.m, b),15+a.e); + return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15); } static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b) { - int e=0; + int e1, e2; spx_float_t r; - /* FIXME: Handle the sign */ - if (a==0) + if (a==0 || b==0) { return FLOAT_ZERO; } - while (a>32767) - { - a >>= 1; - e++; - } - while (a<16384) - { - a <<= 1; - e--; - } - while (b>32767) - { - b >>= 1; - e++; - } - while (b<16384) - { - b <<= 1; - e--; - } + e1 = spx_ilog2(ABS32(a)); + a = VSHR32(a, e1-14); + e2 = spx_ilog2(ABS32(b)); + b = VSHR32(b, e2-14); r.m = MULT16_16_Q15(a,b); - r.e = e+15; + r.e = e1+e2-13; return r; } +/* Do NOT attempt to divide by a negative number */ static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b) { int e=0; spx_float_t r; - /* FIXME: Handle the sign */ if (a==0) { return FLOAT_ZERO; } - while (a=SHL32(EXTEND32(b.m-1),15)) + e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15)) { a >>= 1; e++; @@ -297,41 +282,47 @@ static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b) } +/* Do NOT attempt to divide by a negative number */ static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b) { - int e=0; + int e0=0,e=0; spx_float_t r; - /* FIXME: Handle the sign */ if (a==0) { return FLOAT_ZERO; } - while (b>32767) + if (b>32767) { - b >>= 1; - e--; + e0 = spx_ilog2(b)-14; + b = VSHR32(b, e0); + e0 = -e0; } - while (a=SHL32(b-1,15)) + e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b-1),15)) { a >>= 1; e++; } + e += e0; r.m = DIV32_16(a,b); r.e = e; return r; } +/* Do NOT attempt to divide by a negative number */ static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b) { int e=0; spx_int32_t num; spx_float_t r; + if (b.m<=0) + { + speex_warning_int("Attempted to divide by", b.m); + return FLOAT_ONE; + } num = a.m; + a.m = ABS16(a.m); while (a.m >= b.m) { e++; @@ -347,7 +338,7 @@ static inline spx_float_t FLOAT_SQRT(spx_float_t a) { spx_float_t r; spx_int32_t m; - m = a.m << 14; + m = SHL32(EXTEND32(a.m), 14); r.e = a.e - 14; if (r.e & 1) { @@ -367,6 +358,7 @@ static inline spx_float_t FLOAT_SQRT(spx_float_t a) #define FLOAT_HALF 0.5f #define PSEUDOFLOAT(x) (x) #define FLOAT_MULT(a,b) ((a)*(b)) +#define FLOAT_AMULT(a,b) ((a)*(b)) #define FLOAT_MUL32(a,b) ((a)*(b)) #define FLOAT_DIV32(a,b) ((a)/(b)) #define FLOAT_EXTRACT16(a) (a) diff --git a/libs/speex/libspeex/quant_lsp.c b/libs/speex/libspeex/quant_lsp.c index bfca5870ce..e624d1a28b 100644 --- a/libs/speex/libspeex/quant_lsp.c +++ b/libs/speex/libspeex/quant_lsp.c @@ -35,12 +35,13 @@ #endif #include "quant_lsp.h" +#include "os_support.h" #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -#include "misc.h" +#include "arch.h" #ifdef BFIN_ASM #include "quant_lsp_bfin.h" @@ -304,11 +305,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits) #ifdef DISABLE_WIDEBAND void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } #else extern const signed char high_lsp_cdbk[]; @@ -382,66 +383,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) #endif - -#ifdef EPIC_48K - -extern const signed char cdbk_lsp_vlbr[5120]; -extern const signed char cdbk_lsp2_vlbr[160]; - -void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) -{ - int i; - int id; - spx_word16_t quant_weight[10]; - - for (i=0;i -#include "misc.h" +#include "arch.h" #define MAX_LSP_SIZE 20 @@ -71,13 +71,4 @@ void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) /* Decodes high-band LSPs */ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits); -#ifdef EPIC_48K -/* Quantizes narrowband LSPs with 14 bits */ -void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits); - -/* Decodes quantized narrowband LSPs (14 bits) */ -void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits); -#endif - - #endif diff --git a/libs/speex/libspeex/quant_lsp_bfin.h b/libs/speex/libspeex/quant_lsp_bfin.h index c884078e6b..087b466b75 100644 --- a/libs/speex/libspeex/quant_lsp_bfin.h +++ b/libs/speex/libspeex/quant_lsp_bfin.h @@ -68,19 +68,19 @@ static int lsp_quant( " B0 = %2;\n\t" " R2.L = W [I0++];\n\t" -" LSETUP (lq1, lq2) LC0 = %4;\n\t" -"lq1: R3 = 0;\n\t" /* R3: dist */ -" LSETUP (lq3, lq4) LC1 = %5;\n\t" -"lq3: R1 = B [P2++] (X);\n\t" +" LSETUP (1f, 2f) LC0 = %4;\n\t" +"1: R3 = 0;\n\t" /* R3: dist */ +" LSETUP (3f, 4f) LC1 = %5;\n\t" +"3: R1 = B [P2++] (X);\n\t" " R1 <<= 5;\n\t" " R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t" " R0 = R0.L*R0.L;\n\t" -"lq4: R3 = R3 + R0;\n\t" +"4: R3 = R3 + R0;\n\t" " cc =R3<%0;\n\t" " if cc %0=R3;\n\t" " if cc %1=R5;\n\t" -"lq2: R5 += 1;\n\t" +"2: R5 += 1;\n\t" " L0 = 0;\n\t" : "=&d" (best_dist), "=&d" (best_id) : "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim) @@ -132,10 +132,10 @@ static int lsp_weight_quant( " B0 = %2;\n\t" " B1 = %3;\n\t" -" LSETUP (lwq1, lwq2) LC0 = %5;\n\t" -"lwq1: R3 = 0 (X);\n\t" /* R3: dist */ -" LSETUP (lwq3, lwq4) LC1 = %6;\n\t" -"lwq3: R0.L = W [I0++] || R2.L = W [I1++];\n\t" +" LSETUP (1f, 2f) LC0 = %5;\n\t" +"1: R3 = 0 (X);\n\t" /* R3: dist */ +" LSETUP (3f, 4f) LC1 = %6;\n\t" +"3: R0.L = W [I0++] || R2.L = W [I1++];\n\t" " R1 = B [P2++] (X);\n\t" " R1 <<= 5;\n\t" " R0.L = R0.L - R1.L;\n\t" @@ -143,12 +143,12 @@ static int lsp_weight_quant( " A1 = R2.L*R0.L (M,IS);\n\t" " A1 = A1 >>> 16;\n\t" " R1 = (A1 += R2.L*R0.H) (IS);\n\t" -"lwq4: R3 = R3 + R1;\n\t" +"4: R3 = R3 + R1;\n\t" " cc =R3<%0;\n\t" " if cc %0=R3;\n\t" " if cc %1=R5;\n\t" -"lwq2: R5 += 1;\n\t" +"2: R5 += 1;\n\t" " L0 = 0;\n\t" " L1 = 0;\n\t" : "=&d" (best_dist), "=&d" (best_id) diff --git a/libs/speex/libspeex/resample.c b/libs/speex/libspeex/resample.c new file mode 100644 index 0000000000..bebd1a8666 --- /dev/null +++ b/libs/speex/libspeex/resample.c @@ -0,0 +1,1131 @@ +/* Copyright (C) 2007-2008 Jean-Marc Valin + Copyright (C) 2008 Thorvald Natvig + + File: resample.c + Arbitrary resampling code + + 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 design goals of this code are: + - Very fast algorithm + - SIMD-friendly algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Warning: This resampler is relatively new. Although I think I got rid of + all the major bugs and I don't expect the API to change anymore, there + may be something I've missed. So use with caution. + + This algorithm is based on this original resampling algorithm: + Smith, Julius O. Digital Audio Resampling Home Page + Center for Computer Research in Music and Acoustics (CCRMA), + Stanford University, 2007. + Web published at http://www-ccrma.stanford.edu/~jos/resample/. + + There is one main difference, though. This resampler uses cubic + interpolation instead of linear interpolation in the above paper. This + makes the table much smaller and makes it possible to compute that table + on a per-stream basis. In turn, being able to tweak the table for each + stream makes it possible to both reduce complexity on simple ratios + (e.g. 2/3), and get rid of the rounding operations in the inner loop. + The latter both reduces CPU time and makes the algorithm more SIMD-friendly. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OUTSIDE_SPEEX +#include +static void *speex_alloc (int size) {return calloc(size,1);} +static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} +static void speex_free (void *ptr) {free(ptr);} +#include "speex_resampler.h" +#include "arch.h" +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_resampler.h" +#include "arch.h" +#include "os_support.h" +#endif /* OUTSIDE_SPEEX */ + +#include "stack_alloc.h" +#include + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef _USE_SSE +#include "resample_sse.h" +#endif + +/* Numer of elements to allocate on the stack */ +#ifdef VAR_ARRAYS +#define FIXED_STACK_ALLOC 8192 +#else +#define FIXED_STACK_ALLOC 1024 +#endif + +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); + +struct SpeexResamplerState_ { + spx_uint32_t in_rate; + spx_uint32_t out_rate; + spx_uint32_t num_rate; + spx_uint32_t den_rate; + + int quality; + spx_uint32_t nb_channels; + spx_uint32_t filt_len; + spx_uint32_t mem_alloc_size; + spx_uint32_t buffer_size; + int int_advance; + int frac_advance; + float cutoff; + spx_uint32_t oversample; + int initialised; + int started; + + /* These are per-channel */ + spx_int32_t *last_sample; + spx_uint32_t *samp_frac_num; + spx_uint32_t *magic_samples; + + spx_word16_t *mem; + spx_word16_t *sinc_table; + spx_uint32_t sinc_table_length; + resampler_basic_func resampler_ptr; + + int in_stride; + int out_stride; +} ; + +static double kaiser12_table[68] = { + 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, + 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, + 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, + 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, + 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, + 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, + 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, + 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, + 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, + 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, + 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, + 0.00001000, 0.00000000}; +/* +static double kaiser12_table[36] = { + 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, + 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, + 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, + 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, + 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, + 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; +*/ +static double kaiser10_table[36] = { + 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, + 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, + 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, + 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, + 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, + 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000}; + +static double kaiser8_table[36] = { + 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, + 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, + 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, + 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, + 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, + 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; + +static double kaiser6_table[36] = { + 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, + 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, + 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, + 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, + 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, + 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000}; + +struct FuncDef { + double *table; + int oversample; +}; + +static struct FuncDef _KAISER12 = {kaiser12_table, 64}; +#define KAISER12 (&_KAISER12) +/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; +#define KAISER12 (&_KAISER12)*/ +static struct FuncDef _KAISER10 = {kaiser10_table, 32}; +#define KAISER10 (&_KAISER10) +static struct FuncDef _KAISER8 = {kaiser8_table, 32}; +#define KAISER8 (&_KAISER8) +static struct FuncDef _KAISER6 = {kaiser6_table, 32}; +#define KAISER6 (&_KAISER6) + +struct QualityMapping { + int base_length; + int oversample; + float downsample_bandwidth; + float upsample_bandwidth; + struct FuncDef *window_func; +}; + + +/* This table maps conversion quality to internal parameters. There are two + reasons that explain why the up-sampling bandwidth is larger than the + down-sampling bandwidth: + 1) When up-sampling, we can assume that the spectrum is already attenuated + close to the Nyquist rate (from an A/D or a previous resampling filter) + 2) Any aliasing that occurs very close to the Nyquist rate will be masked + by the sinusoids/noise just below the Nyquist rate (guaranteed only for + up-sampling). +*/ +static const struct QualityMapping quality_map[11] = { + { 8, 4, 0.830f, 0.860f, KAISER6 }, /* Q0 */ + { 16, 4, 0.850f, 0.880f, KAISER6 }, /* Q1 */ + { 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */ + { 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */ + { 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */ + { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */ + { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */ + {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */ + {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */ + {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */ + {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ +}; +/*8,24,40,56,80,104,128,160,200,256,320*/ +static double compute_func(float x, struct FuncDef *func) +{ + float y, frac; + double interp[4]; + int ind; + y = x*func->oversample; + ind = (int)floor(y); + frac = (y-ind); + /* CSE with handle the repeated powers */ + interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac); + interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); + /* Just to make sure we don't have rounding problems */ + interp[1] = 1.f-interp[3]-interp[2]-interp[0]; + + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ + return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +} + +#if 0 +#include +int main(int argc, char **argv) +{ + int i; + for (i=0;i<256;i++) + { + printf ("%f\n", compute_func(i/256., KAISER12)); + } + return 0; +} +#endif + +#ifdef FIXED_POINT +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6f) + return WORD2INT(32768.*cutoff); + else if (fabs(x) > .5f*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func)); +} +#else +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6) + return cutoff; + else if (fabs(x) > .5*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); +} +#endif + +#ifdef FIXED_POINT +static void cubic_coef(spx_word16_t x, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + spx_word16_t x2, x3; + x2 = MULT16_16_P15(x, x); + x3 = MULT16_16_P15(x, x2); + interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15); + interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1)); + interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15); + /* Just to make sure we don't have rounding problems */ + interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3]; + if (interp[2]<32767) + interp[2]+=1; +} +#else +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac; + interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; + /* Just to make sure we don't have rounding problems */ + interp[2] = 1.-interp[0]-interp[1]-interp[3]; +} +#endif + +static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_SINGLE + float accum[4] = {0,0,0,0}; + + for(j=0;j= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + double sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;j= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE + spx_word32_t accum[4] = {0,0,0,0}; + + for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +#else + cubic_coef(frac, interp); + sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = PSHR32(sum,15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +#else + cubic_coef(frac, interp); + sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = PSHR32(sum,15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static void update_filter(SpeexResamplerState *st) +{ + spx_uint32_t old_length; + + old_length = st->filt_len; + st->oversample = quality_map[st->quality].oversample; + st->filt_len = quality_map[st->quality].base_length; + + if (st->num_rate > st->den_rate) + { + /* down-sampling */ + st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; + /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ + st->filt_len = st->filt_len*st->num_rate / st->den_rate; + /* Round down to make sure we have a multiple of 4 */ + st->filt_len &= (~0x3); + if (2*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (4*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (8*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (16*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (st->oversample < 1) + st->oversample = 1; + } else { + /* up-sampling */ + st->cutoff = quality_map[st->quality].upsample_bandwidth; + } + + /* Choose the resampling type that requires the least amount of memory */ + if (st->den_rate <= st->oversample) + { + spx_uint32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->den_rate) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->den_rate; + } + for (i=0;iden_rate;i++) + { + spx_int32_t j; + for (j=0;jfilt_len;j++) + { + st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + } + } +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_direct_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_direct_double; + else + st->resampler_ptr = resampler_basic_direct_single; +#endif + /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ + } else { + spx_int32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->oversample+8) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->oversample+8; + } + for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) + st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func); +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_interpolate_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_interpolate_double; + else + st->resampler_ptr = resampler_basic_interpolate_single; +#endif + /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ + } + st->int_advance = st->num_rate/st->den_rate; + st->frac_advance = st->num_rate%st->den_rate; + + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + if (!st->mem) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;inb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("init filter");*/ + } else if (!st->started) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;inb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("reinit filter");*/ + } else if (st->filt_len > old_length) + { + spx_int32_t i; + /* Increase the filter length */ + /*speex_warning("increase filter size");*/ + int old_alloc_size = st->mem_alloc_size; + if ((st->filt_len-1 + st->buffer_size) > st->mem_alloc_size) + { + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + } + for (i=st->nb_channels-1;i>=0;i--) + { + spx_int32_t j; + spx_uint32_t olen = old_length; + /*if (st->magic_samples[i])*/ + { + /* Try and remove the magic samples as if nothing had happened */ + + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ + olen = old_length + 2*st->magic_samples[i]; + for (j=old_length-2+st->magic_samples[i];j>=0;j--) + st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; + for (j=0;jmagic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = 0; + st->magic_samples[i] = 0; + } + if (st->filt_len > olen) + { + /* If the new filter length is still bigger than the "augmented" length */ + /* Copy data going backward */ + for (j=0;jmem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; + /* Then put zeros for lack of anything better */ + for (;jfilt_len-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; + /* Adjust last_sample */ + st->last_sample[i] += (st->filt_len - olen)/2; + } else { + /* Put back some of the magic! */ + st->magic_samples[i] = (olen - st->filt_len)/2; + for (j=0;jfilt_len-1+st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + } + } + } else if (st->filt_len < old_length) + { + spx_uint32_t i; + /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" + samples so they can be used directly as input the next time(s) */ + for (i=0;inb_channels;i++) + { + spx_uint32_t j; + spx_uint32_t old_magic = st->magic_samples[i]; + st->magic_samples[i] = (old_length - st->filt_len)/2; + /* We must copy some of the memory that's no longer used */ + /* Copy data going backward */ + for (j=0;jfilt_len-1+st->magic_samples[i]+old_magic;j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + st->magic_samples[i] += old_magic; + } + } + +} + +EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); +} + +EXPORT 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) +{ + spx_uint32_t i; + SpeexResamplerState *st; + if (quality > 10 || quality < 0) + { + if (err) + *err = RESAMPLER_ERR_INVALID_ARG; + return NULL; + } + st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); + st->initialised = 0; + st->started = 0; + st->in_rate = 0; + st->out_rate = 0; + st->num_rate = 0; + st->den_rate = 0; + st->quality = -1; + st->sinc_table_length = 0; + st->mem_alloc_size = 0; + st->filt_len = 0; + st->mem = 0; + st->resampler_ptr = 0; + + st->cutoff = 1.f; + st->nb_channels = nb_channels; + st->in_stride = 1; + st->out_stride = 1; + +#ifdef FIXED_POINT + st->buffer_size = 160; +#else + st->buffer_size = 160; +#endif + + /* Per channel data */ + st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int)); + st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + for (i=0;ilast_sample[i] = 0; + st->magic_samples[i] = 0; + st->samp_frac_num[i] = 0; + } + + speex_resampler_set_quality(st, quality); + speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + + + update_filter(st); + + st->initialised = 1; + if (err) + *err = RESAMPLER_ERR_SUCCESS; + + return st; +} + +EXPORT void speex_resampler_destroy(SpeexResamplerState *st) +{ + speex_free(st->mem); + speex_free(st->sinc_table); + speex_free(st->last_sample); + speex_free(st->magic_samples); + speex_free(st->samp_frac_num); + speex_free(st); +} + +static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int j=0; + const int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + spx_uint32_t ilen; + + st->started = 1; + + /* Call the right resampler through the function ptr */ + out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len); + + if (st->last_sample[channel_index] < (spx_int32_t)*in_len) + *in_len = st->last_sample[channel_index]; + *out_len = out_sample; + st->last_sample[channel_index] -= *in_len; + + ilen = *in_len; + + for(j=0;jmagic_samples[channel_index]; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + const int N = st->filt_len; + + speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len); + + st->magic_samples[channel_index] -= tmp_in_len; + + /* If we couldn't process all "magic" input samples, save the rest for next time */ + if (st->magic_samples[channel_index]) + { + spx_uint32_t i; + for (i=0;imagic_samples[channel_index];i++) + mem[N-1+i]=mem[N-1+i+tmp_in_len]; + } + *out += out_len*st->out_stride; + return out_len; +} + +#ifdef FIXED_POINT +EXPORT 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) +#else +EXPORT 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) +#endif +{ + int j; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const int filt_offs = st->filt_len - 1; + const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; + const int istride = st->in_stride; + + if (st->magic_samples[channel_index]) + olen -= speex_resampler_magic(st, channel_index, &out, olen); + if (! st->magic_samples[channel_index]) { + while (ilen && olen) { + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = olen; + + if (in) { + for(j=0;jout_stride; + if (in) + in += ichunk * istride; + } + } + *in_len -= ilen; + *out_len -= olen; + return RESAMPLER_ERR_SUCCESS; +} + +#ifdef FIXED_POINT +EXPORT 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) +#else +EXPORT 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) +#endif +{ + int j; + const int istride_save = st->in_stride; + const int ostride_save = st->out_stride; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1); +#ifdef VAR_ARRAYS + const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC; + VARDECL(spx_word16_t *ystack); + ALLOC(ystack, ylen, spx_word16_t); +#else + const unsigned int ylen = FIXED_STACK_ALLOC; + spx_word16_t ystack[FIXED_STACK_ALLOC]; +#endif + + st->out_stride = 1; + + while (ilen && olen) { + spx_word16_t *y = ystack; + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = (olen > ylen) ? ylen : olen; + spx_uint32_t omagic = 0; + + if (st->magic_samples[channel_index]) { + omagic = speex_resampler_magic(st, channel_index, &y, ochunk); + ochunk -= omagic; + olen -= omagic; + } + if (! st->magic_samples[channel_index]) { + if (in) { + for(j=0;jfilt_len-1]=WORD2INT(in[j*istride_save]); +#else + x[j+st->filt_len-1]=in[j*istride_save]; +#endif + } else { + for(j=0;jfilt_len-1]=0; + } + + speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk); + } else { + ichunk = 0; + ochunk = 0; + } + + for (j=0;jout_stride = ostride_save; + *in_len -= ilen; + *out_len -= olen; + + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;inb_channels;i++) + { + *out_len = bak_len; + if (in != NULL) + speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT 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) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;inb_channels;i++) + { + *out_len = bak_len; + if (in != NULL) + speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); +} + +EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) +{ + *in_rate = st->in_rate; + *out_rate = st->out_rate; +} + +EXPORT 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) +{ + spx_uint32_t fact; + spx_uint32_t old_den; + spx_uint32_t i; + if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) + return RESAMPLER_ERR_SUCCESS; + + old_den = st->den_rate; + st->in_rate = in_rate; + st->out_rate = out_rate; + st->num_rate = ratio_num; + st->den_rate = ratio_den; + /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ + for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) + { + while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) + { + st->num_rate /= fact; + st->den_rate /= fact; + } + } + + if (old_den > 0) + { + for (i=0;inb_channels;i++) + { + st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate-1; + } + } + + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) +{ + *ratio_num = st->num_rate; + *ratio_den = st->den_rate; +} + +EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality) +{ + if (quality > 10 || quality < 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->quality == quality) + return RESAMPLER_ERR_SUCCESS; + st->quality = quality; + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) +{ + *quality = st->quality; +} + +EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->in_stride = stride; +} + +EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->in_stride; +} + +EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->out_stride = stride; +} + +EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->out_stride; +} + +EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st) +{ + return st->filt_len / 2; +} + +EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st) +{ + return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate; +} + +EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;inb_channels;i++) + st->last_sample[i] = st->filt_len/2; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;inb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT const char *speex_resampler_strerror(int err) +{ + switch (err) + { + case RESAMPLER_ERR_SUCCESS: + return "Success."; + case RESAMPLER_ERR_ALLOC_FAILED: + return "Memory allocation failed."; + case RESAMPLER_ERR_BAD_STATE: + return "Bad resampler state."; + case RESAMPLER_ERR_INVALID_ARG: + return "Invalid argument."; + case RESAMPLER_ERR_PTR_OVERLAP: + return "Input and output buffers overlap."; + default: + return "Unknown error. Bad error code or strange version mismatch."; + } +} diff --git a/libs/speex/libspeex/resample_sse.h b/libs/speex/libspeex/resample_sse.h new file mode 100644 index 0000000000..4bd35a2d03 --- /dev/null +++ b/libs/speex/libspeex/resample_sse.h @@ -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 + +#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 +#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 #include "sb_celp.h" -#include "stdlib.h" #include "filters.h" #include "lpc.h" #include "lsp.h" @@ -44,7 +43,13 @@ #include "quant_lsp.h" #include "vq.h" #include "ltp.h" -#include "misc.h" +#include "arch.h" +#include "math_approx.h" +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif /* Default size for the encoder and decoder stack (can be changed at compile time). This does not apply when using variable-size arrays or alloca. */ @@ -60,40 +65,40 @@ #ifdef DISABLE_WIDEBAND void *sb_encoder_init(const SpeexMode *m) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return NULL; } void sb_encoder_destroy(void *state) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } int sb_encode(void *state, void *vin, SpeexBits *bits) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return -2; } void *sb_decoder_init(const SpeexMode *m) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return NULL; } void sb_decoder_destroy(void *state) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } int sb_decode(void *state, SpeexBits *bits, void *vout) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return -2; } int sb_encoder_ctl(void *state, int request, void *ptr) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return -2; } int sb_decoder_ctl(void *state, int request, void *ptr) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); return -2; } #else @@ -109,12 +114,26 @@ int sb_decoder_ctl(void *state, int request, void *ptr) #ifdef FIXED_POINT static const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228}; +static const spx_word16_t fold_quant_bound[32] = { + 39, 44, 50, 57, 64, 73, 83, 94, + 106, 120, 136, 154, 175, 198, 225, 255, + 288, 327, 370, 420, 476, 539, 611, 692, + 784, 889, 1007, 1141, 1293, 1465, 1660, 1881}; #define LSP_MARGIN 410 #define LSP_DELTA1 6553 #define LSP_DELTA2 1638 #else +static const spx_word16_t gc_quant_bound[16] = { + 0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787, + 8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588}; +static const spx_word16_t fold_quant_bound[32] = { + 0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162, + 0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875, + 2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598, + 6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497}; + #define LSP_MARGIN .05 #define LSP_DELTA1 .2 #define LSP_DELTA2 .05 @@ -126,102 +145,47 @@ static const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 63 #ifdef FIXED_POINT static const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2}; -static const spx_word16_t h1[64] = {2, 7, -7, -18, 15, 39, -25, -75, 35, 130, -41, -212, 38, 327, -17, -483, -32, 689, 124, -956, -283, 1307, 543, -1780, -973, 2467, 1733, -3633, -3339, 6409, 9059, -30153, 30153, -9059, -6409, 3339, 3633, -1733, -2467, 973, 1780, -543, -1307, 283, 956, -124, -689, 32, 483, 17, -327, -38, 212, 41, -130, -35, 75, 25, -39, -15, 18, 7, -7, -2}; - - #else static const float h0[64] = { - 3.596189e-05, -0.0001123515, - -0.0001104587, 0.0002790277, - 0.0002298438, -0.0005953563, - -0.0003823631, 0.00113826, - 0.0005308539, -0.001986177, - -0.0006243724, 0.003235877, - 0.0005743159, -0.004989147, - -0.0002584767, 0.007367171, - -0.0004857935, -0.01050689, - 0.001894714, 0.01459396, - -0.004313674, -0.01994365, - 0.00828756, 0.02716055, - -0.01485397, -0.03764973, - 0.026447, 0.05543245, - -0.05095487, -0.09779096, - 0.1382363, 0.4600981, - 0.4600981, 0.1382363, - -0.09779096, -0.05095487, - 0.05543245, 0.026447, - -0.03764973, -0.01485397, - 0.02716055, 0.00828756, - -0.01994365, -0.004313674, - 0.01459396, 0.001894714, - -0.01050689, -0.0004857935, - 0.007367171, -0.0002584767, - -0.004989147, 0.0005743159, - 0.003235877, -0.0006243724, - -0.001986177, 0.0005308539, - 0.00113826, -0.0003823631, - -0.0005953563, 0.0002298438, - 0.0002790277, -0.0001104587, - -0.0001123515, 3.596189e-05 + 3.596189e-05f, -0.0001123515f, + -0.0001104587f, 0.0002790277f, + 0.0002298438f, -0.0005953563f, + -0.0003823631f, 0.00113826f, + 0.0005308539f, -0.001986177f, + -0.0006243724f, 0.003235877f, + 0.0005743159f, -0.004989147f, + -0.0002584767f, 0.007367171f, + -0.0004857935f, -0.01050689f, + 0.001894714f, 0.01459396f, + -0.004313674f, -0.01994365f, + 0.00828756f, 0.02716055f, + -0.01485397f, -0.03764973f, + 0.026447f, 0.05543245f, + -0.05095487f, -0.09779096f, + 0.1382363f, 0.4600981f, + 0.4600981f, 0.1382363f, + -0.09779096f, -0.05095487f, + 0.05543245f, 0.026447f, + -0.03764973f, -0.01485397f, + 0.02716055f, 0.00828756f, + -0.01994365f, -0.004313674f, + 0.01459396f, 0.001894714f, + -0.01050689f, -0.0004857935f, + 0.007367171f, -0.0002584767f, + -0.004989147f, 0.0005743159f, + 0.003235877f, -0.0006243724f, + -0.001986177f, 0.0005308539f, + 0.00113826f, -0.0003823631f, + -0.0005953563f, 0.0002298438f, + 0.0002790277f, -0.0001104587f, + -0.0001123515f, 3.596189e-05f }; -static const float h1[64] = { - 3.596189e-05, 0.0001123515, - -0.0001104587, -0.0002790277, - 0.0002298438, 0.0005953563, - -0.0003823631, -0.00113826, - 0.0005308539, 0.001986177, - -0.0006243724, -0.003235877, - 0.0005743159, 0.004989147, - -0.0002584767, -0.007367171, - -0.0004857935, 0.01050689, - 0.001894714, -0.01459396, - -0.004313674, 0.01994365, - 0.00828756, -0.02716055, - -0.01485397, 0.03764973, - 0.026447, -0.05543245, - -0.05095487, 0.09779096, - 0.1382363, -0.4600981, - 0.4600981, -0.1382363, - -0.09779096, 0.05095487, - 0.05543245, -0.026447, - -0.03764973, 0.01485397, - 0.02716055, -0.00828756, - -0.01994365, 0.004313674, - 0.01459396, -0.001894714, - -0.01050689, 0.0004857935, - 0.007367171, 0.0002584767, - -0.004989147, -0.0005743159, - 0.003235877, 0.0006243724, - -0.001986177, -0.0005308539, - 0.00113826, 0.0003823631, - -0.0005953563, -0.0002298438, - 0.0002790277, 0.0001104587, - -0.0001123515, -3.596189e-05 -}; #endif +extern const spx_word16_t lag_window[]; extern const spx_word16_t lpc_window[]; -static void mix_and_saturate(spx_word32_t *x0, spx_word32_t *x1, spx_word16_t *out, int len) -{ - int i; - for (i=0;i32767) - out[i] = 32767; - else if (tmp<-32767) - out[i] = -32767; - else - out[i] = tmp; - } -} void *sb_encoder_init(const SpeexMode *m) { @@ -233,23 +197,24 @@ void *sb_encoder_init(const SpeexMode *m) st = (SBEncState*)speex_alloc(sizeof(SBEncState)); if (!st) return NULL; -#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) - st->stack = NULL; -#else - st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK); -#endif st->mode = m; mode = (const SpeexSBMode*)m->mode; st->st_low = speex_encoder_init(mode->nb_mode); +#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) + st->stack = NULL; +#else + /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/ + speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack); +#endif + st->full_frame_size = 2*mode->frameSize; st->frame_size = mode->frameSize; st->subframeSize = mode->subframeSize; st->nbSubframes = mode->frameSize/mode->subframeSize; st->windowSize = st->frame_size+st->subframeSize; st->lpcSize=mode->lpcSize; - st->bufSize=mode->bufSize; st->encode_submode = 1; st->submodes=mode->submodes; @@ -260,55 +225,35 @@ void *sb_encoder_init(const SpeexMode *m) tmp=1; speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); - st->lag_factor = mode->lag_factor; st->lpc_floor = mode->lpc_floor; st->gamma1=mode->gamma1; st->gamma2=mode->gamma2; st->first=1; - st->x0d=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->x1d=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->high=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); - st->y0=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); - st->y1=(spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); + st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t)); st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); - st->g0_mem=(spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); - st->g1_mem=(spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); - st->excBuf=(spx_sig_t*)speex_alloc((st->bufSize)*sizeof(spx_sig_t)); - st->exc = st->excBuf + st->bufSize - st->windowSize; - - st->res=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->sw=(spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); st->window= lpc_window; - st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + st->lagWindow = lag_window; - st->autocorr = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - st->lpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); - st->bw_lpc1 = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); - st->bw_lpc2 = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); - st->lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); - st->qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); - st->interp_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); - st->interp_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); - st->interp_lpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); - st->low_innov = (spx_word32_t*)speex_alloc((st->frame_size)*sizeof(spx_word32_t)); - speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, st->low_innov); - st->innov_save = NULL; + st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); + st->innov_rms_save = NULL; st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + for (i=0;ilpcSize;i++) + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); + +#ifndef DISABLE_VBR st->vbr_quality = 8; st->vbr_enabled = 0; st->vbr_max = 0; @@ -316,6 +261,7 @@ void *sb_encoder_init(const SpeexMode *m) st->vad_enabled = 0; st->abr_enabled = 0; st->relative_quality=0; +#endif /* #ifndef DISABLE_VBR */ st->complexity=2; speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); @@ -332,39 +278,19 @@ void sb_encoder_destroy(void *state) speex_encoder_destroy(st->st_low); #if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) - speex_free_scratch(st->stack); + /*speex_free_scratch(st->stack);*/ #endif - speex_free(st->x0d); - speex_free(st->x1d); speex_free(st->high); - speex_free(st->y0); - speex_free(st->y1); speex_free(st->h0_mem); speex_free(st->h1_mem); - speex_free(st->g0_mem); - speex_free(st->g1_mem); - speex_free(st->excBuf); - speex_free(st->res); - speex_free(st->sw); - speex_free(st->lagWindow); - - speex_free(st->autocorr); - speex_free(st->lpc); - speex_free(st->bw_lpc1); - speex_free(st->bw_lpc2); - speex_free(st->lsp); - speex_free(st->qlsp); speex_free(st->old_lsp); speex_free(st->old_qlsp); - speex_free(st->interp_lsp); - speex_free(st->interp_qlsp); - speex_free(st->interp_lpc); speex_free(st->interp_qlpc); speex_free(st->pi_gain); - speex_free(st->low_innov); + speex_free(st->exc_rms); speex_free(st->mem_sp); speex_free(st->mem_sp2); @@ -385,44 +311,57 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) VARDECL(spx_word16_t *target); VARDECL(spx_word16_t *syn_resp); VARDECL(spx_word32_t *low_pi_gain); - VARDECL(spx_word16_t *low_exc); + spx_word16_t *low; + spx_word16_t *high; + VARDECL(spx_word16_t *low_exc_rms); + VARDECL(spx_word16_t *low_innov_rms); const SpeexSBMode *mode; spx_int32_t dtx; spx_word16_t *in = (spx_word16_t*)vin; - + spx_word16_t e_low=0, e_high=0; + VARDECL(spx_coef_t *lpc); + VARDECL(spx_coef_t *interp_lpc); + VARDECL(spx_coef_t *bw_lpc1); + VARDECL(spx_coef_t *bw_lpc2); + VARDECL(spx_lsp_t *lsp); + VARDECL(spx_lsp_t *qlsp); + VARDECL(spx_lsp_t *interp_lsp); + VARDECL(spx_lsp_t *interp_qlsp); + st = (SBEncState*)state; stack=st->stack; mode = (const SpeexSBMode*)(st->mode->mode); - - { - VARDECL(spx_word16_t *low); - ALLOC(low, st->frame_size, spx_word16_t); - - /* Compute the two sub-bands by filtering with h0 and h1*/ - qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); - - for (i=0;iframe_size;i++) - low[i] = SATURATE(PSHR(st->x0d[i],SIG_SHIFT),32767); - - /* Encode the narrowband part*/ - speex_encode_native(st->st_low, low, bits); - - for (i=0;iframe_size;i++) - st->x0d[i] = SHL(low[i],SIG_SHIFT); - } + low = in; + high = in+st->frame_size; + /* High-band buffering / sync with low band */ - for (i=0;iwindowSize-st->frame_size;i++) - st->high[i] = st->high[st->frame_size+i]; - for (i=0;iframe_size;i++) - st->high[st->windowSize-st->frame_size+i]=SATURATE(st->x1d[i],536854528); + /* Compute the two sub-bands by filtering with QMF h0*/ + qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); + +#ifndef DISABLE_VBR + if (st->vbr_enabled || st->vad_enabled) + { + /* Need to compute things here before the signal is trashed by the encoder */ + /*FIXME: Are the two signals (low, high) in sync? */ + e_low = compute_rms16(low, st->frame_size); + e_high = compute_rms16(high, st->frame_size); + } +#endif /* #ifndef DISABLE_VBR */ - speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(spx_sig_t)); + ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t); + speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms); + /* Encode the narrowband part*/ + speex_encode_native(st->st_low, low, bits); + high = high - (st->windowSize-st->frame_size); + SPEEX_COPY(high, st->high, st->windowSize-st->frame_size); + SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size); + ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t); - ALLOC(low_exc, st->frame_size, spx_word16_t); + ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t); speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); + speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms); speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); @@ -431,43 +370,61 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) else dtx=0; + ALLOC(lpc, st->lpcSize, spx_coef_t); + ALLOC(interp_lpc, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc1, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc2, st->lpcSize, spx_coef_t); + + ALLOC(lsp, st->lpcSize, spx_lsp_t); + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_lsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + { + VARDECL(spx_word16_t *autocorr); VARDECL(spx_word16_t *w_sig); + ALLOC(autocorr, st->lpcSize+1, spx_word16_t); ALLOC(w_sig, st->windowSize, spx_word16_t); /* Window for analysis */ - for (i=0;iwindowSize;i++) - w_sig[i] = SHR(MULT16_16(SHR((spx_word32_t)(st->high[i]),SIG_SHIFT),st->window[i]),SIG_SHIFT); - + /* FIXME: This is a kludge */ + if (st->subframeSize==80) + { + for (i=0;iwindowSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT)); + } else { + for (i=0;iwindowSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT)); + } /* Compute auto-correlation */ - _spx_autocorr(w_sig, st->autocorr, st->lpcSize+1, st->windowSize); + _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize); + autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */ + + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;ilpcSize+1;i++) + autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]); + + /* Levinson-Durbin */ + _spx_lpc(lpc, autocorr, st->lpcSize); } - st->autocorr[0] = ADD16(st->autocorr[0],MULT16_16_Q15(st->autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */ - - /* Lag windowing: equivalent to filtering in the power-spectrum domain */ - for (i=0;ilpcSize+1;i++) - st->autocorr[i] = MULT16_16_Q14(st->autocorr[i],st->lagWindow[i]); - - /* Levinson-Durbin */ - _spx_lpc(st->lpc, st->autocorr, st->lpcSize); /* LPC to LSPs (x-domain) transform */ - roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 10, LSP_DELTA1, stack); + roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack); if (roots!=st->lpcSize) { - roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 10, LSP_DELTA2, stack); + roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack); if (roots!=st->lpcSize) { /*If we can't find all LSP's, do some damage control and use a flat filter*/ for (i=0;ilpcSize;i++) { - st->lsp[i]=LSP_SCALING*M_PI*((float)(i+1))/(st->lpcSize+1); + lsp[i]=st->old_lsp[i]; } } } +#ifndef DISABLE_VBR /* VBR code */ if ((st->vbr_enabled || st->vad_enabled) && !dtx) { - float e_low=0, e_high=0; float ratio; if (st->abr_enabled) { @@ -489,10 +446,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) } - /*FIXME: Are the two signals (low, high) in sync? */ - e_low = compute_rms(st->x0d, st->frame_size); - e_high = compute_rms(st->high, st->frame_size); - ratio = 2*log((1+e_high)/(1+e_low)); + ratio = 2*log((1.f+e_high)/(1.f+e_low)); speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); if (ratio<-4) @@ -544,6 +498,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) } /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ } +#endif /* #ifndef DISABLE_VBR */ if (st->encode_submode) { @@ -558,23 +513,14 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) if (dtx || st->submodes[st->submodeID] == NULL) { for (i=0;iframe_size;i++) - st->exc[i]=st->sw[i]=VERY_SMALL; + high[i]=VERY_SMALL; for (i=0;ilpcSize;i++) st->mem_sw[i]=0; st->first=1; /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp); - -#ifdef RESYNTH - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1); -#endif + iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack); if (dtx) return 0; @@ -584,14 +530,14 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) /* LSP quantization */ - SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); + SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits); if (st->first) { for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; + st->old_lsp[i] = lsp[i]; for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; + st->old_qlsp[i] = qlsp[i]; } ALLOC(mem, st->lpcSize, spx_mem_t); @@ -601,37 +547,33 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) for (sub=0;subnbSubframes;sub++) { - spx_sig_t *exc, *sp, *res, *sw, *innov_save=NULL; - spx_word16_t filter_ratio; + VARDECL(spx_word16_t *exc); + VARDECL(spx_word16_t *res); + VARDECL(spx_word16_t *sw); + spx_word16_t *sp; + spx_word16_t filter_ratio; /*Q7*/ int offset; - spx_word32_t rl, rh; + spx_word32_t rl, rh; /*Q13*/ spx_word16_t eh=0; offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; - res=st->res+offset; - sw=st->sw+offset; - /* Pointer for saving innovation */ - if (st->innov_save) - { - innov_save = st->innov_save+2*offset; - for (i=0;i<2*st->subframeSize;i++) - innov_save[i]=0; - } + sp=high+offset; + ALLOC(exc, st->subframeSize, spx_word16_t); + ALLOC(res, st->subframeSize, spx_word16_t); + ALLOC(sw, st->subframeSize, spx_word16_t); /* LSP interpolation (quantized and unquantized) */ - lsp_interpolate(st->old_lsp, st->lsp, st->interp_lsp, st->lpcSize, sub, st->nbSubframes); - lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes); + lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes); + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); - lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN); + lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN); + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack); + lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); + bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); + bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band filters */ @@ -645,24 +587,24 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) rl = low_pi_gain[sub]; #ifdef FIXED_POINT - filter_ratio=PDIV32_16(SHL(rl+82,2),SHR(82+rh,5)); + filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767)); #else filter_ratio=(rl+.01)/(rh+.01); #endif /* Compute "real excitation" */ - fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); + fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack); /* Compute energy of low-band and high-band excitation */ - eh = compute_rms(exc, st->subframeSize); + eh = compute_rms16(exc, st->subframeSize); if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ - float g; - spx_word16_t el; - el = compute_rms(st->low_innov+offset, st->subframeSize); + spx_word32_t g; /*Q7*/ + spx_word16_t el; /*Q0*/ + el = low_innov_rms[sub]; /* Gain to use if we want to use the low-band excitation for high-band */ - g=eh/(1.+el); + g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el))); #if 0 { @@ -680,15 +622,10 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) } #endif -#ifdef FIXED_POINT - g *= filter_ratio/128.; -#else - g *= filter_ratio; -#endif /*print_vec(&g, 1, "gain factor");*/ /* Gain quantization */ { - int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001))); + int quant = scal_quant(g, fold_quant_bound, 32); /*speex_warning_int("tata", quant);*/ if (quant<0) quant=0; @@ -696,135 +633,115 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) quant=31; speex_bits_pack(bits, quant, 5); } - + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = eh; + } + st->exc_rms[sub] = eh; } else { - spx_word16_t gc; - spx_word32_t scale; - spx_word16_t el; - el = compute_rms16(low_exc+offset, st->subframeSize); + spx_word16_t gc; /*Q7*/ + spx_word32_t scale; /*Q14*/ + spx_word16_t el; /*Q0*/ + el = low_exc_rms[sub]; /*Q0*/ gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el); /* This is a kludge that cleans up a historical bug */ if (st->subframeSize==80) - gc *= 0.70711; + gc = MULT16_16_P15(QCONST16(0.70711f,15),gc); /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/ -#ifdef FIXED_POINT { int qgc = scal_quant(gc, gc_quant_bound, 16); speex_bits_pack(bits, qgc, 4); - gc = MULT16_32_Q15(28626,gc_quant_bound[qgc]); + gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]); } -#else - { - int qgc = (int)floor(.5+3.7*(log(gc)+0.15556)); - if (qgc<0) - qgc=0; - if (qgc>15) - qgc=15; - speex_bits_pack(bits, qgc, 4); - gc = exp((1/3.7)*qgc-0.15556); - } -#endif if (st->subframeSize==80) - gc *= 1.4142; + gc = MULT16_16_P14(QCONST16(1.4142f,14), gc); scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6); - compute_impulse_response(st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); + compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); /* Reset excitation */ for (i=0;isubframeSize;i++) - exc[i]=VERY_SMALL; + res[i]=VERY_SMALL; /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ for (i=0;ilpcSize;i++) mem[i]=st->mem_sp[i]; - iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); + iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack); for (i=0;ilpcSize;i++) mem[i]=st->mem_sw[i]; - filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); + filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack); /* Compute weighted signal */ for (i=0;ilpcSize;i++) mem[i]=st->mem_sw[i]; - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); + filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack); /* Compute target signal */ for (i=0;isubframeSize;i++) - target[i]=PSHR32(sw[i]-res[i],SIG_SHIFT); - - for (i=0;isubframeSize;i++) - exc[i]=0; + target[i]=SUB16(sw[i],res[i]); signal_div(target, target, scale, st->subframeSize); /* Reset excitation */ - for (i=0;isubframeSize;i++) - innov[i]=0; + SPEEX_MEMSET(innov, 0, st->subframeSize); /*print_vec(target, st->subframeSize, "\ntarget");*/ - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); /*print_vec(target, st->subframeSize, "after");*/ signal_mul(innov, innov, scale, st->subframeSize); - for (i=0;isubframeSize;i++) - exc[i] = ADD32(exc[i], innov[i]); - - if (st->innov_save) - { - for (i=0;isubframeSize;i++) - innov_save[2*i]=innov[i]; - } - if (SUBMODE(double_codebook)) { char *tmp_stack=stack; VARDECL(spx_sig_t *innov2); ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]*=2.5; - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]); + + SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, SUBMODE(innovation_params), st->lpcSize, st->subframeSize, innov2, syn_resp, bits, stack, st->complexity, 0); + signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize); + for (i=0;isubframeSize;i++) - innov2[i]*=scale*(1/2.5)/SIG_SCALING; - for (i=0;isubframeSize;i++) - exc[i] = ADD32(exc[i],innov2[i]); + innov[i] = ADD32(innov[i],innov2[i]); stack = tmp_stack; } + for (i=0;isubframeSize;i++) + exc[i] = PSHR32(innov[i],SIG_SHIFT); + + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize)); + } + st->exc_rms[sub] = compute_rms16(exc, st->subframeSize); + } + /*Keep the previous memory*/ for (i=0;ilpcSize;i++) mem[i]=st->mem_sp[i]; /* Final signal synthesis from excitation */ - iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); + iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack); /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); + filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack); } - -#ifdef RESYNTH - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1); -#endif for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; + st->old_lsp[i] = lsp[i]; for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; + st->old_qlsp[i] = qlsp[i]; st->first=0; @@ -843,20 +760,18 @@ void *sb_decoder_init(const SpeexMode *m) st = (SBDecState*)speex_alloc(sizeof(SBDecState)); if (!st) return NULL; + st->mode = m; + mode=(const SpeexSBMode*)m->mode; + st->encode_submode = 1; + + st->st_low = speex_decoder_init(mode->nb_mode); #if defined(VAR_ARRAYS) || defined (USE_ALLOCA) st->stack = NULL; #else - st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK); + /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/ + speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack); #endif - st->mode = m; - mode=(const SpeexSBMode*)m->mode; - st->encode_submode = 1; - - - - - st->st_low = speex_decoder_init(mode->nb_mode); st->full_frame_size = 2*mode->frameSize; st->frame_size = mode->frameSize; st->subframeSize = mode->subframeSize; @@ -872,29 +787,18 @@ void *sb_decoder_init(const SpeexMode *m) st->first=1; + st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); + st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); - st->x0d = (spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->x1d = (spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->high = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); - st->y0 = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); - st->y1 = (spx_sig_t*)speex_alloc((st->full_frame_size)*sizeof(spx_sig_t)); + st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t)); - st->g0_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); - st->g1_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); - - st->exc = (spx_sig_t*)speex_alloc((st->frame_size)*sizeof(spx_sig_t)); - st->excBuf = (spx_sig_t*)speex_alloc((st->subframeSize)*sizeof(spx_sig_t)); - - st->qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); - st->interp_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); + st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t)); - st->low_innov = (spx_word32_t*)speex_alloc((st->frame_size)*sizeof(spx_word32_t)); - speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, st->low_innov); st->innov_save = NULL; @@ -913,24 +817,16 @@ void sb_decoder_destroy(void *state) st = (SBDecState*)state; speex_decoder_destroy(st->st_low); #if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) - speex_free_scratch(st->stack); + /*speex_free_scratch(st->stack);*/ #endif - speex_free(st->x0d); - speex_free(st->x1d); - speex_free(st->high); - speex_free(st->y0); - speex_free(st->y1); speex_free(st->g0_mem); speex_free(st->g1_mem); - speex_free(st->exc); speex_free(st->excBuf); - speex_free(st->qlsp); speex_free(st->old_qlsp); - speex_free(st->interp_qlsp); speex_free(st->interp_qlpc); speex_free(st->pi_gain); - speex_free(st->low_innov); + speex_free(st->exc_rms); speex_free(st->mem_sp); speex_free(state); @@ -946,7 +842,7 @@ static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *sta saved_modeid=st->submodeID; st->submodeID=1; } else { - bw_lpc(GAMMA_SCALING*0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize); + bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize); } st->first=1; @@ -955,25 +851,17 @@ static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *sta /* Final signal synthesis from excitation */ if (!dtx) { - spx_word16_t low_ener; - low_ener = .9*compute_rms(st->exc, st->frame_size); - for (i=0;iframe_size;i++) - st->exc[i] = speex_rand(low_ener, &st->seed); + st->last_ener = MULT16_16_Q15(QCONST16(.9f,15),st->last_ener); } - for (i=0;iframe_size;i++) - st->high[i]=st->exc[i]; + out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed); - iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, - st->mem_sp); + iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, + st->mem_sp, stack); /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - mix_and_saturate(st->y0, st->y1, out, st->full_frame_size); - + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); if (dtx) { st->submodeID=saved_modeid; @@ -990,26 +878,24 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) int ret; char *stack; VARDECL(spx_word32_t *low_pi_gain); - VARDECL(spx_word16_t *low_exc); + VARDECL(spx_word16_t *low_exc_rms); VARDECL(spx_coef_t *ak); + VARDECL(spx_lsp_t *qlsp); + VARDECL(spx_lsp_t *interp_qlsp); spx_int32_t dtx; const SpeexSBMode *mode; spx_word16_t *out = (spx_word16_t*)vout; + spx_word16_t *low_innov_alias; + spx_word32_t exc_ener_sum = 0; st = (SBDecState*)state; stack=st->stack; mode = (const SpeexSBMode*)(st->mode->mode); - { - VARDECL(spx_word16_t *low); - ALLOC(low, st->frame_size, spx_word16_t); - - /* Decode the low-band */ - ret = speex_decode_native(st->st_low, bits, low); - - for (i=0;iframe_size;i++) - st->x0d[i] = SHL((spx_sig_t)low[i], SIG_SHIFT); - } + low_innov_alias = out+st->frame_size; + speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias); + /* Decode the low-band */ + ret = speex_decode_native(st->st_low, bits, out); speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx); @@ -1045,7 +931,7 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) } if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL) { - speex_warning("Invalid mode encountered: corrupted stream?"); + speex_notify("Invalid mode encountered. The stream is corrupted."); return -2; } } @@ -1060,66 +946,63 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) } for (i=0;iframe_size;i++) - st->exc[i]=VERY_SMALL; + out[st->frame_size+i]=VERY_SMALL; st->first=1; /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp); + iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack); - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - mix_and_saturate(st->y0, st->y1, out, st->full_frame_size); + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); return 0; } - for (i=0;iframe_size;i++) - st->exc[i]=0; - ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t); - ALLOC(low_exc, st->frame_size, spx_word16_t); + ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t); speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); + speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms); - SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits); if (st->first) { for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; + st->old_qlsp[i] = qlsp[i]; } ALLOC(ak, st->lpcSize, spx_coef_t); for (sub=0;subnbSubframes;sub++) { - spx_sig_t *exc, *sp, *innov_save=NULL; + VARDECL(spx_word32_t *exc); + spx_word16_t *innov_save=NULL; + spx_word16_t *sp; spx_word16_t filter_ratio; spx_word16_t el=0; int offset; spx_word32_t rl=0,rh=0; offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; + sp=out+st->frame_size+offset; + ALLOC(exc, st->subframeSize, spx_word32_t); /* Pointer for saving innovation */ if (st->innov_save) { innov_save = st->innov_save+2*offset; - for (i=0;i<2*st->subframeSize;i++) - innov_save[i]=0; + SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize); } /* LSP interpolation */ - lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes); + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN); + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); /* LSP to LPC */ - lsp_to_lpc(st->interp_qlsp, ak, st->lpcSize, stack); + lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack); /* Calculate reponse ratio between the low and high filter in the middle of the band (4000 Hz) */ @@ -1128,75 +1011,46 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) rh = LPC_SCALING; for (i=0;ilpcSize;i+=2) { - rh += st->interp_qlpc[i+1] - st->interp_qlpc[i]; - st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1]; + rh += ak[i+1] - ak[i]; + st->pi_gain[sub] += ak[i] + ak[i+1]; } rl = low_pi_gain[sub]; #ifdef FIXED_POINT - filter_ratio=PDIV32_16(SHL(rl+82,2),SHR(82+rh,5)); + filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767)); #else filter_ratio=(rl+.01)/(rh+.01); #endif - for (i=0;isubframeSize;i++) - exc[i]=0; + SPEEX_MEMSET(exc, 0, st->subframeSize); if (!SUBMODE(innovation_unquant)) { - float g; + spx_word32_t g; int quant; quant = speex_bits_unpack_unsigned(bits, 5); - g= exp(((float)quant-10)/8.0); + g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10))); -#ifdef FIXED_POINT - g /= filter_ratio/128.; -#else - g /= filter_ratio; -#endif - /* High-band excitation using the low-band excitation and a gain */ + g = PDIV32(g, filter_ratio); -#if 0 - for (i=0;isubframeSize;i++) - exc[i]=mode->folding_gain*g*st->low_innov[offset+i]; -#else + for (i=0;isubframeSize;i+=2) { - float tmp=1; - /*static tmp1=0,tmp2=0; - static int seed=1; - el = compute_rms(low_innov+offset, st->subframeSize);*/ - for (i=0;isubframeSize;i++) - { - float e=tmp*g*mode->folding_gain*st->low_innov[offset+i]; - tmp *= -1; - exc[i] = e; - /*float r = speex_rand(g*el,&seed); - exc[i] = .5*(r+tmp2 + e-tmp1); - tmp1 = e; - tmp2 = r;*/ - } - + exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT); + exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT)); } -#endif } else { spx_word16_t gc; spx_word32_t scale; int qgc = speex_bits_unpack_unsigned(bits, 4); - - el = compute_rms16(low_exc+offset, st->subframeSize); - -#ifdef FIXED_POINT - gc = MULT16_32_Q15(28626,gc_quant_bound[qgc]); -#else - gc = exp((1/3.7)*qgc-0.15556); -#endif + + el = low_exc_rms[sub]; + gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]); if (st->subframeSize==80) - gc *= 1.4142; - - scale = SHL(MULT16_16(PDIV32_16(SHL(gc,SIG_SHIFT-6),filter_ratio),(1+el)),6); + gc = MULT16_16_P14(QCONST16(1.4142f,14),gc); + scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3); SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); @@ -1206,12 +1060,10 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) char *tmp_stack=stack; VARDECL(spx_sig_t *innov2); ALLOC(innov2, st->subframeSize, spx_sig_t); - for (i=0;isubframeSize;i++) - innov2[i]=0; + SPEEX_MEMSET(innov2, 0, st->subframeSize); SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); - for (i=0;isubframeSize;i++) - innov2[i]*=scale/(float)SIG_SCALING*(1/2.5); + signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize); for (i=0;isubframeSize;i++) exc[i] = ADD32(exc[i],innov2[i]); stack = tmp_stack; @@ -1222,27 +1074,23 @@ int sb_decode(void *state, SpeexBits *bits, void *vout) if (st->innov_save) { for (i=0;isubframeSize;i++) - innov_save[2*i]=exc[i]; + innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT)); } + iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp, stack); for (i=0;isubframeSize;i++) - sp[i]=st->excBuf[i]; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - for (i=0;isubframeSize;i++) - st->excBuf[i]=exc[i]; + st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT)); for (i=0;ilpcSize;i++) st->interp_qlpc[i] = ak[i]; - + st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize); + exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes)); } - - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - mix_and_saturate(st->y0, st->y1, out, st->full_frame_size); - + st->last_ener = spx_sqrt(exc_ener_sum); + + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; + st->old_qlsp[i] = qlsp[i]; st->first=0; @@ -1277,6 +1125,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_SET_MODE: speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr); break; +#ifndef DISABLE_VBR case SPEEX_SET_VBR: st->vbr_enabled = (*(spx_int32_t*)ptr); speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr); @@ -1291,6 +1140,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_VAD: (*(spx_int32_t*)ptr) = st->vad_enabled; break; +#endif /* #ifndef DISABLE_VBR */ +#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) case SPEEX_SET_VBR_QUALITY: { spx_int32_t q; @@ -1308,6 +1159,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_VBR_QUALITY: (*(float*)ptr) = st->vbr_quality; break; +#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */ +#ifndef DISABLE_VBR case SPEEX_SET_ABR: st->abr_enabled = (*(spx_int32_t*)ptr); st->vbr_enabled = st->abr_enabled!=0; @@ -1338,6 +1191,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_ABR: (*(spx_int32_t*)ptr) = st->abr_enabled; break; +#endif /* #ifndef DISABLE_VBR */ + case SPEEX_SET_QUALITY: { spx_int32_t nb_qual; @@ -1400,18 +1255,16 @@ int sb_encoder_ctl(void *state, int request, void *ptr) int i; st->first = 1; for (i=0;ilpcSize;i++) - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); for (i=0;ilpcSize;i++) st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=0; for (i=0;ih0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; + st->h0_mem[i]=st->h1_mem[i]=0; } break; case SPEEX_SET_SUBMODE_ENCODING: st->encode_submode = (*(spx_int32_t*)ptr); - speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, &ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr); break; case SPEEX_GET_SUBMODE_ENCODING: (*(spx_int32_t*)ptr) = st->encode_submode; @@ -1426,6 +1279,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_PLC_TUNING: speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr); break; +#ifndef DISABLE_VBR case SPEEX_SET_VBR_MAX_BITRATE: { st->vbr_max = (*(spx_int32_t*)ptr); @@ -1457,6 +1311,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_VBR_MAX_BITRATE: (*(spx_int32_t*)ptr) = st->vbr_max; break; +#endif /* #ifndef DISABLE_VBR */ case SPEEX_SET_HIGHPASS: speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr); break; @@ -1477,33 +1332,24 @@ int sb_encoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_EXC: { int i; - spx_sig_t *e = (spx_sig_t*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - spx_sig_t *e = (spx_sig_t*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; + for (i=0;inbSubframes;i++) + ((spx_word16_t*)ptr)[i] = st->exc_rms[i]; } break; +#ifndef DISABLE_VBR case SPEEX_GET_RELATIVE_QUALITY: (*(float*)ptr)=st->relative_quality; break; +#endif /* #ifndef DISABLE_VBR */ case SPEEX_SET_INNOVATION_SAVE: - st->innov_save = (spx_sig_t*)ptr; + st->innov_rms_save = (spx_word16_t*)ptr; break; case SPEEX_SET_WIDEBAND: speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr); break; - + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; default: speex_warning_int("Unknown nb_ctl request: ", request); return -1; @@ -1581,11 +1427,12 @@ int sb_decoder_ctl(void *state, int request, void *ptr) st->mem_sp[i]=0; for (i=0;ig0_mem[i]=st->g1_mem[i]=0; + st->last_ener=0; } break; case SPEEX_SET_SUBMODE_ENCODING: st->encode_submode = (*(spx_int32_t*)ptr); - speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, &ptr); + speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr); break; case SPEEX_GET_SUBMODE_ENCODING: (*(spx_int32_t*)ptr) = st->encode_submode; @@ -1600,7 +1447,9 @@ int sb_decoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_HIGHPASS: speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr); break; - + case SPEEX_GET_ACTIVITY: + speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr); + break; case SPEEX_GET_PI_GAIN: { int i; @@ -1612,33 +1461,22 @@ int sb_decoder_ctl(void *state, int request, void *ptr) case SPEEX_GET_EXC: { int i; - spx_sig_t *e = (spx_sig_t*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - spx_sig_t *e = (spx_sig_t*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; + for (i=0;inbSubframes;i++) + ((spx_word16_t*)ptr)[i] = st->exc_rms[i]; } break; case SPEEX_GET_DTX_STATUS: speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr); break; case SPEEX_SET_INNOVATION_SAVE: - st->innov_save = (spx_sig_t*)ptr; + st->innov_save = (spx_word16_t*)ptr; break; case SPEEX_SET_WIDEBAND: speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr); break; - + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; default: speex_warning_int("Unknown nb_ctl request: ", request); return -1; diff --git a/libs/speex/libspeex/sb_celp.h b/libs/speex/libspeex/sb_celp.h index 4da03e4394..e8c3761237 100644 --- a/libs/speex/libspeex/sb_celp.h +++ b/libs/speex/libspeex/sb_celp.h @@ -50,46 +50,29 @@ typedef struct SBEncState { int nbSubframes; /**< Number of high-band sub-frames*/ int windowSize; /**< Length of high-band LPC window*/ int lpcSize; /**< Order of high-band LPC analysis */ - int bufSize; /**< Buffer size */ int first; /**< First frame? */ - float lag_factor; /**< Lag-windowing control parameter */ spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */ spx_word16_t gamma1; /**< Perceptual weighting coef 1 */ spx_word16_t gamma2; /**< Perceptual weighting coef 2 */ char *stack; /**< Temporary allocation stack */ - spx_sig_t *x0d, *x1d; /**< QMF filter signals*/ - spx_sig_t *high; /**< High-band signal (buffer) */ - spx_sig_t *y0, *y1; /**< QMF synthesis signals */ + spx_word16_t *high; /**< High-band signal (buffer) */ spx_word16_t *h0_mem, *h1_mem; - spx_word32_t *g0_mem, *g1_mem; /**< QMF memories */ - spx_sig_t *excBuf; /**< High-band excitation */ - spx_sig_t *exc; /**< High-band excitation (for QMF only)*/ - spx_sig_t *res; /**< Zero-input response (ringing) */ - spx_sig_t *sw; /**< Perceptually weighted signal */ const spx_word16_t *window; /**< LPC analysis window */ - spx_word16_t *lagWindow; /**< Auto-correlation window */ - spx_word16_t *autocorr; /**< Auto-correlation (for LPC analysis) */ - spx_coef_t *lpc; /**< LPC coefficients */ - spx_lsp_t *lsp; /**< LSP coefficients */ - spx_lsp_t *qlsp; /**< Quantized LSPs */ + const spx_word16_t *lagWindow; /**< Auto-correlation window */ spx_lsp_t *old_lsp; /**< LSPs of previous frame */ spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */ - spx_lsp_t *interp_lsp; /**< Interpolated LSPs for current sub-frame */ - spx_lsp_t *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */ - spx_coef_t *interp_lpc; /**< Interpolated LPCs for current sub-frame */ spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ - spx_coef_t *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */ - spx_coef_t *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */ spx_mem_t *mem_sp; /**< Synthesis signal memory */ spx_mem_t *mem_sp2; spx_mem_t *mem_sw; /**< Perceptual signal memory */ spx_word32_t *pi_gain; - spx_sig_t *innov_save; /**< If non-NULL, innovation is copied here */ - spx_sig_t *low_innov; /**< Lower-band innovation is copied here magically */ + spx_word16_t *exc_rms; + spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */ +#ifndef DISABLE_VBR float vbr_quality; /**< Quality setting for VBR encoding */ int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */ @@ -100,7 +83,8 @@ typedef struct SBEncState { float abr_count; int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ float relative_quality; - +#endif /* #ifndef DISABLE_VBR */ + int encode_submode; const SpeexSubmode * const *submodes; int submodeID; @@ -125,23 +109,18 @@ typedef struct SBDecState { int lpc_enh_enabled; char *stack; - spx_sig_t *x0d, *x1d; - spx_sig_t *high; - spx_sig_t *y0, *y1; - spx_word32_t *g0_mem, *g1_mem; + spx_word16_t *g0_mem, *g1_mem; - spx_sig_t *exc; - spx_sig_t *excBuf; - spx_lsp_t *qlsp; + spx_word16_t *excBuf; spx_lsp_t *old_qlsp; - spx_lsp_t *interp_qlsp; spx_coef_t *interp_qlpc; spx_mem_t *mem_sp; spx_word32_t *pi_gain; - spx_sig_t *innov_save; /** If non-NULL, innovation is copied here */ - spx_sig_t *low_innov; /** Lower-band innovation is copied here magically */ + spx_word16_t *exc_rms; + spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */ + spx_word16_t last_ener; spx_int32_t seed; int encode_submode; diff --git a/libs/speex/libspeex/scal.c b/libs/speex/libspeex/scal.c new file mode 100644 index 0000000000..c6abfd22d7 --- /dev/null +++ b/libs/speex/libspeex/scal.c @@ -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 + Hands­free 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 +#include + +#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;chring[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;chchannels;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;iframe_size;i++) + buff[i] = buff[i+st->frame_size]; + for (i=0;iframe_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;iframe_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;iframe_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;iframe_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;iframe_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); +} diff --git a/libs/speex/libspeex/smallft.c b/libs/speex/libspeex/smallft.c index 269549db00..5c26d016fe 100644 --- a/libs/speex/libspeex/smallft.c +++ b/libs/speex/libspeex/smallft.c @@ -34,7 +34,8 @@ #include #include "smallft.h" -#include "misc.h" +#include "arch.h" +#include "os_support.h" static void drfti1(int n, float *wa, int *ifac){ static int ntryh[4] = { 4,2,3,5 }; diff --git a/libs/speex/libspeex/speex.c b/libs/speex/libspeex/speex.c index 846e02186c..b425155c2b 100644 --- a/libs/speex/libspeex/speex.c +++ b/libs/speex/libspeex/speex.c @@ -38,6 +38,7 @@ #include "modes.h" #include +#include "os_support.h" #ifndef NULL #define NULL 0 @@ -47,22 +48,22 @@ -void *speex_encoder_init(const SpeexMode *mode) +EXPORT void *speex_encoder_init(const SpeexMode *mode) { return mode->enc_init(mode); } -void *speex_decoder_init(const SpeexMode *mode) +EXPORT void *speex_decoder_init(const SpeexMode *mode) { return mode->dec_init(mode); } -void speex_encoder_destroy(void *state) +EXPORT void speex_encoder_destroy(void *state) { (*((SpeexMode**)state))->enc_destroy(state); } -void speex_decoder_destroy(void *state) +EXPORT void speex_decoder_destroy(void *state) { (*((SpeexMode**)state))->dec_destroy(state); } @@ -83,7 +84,8 @@ int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out) #ifdef FIXED_POINT -int speex_encode(void *state, float *in, SpeexBits *bits) +#ifndef DISABLE_FLOAT_API +EXPORT int speex_encode(void *state, float *in, SpeexBits *bits) { int i; spx_int32_t N; @@ -100,15 +102,17 @@ int speex_encode(void *state, float *in, SpeexBits *bits) } return (*((SpeexMode**)state))->enc(state, short_in, bits); } +#endif /* #ifndef DISABLE_FLOAT_API */ -int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) +EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) { SpeexMode *mode; mode = *(SpeexMode**)state; return (mode)->enc(state, in, bits); } -int speex_decode(void *state, SpeexBits *bits, float *out) +#ifndef DISABLE_FLOAT_API +EXPORT int speex_decode(void *state, SpeexBits *bits, float *out) { int i, ret; spx_int32_t N; @@ -119,8 +123,9 @@ int speex_decode(void *state, SpeexBits *bits, float *out) out[i] = short_out[i]; return ret; } +#endif /* #ifndef DISABLE_FLOAT_API */ -int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) +EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) { SpeexMode *mode = *(SpeexMode**)state; return (mode)->dec(state, bits, out); @@ -128,12 +133,12 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) #else -int speex_encode(void *state, float *in, SpeexBits *bits) +EXPORT int speex_encode(void *state, float *in, SpeexBits *bits) { return (*((SpeexMode**)state))->enc(state, in, bits); } -int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) +EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) { int i; spx_int32_t N; @@ -144,12 +149,12 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) return (*((SpeexMode**)state))->enc(state, float_in, bits); } -int speex_decode(void *state, SpeexBits *bits, float *out) +EXPORT int speex_decode(void *state, SpeexBits *bits, float *out) { return (*((SpeexMode**)state))->dec(state, bits, out); } -int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) +EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) { int i; spx_int32_t N; @@ -172,12 +177,12 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) -int speex_encoder_ctl(void *state, int request, void *ptr) +EXPORT int speex_encoder_ctl(void *state, int request, void *ptr) { return (*((SpeexMode**)state))->enc_ctl(state, request, ptr); } -int speex_decoder_ctl(void *state, int request, void *ptr) +EXPORT int speex_decoder_ctl(void *state, int request, void *ptr) { return (*((SpeexMode**)state))->dec_ctl(state, request, ptr); } @@ -208,32 +213,9 @@ int nb_mode_query(const void *mode, int request, void *ptr) return 0; } -int wb_mode_query(const void *mode, int request, void *ptr) -{ - const SpeexSBMode *m = (const SpeexSBMode*)mode; - - switch (request) - { - case SPEEX_MODE_FRAME_SIZE: - *((int*)ptr)=2*m->frameSize; - break; - case SPEEX_SUBMODE_BITS_PER_FRAME: - if (*((int*)ptr)==0) - *((int*)ptr) = SB_SUBMODE_BITS+1; - else if (m->submodes[*((int*)ptr)]==NULL) - *((int*)ptr) = -1; - else - *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; - break; - default: - speex_warning_int("Unknown wb_mode_query request: ", request); - return -1; - } - return 0; -} -int speex_lib_ctl(int request, void *ptr) +EXPORT int speex_lib_ctl(int request, void *ptr) { switch (request) { diff --git a/libs/speex/libspeex/speex_callbacks.c b/libs/speex/libspeex/speex_callbacks.c index 682322e695..0e077c3805 100644 --- a/libs/speex/libspeex/speex_callbacks.c +++ b/libs/speex/libspeex/speex_callbacks.c @@ -37,9 +37,10 @@ #endif #include -#include "misc.h" +#include "arch.h" +#include "os_support.h" -int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) +EXPORT int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) { int id; SpeexCallback *callback; @@ -71,7 +72,7 @@ int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *st return 0; } -int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t m; m = speex_bits_unpack_unsigned(bits, 4); @@ -79,7 +80,7 @@ int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) return 0; } -int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t m; m = speex_bits_unpack_unsigned(bits, 4); @@ -87,7 +88,7 @@ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) return 0; } -int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t m; m = speex_bits_unpack_unsigned(bits, 4); @@ -95,15 +96,17 @@ int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data return 0; } -int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) +#ifndef DISABLE_VBR +EXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t vbr; vbr = speex_bits_unpack_unsigned(bits, 1); speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr); return 0; } +#endif /* #ifndef DISABLE_VBR */ -int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t enh; enh = speex_bits_unpack_unsigned(bits, 1); @@ -111,16 +114,17 @@ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) return 0; } -int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) +#ifndef DISABLE_VBR +EXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) { float qual; qual = speex_bits_unpack_unsigned(bits, 4); speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual); return 0; } +#endif /* #ifndef DISABLE_VBR */ - -int speex_std_char_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data) { unsigned char ch; ch = speex_bits_unpack_unsigned(bits, 8); @@ -132,7 +136,7 @@ int speex_std_char_handler(SpeexBits *bits, void *state, void *data) /* Default handler for user callbacks: skip it */ -int speex_default_user_handler(SpeexBits *bits, void *state, void *data) +EXPORT int speex_default_user_handler(SpeexBits *bits, void *state, void *data) { int req_size = speex_bits_unpack_unsigned(bits, 4); speex_bits_advance(bits, 5+8*req_size); diff --git a/libs/speex/libspeex/speex_header.c b/libs/speex/libspeex/speex_header.c index 7fc2f5aa93..b7430595ff 100644 --- a/libs/speex/libspeex/speex_header.c +++ b/libs/speex/libspeex/speex_header.c @@ -35,14 +35,31 @@ #include "config.h" #endif -#include "misc.h" +#include "arch.h" #include #include +#include "os_support.h" #ifndef NULL #define NULL 0 #endif +/** Convert little endian */ +static inline spx_int32_t le_int(spx_int32_t i) +{ +#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) + spx_uint32_t ui, ret; + ui = i; + ret = ui>>24; + ret |= (ui>>8)&0x0000ff00; + ret |= (ui<<8)&0x00ff0000; + ret |= (ui<<24); + return ret; +#else + return i; +#endif +} + #define ENDIAN_SWITCH(x) {x=le_int(x);} @@ -66,7 +83,7 @@ typedef struct SpeexHeader { } SpeexHeader; */ -void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m) +EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m) { int i; const char *h="Speex "; @@ -101,12 +118,12 @@ void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const Spe header->reserved2 = 0; } -char *speex_header_to_packet(SpeexHeader *header, int *size) +EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size) { SpeexHeader *le_header; le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - speex_move(le_header, header, sizeof(SpeexHeader)); + SPEEX_COPY(le_header, header, 1); /*Make sure everything is now little-endian*/ ENDIAN_SWITCH(le_header->speex_version_id); @@ -125,7 +142,7 @@ char *speex_header_to_packet(SpeexHeader *header, int *size) return (char *)le_header; } -SpeexHeader *speex_packet_to_header(char *packet, int size) +EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size) { int i; SpeexHeader *le_header; @@ -133,20 +150,20 @@ SpeexHeader *speex_packet_to_header(char *packet, int size) for (i=0;i<8;i++) if (packet[i]!=h[i]) { - speex_warning ("This doesn't look like a Speex file"); + speex_notify("This doesn't look like a Speex file"); return NULL; } /*FIXME: Do we allow larger headers?*/ if (size < (int)sizeof(SpeexHeader)) { - speex_warning("Speex header too small"); + speex_notify("Speex header too small"); return NULL; } le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - speex_move(le_header, packet, sizeof(SpeexHeader)); + SPEEX_COPY(le_header, (SpeexHeader*)packet, 1); /*Make sure everything is converted correctly from little-endian*/ ENDIAN_SWITCH(le_header->speex_version_id); @@ -161,6 +178,23 @@ SpeexHeader *speex_packet_to_header(char *packet, int size) ENDIAN_SWITCH(le_header->frames_per_packet); ENDIAN_SWITCH(le_header->extra_headers); + if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0) + { + speex_notify("Invalid mode specified in Speex header"); + speex_free (le_header); + return NULL; + } + + if (le_header->nb_channels>2) + le_header->nb_channels = 2; + if (le_header->nb_channels<1) + le_header->nb_channels = 1; + return le_header; } + +EXPORT void speex_header_free(void *ptr) +{ + speex_free(ptr); +} diff --git a/libs/speex/libspeex/stack_alloc.h b/libs/speex/libspeex/stack_alloc.h index cb048fa55e..5264e666b0 100644 --- a/libs/speex/libspeex/stack_alloc.h +++ b/libs/speex/libspeex/stack_alloc.h @@ -36,11 +36,15 @@ #define STACK_ALLOC_H #ifdef USE_ALLOCA -#ifdef WIN32 -#include -#else -#include -#endif +# ifdef WIN32 +# include +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# include +# endif +# endif #endif /** @@ -62,15 +66,6 @@ * @param type Type of element */ -/** - * @def PUSHS(stack, type) - * - * Allocates a struct stack - * - * @param stack Stack - * @param type Struct type - */ - /** * @def VARDECL(var) * @@ -97,16 +92,12 @@ #define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) -#define PUSHS(stack, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(long)),VALGRIND_MAKE_WRITABLE(stack, (sizeof(type))),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type)))) - #else #define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) #define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) -#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type)))) - #endif #if defined(VAR_ARRAYS) diff --git a/libs/speex/libspeex/stereo.c b/libs/speex/libspeex/stereo.c index f18387e572..db5ea4a857 100644 --- a/libs/speex/libspeex/stereo.c +++ b/libs/speex/libspeex/stereo.c @@ -35,13 +35,77 @@ #include #include +#include "math_approx.h" #include "vq.h" #include +#include "os_support.h" + +typedef struct RealSpeexStereoState { + spx_word32_t balance; /**< Left/right balance info */ + spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ + spx_word32_t smooth_left; /**< Smoothed left channel gain */ + spx_word32_t smooth_right; /**< Smoothed right channel gain */ + spx_uint32_t reserved1; /**< Reserved for future use */ + spx_int32_t reserved2; /**< Reserved for future use */ +} RealSpeexStereoState; + /*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ +#ifndef FIXED_POINT static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; +static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f}; +#else +static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384}; +static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696}; +static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104, + 134, 172, 221, 284, 364, 468, 600, 771, + 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696, + 7314, 9392, 12059, 15484, 19882, 25529, 32766}; +#endif -void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) +/* This is an ugly compatibility hack that properly resets the stereo state + In case it it compiled in fixed-point, but initialised with the deprecated + floating point static initialiser */ +#ifdef FIXED_POINT +#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0); +#else +#define COMPATIBILITY_HACK(s) +#endif + +EXPORT SpeexStereoState *speex_stereo_state_init() +{ + SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState)); + speex_stereo_state_reset(stereo); + return stereo; +} + +EXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo) +{ + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; +#ifdef FIXED_POINT + stereo->balance = 65536; + stereo->e_ratio = 16384; + stereo->smooth_left = 16384; + stereo->smooth_right = 16384; + stereo->reserved1 = 0xdeadbeef; + stereo->reserved2 = 0; +#else + stereo->balance = 1.0f; + stereo->e_ratio = .5f; + stereo->smooth_left = 1.f; + stereo->smooth_right = 1.f; + stereo->reserved1 = 0; + stereo->reserved2 = 0; +#endif +} + +EXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo) +{ + speex_free(stereo); +} + +#ifndef DISABLE_FLOAT_API +EXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) { int i, tmp; float e_left=0, e_right=0, e_tot=0; @@ -73,118 +137,158 @@ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) speex_bits_pack(bits, (int)balance, 5); - /*Quantize energy ratio*/ - tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); + /* FIXME: this is a hack */ + tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4); speex_bits_pack(bits, tmp, 2); } +#endif /* #ifndef DISABLE_FLOAT_API */ -void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits) +EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits) { int i, tmp; - float e_left=0, e_right=0, e_tot=0; - float balance, e_ratio; + spx_word32_t e_left=0, e_right=0, e_tot=0; + spx_word32_t balance, e_ratio; + spx_word32_t largest, smallest; + int balance_id; +#ifdef FIXED_POINT + int shift; +#endif + + /* In band marker */ + speex_bits_pack(bits, 14, 5); + /* Stereo marker */ + speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); + for (i=0;i0) + if (e_left > e_right) + { speex_bits_pack(bits, 0, 1); - else + largest = e_left; + smallest = e_right; + } else { speex_bits_pack(bits, 1, 1); - balance=floor(.5+fabs(balance)); - if (balance>30) - balance=31; + largest = e_right; + smallest = e_left; + } + + /* Balance quantization */ +#ifdef FIXED_POINT + shift = spx_ilog2(largest)-15; + largest = VSHR32(largest, shift-4); + smallest = VSHR32(smallest, shift); + balance = DIV32(largest, ADD32(smallest, 1)); + if (balance > 32767) + balance = 32767; + balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); +#else + balance=(largest+1.)/(smallest+1.); + balance=4*log(balance); + balance_id=floor(.5+fabs(balance)); + if (balance_id>30) + balance_id=31; +#endif - speex_bits_pack(bits, (int)balance, 5); + speex_bits_pack(bits, balance_id, 5); - /*Quantize energy ratio*/ - tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); + /* "coherence" quantisation */ +#ifdef FIXED_POINT + shift = spx_ilog2(e_tot); + e_tot = VSHR32(e_tot, shift-25); + e_left = VSHR32(e_left, shift-10); + e_right = VSHR32(e_right, shift-10); + e_ratio = DIV32(e_tot, e_left+e_right+1); +#else + e_ratio = e_tot/(1.+e_left+e_right); +#endif + + tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4); + /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/ speex_bits_pack(bits, tmp, 2); } -void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo) +#ifndef DISABLE_FLOAT_API +EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo) { - float balance, e_ratio; int i; - float e_tot=0, e_left, e_right, e_sum; - + spx_word32_t balance; + spx_word16_t e_left, e_right, e_ratio; + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; + + COMPATIBILITY_HACK(stereo); + balance=stereo->balance; e_ratio=stereo->e_ratio; + + /* These two are Q14, with max value just below 2. */ + e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); + e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); + for (i=frame_size-1;i>=0;i--) { - e_tot += ((float)data[i])*data[i]; + spx_word16_t tmp=data[i]; + stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); + stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); + data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp); + data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp); } - e_sum=e_tot/e_ratio; - e_left = e_sum*balance / (1+balance); - e_right = e_sum-e_left; +} +#endif /* #ifndef DISABLE_FLOAT_API */ - e_left = sqrt(e_left/(e_tot+.01)); - e_right = sqrt(e_right/(e_tot+.01)); +EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo) +{ + int i; + spx_word32_t balance; + spx_word16_t e_left, e_right, e_ratio; + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; + + COMPATIBILITY_HACK(stereo); + + balance=stereo->balance; + e_ratio=stereo->e_ratio; + + /* These two are Q14, with max value just below 2. */ + e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); + e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); for (i=frame_size-1;i>=0;i--) { - float ftmp=data[i]; - stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; - stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; - data[2*i] = stereo->smooth_left*ftmp; - data[2*i+1] = stereo->smooth_right*ftmp; + spx_int16_t tmp=data[i]; + stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); + stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); + data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp); + data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp); } } -void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo) +EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) { - float balance, e_ratio; - int i; - float e_tot=0, e_left, e_right, e_sum; - - balance=stereo->balance; - e_ratio=stereo->e_ratio; - for (i=frame_size-1;i>=0;i--) - { - e_tot += ((float)data[i])*data[i]; - } - e_sum=e_tot/e_ratio; - e_left = e_sum*balance / (1+balance); - e_right = e_sum-e_left; - - e_left = sqrt(e_left/(e_tot+.01)); - e_right = sqrt(e_right/(e_tot+.01)); - - for (i=frame_size-1;i>=0;i--) - { - float ftmp=data[i]; - stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; - stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; - data[2*i] = stereo->smooth_left*ftmp; - data[2*i+1] = stereo->smooth_right*ftmp; - } -} - -int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) -{ - SpeexStereoState *stereo; - float sign=1; + RealSpeexStereoState *stereo; + spx_word16_t sign=1, dexp; int tmp; - stereo = (SpeexStereoState*)data; + stereo = (RealSpeexStereoState*)data; + + COMPATIBILITY_HACK(stereo); + if (speex_bits_unpack_unsigned(bits, 1)) sign=-1; - tmp = speex_bits_unpack_unsigned(bits, 5); - stereo->balance = exp(sign*.25*tmp); - + dexp = speex_bits_unpack_unsigned(bits, 5); +#ifndef FIXED_POINT + stereo->balance = exp(sign*.25*dexp); +#else + stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9))); +#endif tmp = speex_bits_unpack_unsigned(bits, 2); stereo->e_ratio = e_ratio_quant[tmp]; diff --git a/libs/speex/libspeex/testdenoise.c b/libs/speex/libspeex/testdenoise.c index 177227d734..49f512023f 100644 --- a/libs/speex/libspeex/testdenoise.c +++ b/libs/speex/libspeex/testdenoise.c @@ -20,13 +20,13 @@ int main() speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); i=0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); - f=8000; - speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); + i=8000; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); i=0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); - f=.4; + f=.0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); - f=.3; + f=.0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); while (1) { @@ -34,7 +34,7 @@ int main() fread(in, sizeof(short), NN, stdin); if (feof(stdin)) break; - vad = speex_preprocess(st, in, NULL); + vad = speex_preprocess_run(st, in); /*fprintf (stderr, "%d\n", vad);*/ fwrite(in, sizeof(short), NN, stdout); count++; diff --git a/libs/speex/libspeex/testecho.c b/libs/speex/libspeex/testecho.c index f78499ee08..5ae855f083 100644 --- a/libs/speex/libspeex/testecho.c +++ b/libs/speex/libspeex/testecho.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "speex/speex_echo.h" #include "speex/speex_preprocess.h" @@ -17,37 +16,38 @@ int main(int argc, char **argv) { - int echo_fd, ref_fd, e_fd; - spx_int32_t noise[NN+1]; + FILE *echo_fd, *ref_fd, *e_fd; short echo_buf[NN], ref_buf[NN], e_buf[NN]; SpeexEchoState *st; SpeexPreprocessState *den; + int sampleRate = 8000; if (argc != 4) { - fprintf (stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n"); + fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n"); exit(1); } - echo_fd = open (argv[2], O_RDONLY); - ref_fd = open (argv[1], O_RDONLY); - e_fd = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644); + echo_fd = fopen(argv[2], "rb"); + ref_fd = fopen(argv[1], "rb"); + e_fd = fopen(argv[3], "wb"); st = speex_echo_state_init(NN, TAIL); - den = speex_preprocess_state_init(NN, 8000); - int tmp = 8000; - speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp); + den = speex_preprocess_state_init(NN, sampleRate); + speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate); + speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st); - while (read(ref_fd, ref_buf, NN*2)) + while (!feof(ref_fd) && !feof(echo_fd)) { - read(echo_fd, echo_buf, NN*2); - speex_echo_cancel(st, ref_buf, echo_buf, e_buf, noise); - /*speex_preprocess(den, e_buf, noise);*/ - write(e_fd, e_buf, NN*2); + fread(ref_buf, sizeof(short), NN, ref_fd); + fread(echo_buf, sizeof(short), NN, echo_fd); + speex_echo_cancellation(st, ref_buf, echo_buf, e_buf); + speex_preprocess_run(den, e_buf); + fwrite(e_buf, sizeof(short), NN, e_fd); } speex_echo_state_destroy(st); speex_preprocess_state_destroy(den); - close(e_fd); - close(echo_fd); - close(ref_fd); + fclose(e_fd); + fclose(echo_fd); + fclose(ref_fd); return 0; } diff --git a/libs/speex/libspeex/testenc.c b/libs/speex/libspeex/testenc.c index eabd02cc76..44c132f1ca 100644 --- a/libs/speex/libspeex/testenc.c +++ b/libs/speex/libspeex/testenc.c @@ -19,7 +19,6 @@ int main(int argc, char **argv) FILE *fin, *fout, *fbits=NULL; short in_short[FRAME_SIZE]; short out_short[FRAME_SIZE]; - float sigpow,errpow,snr, seg_snr=0; int snr_frames = 0; char cbits[200]; int nbBits; @@ -32,11 +31,8 @@ int main(int argc, char **argv) spx_int32_t skip_group_delay; SpeexCallback callback; - sigpow = 0; - errpow = 0; - - st = speex_encoder_init(&speex_nb_mode); - dec = speex_decoder_init(&speex_nb_mode); + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); /* BEGIN: You probably don't need the following in a real application */ callback.callback_id = SPEEX_INBAND_CHAR; @@ -74,13 +70,13 @@ int main(int argc, char **argv) exit(1); } inFile = argv[1]; - fin = fopen(inFile, "r"); + fin = fopen(inFile, "rb"); outFile = argv[2]; - fout = fopen(outFile, "w+"); + fout = fopen(outFile, "wb+"); if (argc==4) { bitsFile = argv[3]; - fbits = fopen(bitsFile, "w"); + fbits = fopen(bitsFile, "wb"); } speex_bits_init(&bits); while (!feof(fin)) @@ -109,6 +105,12 @@ int main(int argc, char **argv) speex_decoder_destroy(dec); speex_bits_destroy(&bits); +#ifndef DISABLE_FLOAT_API + { + float sigpow,errpow,snr, seg_snr=0; + sigpow = 0; + errpow = 0; + /* This code just computes SNR, so you don't need it either */ rewind(fin); rewind(fout); @@ -127,9 +129,6 @@ int main(int argc, char **argv) errpow += e; snr_frames++; } - fclose(fin); - fclose(fout); - snr = 10 * log10( sigpow / errpow ); seg_snr /= snr_frames; fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr); @@ -137,6 +136,11 @@ int main(int argc, char **argv) #ifdef FIXED_DEBUG printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames)); #endif - + } +#endif + + fclose(fin); + fclose(fout); + return 0; } diff --git a/libs/speex/libspeex/testenc_uwb.c b/libs/speex/libspeex/testenc_uwb.c index e9bf18a667..503b64dcef 100644 --- a/libs/speex/libspeex/testenc_uwb.c +++ b/libs/speex/libspeex/testenc_uwb.c @@ -36,8 +36,8 @@ int main(int argc, char **argv) sigpow = 0; errpow = 0; - st = speex_encoder_init(&speex_uwb_mode); - dec = speex_decoder_init(&speex_uwb_mode); + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); callback.callback_id = SPEEX_INBAND_CHAR; callback.func = speex_std_char_handler; @@ -69,13 +69,13 @@ int main(int argc, char **argv) exit(1); } inFile = argv[1]; - fin = fopen(inFile, "r"); + fin = fopen(inFile, "rb"); outFile = argv[2]; - fout = fopen(outFile, "w+"); + fout = fopen(outFile, "wb+"); if (argc==4) { bitsFile = argv[3]; - fbits = fopen(bitsFile, "w"); + fbits = fopen(bitsFile, "wb"); } speex_bits_init(&bits); while (!feof(fin)) diff --git a/libs/speex/libspeex/testenc_wb.c b/libs/speex/libspeex/testenc_wb.c index 8e515cb13c..3f13184a38 100644 --- a/libs/speex/libspeex/testenc_wb.c +++ b/libs/speex/libspeex/testenc_wb.c @@ -19,7 +19,6 @@ int main(int argc, char **argv) FILE *fin, *fout, *fbits=NULL; short in_short[FRAME_SIZE]; short out_short[FRAME_SIZE]; - float in_float[FRAME_SIZE]; float sigpow,errpow,snr, seg_snr=0; int snr_frames = 0; char cbits[200]; @@ -36,8 +35,8 @@ int main(int argc, char **argv) sigpow = 0; errpow = 0; - st = speex_encoder_init(&speex_wb_mode); - dec = speex_decoder_init(&speex_wb_mode); + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB)); callback.callback_id = SPEEX_INBAND_CHAR; callback.func = speex_std_char_handler; @@ -74,13 +73,13 @@ int main(int argc, char **argv) exit(1); } inFile = argv[1]; - fin = fopen(inFile, "r"); + fin = fopen(inFile, "rb"); outFile = argv[2]; - fout = fopen(outFile, "w+"); + fout = fopen(outFile, "wb+"); if (argc==4) { bitsFile = argv[3]; - fbits = fopen(bitsFile, "w"); + fbits = fopen(bitsFile, "wb"); } speex_bits_init(&bits); while (!feof(fin)) @@ -88,8 +87,6 @@ int main(int argc, char **argv) fread(in_short, sizeof(short), FRAME_SIZE, fin); if (feof(fin)) break; - for (i=0;i +#include + +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; +} diff --git a/libs/speex/libspeex/vbr.c b/libs/speex/libspeex/vbr.c index bfd1fa67f1..5b7dd9bfa8 100644 --- a/libs/speex/libspeex/vbr.c +++ b/libs/speex/libspeex/vbr.c @@ -45,31 +45,32 @@ #define MIN_ENERGY 6000 #define NOISE_POW .3 +#ifndef DISABLE_VBR const float vbr_nb_thresh[9][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */ - { 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */ - {10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */ - {11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */ - {11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */ - {11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */ - { 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */ + { 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */ + {10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.5f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */ + {11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 3.9f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */ + {11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 6.0f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 7.0f, 6.0f, 5.0f, 3.0f}, /* 15 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 7.0f, 6.0f, 5.0f}, /* 18 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 9.5f, 7.5f}, /* 24 kbps */ + { 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */ }; const float vbr_hb_thresh[5][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */ - {11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 2 kbps */ + {11.0f, 11.0f, 9.5f, 8.5f, 7.5f, 6.0f, 5.0f, 3.9f, 3.0f, 2.0f, 1.0f}, /* 6 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.7f, 7.8f, 7.0f, 6.5f, 4.0f}, /* 10 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f} /* 18 kbps */ }; const float vbr_uhb_thresh[2][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - { 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */ + { 3.9f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f} /* 2 kbps */ }; void vbr_init(VBRState *vbr) @@ -270,3 +271,5 @@ float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float p void vbr_destroy(VBRState *vbr) { } + +#endif /* #ifndef DISABLE_VBR */ diff --git a/libs/speex/libspeex/vbr.h b/libs/speex/libspeex/vbr.h index 34e1d4c358..ff1e3e46f2 100644 --- a/libs/speex/libspeex/vbr.h +++ b/libs/speex/libspeex/vbr.h @@ -37,7 +37,7 @@ #ifndef VBR_H #define VBR_H -#include "misc.h" +#include "arch.h" #define VBR_MEMORY_SIZE 5 diff --git a/libs/speex/libspeex/vorbis_psy.h b/libs/speex/libspeex/vorbis_psy.h index fbdb7c5506..6871057753 100644 --- a/libs/speex/libspeex/vorbis_psy.h +++ b/libs/speex/libspeex/vorbis_psy.h @@ -39,7 +39,7 @@ #define NOISE_COMPAND_LEVELS 40 -#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f) +#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30) #define fromdB(x) (exp((x)*.11512925f)) /* The bark scale equations are approximations, since the original diff --git a/libs/speex/libspeex/vq.c b/libs/speex/libspeex/vq.c index d40133f3e8..609f124e7f 100644 --- a/libs/speex/libspeex/vq.c +++ b/libs/speex/libspeex/vq.c @@ -36,7 +36,7 @@ #include "vq.h" #include "stack_alloc.h" -#include "misc.h" +#include "arch.h" #ifdef _USE_SSE #include @@ -70,29 +70,6 @@ int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries) return i; } -/*Finds the index of the entry in a codebook that best matches the input*/ -int vq_index(float *in, const float *codebook, int len, int entries) -{ - int i,j; - float min_dist=0; - int best_index=0; - for (i=0;i 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); diff --git a/libs/speex/libspeex/window.c b/libs/speex/libspeex/window.c index 3748f656ab..ac042d45f4 100644 --- a/libs/speex/libspeex/window.c +++ b/libs/speex/libspeex/window.c @@ -33,9 +33,13 @@ #include "config.h" #endif -#include "misc.h" +#include "arch.h" #ifdef FIXED_POINT +const spx_word16_t lag_window[11] = { + 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330 +}; + const spx_word16_t lpc_window[200] = { 1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436, 1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884, @@ -64,31 +68,35 @@ const spx_word16_t lpc_window[200] = { 6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696 }; #else +const spx_word16_t lag_window[11] = { + 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258 +}; + const spx_word16_t lpc_window[200] = { - 0.080000, 0.080158, 0.080630, 0.081418, 0.082520, 0.083935, 0.085663, 0.087703, - 0.090052, 0.092710, 0.095674, 0.098943, 0.102514, 0.106385, 0.110553, 0.115015, - 0.119769, 0.124811, 0.130137, 0.135744, 0.141628, 0.147786, 0.154212, 0.160902, - 0.167852, 0.175057, 0.182513, 0.190213, 0.198153, 0.206328, 0.214731, 0.223357, - 0.232200, 0.241254, 0.250513, 0.259970, 0.269619, 0.279453, 0.289466, 0.299651, - 0.310000, 0.320507, 0.331164, 0.341965, 0.352901, 0.363966, 0.375151, 0.386449, - 0.397852, 0.409353, 0.420943, 0.432615, 0.444361, 0.456172, 0.468040, 0.479958, - 0.491917, 0.503909, 0.515925, 0.527959, 0.540000, 0.552041, 0.564075, 0.576091, - 0.588083, 0.600042, 0.611960, 0.623828, 0.635639, 0.647385, 0.659057, 0.670647, - 0.682148, 0.693551, 0.704849, 0.716034, 0.727099, 0.738035, 0.748836, 0.759493, - 0.770000, 0.780349, 0.790534, 0.800547, 0.810381, 0.820030, 0.829487, 0.838746, - 0.847800, 0.856643, 0.865269, 0.873672, 0.881847, 0.889787, 0.897487, 0.904943, - 0.912148, 0.919098, 0.925788, 0.932214, 0.938372, 0.944256, 0.949863, 0.955189, - 0.960231, 0.964985, 0.969447, 0.973615, 0.977486, 0.981057, 0.984326, 0.987290, - 0.989948, 0.992297, 0.994337, 0.996065, 0.997480, 0.998582, 0.999370, 0.999842, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 0.998640, 0.994566, 0.987787, 0.978324, 0.966203, - 0.951458, 0.934131, 0.914270, 0.891931, 0.867179, 0.840084, 0.810723, 0.779182, - 0.745551, 0.709930, 0.672424, 0.633148, 0.592223, 0.549781, 0.505964, 0.460932, - 0.414863, 0.367968, 0.320511, 0.272858, 0.225569, 0.179655, 0.137254, 0.103524 + 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f, + 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f, + 0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f, + 0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f, + 0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f, + 0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f, + 0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f, + 0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f, + 0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f, + 0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f, + 0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f, + 0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f, + 0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f, + 0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f, + 0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f, + 0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f, + 0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f, + 0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f }; #endif diff --git a/libs/speex/speex.m4 b/libs/speex/speex.m4 index 595797e18a..be144e1fad 100644 --- a/libs/speex/speex.m4 +++ b/libs/speex/speex.m4 @@ -21,7 +21,7 @@ AC_ARG_ENABLE(speextest, [ --disable-speextest Do not try to compile and elif test "x$speex_prefix" != "x" ; then SPEEX_LIBS="-L$speex_prefix/lib" elif test "x$prefix" != "xNONE" ; then - SPEEX_LIBS="" + SPEEX_LIBS="-L$prefix/lib" fi SPEEX_LIBS="$SPEEX_LIBS -lspeex" diff --git a/libs/speex/speex.pc.in b/libs/speex/speex.pc.in index 01275d76a2..3e72a36647 100644 --- a/libs/speex/speex.pc.in +++ b/libs/speex/speex.pc.in @@ -11,4 +11,5 @@ Version: @SPEEX_VERSION@ Requires: Conflicts: Libs: -L${libdir} -lspeex +Libs.private: -lm Cflags: -I${includedir} diff --git a/libs/speex/speexdsp.pc.in b/libs/speex/speexdsp.pc.in new file mode 100644 index 0000000000..bfa8ddcf35 --- /dev/null +++ b/libs/speex/speexdsp.pc.in @@ -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} diff --git a/libs/speex/src/Makefile.am b/libs/speex/src/Makefile.am index 1ef61b2cce..e5f75913d5 100644 --- a/libs/speex/src/Makefile.am +++ b/libs/speex/src/Makefile.am @@ -7,7 +7,6 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_CFLAGS@ -mandir = $(prefix)/share/man man_MANS = speexenc.1 speexdec.1 EXTRA_DIST = $(man_MANS) getopt_win.h getopt.c getopt1.c wave_out.c wave_out.h skeleton.h @@ -18,9 +17,9 @@ noinst_HEADERS = wav_io.h bin_PROGRAMS = speexenc speexdec speexenc_SOURCES = speexenc.c wav_io.c skeleton.c -speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la \ - $(OGG_LIBS) +speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la $(top_builddir)/libspeex/libspeexdsp.la \ + $(OGG_LIBS) @FFT_LIBS@ speexdec_SOURCES = speexdec.c wav_io.c speexdec_LDADD = $(top_builddir)/libspeex/libspeex.la \ - $(OGG_LIBS) + $(OGG_LIBS) @FFT_LIBS@ diff --git a/libs/speex/src/speexdec.1 b/libs/speex/src/speexdec.1 index 7cfd723f38..3545f09414 100644 --- a/libs/speex/src/speexdec.1 +++ b/libs/speex/src/speexdec.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. .TH SPEEXDEC "1" "September 2003" "speexdec version 1.1" "User Commands" .SH NAME -speexdec \- manual page for speexdec version 1.1 +speexdec \- The reference implementation speex decoder. .SH SYNOPSIS .B speexdec [\fIoptions\fR] \fIinput_file.spx \fR[\fIoutput_file\fR] diff --git a/libs/speex/src/speexdec.c b/libs/speex/src/speexdec.c index 94a63c1166..24a62d4eea 100644 --- a/libs/speex/src/speexdec.c +++ b/libs/speex/src/speexdec.c @@ -36,6 +36,8 @@ #include #if !defined WIN32 && !defined _WIN32 #include +#endif +#ifdef HAVE_GETOPT_H #include #endif #ifndef HAVE_GETOPT_LONG @@ -48,8 +50,6 @@ #include #if defined WIN32 || defined _WIN32 -#include -#include "getopt_win.h" #include "wave_out.h" /* We need the following two to set stdout to binary */ #include @@ -84,7 +84,6 @@ #include #include #include -#include "wav_io.h" #define MAX_FRAME_SIZE 2000 @@ -107,7 +106,7 @@ static void print_comments(char *comments, int length) end = c+length; len=readint(c, 0); c+=4; - if (c+len>end) + if (len < 0 || c+len>end) { fprintf (stderr, "Invalid/corrupted comments\n"); return; @@ -131,7 +130,7 @@ static void print_comments(char *comments, int length) } len=readint(c, 0); c+=4; - if (c+len>end) + if (len < 0 || c+len>end) { fprintf (stderr, "Invalid/corrupted comments\n"); return; @@ -232,6 +231,8 @@ FILE *out_file_open(char *outFile, int rate, int *channels) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdout), _O_BINARY); +#elif defined OS2 + _fsetmode(stdout,"b"); #endif fout=stdout; } @@ -289,13 +290,17 @@ void usage() void version() { - printf ("speexdec (Speex decoder) version " SPEEX_VERSION " (compiled " __DATE__ ")\n"); + const char* speex_version; + speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); + printf ("speexdec (Speex decoder) version %s (compiled " __DATE__ ")\n", speex_version); printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n"); } void version_short() { - printf ("speexdec version " SPEEX_VERSION "\n"); + const char* speex_version; + speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); + printf ("speexdec version %s\n", speex_version); printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n"); } @@ -317,6 +322,7 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t { fprintf (stderr, "Mode number %d does not (yet/any longer) exist in this version\n", header->mode); + free(header); return NULL; } @@ -329,17 +335,20 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t if (header->speex_version_id > 1) { fprintf (stderr, "This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", header->speex_version_id); + free(header); return NULL; } if (mode->bitstream_version < header->mode_bitstream_version) { fprintf (stderr, "The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n"); + free(header); return NULL; } if (mode->bitstream_version > header->mode_bitstream_version) { fprintf (stderr, "The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n"); + free(header); return NULL; } @@ -347,19 +356,13 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t if (!st) { fprintf (stderr, "Decoder initialization failed.\n"); + free(header); return NULL; } speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled); speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size); *granule_frame_size = *frame_size; - if (!(*channels==1)) - { - callback.callback_id = SPEEX_INBAND_STEREO; - callback.func = speex_std_stereo_request_handler; - callback.data = stereo; - speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback); - } if (!*rate) *rate = header->rate; /* Adjust rate if --force-* options are used */ @@ -384,6 +387,15 @@ static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t if (*channels==-1) *channels = header->nb_channels; + + if (!(*channels==1)) + { + *channels = 2; + callback.callback_id = SPEEX_INBAND_STEREO; + callback.func = speex_std_stereo_request_handler; + callback.data = stereo; + speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback); + } if (!quiet) { @@ -630,7 +642,7 @@ int main(int argc, char **argv) packet_no=0; while (!eos && ogg_stream_packetout(&os, &op) == 1) { - if (!memcmp(op.packet, "Speex", 5)) { + if (op.bytes>=5 && !memcmp(op.packet, "Speex", 5)) { speex_serialno = os.serialno; } if (speex_serialno == -1 || os.serialno != speex_serialno) diff --git a/libs/speex/src/speexenc.1 b/libs/speex/src/speexenc.1 index d7411615f5..9b0d6a78c2 100644 --- a/libs/speex/src/speexenc.1 +++ b/libs/speex/src/speexenc.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. .TH SPEEXENC "1" "September 2003" "speexenc version 1.1" "User Commands" .SH NAME -speexenc \- manual page for speexenc version 1.1 +speexenc \- The reference implementation speex encoder. .SH SYNOPSIS .B speexenc [\fIoptions\fR] \fIinput_file output_file\fR diff --git a/libs/speex/src/speexenc.c b/libs/speex/src/speexenc.c index e251b9ba35..a2554e1b36 100644 --- a/libs/speex/src/speexenc.c +++ b/libs/speex/src/speexenc.c @@ -36,6 +36,8 @@ #include #if !defined WIN32 && !defined _WIN32 #include +#endif +#ifdef HAVE_GETOPT_H #include #endif #ifndef HAVE_GETOPT_LONG @@ -53,7 +55,6 @@ #include #if defined WIN32 || defined _WIN32 -#include "getopt_win.h" /* We need the following two to set stdout to binary */ #include #include @@ -182,13 +183,17 @@ void add_fisbone_packet (ogg_stream_state *os, spx_int32_t serialno, SpeexHeader void version() { - printf ("speexenc (Speex encoder) version " SPEEX_VERSION " (compiled " __DATE__ ")\n"); + const char* speex_version; + speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); + printf ("speexenc (Speex encoder) version %s (compiled " __DATE__ ")\n", speex_version); printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n"); } void version_short() { - printf ("speexenc version " SPEEX_VERSION "\n"); + const char* speex_version; + speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); + printf ("speexenc version %s\n", speex_version); printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n"); } @@ -316,7 +321,8 @@ int main(int argc, char **argv) SpeexHeader header; int nframes=1; spx_int32_t complexity=3; - char *vendor_string = "Encoded with Speex " SPEEX_VERSION; + const char* speex_version; + char vendor_string[64]; char *comments; int comments_length; int close_in=0, close_out=0; @@ -329,6 +335,9 @@ int main(int argc, char **argv) SpeexPreprocessState *preprocess = NULL; int denoise_enabled=0, agc_enabled=0; spx_int32_t lookahead = 0; + + speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); + snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version); comment_init(&comments, &comments_length, vendor_string); @@ -505,6 +514,8 @@ int main(int argc, char **argv) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); +#elif defined OS2 + _fsetmode(stdin,"b"); #endif fin=stdin; } @@ -949,6 +960,8 @@ void comment_init(char **comments, int* length, char *vendor_string) int len=4+vendor_length+4; char *p=(char*)malloc(len); if(p==NULL){ + fprintf (stderr, "malloc failed in comment_init()\n"); + exit(1); } writeint(p, 0, vendor_length); memcpy(p+4, vendor_string, vendor_length); @@ -967,6 +980,8 @@ void comment_add(char **comments, int* length, char *tag, char *val) p=(char*)realloc(p, len); if(p==NULL){ + fprintf (stderr, "realloc failed in comment_add()\n"); + exit(1); } writeint(p, *length, tag_len+val_len); /* length of comment */ diff --git a/libs/speex/src/wav_io.c b/libs/speex/src/wav_io.c index a68a91a6f2..02931b1a67 100644 --- a/libs/speex/src/wav_io.c +++ b/libs/speex/src/wav_io.c @@ -37,38 +37,7 @@ #include #include #include "speex/speex_types.h" - -static spx_uint32_t le_int(spx_uint32_t i) -{ - spx_uint32_t ret=i; -#ifdef WORDS_BIGENDIAN - ret = i>>24; - ret += (i>>8)&0x0000ff00; - ret += (i<<8)&0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -unsigned short be_short(unsigned short s) -{ - unsigned short ret=s; -#ifndef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} - -unsigned short le_short(unsigned short s) -{ - unsigned short ret=s; -#ifdef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} +#include "wav_io.h" int read_wav_header(FILE *file, int *rate, int *channels, int *format, spx_int32_t *size) diff --git a/libs/speex/src/wav_io.h b/libs/speex/src/wav_io.h index fa5fe7a3b5..07557639a1 100644 --- a/libs/speex/src/wav_io.h +++ b/libs/speex/src/wav_io.h @@ -35,9 +35,29 @@ #include #include "speex/speex_types.h" -unsigned short be_short(unsigned short s); -unsigned short le_short(unsigned short s); -spx_uint32_t le_int(spx_uint32_t i); +#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) +#define le_short(s) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8)) +#define be_short(s) ((short) (s)) +#else +#define le_short(s) ((short) (s)) +#define be_short(s) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8)) +#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 +} int read_wav_header(FILE *file, int *rate, int *channels, int *format, spx_int32_t *size); diff --git a/libs/speex/symbian/bld.inf b/libs/speex/symbian/bld.inf index 71fa4d9142..f03a333d27 100644 --- a/libs/speex/symbian/bld.inf +++ b/libs/speex/symbian/bld.inf @@ -30,6 +30,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +PRJ_EXPORTS + +..\include\speex\speex_bits.h \epoc32\include\speex\speex_bits.h +..\include\speex\speex_callbacks.h \epoc32\include\speex\speex_callbacks.h +..\include\speex\speex_config_types.h \epoc32\include\speex\speex_config_types.h +..\include\speex\speex_echo.h \epoc32\include\speex\speex_echo.h +..\include\speex\speex.h \epoc32\include\speex\speex.h +..\include\speex\speex_header.h \epoc32\include\speex\speex_header.h +..\include\speex\speex_jitter.h \epoc32\include\speex\speex_jitter.h +..\include\speex\speex_preprocess.h \epoc32\include\speex\speex_preprocess.h +..\include\speex\speex_stereo.h \epoc32\include\speex\speex_stereo.h +..\include\speex\speex_types.h \epoc32\include\speex\speex_types.h + + PRJ_MMPFILES speex.mmp diff --git a/libs/speex/symbian/speex.mmp b/libs/speex/symbian/speex.mmp index 5d071ff9f1..67b096e186 100644 --- a/libs/speex/symbian/speex.mmp +++ b/libs/speex/symbian/speex.mmp @@ -36,10 +36,10 @@ UID 0 MACRO HAVE_CONFIG_H SOURCEPATH ..\libspeex SOURCE bits.c cb_search.c exc_5_64_table.c exc_5_256_table.c exc_8_128_table.c -SOURCE exc_10_16_table.c exc_10_32_table.c exc_20_32_table.c filters.c gain_table.c +SOURCE exc_10_16_table.c exc_10_32_table.c exc_20_32_table.c fftwrap.c kiss_fft.c kiss_fftr.c filterbank.c filters.c gain_table.c SOURCE gain_table_lbr.c hexc_10_32_table.c hexc_table.c high_lsp_tables.c jitter.c SOURCE lbr_48k_tables.c lpc.c lsp.c lsp_tables_nb.c ltp.c math_approx.c mdf.c misc.c SOURCE modes.c nb_celp.c preprocess.c quant_lsp.c sb_celp.c smallft.c -SOURCE speex.c speex_callbacks.c speex_header.c stereo.c vbr.c vq.c +SOURCE speex.c speex_callbacks.c speex_header.c stereo.c vbr.c vq.c window.c USERINCLUDE . ..\include\speex SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\include diff --git a/libs/speex/ti/Makefile.am b/libs/speex/ti/Makefile.am index 0b3bc68b0f..200ca19547 100644 --- a/libs/speex/ti/Makefile.am +++ b/libs/speex/ti/Makefile.am @@ -5,5 +5,5 @@ SUBDIRS = speex_C54_test speex_C55_test speex_C64_test -EXTRA_DIST = config.h testenc-TI-C5x.c user_misc.h testenc-TI-C64x.c +EXTRA_DIST = config.h testenc-TI-C5x.c os_support_custom.h testenc-TI-C64x.c diff --git a/libs/speex/ti/config.h b/libs/speex/ti/config.h index 58173fb68d..e0c101bd8b 100644 --- a/libs/speex/ti/config.h +++ b/libs/speex/ti/config.h @@ -35,35 +35,39 @@ #define FRAME_SIZE 160 #define DISABLE_WIDEBAND +/* Disable DC block if doing SNR testing */ +#define DISABLE_HIGHPASS + /* Allow for 2 20ms narrowband blocks per frame, plus a couple of bytes */ #define MAX_CHARS_PER_FRAME (42/BYTES_PER_CHAR) /* for debug */ #undef DECODE_ONLY +#define VERBOSE_ALLOC /* EITHER Allocate from fixed array (C heap not used) */ /* Enable VERBOSE_ALLOC to see how much is used */ #define MANUAL_ALLOC -#define USER_MISC -#define VERBOSE_ALLOC +#define OS_SUPPORT_CUSTOM + /* OR Use CALLOC (heap size must be increased in linker command file) */ //#undef MANUAL_ALLOC -//#undef USER_MISC +//#undef OS_SUPPORT_CUSTOM #if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) //#define PRECISION16 // These values determined by analysis for 8kbps narrowband -#define SPEEXENC_PERSIST_STACK_SIZE 5000 +#define SPEEXENC_PERSIST_STACK_SIZE 1000 #define SPEEXENC_SCRATCH_STACK_SIZE 3000 -#define SPEEXDEC_PERSIST_STACK_SIZE 2500 +#define SPEEXDEC_PERSIST_STACK_SIZE 1000 #define SPEEXDEC_SCRATCH_STACK_SIZE 1000 #else /* C6X */ #define NO_LONGLONG -#define SPEEXENC_PERSIST_STACK_SIZE 10000 +#define SPEEXENC_PERSIST_STACK_SIZE 2000 #define SPEEXENC_SCRATCH_STACK_SIZE 6000 -#define SPEEXDEC_PERSIST_STACK_SIZE 5000 +#define SPEEXDEC_PERSIST_STACK_SIZE 2000 #define SPEEXDEC_SCRATCH_STACK_SIZE 2000 #endif #define SPEEX_PERSIST_STACK_SIZE (SPEEXENC_PERSIST_STACK_SIZE + SPEEXDEC_PERSIST_STACK_SIZE) diff --git a/libs/speex/ti/os_support_custom.h b/libs/speex/ti/os_support_custom.h new file mode 100644 index 0000000000..95dd67909b --- /dev/null +++ b/libs/speex/ti/os_support_custom.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2007 Psi Systems, Inc. + Author: Jean-Marc Valin + File: os_support_custom.h + Memory Allocation overrides to allow user control rather than C alloc/free. + + 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 MANUAL_ALLOC + +/* To avoid changing the Speex call model, this file relies on four static variables + The user main creates two linear buffers, and initializes spxGlobalHeap/ScratchPtr + to point to the start of the two buffers, and initializes spxGlobalHeap/ScratchEnd + to point to the first address following the last byte of the two buffers. + + This mechanism allows, for example, data caching for multichannel applications, + where the Speex state is swapped from a large slow memory to a small fast memory + each time the codec runs. + + Persistent data is allocated in spxGlobalHeap (instead of calloc), while scratch + data is allocated in spxGlobalScratch. +*/ + +extern char *spxGlobalHeapPtr, *spxGlobalHeapEnd; +extern char *spxGlobalScratchPtr, *spxGlobalScratchEnd; + +/* Make sure that all structures are aligned to largest type */ +#define BLOCK_MASK (sizeof(long double)-1) +extern inline void speex_warning(const char *str); + +#define OVERRIDE_SPEEX_ALLOC +static inline void *speex_alloc (int size) +{ + void *ptr; + + ptr = (void *) (((int)spxGlobalHeapPtr + BLOCK_MASK) & ~BLOCK_MASK); //Start on 8 boundary + + spxGlobalHeapPtr = (char *)((int)ptr + size); // Update pointer to next free location + + if (spxGlobalHeapPtr > spxGlobalHeapEnd ) + { +#ifdef VERBOSE_ALLOC + fprintf (stderr, "insufficient space for persistent alloc request %d bytes\n", size); +#endif + return 0; + } + +#ifdef VERBOSE_ALLOC + fprintf (stderr, "Persist Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalHeapEnd - (int)spxGlobalHeapPtr)); +#endif + memset(ptr, 0, size); + return ptr; +} + +#define OVERRIDE_SPEEX_ALLOC_SCRATCH +static inline void *speex_alloc_scratch (int size) +{ + void *ptr; + + ptr = (void *) (((int)spxGlobalScratchPtr + BLOCK_MASK) & ~BLOCK_MASK); //Start on 8 boundary + + spxGlobalScratchPtr = (char *)((int)ptr + size); // Update pointer to next free location + + if (spxGlobalScratchPtr > spxGlobalScratchEnd ) + { +#ifdef VERBOSE_ALLOC + fprintf (stderr, "insufficient space for scratch alloc request %d bytes\n", size); +#endif + return 0; + } + +#ifdef VERBOSE_ALLOC + fprintf (stderr, "Scratch Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalScratchEnd - (int)spxGlobalScratchPtr)); +#endif + memset(ptr, 0, size); + return ptr; +} + +#define OVERRIDE_SPEEX_REALLOC +static inline void *speex_realloc (void *ptr, int size) +{ +#ifdef VERBOSE_ALLOC + speex_warning("realloc attempted, not allowed"); +#endif + return 0; +} + +#define OVERRIDE_SPEEX_FREE +static inline void speex_free (void *ptr) +{ +#ifdef VERBOSE_ALLOC + speex_warning("at speex_free"); +#endif +} +#define OVERRIDE_SPEEX_FREE_SCRATCH +static inline void speex_free_scratch (void *ptr) +{ +#ifdef VERBOSE_ALLOC + speex_warning("at speex_free_scratch"); +#endif +} + +#endif /* !MANUAL_ALLOC */ diff --git a/libs/speex/ti/speex_C54_test/speex_C54_test.pjt b/libs/speex/ti/speex_C54_test/speex_C54_test.pjt index c7f646d474..73b94fa7d8 100644 --- a/libs/speex/ti/speex_C54_test/speex_C54_test.pjt +++ b/libs/speex/ti/speex_C54_test/speex_C54_test.pjt @@ -1,7 +1,7 @@ ; Code Composer Project File, Version 2.0 (do not modify or remove this line) [Project Settings] -ProjectDir="C:\speex_11234\ti\speex_C54_test\" +ProjectDir="C:\Speex\speex_14274\ti\speex_C54_test\" ProjectType=Executable CPUFamily=TMS320C54XX Tool="Compiler" @@ -27,8 +27,6 @@ Source="..\..\libspeex\lpc.c" Source="..\..\libspeex\lsp.c" Source="..\..\libspeex\lsp_tables_nb.c" Source="..\..\libspeex\ltp.c" -Source="..\..\libspeex\math_approx.c" -Source="..\..\libspeex\misc.c" Source="..\..\libspeex\modes.c" Source="..\..\libspeex\nb_celp.c" Source="..\..\libspeex\quant_lsp.c" diff --git a/libs/speex/ti/speex_C55_test/speex_C55_test.pjt b/libs/speex/ti/speex_C55_test/speex_C55_test.pjt index b03504f06b..aad9f01791 100644 --- a/libs/speex/ti/speex_C55_test/speex_C55_test.pjt +++ b/libs/speex/ti/speex_C55_test/speex_C55_test.pjt @@ -1,7 +1,7 @@ ; Code Composer Project File, Version 2.0 (do not modify or remove this line) [Project Settings] -ProjectDir="C:\speex_11234\ti\speex_C55_test\" +ProjectDir="C:\Speex\speex_14274\ti\speex_C55_test\" ProjectType=Executable CPUFamily=TMS320C55XX Tool="Compiler" @@ -27,8 +27,6 @@ Source="..\..\libspeex\lpc.c" Source="..\..\libspeex\lsp.c" Source="..\..\libspeex\lsp_tables_nb.c" Source="..\..\libspeex\ltp.c" -Source="..\..\libspeex\math_approx.c" -Source="..\..\libspeex\misc.c" Source="..\..\libspeex\modes.c" Source="..\..\libspeex\nb_celp.c" Source="..\..\libspeex\quant_lsp.c" diff --git a/libs/speex/ti/speex_C64_test/speex_C64_test.pjt b/libs/speex/ti/speex_C64_test/speex_C64_test.pjt index 899f6e33f6..10c5356e4a 100644 --- a/libs/speex/ti/speex_C64_test/speex_C64_test.pjt +++ b/libs/speex/ti/speex_C64_test/speex_C64_test.pjt @@ -1,7 +1,7 @@ ; Code Composer Project File, Version 2.0 (do not modify or remove this line) [Project Settings] -ProjectDir="C:\speex_11234\ti\speex_C64_test\" +ProjectDir="C:\Speex\speex_14274\ti\speex_C64_test\" ProjectType=Executable CPUFamily=TMS320C64XX Tool="Compiler" @@ -12,7 +12,7 @@ Config="Debug" Config="Release" [Source Files] -Source="..\..\..\CCStudio_v3.1\C6000\cgtools\lib\rts6400.lib" +Source="..\..\..\..\CCStudio_v3.1\C6000\cgtools\lib\rts6400.lib" Source="..\..\libspeex\bits.c" Source="..\..\libspeex\cb_search.c" Source="..\..\libspeex\exc_10_16_table.c" @@ -28,8 +28,6 @@ Source="..\..\libspeex\lpc.c" Source="..\..\libspeex\lsp.c" Source="..\..\libspeex\lsp_tables_nb.c" Source="..\..\libspeex\ltp.c" -Source="..\..\libspeex\math_approx.c" -Source="..\..\libspeex\misc.c" Source="..\..\libspeex\modes.c" Source="..\..\libspeex\nb_celp.c" Source="..\..\libspeex\quant_lsp.c" diff --git a/libs/speex/ti/testenc-TI-C5x.c b/libs/speex/ti/testenc-TI-C5x.c index fe8be68df4..e8e0449dc2 100644 --- a/libs/speex/ti/testenc-TI-C5x.c +++ b/libs/speex/ti/testenc-TI-C5x.c @@ -184,10 +184,17 @@ void main() tmp=1; /* Lowest */ speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); +#ifdef DISABLE_HIGHPASS + /* Turn this off if you want to measure SNR (on by default) */ + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp); + speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp); +#endif + speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); skip_group_delay += tmp; - fprintf (stderr, "decoder lookahead = %d\n", skip_group_delay); + fprintf (stderr, "decoder lookahead = %ld\n", skip_group_delay); #ifdef DECODE_ONLY bitsFile = "c:\\speextrunktest\\samples\\malebitsin.dat"; diff --git a/libs/speex/ti/testenc-TI-C64x.c b/libs/speex/ti/testenc-TI-C64x.c index b30be28d5c..60e755fc65 100644 --- a/libs/speex/ti/testenc-TI-C64x.c +++ b/libs/speex/ti/testenc-TI-C64x.c @@ -146,6 +146,13 @@ void main() tmp=1; /* Lowest */ speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); +#ifdef DISABLE_HIGHPASS + /* Turn this off if you want to measure SNR (on by default) */ + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp); + speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp); +#endif + speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); skip_group_delay += tmp; diff --git a/libs/speex/win32/Makefile.am b/libs/speex/win32/Makefile.am index 0823f46ef6..8cee7fb3ff 100644 --- a/libs/speex/win32/Makefile.am +++ b/libs/speex/win32/Makefile.am @@ -3,6 +3,6 @@ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies -SUBDIRS = libspeex speexenc speexdec VS2003 VS2005 +SUBDIRS = libspeex speexenc speexdec VS2003 VS2005 VS2008 -EXTRA_DIST = speex.iss config.h +EXTRA_DIST = speex.iss config.h libspeex.def libspeexdsp.def diff --git a/libs/speex/win32/VS2003/Makefile.am b/libs/speex/win32/VS2003/Makefile.am index d4698d7ec8..15479c34f0 100644 --- a/libs/speex/win32/VS2003/Makefile.am +++ b/libs/speex/win32/VS2003/Makefile.am @@ -3,6 +3,6 @@ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies -SUBDIRS = libspeex speexenc speexdec +SUBDIRS = libspeex libspeexdsp speexenc speexdec tests -EXTRA_DIST = +EXTRA_DIST = libspeex.sln diff --git a/libs/speex/win32/VS2003/libspeex.sln b/libs/speex/win32/VS2003/libspeex.sln new file mode 100644 index 0000000000..4693b1a91b --- /dev/null +++ b/libs/speex/win32/VS2003/libspeex.sln @@ -0,0 +1,146 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdec", "speexdec\speexdec.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexenc", "speexenc\speexenc.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc", "tests\testenc.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_uwb", "tests\testenc_uwb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_wb", "tests\testenc_wb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + Release_Dynamic_SSE = Release_Dynamic_SSE + Release_Static_SSE = Release_Static_SSE + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE.ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE.Build.0 = Release_Static_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE.Build.0 = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE.Build.0 = Release_Static_SSE|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libs/speex/win32/VS2003/libspeex/Makefile.am b/libs/speex/win32/VS2003/libspeex/Makefile.am index 35cf91830a..5de466c791 100644 --- a/libs/speex/win32/VS2003/libspeex/Makefile.am +++ b/libs/speex/win32/VS2003/libspeex/Makefile.am @@ -3,6 +3,6 @@ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = libspeex.def libspeex.vcproj +EXTRA_DIST = libspeex.vcproj diff --git a/libs/speex/win32/VS2003/libspeex/libspeex.vcproj b/libs/speex/win32/VS2003/libspeex/libspeex.vcproj index daa6216ab0..1bf043abc1 100644 --- a/libs/speex/win32/VS2003/libspeex/libspeex.vcproj +++ b/libs/speex/win32/VS2003/libspeex/libspeex.vcproj @@ -20,12 +20,12 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\..\include;..\.." - PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H; USE_ALLOCA" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" MinimalRebuild="TRUE" BasicRuntimeChecks="3" - RuntimeLibrary="1" + RuntimeLibrary="3" UsePrecompiledHeader="0" - WarningLevel="4" + WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4" CompileAs="1"/> @@ -33,7 +33,7 @@ Name="VCCustomBuildTool"/> + OutputFile="../../../lib/libspeex.lib"/> + OutputFile="../../../lib/libspeex.lib"/> + OutputFile="../../../lib/libspeex.lib"/> - - - - - - - - - - - - - - + OptimizeForWindows98="1" + ImportLibrary="../../../lib/libspeex.lib"/> - - - - @@ -332,26 +277,14 @@ - - - - - - - - + RelativePath="..\..\..\libspeex\modes_wb.c"> + RelativePath="..\..\..\libspeex\nb_celp.c"> @@ -359,9 +292,6 @@ - - @@ -380,16 +310,22 @@ + + + + + RelativePath="..\..\..\libspeex\cb_search_sse.h"> @@ -397,6 +333,12 @@ + + + + @@ -412,51 +354,21 @@ - - + + - - - - - - - - - - - - - - - - - - - - @@ -466,6 +378,31 @@ + + + + + + + + + + + + + + + + + RelativePath="..\..\config.h"> + + diff --git a/libs/speex/win32/VS2003/libspeexdsp/Makefile.am b/libs/speex/win32/VS2003/libspeexdsp/Makefile.am new file mode 100644 index 0000000000..796fefcfc1 --- /dev/null +++ b/libs/speex/win32/VS2003/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/libs/speex/win32/VS2003/libspeexdsp/Makefile.in b/libs/speex/win32/VS2003/libspeexdsp/Makefile.in new file mode 100644 index 0000000000..a02e04dce4 --- /dev/null +++ b/libs/speex/win32/VS2003/libspeexdsp/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2003/libspeexdsp +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = libspeexdsp.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2003/libspeexdsp/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2003/libspeexdsp/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2003/libspeexdsp/libspeexdsp.vcproj b/libs/speex/win32/VS2003/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 0000000000..23bd146877 --- /dev/null +++ b/libs/speex/win32/VS2003/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/speexdec/speexdec.vcproj b/libs/speex/win32/VS2003/speexdec/speexdec.vcproj index a390be4acf..d950422a3b 100644 --- a/libs/speex/win32/VS2003/speexdec/speexdec.vcproj +++ b/libs/speex/win32/VS2003/speexdec/speexdec.vcproj @@ -19,11 +19,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -274,6 +219,9 @@ + + diff --git a/libs/speex/win32/VS2003/tests/Makefile.am b/libs/speex/win32/VS2003/tests/Makefile.am new file mode 100644 index 0000000000..47918c6c22 --- /dev/null +++ b/libs/speex/win32/VS2003/tests/Makefile.am @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testenc.vcproj testenc_uwb.vcproj \ + testenc_wb.vcproj testresample.vcproj + + diff --git a/libs/speex/win32/VS2003/tests/Makefile.in b/libs/speex/win32/VS2003/tests/Makefile.in new file mode 100644 index 0000000000..e6f115fb99 --- /dev/null +++ b/libs/speex/win32/VS2003/tests/Makefile.in @@ -0,0 +1,343 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2003/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testenc.vcproj testenc_uwb.vcproj \ + testenc_wb.vcproj testresample.vcproj + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2003/tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2003/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2003/tests/testdenoise.vcproj b/libs/speex/win32/VS2003/tests/testdenoise.vcproj new file mode 100644 index 0000000000..730df77046 --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testdenoise.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/tests/testecho.vcproj b/libs/speex/win32/VS2003/tests/testecho.vcproj new file mode 100644 index 0000000000..0d1216684d --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testecho.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/tests/testenc.vcproj b/libs/speex/win32/VS2003/tests/testenc.vcproj new file mode 100644 index 0000000000..42488f0779 --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testenc.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/tests/testenc_uwb.vcproj b/libs/speex/win32/VS2003/tests/testenc_uwb.vcproj new file mode 100644 index 0000000000..3178b5271b --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testenc_uwb.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/tests/testenc_wb.vcproj b/libs/speex/win32/VS2003/tests/testenc_wb.vcproj new file mode 100644 index 0000000000..472fc66588 --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testenc_wb.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2003/tests/testresample.vcproj b/libs/speex/win32/VS2003/tests/testresample.vcproj new file mode 100644 index 0000000000..e4e08e43de --- /dev/null +++ b/libs/speex/win32/VS2003/tests/testresample.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/Makefile.am b/libs/speex/win32/VS2005/Makefile.am index d4698d7ec8..15479c34f0 100644 --- a/libs/speex/win32/VS2005/Makefile.am +++ b/libs/speex/win32/VS2005/Makefile.am @@ -3,6 +3,6 @@ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies -SUBDIRS = libspeex speexenc speexdec +SUBDIRS = libspeex libspeexdsp speexenc speexdec tests -EXTRA_DIST = +EXTRA_DIST = libspeex.sln diff --git a/libs/speex/win32/VS2005/libspeex.sln b/libs/speex/win32/VS2005/libspeex.sln new file mode 100644 index 0000000000..0fc8b637e3 --- /dev/null +++ b/libs/speex/win32/VS2005/libspeex.sln @@ -0,0 +1,259 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{E42FDC95-7243-4219-9EA4-ACCE4AB97197}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdec", "speexdec\speexdec.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexenc", "speexenc\speexenc.vcproj", "{CD6043D1-D5E7-46D0-854F-00BB1BC308FC}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc", "tests\testenc.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_uwb", "tests\testenc_uwb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_wb", "tests\testenc_wb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_RTL_dll|Win32 = Debug_RTL_dll|Win32 + Debug_WM5_PPC_ARM|Win32 = Debug_WM5_PPC_ARM|Win32 + Debug|Win32 = Debug|Win32 + Release_Dynamic_SSE|Win32 = Release_Dynamic_SSE|Win32 + Release_Dynamic|Win32 = Release_Dynamic|Win32 + Release_RTL_dll|Win32 = Release_RTL_dll|Win32 + Release_SSE|Win32 = Release_SSE|Win32 + Release_SSE2|Win32 = Release_SSE2|Win32 + Release_WM5_PPC_ARM|Win32 = Release_WM5_PPC_ARM|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug|Win32.ActiveCfg = Debug|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug|Win32.Build.0 = Debug|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_WM5_PPC_ARM|Win32.Build.0 = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release|Win32.ActiveCfg = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/speex/win32/VS2005/libspeex/libspeex.vcproj b/libs/speex/win32/VS2005/libspeex/libspeex.vcproj index 34cf8a0672..79913d0fba 100644 --- a/libs/speex/win32/VS2005/libspeex/libspeex.vcproj +++ b/libs/speex/win32/VS2005/libspeex/libspeex.vcproj @@ -66,7 +66,7 @@ /> + + + + + + + + + + + + + + + + + + + + - - @@ -1441,22 +1528,6 @@ RelativePath="..\..\..\libspeex\high_lsp_tables.c" > - - - - - - - - @@ -1473,32 +1544,16 @@ RelativePath="..\..\..\libspeex\ltp.c" > - - - - - - - - - - @@ -1547,16 +1598,16 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + - - - - @@ -1608,7 +1655,7 @@ > - - - - - - - - - - - - - - - - - - - - @@ -1671,6 +1678,10 @@ RelativePath="..\..\..\libspeex\vq.h" > + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/libspeexdsp/Makefile.am b/libs/speex/win32/VS2005/libspeexdsp/Makefile.am new file mode 100644 index 0000000000..796fefcfc1 --- /dev/null +++ b/libs/speex/win32/VS2005/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/libs/speex/win32/VS2005/libspeexdsp/Makefile.in b/libs/speex/win32/VS2005/libspeexdsp/Makefile.in new file mode 100644 index 0000000000..d1ea96ab0a --- /dev/null +++ b/libs/speex/win32/VS2005/libspeexdsp/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2005/libspeexdsp +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = libspeexdsp.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2005/libspeexdsp/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2005/libspeexdsp/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2005/libspeexdsp/libspeexdsp.vcproj b/libs/speex/win32/VS2005/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 0000000000..309f28a202 --- /dev/null +++ b/libs/speex/win32/VS2005/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,1624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/speexdec/speexdec.vcproj b/libs/speex/win32/VS2005/speexdec/speexdec.vcproj index 1b7a3ee9f2..e5d420375b 100644 --- a/libs/speex/win32/VS2005/speexdec/speexdec.vcproj +++ b/libs/speex/win32/VS2005/speexdec/speexdec.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/tests/testecho.vcproj b/libs/speex/win32/VS2005/tests/testecho.vcproj new file mode 100644 index 0000000000..f8f428fc57 --- /dev/null +++ b/libs/speex/win32/VS2005/tests/testecho.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/tests/testenc.vcproj b/libs/speex/win32/VS2005/tests/testenc.vcproj new file mode 100644 index 0000000000..4a7b3c80a6 --- /dev/null +++ b/libs/speex/win32/VS2005/tests/testenc.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/tests/testenc_uwb.vcproj b/libs/speex/win32/VS2005/tests/testenc_uwb.vcproj new file mode 100644 index 0000000000..3689b4c67e --- /dev/null +++ b/libs/speex/win32/VS2005/tests/testenc_uwb.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/tests/testenc_wb.vcproj b/libs/speex/win32/VS2005/tests/testenc_wb.vcproj new file mode 100644 index 0000000000..9d63fb244e --- /dev/null +++ b/libs/speex/win32/VS2005/tests/testenc_wb.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2005/tests/testresample.vcproj b/libs/speex/win32/VS2005/tests/testresample.vcproj new file mode 100644 index 0000000000..ccc33dd1ed --- /dev/null +++ b/libs/speex/win32/VS2005/tests/testresample.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/Makefile.am b/libs/speex/win32/VS2008/Makefile.am new file mode 100644 index 0000000000..15479c34f0 --- /dev/null +++ b/libs/speex/win32/VS2008/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = libspeex libspeexdsp speexenc speexdec tests + +EXTRA_DIST = libspeex.sln diff --git a/libs/speex/win32/VS2008/Makefile.in b/libs/speex/win32/VS2008/Makefile.in new file mode 100644 index 0000000000..1b2b86b594 --- /dev/null +++ b/libs/speex/win32/VS2008/Makefile.in @@ -0,0 +1,485 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008 +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = libspeex libspeexdsp speexenc speexdec tests +EXTRA_DIST = libspeex.sln +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || mkdir "$(distdir)/$$subdir" \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="../$(top_distdir)" \ + distdir="../$(distdir)/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/libspeex.sln b/libs/speex/win32/VS2008/libspeex.sln new file mode 100644 index 0000000000..b46f42cf46 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeex.sln @@ -0,0 +1,439 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdec", "speexdec\speexdec.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexenc", "speexenc\speexenc.vcproj", "{CD6043D1-D5E7-46D0-854F-00BB1BC308FC}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc", "tests\testenc.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_uwb", "tests\testenc_uwb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testenc_wb", "tests\testenc_wb.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_RTL_dll|Win32 = Debug_RTL_dll|Win32 + Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Debug_WM5_PPC_ARM|Win32 = Debug_WM5_PPC_ARM|Win32 + Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Debug|Win32 = Debug|Win32 + Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Dynamic_SSE|Win32 = Release_Dynamic_SSE|Win32 + Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Dynamic|Win32 = Release_Dynamic|Win32 + Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_RTL_dll|Win32 = Release_RTL_dll|Win32 + Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_SSE|Win32 = Release_SSE|Win32 + Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_SSE2|Win32 = Release_SSE2|Win32 + Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Static_SSE|Win32 = Release_Static_SSE|Win32 + Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_WM5_PPC_ARM|Win32 = Release_WM5_PPC_ARM|Win32 + Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release|Win32 = Release|Win32 + Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Win32.Build.0 = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_RTL_dll|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE2|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/speex/win32/VS2008/libspeex/Makefile.am b/libs/speex/win32/VS2008/libspeex/Makefile.am new file mode 100644 index 0000000000..5de466c791 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeex/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeex.vcproj + + diff --git a/libs/speex/win32/VS2008/libspeex/Makefile.in b/libs/speex/win32/VS2008/libspeex/Makefile.in new file mode 100644 index 0000000000..f689e10428 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeex/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008/libspeex +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = libspeex.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/libspeex/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/libspeex/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/libspeex/libspeex.vcproj b/libs/speex/win32/VS2008/libspeex/libspeex.vcproj new file mode 100644 index 0000000000..ef5a36faa6 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeex/libspeex.vcproj @@ -0,0 +1,1704 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/libspeexdsp/Makefile.am b/libs/speex/win32/VS2008/libspeexdsp/Makefile.am new file mode 100644 index 0000000000..796fefcfc1 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/libs/speex/win32/VS2008/libspeexdsp/Makefile.in b/libs/speex/win32/VS2008/libspeexdsp/Makefile.in new file mode 100644 index 0000000000..878042e057 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeexdsp/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008/libspeexdsp +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = libspeexdsp.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/libspeexdsp/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/libspeexdsp/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj b/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 0000000000..f673eb17f6 --- /dev/null +++ b/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/speexdec/Makefile.am b/libs/speex/win32/VS2008/speexdec/Makefile.am new file mode 100644 index 0000000000..93b93c1769 --- /dev/null +++ b/libs/speex/win32/VS2008/speexdec/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = speexdec.vcproj + + diff --git a/libs/speex/win32/VS2008/speexdec/Makefile.in b/libs/speex/win32/VS2008/speexdec/Makefile.in new file mode 100644 index 0000000000..e1dac3b231 --- /dev/null +++ b/libs/speex/win32/VS2008/speexdec/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008/speexdec +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = speexdec.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/speexdec/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/speexdec/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/speexdec/speexdec.vcproj b/libs/speex/win32/VS2008/speexdec/speexdec.vcproj new file mode 100644 index 0000000000..ead9e7e0e3 --- /dev/null +++ b/libs/speex/win32/VS2008/speexdec/speexdec.vcproj @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/speexenc/Makefile.am b/libs/speex/win32/VS2008/speexenc/Makefile.am new file mode 100644 index 0000000000..49e32dc7bd --- /dev/null +++ b/libs/speex/win32/VS2008/speexenc/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = speexenc.vcproj + + diff --git a/libs/speex/win32/VS2008/speexenc/Makefile.in b/libs/speex/win32/VS2008/speexenc/Makefile.in new file mode 100644 index 0000000000..16c996b0f3 --- /dev/null +++ b/libs/speex/win32/VS2008/speexenc/Makefile.in @@ -0,0 +1,341 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008/speexenc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = speexenc.vcproj +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/speexenc/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/speexenc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/speexenc/speexenc.vcproj b/libs/speex/win32/VS2008/speexenc/speexenc.vcproj new file mode 100644 index 0000000000..2797bf9688 --- /dev/null +++ b/libs/speex/win32/VS2008/speexenc/speexenc.vcproj @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/Makefile.am b/libs/speex/win32/VS2008/tests/Makefile.am new file mode 100644 index 0000000000..47918c6c22 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/Makefile.am @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testenc.vcproj testenc_uwb.vcproj \ + testenc_wb.vcproj testresample.vcproj + + diff --git a/libs/speex/win32/VS2008/tests/Makefile.in b/libs/speex/win32/VS2008/tests/Makefile.in new file mode 100644 index 0000000000..76a208c4f3 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/Makefile.in @@ -0,0 +1,343 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = win32/VS2008/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testenc.vcproj testenc_uwb.vcproj \ + testenc_wb.vcproj testresample.vcproj + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win32/VS2008/tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu win32/VS2008/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/speex/win32/VS2008/tests/testdenoise.vcproj b/libs/speex/win32/VS2008/tests/testdenoise.vcproj new file mode 100644 index 0000000000..1c0f8c1508 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testdenoise.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/testecho.vcproj b/libs/speex/win32/VS2008/tests/testecho.vcproj new file mode 100644 index 0000000000..c2c412681f --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testecho.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/testenc.vcproj b/libs/speex/win32/VS2008/tests/testenc.vcproj new file mode 100644 index 0000000000..5224459c1c --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testenc.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/testenc_uwb.vcproj b/libs/speex/win32/VS2008/tests/testenc_uwb.vcproj new file mode 100644 index 0000000000..f7a7d01a73 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testenc_uwb.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/testenc_wb.vcproj b/libs/speex/win32/VS2008/tests/testenc_wb.vcproj new file mode 100644 index 0000000000..e31006e532 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testenc_wb.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/VS2008/tests/testresample.vcproj b/libs/speex/win32/VS2008/tests/testresample.vcproj new file mode 100644 index 0000000000..45565ed858 --- /dev/null +++ b/libs/speex/win32/VS2008/tests/testresample.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/speex/win32/config.h b/libs/speex/win32/config.h index 1949f33489..abd35f0914 100644 --- a/libs/speex/win32/config.h +++ b/libs/speex/win32/config.h @@ -1,3 +1,20 @@ +// Microsoft version of 'inline' #define inline __inline -#define restrict -#include "misc.h" \ No newline at end of file + +// Visual Studio support alloca(), but it always align variables to 16-bit +// boundary, while SSE need 128-bit alignment. So we disable alloca() when +// SSE is enabled. +#ifndef _USE_SSE +# define USE_ALLOCA +#endif + +/* Default to floating point */ +#ifndef FIXED_POINT +# define FLOATING_POINT +# define USE_SMALLFT +#else +# define USE_KISS_FFT +#endif + +/* We don't support visibility on Win32 */ +#define EXPORT diff --git a/libs/speex/win32/libspeex.def b/libs/speex/win32/libspeex.def new file mode 100644 index 0000000000..e5f815f7f7 --- /dev/null +++ b/libs/speex/win32/libspeex.def @@ -0,0 +1,75 @@ +LIBRARY libspeex +EXPORTS + + +; +; speex.h +; +speex_encoder_init +speex_encoder_destroy +speex_encode +speex_encode_int +speex_encoder_ctl +speex_decoder_init +speex_decoder_destroy +speex_decode +speex_decode_int +speex_decoder_ctl +speex_mode_query +speex_lib_ctl +speex_lib_get_mode + +; +; speex_bits.h +; +speex_bits_init +speex_bits_init_buffer +speex_bits_set_bit_buffer +speex_bits_destroy +speex_bits_reset +speex_bits_rewind +speex_bits_read_from +speex_bits_read_whole_bytes +speex_bits_write +speex_bits_write_whole_bytes +speex_bits_pack +speex_bits_unpack_signed +speex_bits_unpack_unsigned +speex_bits_nbytes +speex_bits_peek_unsigned +speex_bits_peek +speex_bits_advance +speex_bits_remaining +speex_bits_insert_terminator + +; +; speex_callbacks.h +; +speex_inband_handler +speex_std_mode_request_handler +speex_std_high_mode_request_handler +speex_std_char_handler +speex_default_user_handler +speex_std_low_mode_request_handler +speex_std_vbr_request_handler +speex_std_enh_request_handler +speex_std_vbr_quality_request_handler + +; +; speex_header.h +; +speex_init_header +speex_header_to_packet +speex_packet_to_header + +; +; speex_stereo.h +; +speex_stereo_state_init +speex_stereo_state_reset +speex_stereo_state_destroy +speex_encode_stereo +speex_encode_stereo_int +speex_decode_stereo +speex_decode_stereo_int +speex_std_stereo_request_handler diff --git a/libs/speex/win32/libspeex/Makefile.am b/libs/speex/win32/libspeex/Makefile.am index 9430c78ce3..9cf4e85137 100644 --- a/libs/speex/win32/libspeex/Makefile.am +++ b/libs/speex/win32/libspeex/Makefile.am @@ -3,4 +3,4 @@ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = libspeex.dsp libspeex.dsw libspeex_dynamic.dsp speex.def +EXTRA_DIST = libspeex.dsw libspeex.dsp libspeex_dynamic.dsp libspeexdsp.dsp libspeexdsp_dynamic.dsp diff --git a/libs/speex/win32/libspeex/libspeex.dsp b/libs/speex/win32/libspeex/libspeex.dsp index 47a8b5c5b9..9cfa169296 100644 --- a/libs/speex/win32/libspeex/libspeex.dsp +++ b/libs/speex/win32/libspeex/libspeex.dsp @@ -42,7 +42,8 @@ RSC=rc.exe # PROP Target_Dir "" F90=df.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /GX /Ox /Ot /Og /Oi /Ob2 /I "../../include" /I "../" /D inline=__inline /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c +# ADD CPP /nologo /MD /GX- /O2 /Ob2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe @@ -50,7 +51,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeex.lib" !ELSEIF "$(CFG)" == "libspeex - Win32 Debug" @@ -66,7 +67,8 @@ LIB32=link.exe -lib # PROP Target_Dir "" F90=df.exe # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /GX /Ox /Ot /Og /Oi /Ob2 /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX- /Zi /Od /Ob2 /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe @@ -74,7 +76,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeex.lib" !ENDIF @@ -159,23 +161,15 @@ SOURCE=..\..\libspeex\ltp.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\math_approx.c -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\misc.c -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\modes.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\nb_celp.c +SOURCE=..\..\libspeex\modes_wb.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\preprocess.c +SOURCE=..\..\libspeex\nb_celp.c # End Source File # Begin Source File @@ -187,10 +181,6 @@ SOURCE=..\..\libspeex\sb_celp.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\smallft.c -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\speex.c # End Source File # Begin Source File @@ -213,20 +203,44 @@ SOURCE=..\..\libspeex\vbr.c SOURCE=..\..\libspeex\vq.c # End Source File +# Begin Source File + +SOURCE=..\..\libspeex\window.c +# End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\cb_search.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\cb_search_sse.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\filters.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\filters_sse.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\lpc.h # End Source File # Begin Source File @@ -239,7 +253,11 @@ SOURCE=..\..\libspeex\ltp.h # End Source File # Begin Source File -SOURCE=..\..\libspeex\misc.h +SOURCE=..\..\libspeex\ltp_sse.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h # End Source File # Begin Source File @@ -251,6 +269,10 @@ SOURCE=..\..\libspeex\nb_celp.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\quant_lsp.h # End Source File # Begin Source File @@ -259,34 +281,6 @@ SOURCE=..\..\libspeex\sb_celp.h # End Source File # Begin Source File -SOURCE=..\..\libspeex\smallft.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_bits.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_callbacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_denoise.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_header.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_stereo.h -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\stack_alloc.h # End Source File # Begin Source File @@ -297,6 +291,42 @@ SOURCE=..\..\libspeex\vbr.h SOURCE=..\..\libspeex\vq.h # End Source File +# Begin Source File + +SOURCE=..\..\libspeex\vq_sse.h +# End Source File # End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_callbacks.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_header.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_stereo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File # End Target # End Project diff --git a/libs/speex/win32/libspeex/libspeex.dsw b/libs/speex/win32/libspeex/libspeex.dsw index 9fb56fefec..ff24f2a89e 100644 --- a/libs/speex/win32/libspeex/libspeex.dsw +++ b/libs/speex/win32/libspeex/libspeex.dsw @@ -27,6 +27,30 @@ Package=<4> ############################################################################### +Project: "libspeexdsp"=.\libspeexdsp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "libspeexdsp_dynamic"=.\libspeexdsp_dynamic.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Global: Package=<5> diff --git a/libs/speex/win32/libspeex/libspeex_dynamic.dsp b/libs/speex/win32/libspeex/libspeex_dynamic.dsp index 5e00972883..cd1945ca69 100644 --- a/libs/speex/win32/libspeex/libspeex_dynamic.dsp +++ b/libs/speex/win32/libspeex/libspeex_dynamic.dsp @@ -43,7 +43,8 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /D "HAVE_CONFIG_H" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" @@ -53,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/libspeex.dll" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\bin\libspeex.dll" /implib:"..\..\lib\libspeex.lib" !ELSEIF "$(CFG)" == "libspeex_dynamic - Win32 Debug" @@ -69,7 +70,8 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /D "HAVE_CONFIG_H" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /GZ /c +# SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -79,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/libspeex.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\bin\libspeex.dll" /implib:"..\..\lib\libspeex.lib" /pdbtype:sept !ENDIF @@ -89,7 +91,7 @@ LINK32=link.exe # Name "libspeex_dynamic - Win32 Debug" # Begin Group "Source Files" -# PROP Default_Filter "" +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\libspeex\bits.c @@ -164,23 +166,15 @@ SOURCE=..\..\libspeex\ltp.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\math_approx.c -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\misc.c -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\modes.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\nb_celp.c +SOURCE=..\..\libspeex\modes_wb.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\preprocess.c +SOURCE=..\..\libspeex\nb_celp.c # End Source File # Begin Source File @@ -192,18 +186,10 @@ SOURCE=..\..\libspeex\sb_celp.c # End Source File # Begin Source File -SOURCE=..\..\libspeex\smallft.c -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\speex.c # End Source File # Begin Source File -SOURCE=.\speex.def -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\speex_callbacks.c # End Source File # Begin Source File @@ -222,20 +208,44 @@ SOURCE=..\..\libspeex\vbr.c SOURCE=..\..\libspeex\vq.c # End Source File +# Begin Source File + +SOURCE=..\..\libspeex\window.c +# End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\cb_search.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\cb_search_sse.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\filters.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\filters_sse.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\lpc.h # End Source File # Begin Source File @@ -248,7 +258,11 @@ SOURCE=..\..\libspeex\ltp.h # End Source File # Begin Source File -SOURCE=..\..\libspeex\misc.h +SOURCE=..\..\libspeex\ltp_sse.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h # End Source File # Begin Source File @@ -260,6 +274,10 @@ SOURCE=..\..\libspeex\nb_celp.h # End Source File # Begin Source File +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + SOURCE=..\..\libspeex\quant_lsp.h # End Source File # Begin Source File @@ -268,34 +286,6 @@ SOURCE=..\..\libspeex\sb_celp.h # End Source File # Begin Source File -SOURCE=..\..\libspeex\smallft.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_bits.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_callbacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_denoise.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_header.h -# End Source File -# Begin Source File - -SOURCE=..\..\libspeex\speex_stereo.h -# End Source File -# Begin Source File - SOURCE=..\..\libspeex\stack_alloc.h # End Source File # Begin Source File @@ -306,6 +296,46 @@ SOURCE=..\..\libspeex\vbr.h SOURCE=..\..\libspeex\vq.h # End Source File +# Begin Source File + +SOURCE=..\..\libspeex\vq_sse.h +# End Source File # End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_callbacks.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_header.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_stereo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# Begin Source File + +SOURCE=..\libspeex.def +# End Source File # End Target # End Project diff --git a/libs/speex/win32/libspeex/libspeexdsp.dsp b/libs/speex/win32/libspeex/libspeexdsp.dsp new file mode 100644 index 0000000000..0e39adade6 --- /dev/null +++ b/libs/speex/win32/libspeex/libspeexdsp.dsp @@ -0,0 +1,224 @@ +# Microsoft Developer Studio Project File - Name="libspeexdsp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libspeexdsp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp.mak" CFG="libspeexdsp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libspeexdsp - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libspeexdsp - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libspeexdsp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W1 /GX- /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeexdsp.lib" + +!ELSEIF "$(CFG)" == "libspeexdsp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libspeexdsp___Win32_Debug" +# PROP BASE Intermediate_Dir "libspeexdsp___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "libspeexdsp___Win32_Debug" +# PROP Intermediate_Dir "libspeexdsp___Win32_Debug" +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX- /Zi /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeexdsp.lib" + +!ENDIF + +# Begin Target + +# Name "libspeexdsp - Win32 Release" +# Name "libspeexdsp - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\libspeex\buffer.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\jitter.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\mdf.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\preprocess.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\resample.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\libspeex\_kiss_fft_guts.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\pseudofloat.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.h +# End Source File +# End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_echo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_jitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_preprocess.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_resampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# End Target +# End Project diff --git a/libs/speex/win32/libspeex/libspeexdsp_dynamic.dsp b/libs/speex/win32/libspeex/libspeexdsp_dynamic.dsp new file mode 100644 index 0000000000..1a1a211577 --- /dev/null +++ b/libs/speex/win32/libspeex/libspeexdsp_dynamic.dsp @@ -0,0 +1,233 @@ +# Microsoft Developer Studio Project File - Name="libspeexdsp_dynamic" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=libspeexdsp_dynamic - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp_dynamic.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp_dynamic.mak" CFG="libspeexdsp_dynamic - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libspeexdsp_dynamic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libspeexdsp_dynamic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libspeexdsp_dynamic - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libspeexdsp_dynamic___Win32_Release" +# PROP BASE Intermediate_Dir "libspeexdsp_dynamic___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Dynamic_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\bin\libspeexdsp.dll" /implib:"..\..\lib\libspeexdsp.lib" + +!ELSEIF "$(CFG)" == "libspeexdsp_dynamic - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libspeexdsp_dynamic___Win32_Debug" +# PROP BASE Intermediate_Dir "libspeexdsp_dynamic___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Dynamic_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\bin\libspeexdsp.dll" /implib:"..\..\lib\libspeexdsp.lib" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "libspeexdsp_dynamic - Win32 Release" +# Name "libspeexdsp_dynamic - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\libspeex\buffer.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\jitter.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\mdf.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\preprocess.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\resample.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\libspeex\_kiss_fft_guts.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\pseudofloat.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_buffer.h +# End Source File +# End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_echo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_jitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_preprocess.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_resampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# Begin Source File + +SOURCE=..\libspeexdsp.def +# End Source File +# End Target +# End Project diff --git a/libs/speex/win32/libspeexdsp.def b/libs/speex/win32/libspeexdsp.def new file mode 100644 index 0000000000..bea3358b9a --- /dev/null +++ b/libs/speex/win32/libspeexdsp.def @@ -0,0 +1,72 @@ +LIBRARY libspeexdsp +EXPORTS + + +; +; speex_buffer.h +; +speex_buffer_init +speex_buffer_destroy +speex_buffer_write +speex_buffer_writezeros +speex_buffer_read +speex_buffer_get_available +speex_buffer_resize + +; +; speex_echo.h +; +speex_echo_state_init +speex_echo_state_destroy +speex_echo_cancellation +speex_echo_cancel +speex_echo_capture +speex_echo_playback +speex_echo_state_reset +speex_echo_ctl + +; +; speex_jitter.h +; +jitter_buffer_init +jitter_buffer_reset +jitter_buffer_destroy +jitter_buffer_put +jitter_buffer_get +jitter_buffer_get_pointer_timestamp +jitter_buffer_tick +jitter_buffer_update_delay + +; +; speex_preprocess.h +; +speex_preprocess_state_init +speex_preprocess_state_destroy +speex_preprocess_run +speex_preprocess +speex_preprocess_estimate_update +speex_preprocess_ctl + +; +; speex_resampler.h +; +speex_resampler_init +speex_resampler_init_frac +speex_resampler_destroy +speex_resampler_process_float +speex_resampler_process_int +speex_resampler_process_interleaved_float +speex_resampler_process_interleaved_int +speex_resampler_set_rate +speex_resampler_get_rate +speex_resampler_set_rate_frac +speex_resampler_get_ratio +speex_resampler_set_quality +speex_resampler_get_quality +speex_resampler_set_input_stride +speex_resampler_get_input_stride +speex_resampler_set_output_stride +speex_resampler_get_output_stride +speex_resampler_skip_zeros +speex_resampler_reset_mem +speex_resampler_strerror diff --git a/libs/speex/win32/speexdec/speexdec.dsp b/libs/speex/win32/speexdec/speexdec.dsp index 64fcd462e8..10b732d2a3 100644 --- a/libs/speex/win32/speexdec/speexdec.dsp +++ b/libs/speex/win32/speexdec/speexdec.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /GX /O2 /I "../../libspeex" /I "../../../ogg/include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /GX /O2 /I "../../../libogg/include" /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMT.lib" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMT.lib" /out:"../../bin/speexdec.exe" !ELSEIF "$(CFG)" == "speexdec - Win32 Debug" @@ -66,7 +66,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../libspeex" /I "../../../ogg/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../libogg/include" /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe @@ -74,7 +74,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/speexdec.exe" /pdbtype:sept !ENDIF diff --git a/libs/speex/win32/speexdec/speexdec.dsw b/libs/speex/win32/speexdec/speexdec.dsw index 37f2d1f213..a7de36240a 100644 --- a/libs/speex/win32/speexdec/speexdec.dsw +++ b/libs/speex/win32/speexdec/speexdec.dsw @@ -15,7 +15,7 @@ Package=<4> ############################################################################### -Project: "ogg_static"="..\..\..\MYOV-1.0\ogg\win32\ogg_static.dsp" - Package Owner=<4> +Project: "ogg_static"="..\..\..\libogg\win32\ogg_static.dsp" - Package Owner=<4> Package=<5> {{{ diff --git a/libs/speex/win32/speexenc/speexenc.dsp b/libs/speex/win32/speexenc/speexenc.dsp index 4b9dd89681..eeae18e1b0 100644 --- a/libs/speex/win32/speexenc/speexenc.dsp +++ b/libs/speex/win32/speexenc/speexenc.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /GX /Ox /Ot /Og /Oi /Ob2 /I "../../libspeex" /I "../../../ogg/include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /GX /Ox /Ot /Og /Oi /Ob2 /I "../" /I "../../include" /I "../../../libogg/include" /D "HAVE_CONFIG_H" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMT.lib" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMT.lib" /out:"../../bin/speexenc.exe" !ELSEIF "$(CFG)" == "speexenc - Win32 Debug" @@ -66,7 +66,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../libspeex" /I "../../../ogg/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../" /I "../../include" /I "../../../libogg/include" /D "HAVE_CONFIG_H" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe @@ -74,7 +74,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/speexenc.exe" /pdbtype:sept !ENDIF @@ -95,6 +95,10 @@ SOURCE=..\..\src\getopt1.c # End Source File # Begin Source File +SOURCE=..\..\src\skeleton.c +# End Source File +# Begin Source File + SOURCE=..\..\src\speexenc.c # End Source File # Begin Source File @@ -111,6 +115,10 @@ SOURCE=..\..\src\getopt_win.h # End Source File # Begin Source File +SOURCE=..\..\src\skeleton.h +# End Source File +# Begin Source File + SOURCE=..\..\src\wav_io.h # End Source File # End Group diff --git a/libs/speex/win32/speexenc/speexenc.dsw b/libs/speex/win32/speexenc/speexenc.dsw index 55aa72dbd8..d1e77b8a23 100644 --- a/libs/speex/win32/speexenc/speexenc.dsw +++ b/libs/speex/win32/speexenc/speexenc.dsw @@ -15,7 +15,19 @@ Package=<4> ############################################################################### -Project: "ogg_static"="..\..\..\MYOV-1.0\ogg\win32\ogg_static.dsp" - Package Owner=<4> +Project: "libspeexdsp"=..\libspeex\libspeexdsp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "ogg_static"=..\..\..\libogg\win32\ogg_static.dsp - Package Owner=<4> Package=<5> {{{ @@ -41,6 +53,9 @@ Package=<4> Begin Project Dependency Project_Dep_Name ogg_static End Project Dependency + Begin Project Dependency + Project_Dep_Name libspeexdsp + End Project Dependency }}} ###############################################################################