diff options
123 files changed, 9177 insertions, 4351 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..636dd55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +*.o +*.lo +Makefile.in +*~ +*.orig +fixed +float +Speex.kdevelop.pcs +Speex.kdevses +aclocal.m4 +autom4te.cache +config.guess +config.h.in +config.sub +configure +depcomp +install-sh +ltmain.sh +missing +Makefile +.deps +.libs +*.la +work +Speex.spec +config.h +config.log +config.status +include/speex/speex_config_types.h +*.swp +testdenoise +testecho +testenc +testenc_uwb +testenc_wb +libtool +speex.pc +speexdec +src/speexenc +stamp-* +patches @@ -1,10 +1,11 @@ -Copyright 2002-2007 - Xiph.org Foundation - Jean-Marc Valin - David Rowe - EpicGames - Analog Devices - Commonwealth Scientific and Industrial Research Organisation (CSIRO) +Copyright 2002-2007 Xiph.org Foundation +Copyright 2002-2007 Jean-Marc Valin +Copyright 2005-2007 Analog Devices Inc. +Copyright 2005-2007 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/Makefile.am b/Makefile.am index 5908efb..4b99faf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,7 +8,7 @@ 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 diff --git a/Speex.kdevelop b/Speex.kdevelop index 46524c4..1b3d683 100644 --- a/Speex.kdevelop +++ b/Speex.kdevelop @@ -9,16 +9,16 @@ <ignoreparts/> <projectdirectory>.</projectdirectory> <absoluteprojectpath>false</absoluteprojectpath> - <description></description> + <description/> <secondaryLanguages/> <versioncontrol>kdevsubversion</versioncontrol> - <defaultencoding></defaultencoding> + <defaultencoding/> <projectname>Speex</projectname> </general> <kdevautoproject> <general> <activetarget>libspeex/libspeex.la</activetarget> - <useconfiguration>default</useconfiguration> + <useconfiguration>float</useconfiguration> </general> <run> <mainprogram>src/Speex</mainprogram> @@ -32,21 +32,40 @@ <autokdesu>false</autokdesu> </run> <configurations> - <optimized> - <builddir>optimized</builddir> - <ccompiler>GccOptions</ccompiler> - <cxxcompiler>GppOptions</cxxcompiler> - <f77compiler>G77Options</f77compiler> - <cflags>-O2 -g0</cflags> - </optimized> - <debug> - <configargs>--enable-debug=full</configargs> - <builddir>debug</builddir> - <ccompiler>GccOptions</ccompiler> - <cxxcompiler>GppOptions</cxxcompiler> - <f77compiler>G77Options</f77compiler> - <cflags>-O0 -g3</cflags> - </debug> + <float> + <builddir>float</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevpgf77options</f77compiler> + <cflags>-O2 -g -Wall</cflags> + <envvars/> + <configargs>--disable-shared</configargs> + <topsourcedir/> + <cppflags/> + <ldflags/> + <ccompilerbinary/> + <cxxcompilerbinary/> + <f77compilerbinary/> + <cxxflags/> + <f77flags/> + </float> + <fixed> + <configargs>--enable-fixed-point --disable-shared</configargs> + <builddir>fixed</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevpgf77options</f77compiler> + <cflags>-O2 -g -Wall</cflags> + <envvars/> + <topsourcedir/> + <cppflags/> + <ldflags/> + <ccompilerbinary/> + <cxxcompilerbinary/> + <f77compilerbinary/> + <cxxflags/> + <f77flags/> + </fixed> <default> <envvars/> </default> @@ -68,10 +87,10 @@ <general> <dbgshell>libtool</dbgshell> <programargs/> - <gdbpath></gdbpath> - <configGdbScript></configGdbScript> - <runShellScript></runShellScript> - <runGdbScript></runGdbScript> + <gdbpath/> + <configGdbScript/> + <runShellScript/> + <runGdbScript/> <breakonloadinglibs>true</breakonloadinglibs> <separatetty>false</separatetty> <floatingtoolbar>false</floatingtoolbar> @@ -117,6 +136,8 @@ <usePermanentCaching>true</usePermanentCaching> <alwaysIncludeNamespaces>true</alwaysIncludeNamespaces> <includePaths>.;</includePaths> + <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental> + <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental> </codecompletion> <qt> <used>false</used> @@ -125,11 +146,11 @@ <includestyle>3</includestyle> <designerintegration>EmbeddedKDevDesigner</designerintegration> <qmake>/usr/share/qt3/bin/qmake</qmake> - <designer></designer> + <designer>/usr/bin/designer-qt3</designer> <designerpluginpaths/> </qt> <creategettersetter> - <prefixGet></prefixGet> + <prefixGet/> <prefixSet>set</prefixSet> <prefixVariable>m_,_</prefixVariable> <parameterName>theValue</parameterName> diff --git a/Speex.spec.in b/Speex.spec.in index 416f435..bccfc23 100644 --- a/Speex.spec.in +++ b/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 @@ -1,49 +1,39 @@ -For 1.2beta2: -*Use full complex values for fft results? -*get rid of crap that shouldn't be exposed in speex.h -*Reduce wideband RAM requirements -*Make foreground filter 16 bits in AEC. -*Enable resampler in build -*Add dumping of data for debug purposes. -*remove wideband pseudo-stack -*pitch prediction saturation to prevent NaN-based DoS attacks. -*Fix jitter buffer - -speex_decoder_ctl() call to detect silence -Complete resampler API (error codes) -Fix resampler corner case -Use lower sinc oversampling when down-sampling -**Fix register issue on Blackfin -Merge TriMedia stuff -Make it possible to decode a "raw" packet with SpeexBits +For 1.2beta3: Control delay in new AEC API. +Implement speex_header_free() +better error reporting +get rid of floats in initialisation (make the lag window a const array) +split encoder and decoder? +improve float<->int conversion +NaN checks? + -Later: +Eventually: +Fix last frame of speexenc +Merge TriMedia stuff +packet dump Do VAD properly Warning/error handling --enable-{aec,preprocessor,jitter,resampler} - Optimisations - Add restrict in a few places? -- enable 4x4 version of pitch_xcorr()? +- enable 4x4 version of pitch_xcorr() at least on some archs? Would be nice: -Implement wideband split as IIR instead of QMF. +Implement wideband split as IIR instead of QMF? Allocator override (speex_lib_ctl?) -Better error handling Fixed-point: - - Wideband + - VBR + - encoder init (lag_window, lsp) - Jitter buffer + - AGC Denoiser: - Better noise adaptation AGC: - Use median filtering instead of "non-linear mean"? -Features --Improve error handling (with perror-like call?) - Standards -Complete Speex RTP profile -MIME type registration @@ -119,4 +119,5 @@ echo " autoconf" autoconf || exit 1 cd $olddir -$srcdir/configure --enable-maintainer-mode "$@" && echo +#$srcdir/configure --enable-maintainer-mode "$@" && echo +echo "You can now run configure" diff --git a/configure.ac b/configure.ac index 114eef0..3528d8c 100644 --- a/configure.ac +++ b/configure.ac @@ -6,11 +6,11 @@ AM_CONFIG_HEADER([config.h]) SPEEX_MAJOR_VERSION=1 SPEEX_MINOR_VERSION=1 -SPEEX_MICRO_VERSION=14 -SPEEX_EXTRA_VERSION=-svn +SPEEX_MICRO_VERSION=15 +SPEEX_EXTRA_VERSION=-git #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.2beta3" SPEEX_LT_CURRENT=5 SPEEX_LT_REVISION=0 @@ -40,7 +40,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 +50,14 @@ has_var_arrays=no ) AC_MSG_RESULT($has_var_arrays) +AC_CHECK_HEADERS(alloca.h) AC_MSG_CHECKING(for alloca) -AC_TRY_COMPILE( [#include <alloca.h>], [ +AC_TRY_COMPILE( [ +#ifdef HAVE_ALLOCA_H +# include <alloca.h> +#endif +#include <stdlib.h> +], [ int foo=10; int *array = alloca(foo); ], @@ -89,16 +96,6 @@ 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]) @@ -113,6 +110,19 @@ fi AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point], [if test "$enableval" = yes; then 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])) + +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], @@ -125,7 +135,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" @@ -136,22 +146,12 @@ 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_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) @@ -186,13 +186,16 @@ AC_SUBST(SIZE16) AC_SUBST(SIZE32) 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 diff --git a/doc/Makefile.am b/doc/Makefile.am index a70a97b..d2896ef 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,5 +1,3 @@ -docdir=$(prefix)/share/doc/@PACKAGE@-@VERSION@ - doc_DATA = manual.pdf EXTRA_DIST = $(doc_DATA) diff --git a/doc/draft-ietf-avt-rtp-speex-01-tmp.txt b/doc/draft-ietf-avt-rtp-speex-01-tmp.txt new file mode 100644 index 0000000..1410b85 --- /dev/null +++ b/doc/draft-ietf-avt-rtp-speex-01-tmp.txt @@ -0,0 +1,1008 @@ + + + +AVT G. Herlein +Internet-Draft +Intended status: Standards Track J. Valin +Expires: October 24, 2007 University of Sherbrooke + A. Heggestad + April 22, 2007 + + + RTP Payload Format for the Speex Codec + draft-ietf-avt-rtp-speex-01 (non-final) + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on October 24, 2007. + +Copyright Notice + + Copyright (C) The Internet Society (2007). + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 1] + +Internet-Draft Speex April 2007 + + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 2] + +Internet-Draft Speex April 2007 + + +Editors Note + + All references to RFC XXXX are to be replaced by references to the + RFC number of this memo, when published. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. RTP usage for Speex . . . . . . . . . . . . . . . . . . . . . 6 + 3.1. RTP Speex Header Fields . . . . . . . . . . . . . . . . . 6 + 3.2. RTP payload format for Speex . . . . . . . . . . . . . . . 6 + 3.3. Speex payload . . . . . . . . . . . . . . . . . . . . . . 6 + 3.4. Example Speex packet . . . . . . . . . . . . . . . . . . . 7 + 3.5. Multiple Speex frames in a RTP packet . . . . . . . . . . 7 + 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 + 4.1. Media Type Registration . . . . . . . . . . . . . . . . . 9 + 4.1.1. Registration of media type audio/speex . . . . . . . . 9 + 5. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . . 11 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . 14 + 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 15 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 16 + 8.1. Normative References . . . . . . . . . . . . . . . . . . . 16 + 8.2. Informative References . . . . . . . . . . . . . . . . . . 16 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 17 + Intellectual Property and Copyright Statements . . . . . . . . . . 18 + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 3] + +Internet-Draft Speex April 2007 + + +1. Introduction + + Speex is based on the CELP [CELP] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or ultra- + wideband (nominal 32kHz). The main characteristics can be summarized + as follows: + + o Free software/open-source + + o Integration of wideband and narrowband in the same bit-stream + + o Wide range of bit-rates available + + o Dynamic bit-rate switching and variable bit-rate (VBR) + + o Voice Activity Detection (VAD, integrated with VBR) + + o Variable complexity + + To be compliant with this specification, implementations MUST support + 8 kHz sampling rate (narrowband)" and SHOULD support 8 kbps bitrate. + The sampling rate MUST be 8, 16 or 32 kHz. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 4] + +Internet-Draft Speex April 2007 + + +2. Terminology + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC2119 [RFC2119] and + indicate requirement levels for compliant RTP implementations. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 5] + +Internet-Draft Speex April 2007 + + +3. RTP usage for Speex + +3.1. RTP Speex Header Fields + + The RTP header is defined in the RTP specification [RFC3550]. This + section defines how fields in the RTP header are used. + + Payload Type (PT): The assignment of an RTP payload type for this + packet format is outside the scope of this document; it is + specified by the RTP profile under which this payload format is + used, or signaled dynamically out-of-band (e.g., using SDP). + + Marker (M) bit: The M bit is set to one to indicate that the RTP + packet payload contains at least one complete frame + + Extension (X) bit: Defined by the RTP profile used. + + Timestamp: A 32-bit word that corresponds to the sampling instant + for the first frame in the RTP packet. + +3.2. RTP payload format for Speex + + The RTP payload for Speex has the format shown in Figure 1. No + additional header fields specific to this payload format are + required. For RTP based transportation of Speex encoded audio the + standard RTP header [RFC3550] is followed by one or more payload data + blocks. An optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1: RTP payload for Speex + +3.3. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [speexenc], and present the same sequence to the decoder. + The payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. 110 + + + +Herlein, et al. Expires October 24, 2007 [Page 6] + +Internet-Draft Speex April 2007 + + + octets and the total number of Speex frames SHOULD be kept less than + the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + Sampling rate values of 8000, 16000 or 32000 Hz MUST be used. Any + other sampling rates MUST NOT be used. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + packet, and only to ensure the packet contents ends on an octet + boundary. + +3.4. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.5. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [speexenc] are able to detect the bitrate from the + + + +Herlein, et al. Expires October 24, 2007 [Page 7] + +Internet-Draft Speex April 2007 + + + payload and are responsible for detecting the 20 msec boundaries + between each frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex frame 1.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 1.. | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 8] + +Internet-Draft Speex April 2007 + + +4. IANA Considerations + + This document defines the Speex media type. + +4.1. Media Type Registration + + This section describes the media types and names associated with this + payload format. The section registers the media types, as per + RFC4288 [RFC4288] + +4.1.1. Registration of media type audio/speex + + Media type name: audio + + Media subtype name: speex + + Required parameters: + + None + + Optional parameters: + + ptime: see RFC 4566. SHOULD be a multiple of 20 msec. + + maxptime: see RFC 4566. SHOULD be a multiple of 20 msec. + + Encoding considerations: + + This media type is framed and binary, see section 4.8 in + [RFC4288]. + + Security considerations: See Section 6 + + Interoperability considerations: + + None. + + Published specification: RFC XXXX [This RFC]. + + Applications which use this media type: + + Audio streaming and conferencing applications. + + Additional information: none + + Person and email address to contact for further information : + + + + + +Herlein, et al. Expires October 24, 2007 [Page 9] + +Internet-Draft Speex April 2007 + + + Alfred E. Heggestad: aeh@db.org + + Intended usage: COMMON + + Restrictions on usage: + + This media type depends on RTP framing, and hence is only defined + for transfer via RTP [RFC3550]. Transport within other framing + protocols is not defined at this time. + + Author: Alfred E. Heggestad + + Change controller: + + IETF Audio/Video Transport working group delegated from the IESG. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 10] + +Internet-Draft Speex April 2007 + + +5. SDP usage of Speex + + When conveying information by SDP [RFC4566], the encoding name MUST + be set to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 could + have been chosen (the allowed range for dynamic types). + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [RFC4566]. The + following example illustrates the case where the offerer cannot + receive more than 10 kbit/s. + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than 10 + kbit/s. Note that the "b=" constraint also applies on all payload + types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder is + to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + + sr: actual sample rate in Hz. + + + ebw: encoding bandwidth - either 'narrow' or 'wide' or 'ultra' + (corresponds to nominal 8000, 16000, and 32000 Hz sampling rates). + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 11] + +Internet-Draft Speex April 2007 + + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults to + off). If on, variable bit rate is enabled. If off, disabled. If + set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + that period. + + + cng: comfort noise generation - either 'on' or 'off'. If off then + silence frames will be silent; if 'on' then those frames will be + filled with comfort noise. + + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} defaults to 3 + in narrowband, 6 in wide and ultra-wide. + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive a Speex + stream at 8000Hz, but only using speex mode 4. + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + a=fmtp:97 mode=any;mode=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be ignored and clients MUST use the + default value of 20 instead. + + Implementations SHOULD support ptime of 20 msec (i.e. one frame per + packet) + + In the example below the ptime value is set to 40, indicating that + + + +Herlein, et al. Expires October 24, 2007 [Page 12] + +Internet-Draft Speex April 2007 + + + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the life + of an RTP session the ptime value changes, when there are multiple + Speex frames for example, the SDP value must also reflect the new + value. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 13] + +Internet-Draft Speex April 2007 + + +6. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [RFC3550], and any appropriate RTP profile. This + implies that confidentiality of the media streams is achieved by + encryption. Because the data compression used with this payload + format is applied end-to-end, encryption may be performed after + compression so there is no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 14] + +Internet-Draft Speex April 2007 + + +7. Acknowledgements + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + + Thanks to former authors of this document; Simon Morlat, Roger + Hardiman, Phil Kerr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 15] + +Internet-Draft Speex April 2007 + + +8. References + +8.1. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. + Jacobson, "RTP: A Transport Protocol for Real-Time + Applications", STD 64, RFC 3550, July 2003. + + [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session + Description Protocol", RFC 4566, July 2006. + +8.2. Informative References + + [CELP] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + [RFC4288] Freed, N. and J. Klensin, "Media Type Specifications and + Registration Procedures", BCP 13, RFC 4288, December 2005. + + [speexenc] + Valin, J., "Speexenc/speexdec, reference command-line + encoder/decoder", Speex website http://www.speex.org/. + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 16] + +Internet-Draft Speex April 2007 + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + Email: gherlein@herlein.com + + + Jean-Marc Valin + University of Sherbrooke + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universite + Sherbrooke, Quebec J1K 2R1 + Canada + + Email: jean-marc.valin@usherbrooke.ca + + + Alfred E. Heggestad + Biskop J. Nilssonsgt. 20a + Oslo 0659 + Norway + + Email: aeh@db.org + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 17] + +Internet-Draft Speex April 2007 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2007). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Acknowledgment + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + +Herlein, et al. Expires October 24, 2007 [Page 18] + diff --git a/doc/manual.lyx b/doc/manual.lyx index b0c6a4a..671463d 100644 --- a/doc/manual.lyx +++ b/doc/manual.lyx @@ -1,17 +1,25 @@ -#LyX 1.4.4 created this file. For more info see http://www.lyx.org/ -\lyxformat 245 +#LyX 1.5.0 created this file. For more info see http://www.lyx.org/ +\lyxformat 276 \begin_document \begin_header \textclass scrbook \language english \inputencoding auto -\fontscheme pslatex +\font_roman times +\font_sans helvet +\font_typewriter courier +\font_default_family default +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 \graphics default \paperfontsize 10 \spacing single \papersize letterpaper \use_geometry true \use_amsmath 2 +\use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait @@ -27,8 +35,11 @@ \papercolumns 1 \papersides 1 \paperpagestyle headings +\listings_params "basicstyle={\ttfamily},breaklines=true,language=C,xleftmargin=0mm" \tracking_changes false -\output_changes true +\output_changes false +\author "" +\author "" \end_header \begin_body @@ -36,7 +47,7 @@ \begin_layout Title The Speex Codec Manual \newline -For Version 1.2 Beta 2 +Version 1.2 Beta 3 \end_layout \begin_layout Author @@ -80,7 +91,7 @@ on License". \newpage -\begin_inset LatexCommand \tableofcontents{} +\begin_inset LatexCommand tableofcontents \end_inset @@ -110,10 +121,10 @@ http://www.speex.org/ \family default ) exists because there is a need for a speech codec that is open-source and free from software patent royalties. - These are essential conditions for being usable by any open-source software. + These are essential conditions for being usable in any open-source software. In essence, Speex is to speech what Vorbis is to audio/music. Unlike many other speech codecs, Speex is not designed for mobile phones - but rather for packet networks and voice over IP (VoIP) application. + but rather for packet networks and voice over IP (VoIP) applications. File-based compression is of course also supported. \end_layout @@ -131,13 +142,14 @@ Designing for VoIP instead of mobile phones means that Speex is robust to lost packets, but not to corrupted ones. This is based on the assumption that in VoIP, packets either arrive unaltered or don't arrive at all. - Because Speex is targeted at a wide range of devices, it has modest complexity - (variable) and memory footprint. + Because Speex is targeted at a wide range of devices, it has modest (adjustable +) complexity and a small memory footprint. \end_layout \begin_layout Standard All the design goals led to the choice of CELP -\begin_inset LatexCommand \index{CELP} +\begin_inset LatexCommand index +name "CELP" \end_inset @@ -151,7 +163,8 @@ All the design goals led to the choice of CELP \begin_layout Section Getting help -\begin_inset LatexCommand \label{sec:Getting-help} +\begin_inset LatexCommand label +name "sec:Getting-help" \end_inset @@ -195,7 +208,7 @@ Before asking for help (mailing list or IRC), \series bold it is important to first read this manual \series default -. + (OK, so if you made it here it's already a good sign). It is generally considered rude to ask on a mailing list about topics that are clearly detailed in the documentation. On the other hand, it's perfectly OK (and encouraged) to ask for clarifications @@ -211,7 +224,8 @@ Here are some additional guidelines related to the mailing list. Before reporting bugs in Speex to the list, it is strongly recommended (if possible) to first test whether these bugs can be reproduced using the speexenc and speexdec (see Section -\begin_inset LatexCommand \ref{sec:Command-line-encoder/decoder} +\begin_inset LatexCommand ref +reference "sec:Command-line-encoder/decoder" \end_inset @@ -228,31 +242,36 @@ About this document \begin_layout Standard This document is divided in the following way. Section -\begin_inset LatexCommand \ref{sec:Feature-description} +\begin_inset LatexCommand ref +reference "sec:Feature-description" \end_inset describes the different Speex features and defines many basic terms that are used throughout this manual. Section -\begin_inset LatexCommand \ref{sec:Command-line-encoder/decoder} +\begin_inset LatexCommand ref +reference "sec:Command-line-encoder/decoder" \end_inset documents the standard command-line tools provided in the Speex distribution. Section -\begin_inset LatexCommand \ref{sec:Programming-with-Speex} +\begin_inset LatexCommand ref +reference "sec:Programming-with-Speex" \end_inset includes detailed instructions about programming using the libspeex -\begin_inset LatexCommand \index{libspeex} +\begin_inset LatexCommand index +name "libspeex" \end_inset API. Section -\begin_inset LatexCommand \ref{sec:Formats-and-standards} +\begin_inset LatexCommand ref +reference "sec:Formats-and-standards" \end_inset @@ -267,17 +286,20 @@ The three last sections describe the algorithms used in Speex. They are intended for people who want to understand how Speex really works and/or want to do research based on Speex. Section -\begin_inset LatexCommand \ref{sec:Introduction-to-CELP} +\begin_inset LatexCommand ref +reference "sec:Introduction-to-CELP" \end_inset explains the general idea behind CELP, while sections -\begin_inset LatexCommand \ref{sec:Speex-narrowband-mode} +\begin_inset LatexCommand ref +reference "sec:Speex-narrowband-mode" \end_inset and -\begin_inset LatexCommand \ref{sec:Speex-wideband-mode} +\begin_inset LatexCommand ref +reference "sec:Speex-wideband-mode" \end_inset @@ -292,7 +314,8 @@ The three last sections describe the algorithms used in Speex. \begin_layout Chapter Codec description -\begin_inset LatexCommand \label{sec:Feature-description} +\begin_inset LatexCommand label +name "sec:Feature-description" \end_inset @@ -316,7 +339,8 @@ Before introducing all the Speex features, here are some concepts in speech \begin_layout Subsection* Sampling rate -\begin_inset LatexCommand \index{sampling rate} +\begin_inset LatexCommand index +name "sampling rate" \end_inset @@ -344,17 +368,20 @@ The sampling rate expressed in Hertz (Hz) is the number of samples taken Speex is mainly designed for three different sampling rates: 8 kHz, 16 kHz, and 32 kHz. These are respectively refered to as narrowband -\begin_inset LatexCommand \index{narrowband} +\begin_inset LatexCommand index +name "narrowband" \end_inset , wideband -\begin_inset LatexCommand \index{wideband} +\begin_inset LatexCommand index +name "wideband" \end_inset and ultra-wideband -\begin_inset LatexCommand \index{ultra-wideband} +\begin_inset LatexCommand index +name "ultra-wideband" \end_inset @@ -384,7 +411,10 @@ kilo \series bold bits \series default - per second +\emph default + +\emph on +per second \emph default (k \series bold @@ -396,7 +426,10 @@ kilo \series bold bytes \series default - per second +\emph default + +\emph on +per second \emph default (k \series bold @@ -407,7 +440,8 @@ ps). \begin_layout Subsection* Quality -\begin_inset LatexCommand \index{quality} +\begin_inset LatexCommand index +name "quality" \end_inset @@ -422,7 +456,8 @@ Speex is a lossy codec, which means that it achives compression at the expense The Speex encoding process is controlled most of the time by a quality parameter that ranges from 0 to 10. In constant bit-rate -\begin_inset LatexCommand \index{constant bit-rate} +\begin_inset LatexCommand index +name "constant bit-rate" \end_inset @@ -433,7 +468,8 @@ Speex is a lossy codec, which means that it achives compression at the expense \begin_layout Subsection* Complexity -\begin_inset LatexCommand \index{complexity} +\begin_inset LatexCommand index +name "complexity" \end_inset @@ -458,7 +494,8 @@ bzip2 5 times higher than for complexity 1. In practice, the best trade-off is between complexity 2 and 4, though higher settings are often useful when encoding non-speech sounds like DTMF -\begin_inset LatexCommand \index{DTMF} +\begin_inset LatexCommand index +name "DTMF" \end_inset @@ -467,7 +504,8 @@ bzip2 \begin_layout Subsection* Variable Bit-Rate -\begin_inset LatexCommand \index{variable bit-rate} +\begin_inset LatexCommand index +name "variable bit-rate" \end_inset @@ -499,7 +537,8 @@ difficulty \begin_layout Subsection* Average Bit-Rate -\begin_inset LatexCommand \index{average bit-rate} +\begin_inset LatexCommand index +name "average bit-rate" \end_inset @@ -516,7 +555,8 @@ Average bit-rate solves one of the problems of VBR, as it dynamically adjusts \begin_layout Subsection* Voice Activity Detection -\begin_inset LatexCommand \index{voice activity detection} +\begin_inset LatexCommand index +name "voice activity detection" \end_inset @@ -543,7 +583,8 @@ comfort noise generation \begin_layout Subsection* Discontinuous Transmission -\begin_inset LatexCommand \index{discontinuous transmission} +\begin_inset LatexCommand index +name "discontinuous transmission" \end_inset @@ -559,7 +600,8 @@ Discontinuous transmission is an addition to VAD/VBR operation, that allows \begin_layout Subsection* Perceptual enhancement -\begin_inset LatexCommand \index{perceptual enhancement} +\begin_inset LatexCommand index +name "perceptual enhancement" \end_inset @@ -585,7 +627,8 @@ sounds \begin_layout Subsection* Latency and algorithmic delay -\begin_inset LatexCommand \index{algorithmic delay} +\begin_inset LatexCommand index +name "algorithmic delay" \end_inset @@ -619,12 +662,14 @@ The main characteristics of Speex can be summarized as follows: \begin_layout Itemize Free software/open-source -\begin_inset LatexCommand \index{open-source} +\begin_inset LatexCommand index +name "open-source" \end_inset , patent -\begin_inset LatexCommand \index{patent} +\begin_inset LatexCommand index +name "patent" \end_inset @@ -633,12 +678,14 @@ Free software/open-source \begin_layout Itemize Integration of narrowband -\begin_inset LatexCommand \index{narrowband} +\begin_inset LatexCommand index +name "narrowband" \end_inset and wideband -\begin_inset LatexCommand \index{wideband} +\begin_inset LatexCommand index +name "wideband" \end_inset @@ -651,7 +698,8 @@ Wide range of bit-rates available (from 2.15 kbps to 44 kbps) \begin_layout Itemize Dynamic bit-rate switching (AMR) and Variable Bit-Rate -\begin_inset LatexCommand \index{variable bit-rate} +\begin_inset LatexCommand index +name "variable bit-rate" \end_inset @@ -660,7 +708,8 @@ Dynamic bit-rate switching (AMR) and Variable Bit-Rate \begin_layout Itemize Voice Activity Detection -\begin_inset LatexCommand \index{voice activity detection} +\begin_inset LatexCommand index +name "voice activity detection" \end_inset @@ -669,7 +718,8 @@ Voice Activity Detection \begin_layout Itemize Variable complexity -\begin_inset LatexCommand \index{complexity} +\begin_inset LatexCommand index +name "complexity" \end_inset @@ -681,7 +731,7 @@ Embedded wideband structure (scalable sampling rate) \end_layout \begin_layout Itemize -Ultra-wideband mode at 32 kHz +Ultra-wideband sampling rate at 32 kHz \end_layout \begin_layout Itemize @@ -765,7 +815,8 @@ Acoustic Echo Canceller \begin_layout Standard In any hands-free communication system (Fig. -\begin_inset LatexCommand \ref{fig:Acoustic-echo-model} +\begin_inset LatexCommand ref +reference "fig:Acoustic-echo-model" \end_inset @@ -825,9 +876,13 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Acoustic echo model -\begin_inset LatexCommand \label{fig:Acoustic-echo-model} +\begin_inset LatexCommand label +name "fig:Acoustic-echo-model" \end_inset @@ -839,6 +894,27 @@ Acoustic echo model \end_layout +\end_inset + + +\end_layout + +\begin_layout Section +Resampler +\end_layout + +\begin_layout Standard +In some cases, it may be useful to convert audio from one sampling rate + to another. + There are many reasons for that. + It can be for mixing streams that have different sampling rates, for supporting + sampling rates that the soundcard doesn't support, for transcoding, etc. + That's why there is now a resampler that is part of the Speex project. + This resampler can be used to convert between any two arbitrary rates (the + ratio must only be a rational number) and there is control over the quality/com +plexity tradeoff. +\end_layout + \begin_layout Standard \newpage @@ -900,7 +976,8 @@ The options supported by the Speex configure script are: \begin_layout Description --enable-fixed-point -\begin_inset LatexCommand \index{fixed-point} +\begin_inset LatexCommand index +name "fixed-point" \end_inset @@ -920,7 +997,8 @@ The options supported by the Speex configure script are: \begin_layout Description --enable-fixed-point-debug Use only for debugging the fixed-point -\begin_inset LatexCommand \index{fixed-point} +\begin_inset LatexCommand index +name "fixed-point" \end_inset @@ -929,7 +1007,7 @@ The options supported by the Speex configure script are: \begin_layout Description --enable-epic-48k Enable a special (and non-compatible) 4.8 kbps narrowband - mode + mode (broken in 1.1.x and 1.2beta) \end_layout \begin_layout Description @@ -1032,6 +1110,205 @@ The source code directory include additional information for compiling on certain architectures or operating systems in README.xxx files. \end_layout +\begin_layout Section +Porting and Optimising +\end_layout + +\begin_layout Standard +Here are a few things to consider when porting or optimising Speex for a + new platform or an existing one. +\end_layout + +\begin_layout Subsection +CPU optimisation +\end_layout + +\begin_layout Standard +The single that will affect the CPU usage of Speex the most is whether it + is compiled for floating point or fixed-point. + If your CPU/DSP does not have a floating-point unit FPU, then compiling + as fixed-point will be orders of magnitudes faster. + If there is an FPU present, then it is important to test which version + is faster. + On the x86 architecture, floating-point is +\series bold +generally +\series default + faster, but not always. + To compile Speex as fixed-point, you need to pass --fixed-point to the + configure script or define the FIXED_POINT maccro for the compiler. +\end_layout + +\begin_layout Standard +Other important things to check on some DSP architectures are: +\end_layout + +\begin_layout Itemize +Make sure the cache is set to write-back mode +\end_layout + +\begin_layout Itemize +If the chip has SRAM instead of cache, make sure as much code and data are + in SRAM, rather than in RAM +\end_layout + +\begin_layout Standard +If you are going to be writing assembly, then the following functions are + +\series bold +usually +\series default + the first ones you should consider optimising: +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +filter_mem16() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +iir_mem16() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +pitch_xcorr() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +interp_pitch() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Memory optimisation +\end_layout + +\begin_layout Standard +Memory optimisation is mainly something that should be considered for small + embedded platforms. + For PCs, Speex is already so tiny that it's just not worth doing any of + the things suggested here. + There are several ways to reduce the memory usage of Speex, both in terms + of code size and data size. + For optimising code size, the trick is to first remove features you do + not need. + Some examples of things that can easily be disabled +\series bold +if you don't need them +\series default + are: +\end_layout + +\begin_layout Itemize +Wideband support (--disable-wideband) +\end_layout + +\begin_layout Itemize +Support for stereo (removing stereo.c) +\end_layout + +\begin_layout Itemize +VBR support (vbr.c and a few lines in nb_celp.c) +\end_layout + +\begin_layout Itemize +Static codebooks that are not needed for the bit-rates you are using (*_table.c + files) +\end_layout + +\begin_layout Standard +Speex also has several methods for allocating temporary arrays. + When using a compiler that supports C99 properly (as of 2007, Microsoft + compilers don't, but gcc does), it is best to define VAR_ARRAYS. + That makes use of the variable-size array feature of C99. + The next best is to define USE_ALLOCA so that Speex can use alloca() to + allocate the temporary arrays. + Note that on many systems, alloca() is buggy so it may not work. + If none of VAR_ARRAYS and USE_ALLOCA are defined, then Speex falls back + to allocating a large +\begin_inset Quotes eld +\end_inset + +scratch space +\begin_inset Quotes erd +\end_inset + + and doing its own internal allocation. + The main disadvantage of this solution is that it is wasteful. + It needs to allocate enough stack for the worst case scenario (worst bit-rate, + highest complexity setting, ...) and by default, the memory isn't shared between + multiple encoder/decoder states. + Still, if the +\begin_inset Quotes eld +\end_inset + +manual +\begin_inset Quotes erd +\end_inset + + allocation is the only option left, there are a few things that can be + improved. + By overriding the speex_alloc_scratch() call in os_support.h, it is possible + to always return the same memory area for all states +\begin_inset Foot +status collapsed + +\begin_layout Standard +In this case, one must be careful with threads +\end_layout + +\end_inset + +. + In addition to that, by redefining the NB_ENC_STACK and NB_DEC_STACK (or + similar for wideband), it is possible to only allocate memory for a scenario + that is known in advange. + In this case, it is important to measure the amount of memory required + for the specific sampling rate, bit-rate and complexity level being used. +\end_layout + \begin_layout Standard \newpage @@ -1040,7 +1317,8 @@ The source code directory include additional information for compiling on \begin_layout Chapter Command-line encoder/decoder -\begin_inset LatexCommand \label{sec:Command-line-encoder/decoder} +\begin_inset LatexCommand label +name "sec:Command-line-encoder/decoder" \end_inset @@ -1057,14 +1335,19 @@ speexenc speexdec \emph default ). - This section describes how to use these tools. + Those tools produce and read Speex files encapsulated in the Ogg container. + Although it is possible to encapsulate Speex in any container, Ogg is the + recommended container for files. + This section describes how to use the command line tools for Speex files + in Ogg. \end_layout \begin_layout Section \emph on speexenc -\begin_inset LatexCommand \index{speexenc} +\begin_inset LatexCommand index +name "speexenc" \end_inset @@ -1219,7 +1502,8 @@ n Sampling rate for raw input \emph on speexdec -\begin_inset LatexCommand \index{speexdec} +\begin_inset LatexCommand index +name "speexdec" \end_inset @@ -1304,18 +1588,19 @@ n Simulate n % random packet loss \end_layout \begin_layout Chapter -Programming with Speex (the libspeex -\begin_inset LatexCommand \index{libspeex} - -\end_inset +Using the Speex Codec API ( +\emph on +libspeex +\emph default - API -\begin_inset LatexCommand \index{API} +\begin_inset LatexCommand index +name "libspeex" \end_inset ) -\begin_inset LatexCommand \label{sec:Programming-with-Speex} +\begin_inset LatexCommand label +name "sec:Programming-with-Speex" \end_inset @@ -1323,9 +1608,30 @@ Programming with Speex (the libspeex \end_layout \begin_layout Standard -This section explains how to use the Speex API. +The +\emph on +libspeex +\emph default + library contains all the functions for encoding and decoding speech with + the Speex codec. + When linking on a UNIX system, one must add +\emph on +-lspeex -lm +\emph default + to the compiler command line. + One important thing to know is that +\series bold +libspeex calls are reentrant, but not thread-safe +\series default +. + That means that it is fine to use calls from many threads, but +\series bold +calls using the same state from multiple threads must be protected by mutexes +\series default +. Examples of code can also be found in Appendix -\begin_inset LatexCommand \ref{sec:Sample-code} +\begin_inset LatexCommand ref +reference "sec:Sample-code" \end_inset @@ -1335,7 +1641,8 @@ This section explains how to use the Speex API. \begin_layout Section Encoding -\begin_inset LatexCommand \label{sub:Encoding} +\begin_inset LatexCommand label +name "sub:Encoding" \end_inset @@ -1346,38 +1653,56 @@ Encoding In order to encode speech using Speex, one first needs to: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + #include <speex/speex.h> \end_layout +\end_inset + +Then in the code, a Speex bit-packing struct must be declared, along with + a Speex encoder state: +\begin_inset listings +inline false +status open + \begin_layout Standard -Then a Speex bit-packing struct must be declared as: -\end_layout -\begin_layout LyX-Code SpeexBits bits; \end_layout \begin_layout Standard -along with a Speex encoder state -\end_layout -\begin_layout LyX-Code void *enc_state; \end_layout -\begin_layout Standard +\end_inset + The two are initialized by: -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code speex_bits_init(&bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + enc_state = speex_encoder_init(&speex_nb_mode); \end_layout +\end_inset + + +\end_layout + \begin_layout Standard For wideband coding, \emph on @@ -1388,8 +1713,8 @@ speex_nb_mode speex_wb_mode \emph default . - In most cases, you will need to know the frame size used by the mode you - are using. + In most cases, you will need to know the frame size used at the sampling + rate you are using. You can get that value in the \emph on frame_size @@ -1401,10 +1726,21 @@ samples , not bytes) with: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + speex_encoder_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&frame_size); \end_layout +\end_inset + + +\end_layout + \begin_layout Standard In practice, \emph on @@ -1417,11 +1753,18 @@ frame_size This is set by: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + speex_encoder_ctl(enc_state,SPEEX_SET_QUALITY,&quality); \end_layout -\begin_layout Standard +\end_inset + where \emph on quality @@ -1429,7 +1772,8 @@ quality is an integer value ranging from 0 to 10 (inclusively). The mapping between quality and bit-rate is described in Fig. -\begin_inset LatexCommand \ref{cap:quality_vs_bps} +\begin_inset LatexCommand ref +reference "cap:quality_vs_bps" \end_inset @@ -1440,18 +1784,31 @@ quality Once the initialization is done, for every input frame: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + speex_bits_reset(&bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + speex_encode_int(enc_state, input_frame, &bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + nbBytes = speex_bits_write(&bits, byte_ptr, MAX_NB_BYTES); \end_layout +\end_inset + + +\end_layout + \begin_layout Standard where \emph on @@ -1461,9 +1818,9 @@ input_frame \emph on ( \emph default -short +short \emph on - *) +*) \emph default pointing to the beginning of a speech frame, \emph on @@ -1512,11 +1869,11 @@ speex_encode() ARM) more complicated. Internally, \emph on -speex_encode() +speex_encode() \emph default -and + and \emph on - speex_encode_int() +speex_encode_int() \emph default are processed in the same way. Whether the encoder uses the fixed-point version is only decided by the @@ -1527,14 +1884,26 @@ and After you're done with the encoding, free all resources with: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + speex_bits_destroy(&bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + speex_encoder_destroy(enc_state); \end_layout +\end_inset + + +\end_layout + \begin_layout Standard That's about it for the encoder. @@ -1542,7 +1911,8 @@ That's about it for the encoder. \begin_layout Section Decoding -\begin_inset LatexCommand \label{sub:Decoding} +\begin_inset LatexCommand label +name "sub:Decoding" \end_inset @@ -1551,40 +1921,61 @@ Decoding \begin_layout Standard In order to decode speech using Speex, you first need to: -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code #include <speex/speex.h> \end_layout -\begin_layout Standard +\end_inset + You also need to declare a Speex bit-packing struct -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code SpeexBits bits; \end_layout -\begin_layout Standard +\end_inset + and a Speex decoder state -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code void *dec_state; \end_layout -\begin_layout Standard +\end_inset + The two are initialized by: -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code speex_bits_init(&bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + dec_state = speex_decoder_init(&speex_nb_mode); \end_layout +\end_inset + + +\end_layout + \begin_layout Standard For wideband decoding, \emph on @@ -1607,8 +1998,19 @@ samples , not bytes) with: \end_layout -\begin_layout LyX-Code -speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size); +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size); +\end_layout + +\end_inset + + \end_layout \begin_layout Standard @@ -1617,8 +2019,19 @@ There is also a parameter that can be set for the decoder: whether or not This can be set by: \end_layout -\begin_layout LyX-Code -speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh); +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh); +\end_layout + +\end_inset + + \end_layout \begin_layout Standard @@ -1634,15 +2047,23 @@ enh Again, once the decoder initialization is done, for every input frame: \end_layout -\begin_layout LyX-Code +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + speex_bits_read_from(&bits, input_bytes, nbBytes); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + speex_decode_int(dec_state, &bits, output_frame); \end_layout -\begin_layout Standard +\end_inset + where input_bytes is a \emph on (char *) @@ -1676,983 +2097,800 @@ speex_decode() (float *) \emph default as the output for the audio. + After you're done with the decoding, free all resources with: \end_layout \begin_layout Standard -After you're done with the decoding, free all resources with: -\end_layout +\begin_inset listings +inline false +status open + +\begin_layout Standard -\begin_layout LyX-Code speex_bits_destroy(&bits); \end_layout -\begin_layout LyX-Code +\begin_layout Standard + speex_decoder_destroy(dec_state); \end_layout -\begin_layout Section -Preprocessor -\begin_inset LatexCommand \label{sub:Preprocessor} - \end_inset \end_layout -\begin_layout Standard -In order to use the Speex preprocessor -\begin_inset LatexCommand \index{preprocessor} +\begin_layout Section +Codec Options (speex_*_ctl) +\begin_inset LatexCommand label +name "sub:Codec-Options" \end_inset -, you first need to: -\end_layout -\begin_layout LyX-Code -#include <speex/speex_preprocess.h> \end_layout -\begin_layout Standard -Then, a preprocessor state can be created as: +\begin_layout Quote +\align center + +\emph on +Entities should not be multiplied beyond necessity -- William of Ockham. \end_layout -\begin_layout LyX-Code -SpeexPreprocessState *preprocess_state = speex_preprocess_state_init(frame_size, - sampling_rate); +\begin_layout Quote +\align center + +\emph on +Just because there's an option for it doesn't mean you have to turn it on + -- me. \end_layout \begin_layout Standard -It is recommended to use the same value for -\family typewriter -frame_size -\family default - as is used by the encoder (20 +The Speex encoder and decoder support many options and requests that can + be accessed through the \emph on -ms +speex_encoder_ctl \emph default -). + and +\emph on +speex_decoder_ctl +\emph default + functions. + These functions are similar to the +\emph on +ioctl +\emph default + system call and their prototypes are: \end_layout \begin_layout Standard -For each input frame, you need to call: -\end_layout - -\begin_layout LyX-Code -speex_preprocess_run(preprocess_state, audio_frame); -\end_layout +\begin_inset listings +inline false +status open \begin_layout Standard -where -\family typewriter -audio_frame -\family default - is used both as input and output. + +void speex_encoder_ctl(void *encoder, int request, void *ptr); \end_layout \begin_layout Standard -In cases where the output audio is not useful for a certain frame, it is - possible to use instead: -\end_layout -\begin_layout LyX-Code -speex_preprocess_estimate_update(preprocess_state, audio_frame); +void speex_decoder_ctl(void *encoder, int request, void *ptr); \end_layout -\begin_layout Standard -This call will update all the preprocessor internal state variables without - computing the output audio, thus saving some CPU cycles. -\end_layout +\end_inset -\begin_layout Standard -The behaviour of the preprocessor can be changed using: -\end_layout -\begin_layout LyX-Code -speex_preprocess_ctl(preprocess_state, request, ptr); \end_layout \begin_layout Standard -which is used in the same way as the encoder and decoder equivalent. - Options are listed in Section . +Despite those functions, the defaults are usually good for many applications + and +\series bold +optional settings should only be used when one understands them and knows + that they are needed +\series default +. + A common error is to attempt to set many unnecessary settings. + \end_layout \begin_layout Standard -The preprocessor state can be destroyed using: -\end_layout +Here is a list of the values allowed for the requests. + Some only apply to the encoder or the decoder. + Because the last argument is of type +\begin_inset listings +inline true +status collapsed -\begin_layout LyX-Code -speex_preprocess_state_destroy(preprocess_state); -\end_layout +\begin_layout Standard -\begin_layout Section -Echo Cancellation -\begin_inset LatexCommand \label{sub:Echo-Cancellation} +void * +\end_layout \end_inset - -\end_layout +, the +\begin_inset listings +inline true +status collapsed \begin_layout Standard -The Speex library now includes an echo cancellation -\begin_inset LatexCommand \index{echo cancellation} + +_ctl() +\end_layout \end_inset - algorithm suitable for Acoustic Echo Cancellation -\begin_inset LatexCommand \index{acoustic echo cancellation} + functions are +\series bold +not type safe +\series default +, and shoud thus be used with care. + The type +\begin_inset listings +inline true +status collapsed -\end_inset +\begin_layout Standard - (AEC). - In order to use the echo canceller, you first need to +spx_int32_t \end_layout -\begin_layout LyX-Code -#include <speex/speex_echo.h> -\end_layout +\end_inset + + is the same as the C99 +\begin_inset listings +inline true +status collapsed \begin_layout Standard -Then, an echo canceller state can be created by: -\end_layout -\begin_layout LyX-Code -SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length); +int32_t \end_layout -\begin_layout Standard -where -\family typewriter -frame_size -\family default - is the amount of data (in samples) you want to process at once and -\family typewriter -filter_length -\family default - is the length (in samples) of the echo cancelling filter you want to use - (also known as -\shape italic -tail length -\shape default +\end_inset -\begin_inset LatexCommand \index{tail length} + type. +\end_layout +\begin_layout Description +SPEEX_SET_ENH +\begin_inset Formula $\ddagger$ \end_inset -). - It is recommended to use a frame size in the order of 20 ms (or equal to - the codec frame size) and make sure it is easy to perform an FFT of that - size (powers of two are better than prime sizes). - The recommended tail length is approximately the third of the room reverberatio -n time. - For example, in a small room, reverberation time is in the order of 300 - ms, so a tail length of 100 ms is a good choice (800 samples at 8000 Hz - sampling rate). -\end_layout + Set perceptual enhancer +\begin_inset LatexCommand index +name "perceptual enhancement" -\begin_layout Standard -Once the echo canceller state is created, audio can be processed by: -\end_layout +\end_inset -\begin_layout LyX-Code -speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); -\end_layout + to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -where -\family typewriter -input_frame -\family default - is the audio as captured by the microphone, -\family typewriter -echo_frame -\family default - is the signal that was played in the speaker (and needs to be removed) - and -\family typewriter -output_frame -\family default - is the signal with echo removed. - -\end_layout -\begin_layout Standard -One important thing to keep in mind is the relationship between -\family typewriter -input_frame -\family default - and -\family typewriter -echo_frame -\family default -. - It is important that, at any time, any echo that is present in the input - has already been sent to the echo canceller as -\family typewriter -echo_frame -\family default -. - In other words, the echo canceller cannot remove a signal that it hasn't - yet received. - On the other hand, the delay between the input signal and the echo signal - must be small enough because otherwise part of the echo cancellation filter - is inefficient. - In the ideal case, you code would look like: +spx_int32_t \end_layout -\begin_layout LyX-Code -write_to_soundcard(echo_frame, frame_size); -\end_layout +\end_inset -\begin_layout LyX-Code -read_from_soundcard(input_frame, frame_size); +) \end_layout -\begin_layout LyX-Code -speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); -\end_layout +\begin_layout Description +SPEEX_GET_ENH +\begin_inset Formula $\ddagger$ +\end_inset + + Get perceptual enhancer status ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -If you wish to further reduce the echo present in the signal, you can do - so by -\family typewriter -associating the echo canceller to the preprocessor -\family default - (see Section -\begin_inset LatexCommand \ref{sub:Preprocessor} + +spx_int32_t +\end_layout \end_inset -). - This is done by calling: +) \end_layout -\begin_layout LyX-Code -speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE, - echo_state); -\end_layout +\begin_layout Description +SPEEX_GET_FRAME_SIZE Get the number of samples per frame for the current + mode ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -in the initialisation. -\end_layout -\begin_layout Standard -As of version 1.2-beta2, there is an alternative, simpler API that can be - used instead of -\emph on -speex_echo_cancellation() -\emph default -. - When audio capture and playback are handled asynchronously (e.g. - in different threads or using the -\emph on -poll() -\emph default - or -\emph on -select() -\emph default - system call), it can be difficult to keep track of what input_frame comes - with what echo_frame. - Instead, the playback comtext/thread can simply call: +spx_int32_t \end_layout -\begin_layout LyX-Code -speex_echo_playback(echo_state, echo_frame); -\end_layout +\end_inset -\begin_layout Standard -every time an audio frame is played. - Then, the capture context/thread calls: +) \end_layout -\begin_layout LyX-Code -speex_echo_capture(echo_state, input_frame, output_frame); -\end_layout +\begin_layout Description +SPEEX_SET_QUALITY +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Standard -for every frame captured. - Internally, -\emph on -speex_echo_playback() -\emph default - simply buffers the playback frame so it can be used by -\emph on -speex_echo_capture() -\emph default - to call -\emph on -speex_echo_cancel() -\emph default -. - A side effect of using this alternate API is that the playback audio is - delayed by two frames, which is the normal delay caused by the soundcard. - When capture and playback are already synchronised, -\emph on -speex_echo_cancellation() -\emph default - is preferable since it gives better control on the exact input/echo timing. -\end_layout + Set the encoder speech quality ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -The echo cancellation state can be destroyed with: -\end_layout -\begin_layout LyX-Code -speex_echo_state_destroy(echo_state); +spx_int32_t \end_layout -\begin_layout Standard -It is also possible to reset the state of the echo canceller so it can be - reused without the need to create another state with: -\end_layout +\end_inset -\begin_layout LyX-Code -speex_echo_state_reset(echo_state); + from 0 to 10) \end_layout -\begin_layout Subsection -Troubleshooting -\end_layout +\begin_layout Description +SPEEX_GET_QUALITY +\begin_inset Formula $\dagger$ +\end_inset + + Get the current encoder speech quality ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -There are several things that may prevent the echo canceller from working - properly. - One of them is a bug (or something suboptimal) in the code, but there are - many others you should consider first + +spx_int32_t \end_layout -\begin_layout Itemize -Using a different soundcard to do the capture and plaback will *not* work, - regardless of what you may think. - The only exception to that is if the two cards can be made to have their - sampling clock -\begin_inset Quotes eld \end_inset -locked -\begin_inset Quotes erd + from 0 to 10) +\end_layout + +\begin_layout Description +SPEEX_SET_MODE +\begin_inset Formula $\dagger$ \end_inset - on the same clock source. + Set the mode number, as specified in the RTP spec ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Itemize -The delay between the record and playback signals must be minimal. - Any signal played has to -\begin_inset Quotes eld \end_inset -appear -\begin_inset Quotes erd -\end_inset +) +\end_layout - on the playback (far end) signal slightly before the echo canceller -\begin_inset Quotes eld +\begin_layout Description +SPEEX_GET_MODE +\begin_inset Formula $\dagger$ \end_inset -sees -\begin_inset Quotes erd -\end_inset + Get the current mode number, as specified in the RTP spec ( +\begin_inset listings +inline true +status collapsed - it in the near end signal, but excessive delay means that part of the filter - length is wasted. - In the worst situations, the delay is such that it is longer than the filter - length, in which case, no echo can be cancelled. -\end_layout +\begin_layout Standard -\begin_layout Itemize -When it comes to echo tail length (filter length), longer is *not* better. - Actually, the longer the tail length, the longer it takes for the filter - to adapt. - Of course, a tail length that is too short will not cancel enough echo, - but the most common problem seen is that people set a very long tail length - and then wonder why no echo is being cancelled. +spx_int32_t \end_layout -\begin_layout Itemize -Non-linear distortion cannot (by definition) be modeled by the linear adaptive - filter used in the echo canceller and thus cannot be cancelled. - Use good audio gear and avoid saturation/clipping. +\end_inset + +) \end_layout -\begin_layout Standard -Also useful is reading -\emph on -Echo Cancellation Demystified -\emph default - by Alexey Frunze -\begin_inset Foot +\begin_layout Description +SPEEX_SET_VBR +\begin_inset Formula $\dagger$ +\end_inset + + Set variable bit-rate (VBR) to on (1) or off (0) ( +\begin_inset listings +inline true status collapsed \begin_layout Standard -http://www.embeddedstar.com/articles/2003/7/article20030720-1.html + +spx_int32_t \end_layout \end_inset -, which explains the fundamental principles of echo cancellation. - The details of the algorithm described in the article are different, but - the general ideas of echo cancellation through adaptive filters are the - same. +) \end_layout -\begin_layout Standard -As of version 1.2beta2, a new -\family typewriter -echo_diagnostic.m -\family default - tool is included in the source distribution. - The first step is to define DUMP_ECHO_CANCEL_DATA during the build. - This causes the echo canceller to automatically save the near-end, far-end - and output signals to files (aec_rec.sw aec_play.sw and aec_out.sw). - These are exactly what the AEC receives and outputs. - From there, it is necessary to start Octave and type: -\end_layout +\begin_layout Description +SPEEX_GET_VBR +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout LyX-Code -echo_diagnostic('aec_rec.sw', 'aec_play.sw', 'aec_diagnostic.sw', 1024); -\end_layout + Get variable bit-rate +\begin_inset LatexCommand index +name "variable bit-rate" -\begin_layout Standard -The value of 1024 is the filter length and can be changed. - There will be some (hopefully) useful messages printed and echo cancelled - audio will be saved to aec_diagnostic.sw . - If even that output is bad (almost no cancellation) then there is probably - problem with the playback or recording process. -\end_layout +\end_inset -\begin_layout Section -Jitter Buffer -\end_layout + (VBR) status ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -There are two jitter buffers. - Both can be enabled by including: -\end_layout -\begin_layout LyX-Code -#include <speex/speex_jitter.c> +spx_int32_t \end_layout -\begin_layout Subsection -Generic Jitter Buffer -\end_layout +\end_inset -\begin_layout Subsection -Speex Jitter Buffer +) \end_layout -\begin_layout Section -Resampler -\end_layout +\begin_layout Description +SPEEX_SET_VBR_QUALITY +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Standard -As of version 1.2beta2, Speex includes a resampling modules. - To make use of the resampler, it is necessary to include its header file: + Set the encoder VBR speech quality (float 0 to 10) \end_layout -\begin_layout LyX-Code -#include <speex/speex_resampler.h> -\end_layout +\begin_layout Description +SPEEX_GET_VBR_QUALITY +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Standard -For each stream that is to be resampled, it is necessary to create a resampler - state with: + Get the current encoder VBR speech quality (float 0 to 10) \end_layout -\begin_layout LyX-Code -SpeexResamplerState *resampler; -\end_layout +\begin_layout Description +SPEEX_SET_COMPLEXITY +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout LyX-Code -resampler = speex_resampler_init(nb_channels, input_rate, output_rate, quality, - &err); -\end_layout + Set the CPU resources allowed for the encoder ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -where nb_channels is the number of channels that will be used (either interleave -d or non-interleaved), input_rate is the sampling rate of the input stream, - output_rate is the sampling rate of the output stream and quality is the - requested quality setting (0 to 10). - The quality parameter is useful for controlling the quality/complexity/latency - tradeoff. - Using a higher quality setting means less noise/aliasing, a higher complexity - and a higher latency. - Usually, a quality of 3 is acceptable for most desktop uses and quality - 10 is mostly recommended for pro audio work. - Quality 0 usually has a decent sound (certainly better than using linear - interpolation resampling), but artifacts may be heard. -\end_layout -\begin_layout Standard -The actual resampling is performed using +spx_int32_t \end_layout -\begin_layout LyX-Code -err = speex_resampler_process_int(resampler, channelID, in, &in_length, - out, &out_length); -\end_layout +\end_inset -\begin_layout Standard -where channelID is the ID of the channel to be processed. - For a mono stream, use 0. - The -\emph on -in -\emph default - pointer points to the first sample of the input buffer for the selected - channel and -\emph on -out -\emph default - points to the first sample of the output. - The size of the input and output buffers are specified by -\emph on -in_length -\emph default - and -\emph on -out_length -\emph default - respectively. - Upon completion, these values are replaced by the number of samples read - and written by the resampler. - Unless an error occurs, either all input samples will be read or all output - samples will be written to (or both). - For floating-point samples, the function speex_resampler_process_float() - behaves similarly. + from 1 to 10) \end_layout +\begin_layout Description +SPEEX_GET_COMPLEXITY +\begin_inset Formula $\dagger$ +\end_inset + + Get the CPU resources allowed for the encoder ( +\begin_inset listings +inline true +status collapsed + \begin_layout Standard -It is also possible to process multiple channels at once. - -\end_layout -\begin_layout Section -Codec Options (speex_*_ctl) -\begin_inset LatexCommand \label{sub:Codec-Options} +spx_int32_t +\end_layout \end_inset - + from 1 to 10) \end_layout -\begin_layout Quote -\align center +\begin_layout Description +SPEEX_SET_BITRATE +\begin_inset Formula $\dagger$ +\end_inset -\emph on -Entities should not be multiplied beyond necessity -- William of Ockham. + Set the bit-rate to use to the closest value not exceeding the parameter + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Quote -\align center +\end_inset -\emph on -Just because there's an option doesn't mean you have to use it -- me. + in bits per second) \end_layout +\begin_layout Description +SPEEX_GET_BITRATE Get the current bit-rate in use ( +\begin_inset listings +inline true +status collapsed + \begin_layout Standard -The Speex encoder and decoder support many options and requests that can - be accessed through the -\emph on -speex_encoder_ctl -\emph default - and -\emph on -speex_decoder_ctl -\emph default - functions. - Despite that, the defaults are good for many applications and -\series bold -optional settings should only be used when one understands them and knows - that they are needed -\series default -. - A common error is to attempt to set many unnecessary settings. - These functions are similar to the -\emph on -ioctl -\emph default - system call and their prototypes are: -\end_layout -\begin_layout LyX-Code -void speex_encoder_ctl(void *encoder, int request, void *ptr); +spx_int32_t \end_layout -\begin_layout LyX-Code -void speex_decoder_ctl(void *encoder, int request, void *ptr); -\end_layout +\end_inset -\begin_layout Standard -The different values of request allowed are (note that some only apply to - the encoder or the decoder): + in bits per second) \end_layout \begin_layout Description -SPEEX_SET_ENH** Set perceptual enhancer -\begin_inset LatexCommand \index{perceptual enhancement} +SPEEX_SET_SAMPLING_RATE Set real sampling rate ( +\begin_inset listings +inline true +status collapsed -\end_inset +\begin_layout Standard - to on (1) or off (0) (integer) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_GET_ENH** Get perceptual enhancer status (integer) +\end_inset + + in Hz) \end_layout \begin_layout Description -SPEEX_GET_FRAME_SIZE Get the number of samples per frame for the current - mode (integer) +SPEEX_GET_SAMPLING_RATE Get real sampling rate ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SET_QUALITY* Set the encoder speech quality (integer 0 to 10) +\end_inset + + in Hz) \end_layout \begin_layout Description -SPEEX_GET_QUALITY* Get the current encoder speech quality (integer 0 to - 10) +SPEEX_RESET_STATE Reset the encoder/decoder state to its original state, + clearing all memories (no argument) \end_layout \begin_layout Description -SPEEX_SET_MODE* +SPEEX_SET_VAD \begin_inset Formula $\dagger$ \end_inset + Set voice activity detection +\begin_inset LatexCommand index +name "voice activity detection" -\end_layout - -\begin_layout Description -SPEEX_GET_MODE* -\begin_inset Formula $\dagger$ \end_inset + (VAD) to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SET_LOW_MODE* -\begin_inset Formula $\dagger$ \end_inset - +) \end_layout \begin_layout Description -SPEEX_GET_LOW_MODE* +SPEEX_GET_VAD \begin_inset Formula $\dagger$ \end_inset + Get voice activity detection (VAD) status ( +\begin_inset listings +inline true +status collapsed +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SET_HIGH_MODE* -\begin_inset Formula $\dagger$ \end_inset - +) \end_layout \begin_layout Description -SPEEX_GET_HIGH_MODE* +SPEEX_SET_DTX \begin_inset Formula $\dagger$ \end_inset + Set discontinuous transmission +\begin_inset LatexCommand index +name "discontinuous transmission" -\end_layout - -\begin_layout Description -SPEEX_SET_VBR* Set variable bit-rate (VBR) to on (1) or off (0) (integer) -\end_layout +\end_inset -\begin_layout Description -SPEEX_GET_VBR* Get variable bit-rate -\begin_inset LatexCommand \index{variable bit-rate} + (DTX) to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed -\end_inset +\begin_layout Standard - (VBR) status (integer) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SET_VBR_QUALITY* Set the encoder VBR speech quality (float 0 to 10) -\end_layout +\end_inset -\begin_layout Description -SPEEX_GET_VBR_QUALITY* Get the current encoder VBR speech quality (float - 0 to 10) +) \end_layout \begin_layout Description -SPEEX_SET_COMPLEXITY* Set the CPU resources allowed for the encoder (integer - 1 to 10) -\end_layout +SPEEX_GET_DTX +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Description -SPEEX_GET_COMPLEXITY* Get the CPU resources allowed for the encoder (integer - 1 to 10) -\end_layout + Get discontinuous transmission (DTX) status ( +\begin_inset listings +inline true +status collapsed -\begin_layout Description -SPEEX_SET_BITRATE* Set the bit-rate to use to the closest value not exceeding - the parameter (integer in bps) -\end_layout +\begin_layout Standard -\begin_layout Description -SPEEX_GET_BITRATE Get the current bit-rate in use (integer in bps) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SET_SAMPLING_RATE Set real sampling rate (integer in Hz) -\end_layout +\end_inset -\begin_layout Description -SPEEX_GET_SAMPLING_RATE Get real sampling rate (integer in Hz) +) \end_layout \begin_layout Description -SPEEX_RESET_STATE Reset the encoder/decoder state to its original state - (zeros all memories) -\end_layout +SPEEX_SET_ABR +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Description -SPEEX_SET_VAD* Set voice activity detection -\begin_inset LatexCommand \index{voice activity detection} + Set average bit-rate +\begin_inset LatexCommand index +name "average bit-rate" \end_inset - (VAD) to on (1) or off (0) (integer) -\end_layout + (ABR) to a value n in bits per second ( +\begin_inset listings +inline true +status collapsed -\begin_layout Description -SPEEX_GET_VAD* Get voice activity detection (VAD) status (integer) -\end_layout +\begin_layout Standard -\begin_layout Description -SPEEX_SET_DTX* Set discontinuous transmission -\begin_inset LatexCommand \index{discontinuous transmission} +spx_int32_t +\end_layout \end_inset - (DTX) to on (1) or off (0) (integer) + in bits per second) \end_layout \begin_layout Description -SPEEX_GET_DTX* Get discontinuous transmission (DTX) status (integer) -\end_layout +SPEEX_GET_ABR +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Description -SPEEX_SET_ABR* Set average bit-rate -\begin_inset LatexCommand \index{average bit-rate} + Get average bit-rate (ABR) setting ( +\begin_inset listings +inline true +status collapsed -\end_inset +\begin_layout Standard - (ABR) to a value n in bits per second (integer in bps) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_GET_ABR* Get average bit-rate (ABR) setting (integer in bps) -\end_layout +\end_inset -\begin_layout Description -SPEEX_SET_PLC_TUNING* Tell the encoder to optimize encoding for a certain - percentage of packet loss (integer in percent) + in bits per second) \end_layout \begin_layout Description -SPEEX_GET_PLC_TUNING* Get the current tuning of the encoder for PLC (integer - in percent) -\end_layout +SPEEX_SET_PLC_TUNING +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Description -* applies only to the encoder + Tell the encoder to optimize encoding for a certain percentage of packet + loss ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t \end_layout -\begin_layout Description -** applies only to the decoder +\end_inset + + in percent) \end_layout \begin_layout Description +SPEEX_GET_PLC_TUNING \begin_inset Formula $\dagger$ \end_inset - normally only used internally -\end_layout + Get the current tuning of the encoder for PLC ( +\begin_inset listings +inline true +status collapsed -\begin_layout Section -Mode queries -\begin_inset LatexCommand \label{sub:Mode-queries} +\begin_layout Standard -\end_inset +spx_int32_t +\end_layout +\end_inset + in percent) \end_layout -\begin_layout Standard -Speex modes have a query system similar to the speex_encoder_ctl and speex_decod -er_ctl calls. - Since modes are read-only, it is only possible to get information about - a particular mode. - The function used to do that is: -\end_layout +\begin_layout Description +SPEEX_SET_VBR_MAX_BITRATE +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout LyX-Code -void speex_mode_query(SpeexMode *mode, int request, void *ptr); -\end_layout + Set the maximum bit-rate allowed in VBR operation ( +\begin_inset listings +inline true +status collapsed \begin_layout Standard -The admissible values for request are (unless otherwise note, the values - are returned through -\emph on -ptr -\emph default -): -\end_layout -\begin_layout Description -SPEEX_MODE_FRAME_SIZE Get the frame size (in samples) for the mode +spx_int32_t \end_layout -\begin_layout Description -SPEEX_SUBMODE_BITRATE Get the bit-rate for a submode number specified through - -\emph on -ptr -\emph default - (integer in bps). - -\end_layout +\end_inset -\begin_layout Section -Preprocessor options -\begin_inset LatexCommand \label{sub:Preprocessor-options} + in bits per second) +\end_layout +\begin_layout Description +SPEEX_GET_VBR_MAX_BITRATE +\begin_inset Formula $\dagger$ \end_inset + Get the current maximum bit-rate allowed in VBR operation ( +\begin_inset listings +inline true +status collapsed -\end_layout +\begin_layout Standard -\begin_layout Description -SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(2) (integer) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_PREPROCESS_GET_DENOISE Get denoising status (integer) -\end_layout +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(2) - (integer) + in bits per second) \end_layout \begin_layout Description -SPEEX_PREPROCESS_GET_AGC Get AGC status (integer) -\end_layout +SPEEX_SET_HIGHPASS Set the high-pass filter on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed -\begin_layout Description -SPEEX_PREPROCESS_SET_VAD Turns voice activity detector (VAD) on(1) or off(2) - (integer) -\end_layout +\begin_layout Standard -\begin_layout Description -SPEEX_PREPROCESS_GET_VAD Get VAD status (integer) +spx_int32_t \end_layout -\begin_layout Description -SPEEX_PREPROCESS_SET_AGC_LEVEL -\end_layout +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_GET_AGC_LEVEL +) \end_layout \begin_layout Description -SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(2) - (integer) -\end_layout +SPEEX_TET_HIGHPASS Get the current high-pass filter status ( +\begin_inset listings +inline true +status collapsed -\begin_layout Description -SPEEX_PREPROCESS_GET_DEREVERB Get reverberation removal status (integer) -\end_layout +\begin_layout Standard -\begin_layout Description -SPEEX_PREPROCESS_SET_DEREVERB_LEVEL +spx_int32_t \end_layout -\begin_layout Description -SPEEX_PREPROCESS_GET_DEREVERB_LEVEL -\end_layout +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_SET_DEREVERB_DECAY +) \end_layout \begin_layout Description -SPEEX_PREPROCESS_GET_DEREVERB_DECAY -\end_layout +\begin_inset Formula $\dagger$ +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_SET_PROB_START + applies only to the encoder \end_layout \begin_layout Description -SPEEX_PREPROCESS_GET_PROB_START -\end_layout +\begin_inset Formula $\ddagger$ +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_SET_PROB_CONTINUE + applies only to the decoder \end_layout -\begin_layout Description -SPEEX_PREPROCESS_GET_PROB_CONTINUE -\end_layout +\begin_layout Section +Mode queries +\begin_inset LatexCommand label +name "sub:Mode-queries" -\begin_layout Description -SPEEX_PREPROCESS_SET_NOISE_SUPPRESS Set maximum attenuation of the noise - in dB (negative number) -\end_layout +\end_inset -\begin_layout Description -SPEEX_PREPROCESS_GET_NOISE_SUPPRESS Get maximum attenuation of the noise - in dB (negative number) -\end_layout -\begin_layout Description -SPEEX_PREPROCESS_SET_ECHO_SUPPRESS Set maximum attenuation of the residual - echo in dB (negative number) \end_layout -\begin_layout Description -SPEEX_PREPROCESS_GET_ECHO_SUPPRESS Set maximum attenuation of the residual - echo in dB (negative number) -\end_layout +\begin_layout Standard +Speex modes have a query system similar to the speex_encoder_ctl and speex_decod +er_ctl calls. + Since modes are read-only, it is only possible to get information about + a particular mode. + The function used to do that is: +\begin_inset listings +inline false +status open -\begin_layout Description -SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the - echo in dB when near end is active (negative number) +\begin_layout Standard + +void speex_mode_query(SpeexMode *mode, int request, void *ptr); \end_layout -\begin_layout Description -SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the - echo in dB when near end is active (negative number) +\end_inset + +The admissible values for request are (unless otherwise note, the values + are returned through +\emph on +ptr +\emph default +): \end_layout \begin_layout Description -SPEEX_PREPROCESS_SET_ECHO_STATE Set the associated echo canceller for residual - echo suppression (NULL for no residual echo suppression) +SPEEX_MODE_FRAME_SIZE Get the frame size (in samples) for the mode \end_layout \begin_layout Description -SPEEX_PREPROCESS_GET_ECHO_STATE Get the associated echo canceller +SPEEX_SUBMODE_BITRATE Get the bit-rate for a submode number specified through + +\emph on +ptr +\emph default + (integer in bps). + \end_layout \begin_layout Section Packing and in-band signalling -\begin_inset LatexCommand \index{in-band signalling} +\begin_inset LatexCommand index +name "in-band signalling" \end_inset @@ -2671,7 +2909,8 @@ Sometimes it is desirable to pack more than one frame per packet (or other mechanism, it is possible to include a terminator code. That terminator consists of the code 15 (decimal) encoded with 5 bits, as shown in Table -\begin_inset LatexCommand \ref{cap:quality_vs_bps} +\begin_inset LatexCommand ref +reference "cap:quality_vs_bps" \end_inset @@ -2702,7 +2941,8 @@ pseudo-frames of mode 14 which contain a 4-bit message type code, followed by the message. Table -\begin_inset LatexCommand \ref{cap:In-band-signalling-codes} +\begin_inset LatexCommand ref +reference "cap:In-band-signalling-codes" \end_inset @@ -3261,9 +3501,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard In-band signalling codes -\begin_inset LatexCommand \label{cap:In-band-signalling-codes} +\begin_inset LatexCommand label +name "cap:In-band-signalling-codes" + +\end_inset + + +\end_layout \end_inset @@ -3279,6 +3528,1304 @@ In-band signalling codes Finally, applications may define custom in-band messages using mode 13. The size of the message in bytes is encoded with 5 bits, so that the decoder can skip it if it doesn't know how to interpret it. +\newpage + +\end_layout + +\begin_layout Chapter +Speech Processing API ( +\emph on +libspeexdsp +\emph default +) +\end_layout + +\begin_layout Standard +As of version 1.2beta3, the non-codec parts of the Speex package are now + in a separate library called +\emph on +libspeexdsp +\emph default +. + This library includes the preprocessor, the acoustic echo canceller, the + jitter buffer, and the resampler. + In a UNIX environment, it can be linked into a program by adding +\emph on +-lspeexdsp -lm +\emph default + to the compiler command line. + Just like for libspeex, +\series bold +libspeexdsp calls are reentrant, but not thread-safe +\series default +. + That means that it is fine to use calls from many threads, but +\series bold +calls using the same state from multiple threads must be protected by mutexes +\series default +. +\end_layout + +\begin_layout Section +Preprocessor +\begin_inset LatexCommand label +name "sub:Preprocessor" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +In order to use the Speex preprocessor +\begin_inset LatexCommand index +name "preprocessor" + +\end_inset + +, you first need to: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +#include <speex/speex_preprocess.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +Then, a preprocessor state can be created as: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +SpeexPreprocessState *preprocess_state = speex_preprocess_state_init(frame_size, + sampling_rate); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +and it is recommended to use the same value for +\family typewriter +frame_size +\family default + as is used by the encoder (20 +\emph on +ms +\emph default +). +\end_layout + +\begin_layout Standard +For each input frame, you need to call: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_preprocess_run(preprocess_state, audio_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +where +\family typewriter +audio_frame +\family default + is used both as input and output. + In cases where the output audio is not useful for a certain frame, it is + possible to use instead: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_preprocess_estimate_update(preprocess_state, audio_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +This call will update all the preprocessor internal state variables without + computing the output audio, thus saving some CPU cycles. +\end_layout + +\begin_layout Standard +The behaviour of the preprocessor can be changed using: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_preprocess_ctl(preprocess_state, request, ptr); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +which is used in the same way as the encoder and decoder equivalent. + Options are listed in Section +\begin_inset LatexCommand ref +reference "sub:Preprocessor-options" + +\end_inset + +. +\end_layout + +\begin_layout Standard +The preprocessor state can be destroyed using: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_preprocess_state_destroy(preprocess_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Preprocessor options +\begin_inset LatexCommand label +name "sub:Preprocessor-options" + +\end_inset + + +\end_layout + +\begin_layout Standard +As with the codec, the preprocessor also has options that can be controlled + using an ioctl()-like call. + The available options are: +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(2) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DENOISE Get denoising status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(2) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_AGC Get AGC status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_VAD Turns voice activity detector (VAD) on(1) or off(2) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_VAD Get VAD status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_AGC_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_AGC_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(2) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB Get reverberation removal status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB_DECAY +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB_DECAY +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_PROB_START +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_PROB_START +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_PROB_CONTINUE +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_PROB_CONTINUE +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_NOISE_SUPPRESS Set maximum attenuation of the noise + in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_NOISE_SUPPRESS Get maximum attenuation of the noise + in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_SUPPRESS Set maximum attenuation of the residual + echo in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_SUPPRESS Set maximum attenuation of the residual + echo in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the + echo in dB when near end is active (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the + echo in dB when near end is active (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_STATE Set the associated echo canceller for residual + echo suppression (NULL for no residual echo suppression) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_STATE Get the associated echo canceller +\end_layout + +\begin_layout Section +Echo Cancellation +\begin_inset LatexCommand label +name "sub:Echo-Cancellation" + +\end_inset + + +\end_layout + +\begin_layout Standard +The Speex library now includes an echo cancellation +\begin_inset LatexCommand index +name "echo cancellation" + +\end_inset + + algorithm suitable for Acoustic Echo Cancellation +\begin_inset LatexCommand index +name "acoustic echo cancellation" + +\end_inset + + (AEC). + In order to use the echo canceller, you first need to +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +#include <speex/speex_echo.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Then, an echo canceller state can be created by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\family typewriter +frame_size +\family default + is the amount of data (in samples) you want to process at once and +\family typewriter +filter_length +\family default + is the length (in samples) of the echo cancelling filter you want to use + (also known as +\shape italic +tail length +\shape default + +\begin_inset LatexCommand index +name "tail length" + +\end_inset + +). + It is recommended to use a frame size in the order of 20 ms (or equal to + the codec frame size) and make sure it is easy to perform an FFT of that + size (powers of two are better than prime sizes). + The recommended tail length is approximately the third of the room reverberatio +n time. + For example, in a small room, reverberation time is in the order of 300 + ms, so a tail length of 100 ms is a good choice (800 samples at 8000 Hz + sampling rate). +\end_layout + +\begin_layout Standard +Once the echo canceller state is created, audio can be processed by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\family typewriter +input_frame +\family default + is the audio as captured by the microphone, +\family typewriter +echo_frame +\family default + is the signal that was played in the speaker (and needs to be removed) + and +\family typewriter +output_frame +\family default + is the signal with echo removed. + +\end_layout + +\begin_layout Standard +One important thing to keep in mind is the relationship between +\family typewriter +input_frame +\family default + and +\family typewriter +echo_frame +\family default +. + It is important that, at any time, any echo that is present in the input + has already been sent to the echo canceller as +\family typewriter +echo_frame +\family default +. + In other words, the echo canceller cannot remove a signal that it hasn't + yet received. + On the other hand, the delay between the input signal and the echo signal + must be small enough because otherwise part of the echo cancellation filter + is inefficient. + In the ideal case, you code would look like: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Standard + +write_to_soundcard(echo_frame, frame_size); +\end_layout + +\begin_layout Standard + +read_from_soundcard(input_frame, frame_size); +\end_layout + +\begin_layout Standard + +speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If you wish to further reduce the echo present in the signal, you can do + so by associating the echo canceller to the preprocessor (see Section +\begin_inset LatexCommand ref +reference "sub:Preprocessor" + +\end_inset + +). + This is done by calling: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Standard + +speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE,echo_stat +e); +\end_layout + +\end_inset + +in the initialisation. +\end_layout + +\begin_layout Standard +As of version 1.2-beta2, there is an alternative, simpler API that can be + used instead of +\emph on +speex_echo_cancellation() +\emph default +. + When audio capture and playback are handled asynchronously (e.g. + in different threads or using the +\emph on +poll() +\emph default + or +\emph on +select() +\emph default + system call), it can be difficult to keep track of what input_frame comes + with what echo_frame. + Instead, the playback comtext/thread can simply call: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_echo_playback(echo_state, echo_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +every time an audio frame is played. + Then, the capture context/thread calls: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_echo_capture(echo_state, input_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +for every frame captured. + Internally, +\emph on +speex_echo_playback() +\emph default + simply buffers the playback frame so it can be used by +\emph on +speex_echo_capture() +\emph default + to call +\emph on +speex_echo_cancel() +\emph default +. + A side effect of using this alternate API is that the playback audio is + delayed by two frames, which is the normal delay caused by the soundcard. + When capture and playback are already synchronised, +\emph on +speex_echo_cancellation() +\emph default + is preferable since it gives better control on the exact input/echo timing. +\end_layout + +\begin_layout Standard +The echo cancellation state can be destroyed with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_echo_state_destroy(echo_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +It is also possible to reset the state of the echo canceller so it can be + reused without the need to create another state with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +speex_echo_state_reset(echo_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Troubleshooting +\end_layout + +\begin_layout Standard +There are several things that may prevent the echo canceller from working + properly. + One of them is a bug (or something suboptimal) in the code, but there are + many others you should consider first +\end_layout + +\begin_layout Itemize +Using a different soundcard to do the capture and plaback will +\series bold +not +\series default + work, regardless of what you may think. + The only exception to that is if the two cards can be made to have their + sampling clock +\begin_inset Quotes eld +\end_inset + +locked +\begin_inset Quotes erd +\end_inset + + on the same clock source. + If not, the clocks will always have a small amount of drift, which will + prevent the echo canceller from adapting. +\end_layout + +\begin_layout Itemize +The delay between the record and playback signals must be minimal. + Any signal played has to +\begin_inset Quotes eld +\end_inset + +appear +\begin_inset Quotes erd +\end_inset + + on the playback (far end) signal slightly before the echo canceller +\begin_inset Quotes eld +\end_inset + +sees +\begin_inset Quotes erd +\end_inset + + it in the near end signal, but excessive delay means that part of the filter + length is wasted. + In the worst situations, the delay is such that it is longer than the filter + length, in which case, no echo can be cancelled. +\end_layout + +\begin_layout Itemize +When it comes to echo tail length (filter length), longer is *not* better. + Actually, the longer the tail length, the longer it takes for the filter + to adapt. + Of course, a tail length that is too short will not cancel enough echo, + but the most common problem seen is that people set a very long tail length + and then wonder why no echo is being cancelled. +\end_layout + +\begin_layout Itemize +Non-linear distortion cannot (by definition) be modeled by the linear adaptive + filter used in the echo canceller and thus cannot be cancelled. + Use good audio gear and avoid saturation/clipping. +\end_layout + +\begin_layout Standard +Also useful is reading +\emph on +Echo Cancellation Demystified +\emph default + by Alexey Frunze +\begin_inset Foot +status collapsed + +\begin_layout Standard +http://www.embeddedstar.com/articles/2003/7/article20030720-1.html +\end_layout + +\end_inset + +, which explains the fundamental principles of echo cancellation. + The details of the algorithm described in the article are different, but + the general ideas of echo cancellation through adaptive filters are the + same. +\end_layout + +\begin_layout Standard +As of version 1.2beta2, a new +\family typewriter +echo_diagnostic.m +\family default + tool is included in the source distribution. + The first step is to define DUMP_ECHO_CANCEL_DATA during the build. + This causes the echo canceller to automatically save the near-end, far-end + and output signals to files (aec_rec.sw aec_play.sw and aec_out.sw). + These are exactly what the AEC receives and outputs. + From there, it is necessary to start Octave and type: +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "language=Matlab" +inline false +status open + +\begin_layout Standard + +echo_diagnostic('aec_rec.sw', 'aec_play.sw', 'aec_diagnostic.sw', 1024); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The value of 1024 is the filter length and can be changed. + There will be some (hopefully) useful messages printed and echo cancelled + audio will be saved to aec_diagnostic.sw . + If even that output is bad (almost no cancellation) then there is probably + problem with the playback or recording process. +\end_layout + +\begin_layout Section +Jitter Buffer +\end_layout + +\begin_layout Standard +The jitter buffer can be enabled by including: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Standard + +#include <speex/speex_jitter.h> +\end_layout + +\end_inset + + and a new jitter buffer state can be initialised by: +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Standard + +JitterBuffer *state = jitter_buffer_init(tick); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where the +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +tick +\end_layout + +\end_inset + + argument is the time resolution (in timestamp units) used for the jitter + buffer, and is generally the period at which the data is played out of + the jitter buffer. + +\end_layout + +\begin_layout Standard +The jitter buffer API is based on the +\begin_inset listings +inline true +status open + +\begin_layout Standard + +JitterBufferPacket +\end_layout + +\end_inset + + type, which is defined as: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +typedef struct { +\end_layout + +\begin_layout Standard + + char *data; /* Data bytes contained in the packet */ +\end_layout + +\begin_layout Standard + + spx_uint32_t len; /* Length of the packet in bytes */ +\end_layout + +\begin_layout Standard + + spx_uint32_t timestamp; /* Timestamp for the packet */ +\end_layout + +\begin_layout Standard + + spx_uint32_t span; /* Time covered by the packet (timestamp units) + */ +\end_layout + +\begin_layout Standard + +} JitterBufferPacket; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +When a packet arrives, it need to be inserter into the jitter buffer by: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +JitterBufferPacket packet; +\end_layout + +\begin_layout Standard + +/* Fill in the packet fields */ +\end_layout + +\begin_layout Standard + +jitter_buffer_put(state, &packet); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +When the decoder is ready to decode a packet the packet to be decoded can + be obtained by: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +int start_offset; +\end_layout + +\begin_layout Standard + +err = jitter_buffer_get(state, &packet, &start_offset); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If +\begin_inset listings +inline true +status open + +\begin_layout Standard + +jitter_buffer_put() +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status open + +\begin_layout Standard + +jitter_buffer_get() +\end_layout + +\end_inset + + are called from different threads, then +\series bold +you need to protect the jitter buffer state with a mutex +\series default +. + +\end_layout + +\begin_layout Standard +Because the jitter buffer is designed not to use an explicit timer, it needs + to be told about the time explicitly. + This is done by calling: +\begin_inset listings +inline false +status open + +\begin_layout Standard + +jitter_buffer_tick(state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This needs to be done every time +\begin_inset listings +inline true +status collapsed + +\begin_layout Standard + +tick +\end_layout + +\end_inset + + units have elapsed. + +\end_layout + +\begin_layout Section +Resampler +\end_layout + +\begin_layout Standard +Speex includes a resampling modules. + To make use of the resampler, it is necessary to include its header file: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +#include <speex/speex_resampler.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +For each stream that is to be resampled, it is necessary to create a resampler + state with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +SpeexResamplerState *resampler; +\end_layout + +\begin_layout Standard + +resampler = speex_resampler_init(nb_channels, input_rate, output_rate, quality, + &err); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where nb_channels is the number of channels that will be used (either interleave +d or non-interleaved), input_rate is the sampling rate of the input stream, + output_rate is the sampling rate of the output stream and quality is the + requested quality setting (0 to 10). + The quality parameter is useful for controlling the quality/complexity/latency + tradeoff. + Using a higher quality setting means less noise/aliasing, a higher complexity + and a higher latency. + Usually, a quality of 3 is acceptable for most desktop uses and quality + 10 is mostly recommended for pro audio work. + Quality 0 usually has a decent sound (certainly better than using linear + interpolation resampling), but artifacts may be heard. +\end_layout + +\begin_layout Standard +The actual resampling is performed using +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Standard + +err = speex_resampler_process_int(resampler, channelID, in, &in_length, + out, &out_length); +\end_layout + +\end_inset + +where channelID is the ID of the channel to be processed. + For a mono stream, use 0. + The +\emph on +in +\emph default + pointer points to the first sample of the input buffer for the selected + channel and +\emph on +out +\emph default + points to the first sample of the output. + The size of the input and output buffers are specified by +\emph on +in_length +\emph default + and +\emph on +out_length +\emph default + respectively. + Upon completion, these values are replaced by the number of samples read + and written by the resampler. + Unless an error occurs, either all input samples will be read or all output + samples will be written to (or both). + For floating-point samples, the function speex_resampler_process_float() + behaves similarly. +\end_layout + +\begin_layout Standard +It is also possible to process multiple channels at once. + +\end_layout + +\begin_layout Section +Ring Buffer +\end_layout + +\begin_layout Standard +Put some stuff there... \end_layout \begin_layout Standard @@ -3289,12 +4836,14 @@ Finally, applications may define custom in-band messages using mode 13. \begin_layout Chapter Formats and standards -\begin_inset LatexCommand \index{standards} +\begin_inset LatexCommand index +name "standards" \end_inset -\begin_inset LatexCommand \label{sec:Formats-and-standards} +\begin_inset LatexCommand label +name "sec:Formats-and-standards" \end_inset @@ -3348,7 +4897,8 @@ For encoders, at least one narrowband or wideband mode MUST be supported. \begin_layout Section RTP -\begin_inset LatexCommand \index{RTP} +\begin_inset LatexCommand index +name "RTP" \end_inset @@ -3357,12 +4907,14 @@ RTP \begin_layout Standard The RTP payload draft is included in appendix -\begin_inset LatexCommand \ref{sec:IETF-draft} +\begin_inset LatexCommand ref +reference "sec:IETF-draft" \end_inset and the latest version is available at -\begin_inset LatexCommand \url{http://www.speex.org/drafts/latest} +\begin_inset LatexCommand url +target "http://www.speex.org/drafts/latest" \end_inset @@ -3387,7 +4939,8 @@ audio/speex \begin_layout Section Ogg -\begin_inset LatexCommand \index{Ogg} +\begin_inset LatexCommand index +name "Ogg" \end_inset @@ -3398,7 +4951,8 @@ Ogg Speex bit-streams can be stored in Ogg files. In this case, the first packet of the Ogg file contains the Speex header described in table -\begin_inset LatexCommand \ref{cap:ogg_speex_header} +\begin_inset LatexCommand ref +reference "cap:ogg_speex_header" \end_inset @@ -3999,9 +5553,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Ogg/Speex header packet -\begin_inset LatexCommand \label{cap:ogg_speex_header} +\begin_inset LatexCommand label +name "cap:ogg_speex_header" + +\end_inset + + +\end_layout \end_inset @@ -4031,12 +5594,14 @@ clearpage \begin_layout Chapter Introduction to CELP Coding -\begin_inset LatexCommand \index{CELP} +\begin_inset LatexCommand index +name "CELP" \end_inset -\begin_inset LatexCommand \label{sec:Introduction-to-CELP} +\begin_inset LatexCommand label +name "sec:Introduction-to-CELP" \end_inset @@ -4055,7 +5620,8 @@ Do not meddle in the affairs of poles, for they are subtle and quick to Speex is based on CELP, which stands for Code Excited Linear Prediction. This section attempts to introduce the principles behind CELP, so if you are already familiar with CELP, you can safely skip to section -\begin_inset LatexCommand \ref{sec:Speex-narrowband-mode} +\begin_inset LatexCommand ref +reference "sec:Speex-narrowband-mode" \end_inset @@ -4117,7 +5683,8 @@ The source-filter model of speech production assumes that the vocal cords The source-filter model is usually tied with the use of Linear prediction. The CELP model is based on source-filter model, as can be seen from the CELP decoder illustrated in Figure -\begin_inset LatexCommand \ref{fig:The-CELP-model} +\begin_inset LatexCommand ref +reference "fig:The-CELP-model" \end_inset @@ -4168,9 +5735,13 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard The CELP model of speech synthesis (decoder) -\begin_inset LatexCommand \label{fig:The-CELP-model} +\begin_inset LatexCommand label +name "fig:The-CELP-model" \end_inset @@ -4182,9 +5753,15 @@ The CELP model of speech synthesis (decoder) \end_layout +\end_inset + + +\end_layout + \begin_layout Section Linear Prediction (LPC) -\begin_inset LatexCommand \index{linear prediction} +\begin_inset LatexCommand index +name "linear prediction" \end_inset @@ -4292,7 +5869,8 @@ with \end_inset , the auto-correlation -\begin_inset LatexCommand \index{auto-correlation} +\begin_inset LatexCommand index +name "auto-correlation" \end_inset @@ -4317,8 +5895,9 @@ Because \begin_inset Formula $\mathbf{R}$ \end_inset - is toeplitz hermitian, the Levinson-Durbin -\begin_inset LatexCommand \index{Levinson-Durbin} + is Hermitian Toeplitz, the Levinson-Durbin +\begin_inset LatexCommand index +name "Levinson-Durbin" \end_inset @@ -4354,7 +5933,8 @@ Because \begin_layout Section Pitch Prediction -\begin_inset LatexCommand \index{pitch} +\begin_inset LatexCommand index +name "pitch" \end_inset @@ -4373,14 +5953,10 @@ During voiced segments, the speech signal is periodic, so it is possible \begin_layout Standard \begin_inset Formula \[ -e[n]\simeq p[n]=\beta e[n-T]\] +e[n]\simeq p[n]=\beta e[n-T]\ ,\] \end_inset - -\end_layout - -\begin_layout Standard where \begin_inset Formula $T$ \end_inset @@ -4424,12 +6000,12 @@ innovation Code \emph default Excited Linear Prediction. - The final excitation is given by: + The final excitation is given by \end_layout \begin_layout Standard \begin_inset Formula \[ -e[n]=p[n]+c[n]=\beta e[n-T]+c[n]\] +e[n]=p[n]+c[n]=\beta e[n-T]+c[n]\ .\] \end_inset @@ -4448,7 +6024,7 @@ z \begin_inset Formula $X(z)$ \end_inset - as + as \begin_inset Formula \[ X(z)=\frac{C(z)}{A(z)\left(1-\beta z^{-T}\right)}\] @@ -4459,12 +6035,14 @@ X(z)=\frac{C(z)}{A(z)\left(1-\beta z^{-T}\right)}\] \begin_layout Section Noise Weighting -\begin_inset LatexCommand \index{error weighting} +\begin_inset LatexCommand index +name "error weighting" \end_inset -\begin_inset LatexCommand \index{analysis-by-synthesis} +\begin_inset LatexCommand index +name "analysis-by-synthesis" \end_inset @@ -4505,9 +6083,9 @@ vice versa \begin_inset Formula $1/A(z)$ \end_inset -, CELP codecs typically derive the noise weighting filter as: +, CELP codecs typically derive the noise weighting filter as \begin_inset Formula \begin{equation} -W(z)=\frac{A(z/\gamma_{1})}{A(z/\gamma_{2})}\label{eq:gamma-weighting}\end{equation} +W(z)=\frac{A(z/\gamma_{1})}{A(z/\gamma_{2})}\ ,\label{eq:gamma-weighting}\end{equation} \end_inset @@ -4564,13 +6142,15 @@ The weighting filter is applied to the error signal used to optimize the function. Fig. -\begin_inset LatexCommand \ref{cap:Standard-noise-shaping} +\begin_inset LatexCommand ref +reference "cap:Standard-noise-shaping" \end_inset illustrates the noise shaping that results from Eq. -\begin_inset LatexCommand \ref{eq:gamma-weighting} +\begin_inset LatexCommand ref +reference "eq:gamma-weighting" \end_inset @@ -4629,10 +6209,19 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Standard noise shaping in CELP. Arbitrary y-axis offset. -\begin_inset LatexCommand \label{cap:Standard-noise-shaping} +\begin_inset LatexCommand label +name "cap:Standard-noise-shaping" + +\end_inset + + +\end_layout \end_inset @@ -4682,12 +6271,14 @@ In order to achieve real-time encoding using limited computing resources, \begin_layout Chapter Speex narrowband mode -\begin_inset LatexCommand \label{sec:Speex-narrowband-mode} +\begin_inset LatexCommand label +name "sec:Speex-narrowband-mode" \end_inset -\begin_inset LatexCommand \index{narrowband} +\begin_inset LatexCommand index +name "narrowband" \end_inset @@ -4727,7 +6318,8 @@ sub-vector fixed (innovation) codebooks \begin_layout Section Whole-Frame Analysis -\begin_inset LatexCommand \index{linear prediction} +\begin_inset LatexCommand index +name "linear prediction" \end_inset @@ -4745,7 +6337,8 @@ In narrowband, Speex frames are 20 ms long (160 samples) and are subdivided , as shown in Fig. -\begin_inset LatexCommand \ref{cap:Frame-open-loop-analysis} +\begin_inset LatexCommand ref +reference "cap:Frame-open-loop-analysis" \end_inset @@ -4758,7 +6351,8 @@ Linear prediction analysis is performed once per frame using an asymmetric Hamming window centered on the fourth sub-frame. Because linear prediction coefficients (LPC) are not robust to quantization, they are first are converted to line spectral pairs (LSP) -\begin_inset LatexCommand \index{line spectral pair} +\begin_inset LatexCommand index +name "line spectral pair" \end_inset @@ -4835,9 +6429,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Frame open-loop analysis -\begin_inset LatexCommand \label{cap:Frame-open-loop-analysis} +\begin_inset LatexCommand label +name "cap:Frame-open-loop-analysis" + +\end_inset + + +\end_layout \end_inset @@ -4896,9 +6499,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Analysis-by-synthesis closed-loop optimization on a sub-frame. -\begin_inset LatexCommand \label{cap:Sub-frame-AbS} +\begin_inset LatexCommand label +name "cap:Sub-frame-AbS" + +\end_inset + + +\end_layout \end_inset @@ -4913,7 +6525,8 @@ Analysis-by-synthesis closed-loop optimization on a sub-frame. \begin_layout Standard The analysis-by-synthesis (AbS) encoder loop is described in Fig. -\begin_inset LatexCommand \ref{cap:Sub-frame-AbS} +\begin_inset LatexCommand ref +reference "cap:Sub-frame-AbS" \end_inset @@ -5026,7 +6639,8 @@ There are 7 different narrowband bit-rates defined for Speex, ranging from 250 bps to 24.6 kbps, although the modes below 5.9 kbps should not be used for speech. The bit-allocation for each mode is detailed in table -\begin_inset LatexCommand \ref{cap:bits-narrowband} +\begin_inset LatexCommand ref +reference "cap:bits-narrowband" \end_inset @@ -6317,9 +7931,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Bit allocation for narrowband modes -\begin_inset LatexCommand \label{cap:bits-narrowband} +\begin_inset LatexCommand label +name "cap:bits-narrowband" + +\end_inset + + +\end_layout \end_inset @@ -6333,13 +7956,15 @@ Bit allocation for narrowband modes \begin_layout Standard So far, no MOS (Mean Opinion Score -\begin_inset LatexCommand \index{mean opinion score} +\begin_inset LatexCommand index +name "mean opinion score" \end_inset ) subjective evaluation has been performed for Speex. - In order to give an idea of the quality achivable with it, table -\begin_inset LatexCommand \ref{cap:quality_vs_bps} + In order to give an idea of the quality achievable with it, table +\begin_inset LatexCommand ref +reference "cap:quality_vs_bps" \end_inset @@ -6352,7 +7977,8 @@ So far, no MOS (Mean Opinion Score Note that the complexity is only approximate (within 0.5 mflops and using the lowest complexity setting). Decoding requires approximately 0.5 mflops -\begin_inset LatexCommand \index{complexity} +\begin_inset LatexCommand index +name "complexity" \end_inset @@ -6412,7 +8038,8 @@ Quality \begin_layout Standard Bit-rate -\begin_inset LatexCommand \index{bit-rate} +\begin_inset LatexCommand index +name "bit-rate" \end_inset @@ -6426,7 +8053,8 @@ Bit-rate \begin_layout Standard mflops -\begin_inset LatexCommand \index{complexity} +\begin_inset LatexCommand index +name "complexity" \end_inset @@ -7217,9 +8845,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Quality versus bit-rate -\begin_inset LatexCommand \label{cap:quality_vs_bps} +\begin_inset LatexCommand label +name "cap:quality_vs_bps" + +\end_inset + + +\end_layout \end_inset @@ -7233,7 +8870,8 @@ Quality versus bit-rate \begin_layout Section Perceptual enhancement -\begin_inset LatexCommand \index{perceptual enhancement} +\begin_inset LatexCommand index +name "perceptual enhancement" \end_inset @@ -7294,12 +8932,14 @@ where \begin_layout Chapter Speex wideband mode (sub-band CELP) -\begin_inset LatexCommand \index{wideband} +\begin_inset LatexCommand index +name "wideband" \end_inset -\begin_inset LatexCommand \label{sec:Speex-wideband-mode} +\begin_inset LatexCommand label +name "sec:Speex-wideband-mode" \end_inset @@ -7320,7 +8960,8 @@ irror f \emph default ilter -\begin_inset LatexCommand \index{quadrature mirror filter} +\begin_inset LatexCommand index +name "quadrature mirror filter" \end_inset @@ -7328,7 +8969,8 @@ ilter The 16 kHz signal is thus divided into two 8 kHz signals, one representing the low band (0-4 kHz), the other the high band (4-8 kHz). The low band is encoded with the narrowband mode described in section -\begin_inset LatexCommand \ref{sec:Speex-narrowband-mode} +\begin_inset LatexCommand ref +reference "sec:Speex-narrowband-mode" \end_inset @@ -7390,13 +9032,23 @@ Bit allocation For the wideband mode, the entire narrowband frame is packed before the high-band is encoded. The narrowband part of the bit-stream is as defined in table -\begin_inset LatexCommand \ref{cap:bits-narrowband} +\begin_inset LatexCommand ref +reference "cap:bits-narrowband" \end_inset . The high-band follows, as described in table -\begin_inset LatexCommand \ref{cap:bits-wideband} +\begin_inset LatexCommand ref +reference "cap:bits-wideband" + +\end_inset + +. + For wideband, the mode ID is the same as the Speex quality setting and + is defined in table +\begin_inset LatexCommand ref +reference "tab:wideband-quality" \end_inset @@ -7913,9 +9565,18 @@ end{center} \end_layout -\begin_layout Caption +\begin_layout Standard +\begin_inset Caption + +\begin_layout Standard Bit allocation for high-band in wideband mode -\begin_inset LatexCommand \label{cap:bits-wideband} +\begin_inset LatexCommand label +name "cap:bits-wideband" + +\end_inset + + +\end_layout \end_inset @@ -7928,381 +9589,466 @@ Bit allocation for high-band in wideband mode \end_layout \begin_layout Standard -\begin_inset ERT +\begin_inset Float table +placement h +wide true +sideways false status open \begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Standard \backslash -clearpage +begin{center} \end_layout \end_inset -\end_layout +\begin_inset Tabular +<lyxtabular version="3" rows="12" columns="3"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -\begin_inset ERT -status collapsed +Mode/Quality +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard +Bit-rate +\begin_inset LatexCommand index +name "bit-rate" +\end_inset -\backslash -clearpage + (bps) \end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text - +\begin_layout Standard +Quality/description \end_layout -\begin_layout Chapter -\start_of_appendix -FAQ -\end_layout +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -\begin_layout Subsection* -Vorbis is open-source -\begin_inset LatexCommand \index{open-source} +\begin_layout Standard +0 +\end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text - and patent-free -\begin_inset LatexCommand \index{patent} +\begin_layout Standard +3,950 +\end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text -; why do we need Speex? +\begin_layout Standard +Barely intelligible (mostly for comfort noise) \end_layout +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + \begin_layout Standard -Vorbis is a great project but its goals are not the same as Speex. - Vorbis is mostly aimed at compressing music and audio in general, while - Speex targets speech only. - For that reason Speex can achieve much better results than Vorbis on speech, - typically 2-4 times higher compression at equal quality. +1 \end_layout -\begin_layout Subsection* -Isn't there an open-source implementation of the GSM-FR codec? Why is Speex - necessary? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -First of all, it's not clear whether GSM-FR is covered by a Philips patent - (see http://kbs.cs.tu-berlin.de/~jutta/toast.html). - Also, GSM-FR offers mediocre quality at a relatively high bit-rate, while - Speex can offer equivalent quality at almost half the bit-rate. - Last but not least, Speex offers a wide range of bit-rates and sampling - rates, while GSM-FR is limited to 8 kHz speech at 13 kbps. +5,750 \end_layout -\begin_layout Subsection* -Under what license is Speex released? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -As of version 1.0 beta 1, Speex is released under Xiph's version of the (revised) - BSD license (see Appendix -\begin_inset LatexCommand \ref{sec:Speex-License} +Very noticeable artifacts/noise, poor intelligibility +\end_layout \end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -). - This license is one of the most permissive open-source licenses. +\begin_layout Standard +2 \end_layout -\begin_layout Subsection* -Am I allowed to use Speex in commercial software? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -Yes. - As long as you comply with the license. - This basically means you have to keep the copyright notice and you can't - use our name to promote your product without authorization. - For more details, see license in Appendix -\begin_inset LatexCommand \ref{sec:Speex-License} +7,750 +\end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text -. +\begin_layout Standard +Very noticeable artifacts/noise, good intelligibility \end_layout -\begin_layout Subsection* -Ogg -\begin_inset LatexCommand \index{Ogg} - \end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -, Speex, Vorbis -\begin_inset LatexCommand \index{Vorbis} +\begin_layout Standard +3 +\end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -, what's the difference? +\begin_layout Standard +9,800 \end_layout -\begin_layout Standard -Ogg is a container format for holding multimedia data. - Vorbis is an audio codec that uses Ogg to store its bit-streams as files, - hence the name Ogg Vorbis. - Speex also uses the Ogg format to store its bit-streams as files, so technicall -y they would be -\begin_inset Quotes eld \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +Artifacts/noise sometimes annoying +\end_layout -Ogg Speex -\begin_inset Quotes erd \end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text - files (I prefer to call them just Speex files). - One difference with Vorbis however, is that Speex is less tied with Ogg. - Actually, if you just do Voice over IP (VoIP), you don't need Ogg at all. +\begin_layout Standard +4 \end_layout -\begin_layout Subsection* -What's the extension for Speex? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -Speex files have the .spx extension. - Note, however that the Speex tools (speexenc, speexdec) do not rely on - the extension at all, so any extension will work. +12,800 \end_layout -\begin_layout Subsection* -Can I use Speex for compressing music -\begin_inset LatexCommand \index{music} - \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text -? +\begin_layout Standard +Artifacts/noise usually noticeable \end_layout +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + \begin_layout Standard -Just like Vorbis is not really adapted to speech, Speex is really not adapted - for music. - In most cases, you'll be better of with Vorbis when it comes to music. +5 \end_layout -\begin_layout Subsection* -I converted some MP3s to Speex and the quality is bad. - What's wrong? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -This is called transcoding and it will always result in much poorer quality - than the original MP3. - Unless you have a really good (size) reason to do so, never transcode speech. - This is even valid for self transcoding (tandeming), i.e. - If you decode a Speex file and re-encode it again at the same bit-rate, - you will lose quality. +16,800 \end_layout -\begin_layout Subsection* -Does Speex run on Windows? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -Compilation on Windows has been supported since version 0.8.0. - There are also several front-ends available from the website. +Artifacts/noise sometimes noticeable \end_layout -\begin_layout Subsection* -Why is encoding so slow compared to decoding? -\end_layout +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -For most kinds of compression, encoding is inherently slower than decoding. - In the case of Speex, encoding consists of finding, for each vector of - 5 to 10 samples, the entry that matches the best within a codebook consisting - of 16 to 256 entries. - On the other hand, at decoding all that needs to be done is look up the - right entry in the codebook using the encoded index. - Since a lookup is much faster than a search, the decoder works much faster - than the encoder. +6 \end_layout -\begin_layout Subsection* -Why is Speex so slow on my iPaq (or insert any platform without an FPU)? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -You probably didn't build Speex with the fixed-point option (--enable-fixed-poin -t). - Even if you did, not all modes have been ported to use fixed-point arithmetic, - so the code may be slowed down by a few float operations left (e.g. - in the wideband mode). +20,600 \end_layout -\begin_layout Subsection* -I'm getting unusual background noise (hiss) when using libspeex in my applicatio -n. - How do I fix that? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -One of the causes could be scaling of the input speech. - Speex expects signals to have a -\begin_inset Formula $\pm2^{15}$ -\end_inset +Need good headphones to tell the difference +\end_layout - (signed short) dynamic range. - If the dynamic range of your signals is too small (e.g. - -\begin_inset Formula $\pm1.0$ \end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +7 +\end_layout -), you will suffer important quantization noise. - A good target is to have a dynamic range around -\begin_inset Formula $\pm8000$ \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text - which is large enough, but small enough to make sure there's no clipping - when converting back to signed short. +\begin_layout Standard +23,800 \end_layout -\begin_layout Subsection* -I get very distorted speech when using libspeex in my application. - What's wrong? -\end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text \begin_layout Standard -There are many possible causes for that. - One of them is errors in the way the bits are manipulated. - Another possible cause is the use of the same encoder or decoder state - for more than one audio stream (channel), which produces strange effects - with the filter memories. - If the input speech has an amplitude close to -\begin_inset Formula $\pm2^{15}$ +Need good headphones to tell the difference +\end_layout + \end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -, it is possible that at decoding, the amplitude be a bit higher than that, - causing clipping when saving as 16-bit PCM. +\begin_layout Standard +8 \end_layout -\begin_layout Subsection* -How does Speex compare to other proprietary codecs? +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +27,800 \end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + \begin_layout Standard -It's hard to give precise figures since no formal listening tests have been - performed yet. - All I can say is that in terms of quality, Speex competes on the same ground - as other proprietary codecs (not necessarily the best, but not the worst - either). - Speex also has many features that are not present in most other codecs. - These include variable bit-rate (VBR), integration of narrowband and wideband, - as well as stereo support. - Of course, another area where Speex is really hard to beat is the quality/price - ratio. - Unlike many very expensive codecs, Speex is free and anyone may distribute - or modify it at will. +Hard to tell the difference even with good headphones \end_layout -\begin_layout Subsection* -Can Speex pass DTMF -\begin_inset LatexCommand \index{DTMF} +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +9 +\end_layout \end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text -? +\begin_layout Standard +34,200 \end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + \begin_layout Standard -I guess it all depends on the bit-rate used. - Though no formal testing has yet been performed, I'd say is correctly at - 8 kbps and above. - Also, make sure you don't use the lowest complexity (see SPEEX_SET_COMPLEXITY - or --comp option), as it causes significant noise. +Hard to tell the difference even with good headphones \end_layout -\begin_layout Subsection* -Can Speex pass V.9x modem signals correctly? +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +10 \end_layout +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + \begin_layout Standard -If I could do that I'd be very rich by now :-) Seriously, that would break - fundamental laws of information theory. +42,200 \end_layout -\begin_layout Subsection* -What is your (Jean-Marc) relationship with the University of Sherbrooke - and how does Speex fit into that? +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Standard +Completely transparent for voice, good quality music \end_layout +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + \begin_layout Standard -I have completed my -\emph on -Ph.D. -\emph default - at the University of Sherbrooke in 2005 in mobile robotics. - Although I did my master with the Sherbrooke speech coding group (in speech - enhancement, not coding), was no longer associated with them when developing - Speex. - It should -\series bold -not -\series default - be understood that they or the University of Sherbrooke have anything to - do with the Speex project. - Furthermore, Speex does not make use of any code or proprietary technology - developed in the Sherbrooke speech coding group. - -\end_layout -\begin_layout Subsection* -CELP, ACELP -\begin_inset LatexCommand \index{ACELP} +\backslash +end{center} +\end_layout \end_inset -, what's the difference? + \end_layout \begin_layout Standard -CELP stands for -\begin_inset Quotes eld +\begin_inset Caption + +\begin_layout Standard +Quality versus bit-rate for the wideband encoder +\begin_inset LatexCommand label +name "tab:wideband-quality" + \end_inset -Code Excited Linear Prediction -\begin_inset Quotes erd + +\end_layout + \end_inset -, while ACELP stands for -\begin_inset Quotes eld + +\end_layout + \end_inset -\emph on -Algebraic -\emph default - Code Excited Linear Prediction -\begin_inset Quotes erd +\end_layout + +\begin_layout Standard +\begin_inset ERT +status open + +\begin_layout Standard + + +\backslash +clearpage +\end_layout + \end_inset -. - That means ACELP is a CELP technique that uses an algebraic codebook represente -d as a sum of unit pulses, thus making the codebook search much more efficient. - This technique was invented at the University of Sherbrooke and is now - one of the most widely used form of CELP. - Unfortunately, since it is patented, it cannot be used in Speex. + \end_layout \begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Standard + + +\backslash +clearpage +\end_layout + +\end_inset -\newpage \end_layout \begin_layout Chapter +\start_of_appendix Sample code -\begin_inset LatexCommand \label{sec:Sample-code} +\begin_inset LatexCommand label +name "sec:Sample-code" \end_inset @@ -8331,11 +10077,15 @@ sampleenc.c \begin_layout Standard sampleenc takes a raw 16 bits/sample file, encodes it and outputs a Speex stream to stdout. - Note that the packing used is NOT compatible with that of speexenc/speexdec. + Note that the packing used is +\series bold +not +\series default + compatible with that of speexenc/speexdec. \end_layout \begin_layout Standard -\begin_inset Include \verbatiminput{sampleenc.c} +\begin_inset Include \lstinputlisting{sampleenc.c}[caption={Source code for sampleenc},label={sampleenc-source-code},numbers=left,numberstyle={\footnotesize}] preview false \end_inset @@ -8350,11 +10100,34 @@ sampledec.c \begin_layout Standard sampledec reads a Speex stream from stdin, decodes it and outputs it to a raw 16 bits/sample file. - Note that the packing used is NOT compatible with that of speexenc/speexdec. + Note that the packing used is +\series bold +not +\series default + compatible with that of speexenc/speexdec. \end_layout \begin_layout Standard -\begin_inset Include \verbatiminput{sampledec.c} +\begin_inset Include \lstinputlisting{sampledec.c}[caption={Source code for sampledec},label={sampledec-source-code},numbers=left,numberstyle={\footnotesize}] +preview false + +\end_inset + + +\end_layout + +\begin_layout Standard + +\newpage + +\end_layout + +\begin_layout Chapter +Jitter Buffer for Speex +\end_layout + +\begin_layout Standard +\begin_inset Include \lstinputlisting{../speexclient/speex_jitter_buffer.c}[caption={Example of using the jitter buffer for Speex packets},label={example-speex-jitter},numbers=left,numberstyle={\footnotesize}] preview false \end_inset @@ -8370,7 +10143,8 @@ preview false \begin_layout Chapter IETF RTP Profile -\begin_inset LatexCommand \label{sec:IETF-draft} +\begin_inset LatexCommand label +name "sec:IETF-draft" \end_inset @@ -8378,7 +10152,7 @@ IETF RTP Profile \end_layout \begin_layout Standard -\begin_inset Include \verbatiminput{draft-herlein-speex-rtp-profile-02.txt} +\begin_inset Include \verbatiminput{draft-ietf-avt-rtp-speex-01-tmp.txt} preview false \end_inset @@ -8394,7 +10168,8 @@ preview false \begin_layout Chapter Speex License -\begin_inset LatexCommand \label{sec:Speex-License} +\begin_inset LatexCommand label +name "sec:Speex-License" \end_inset @@ -8402,40 +10177,12 @@ Speex License \end_layout \begin_layout Standard -Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: -\end_layout +\begin_inset Include \verbatiminput{../COPYING} +preview false -\begin_layout Itemize -Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -\end_layout +\end_inset -\begin_layout Itemize -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. -\end_layout -\begin_layout Itemize -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. -\end_layout - -\begin_layout Standard -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. - \end_layout \begin_layout Standard @@ -8933,7 +10680,7 @@ n. \end_layout \begin_layout Standard -\begin_inset LatexCommand \printindex{} +\begin_inset LatexCommand printindex \end_inset diff --git a/doc/manual.pdf b/doc/manual.pdf Binary files differindex ec77341..23b9da9 100644 --- a/doc/manual.pdf +++ b/doc/manual.pdf diff --git a/include/speex/Makefile.am b/include/speex/Makefile.am index 08cd88b..2ae34f9 100644 --- a/include/speex/Makefile.am +++ b/include/speex/Makefile.am @@ -3,14 +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 \ - speex_resampler.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/include/speex/speex.h b/include/speex/speex.h index f17fa19..54349a1 100644 --- a/include/speex/speex.h +++ b/include/speex/speex.h @@ -155,6 +155,10 @@ extern "C" { /** Get status of input/output high-pass filtering */ #define SPEEX_GET_HIGHPASS 45 +/** 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:*/ /** Equivalent to SPEEX_SET_ENH */ @@ -406,17 +410,17 @@ 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 diff --git a/include/speex/speex_bits.h b/include/speex/speex_bits.h index 88334c4..a26fb4c 100644 --- a/include/speex/speex_bits.h +++ b/include/speex/speex_bits.h @@ -64,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); diff --git a/include/speex/speex_buffer.h b/include/speex/speex_buffer.h new file mode 100644 index 0000000..df56f5f --- /dev/null +++ b/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/include/speex/speex_callbacks.h b/include/speex/speex_callbacks.h index 7892e2f..6f450b3 100644 --- a/include/speex/speex_callbacks.h +++ b/include/speex/speex_callbacks.h @@ -119,7 +119,7 @@ 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 ehnancer on/off, no questions asked) */ +/** 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) */ diff --git a/include/speex/speex_echo.h b/include/speex/speex_echo.h index f5e4b89..91314f5 100644 --- a/include/speex/speex_echo.h +++ b/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,44 +51,73 @@ extern "C" { /** Get sampling rate */ #define SPEEX_ECHO_GET_SAMPLING_RATE 25 - -/*struct drft_lookup;*/ +/** 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 */ -SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers); +/** 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, int nb_mic, int nb_speakers); -/** Destroys an echo canceller state */ -void mc_echo_state_destroy(SpeexEchoState *st); +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ +void speex_echo_state_destroy(SpeexEchoState *st); -/** Performs echo cancellation a frame */ -void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); +/** 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 */ -void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); +/** 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 mc_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); +/** 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 */ -void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play); +/** 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 */ -void mc_echo_state_reset(SpeexEchoState *st); +/** 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 mc_echo_ctl(SpeexEchoState *st, int request, void *ptr); +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); #ifdef __cplusplus } #endif + +/** @}*/ #endif diff --git a/include/speex/speex_jitter.h b/include/speex/speex_jitter.h index 570e22b..5bae9cb 100644 --- a/include/speex/speex_jitter.h +++ b/include/speex/speex_jitter.h @@ -41,8 +41,7 @@ * @{ */ -#include "speex.h" -#include "speex_bits.h" +#include "speex/speex_types.h" #ifdef __cplusplus extern "C" { @@ -63,13 +62,16 @@ struct _JitterBufferPacket { 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_uint16_t flags; /**< Info about the returned packet */ + 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 missing */ #define JITTER_BUFFER_MISSING 1 -/** Packet is incomplete (does not cover the entive tick */ +/** Packet is incomplete (does not cover the entire tick */ #define JITTER_BUFFER_INCOMPLETE 2 /** There was an error in the jitter buffer */ #define JITTER_BUFFER_INTERNAL_ERROR -1 @@ -81,20 +83,44 @@ struct _JitterBufferPacket { #define JITTER_BUFFER_SET_MARGIN 0 /** Get minimum amount of extra buffering required (margin) */ #define JITTER_BUFFER_GET_MARGIN 1 -/* JITTER_BUFFER_SET_AVALIABLE_COUNT wouldn't make sense */ -/** Get the amount of avaliable packets currently buffered */ +/* 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 -#define JITTER_BUFFER_ADJUST_INTERPOLATE -1 -#define JITTER_BUFFER_ADJUST_OK 0 -#define JITTER_BUFFER_ADJUST_DROP 1 +/** 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 tick Number of samples per "tick", i.e. the time period of the elements that will be retrieved * @return Newly created jitter buffer state */ -JitterBuffer *jitter_buffer_init(int tick); +JitterBuffer *jitter_buffer_init(void); /** Restores jitter buffer to its original state * @@ -119,9 +145,18 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); * * @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 *start_offset); +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** 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 * @@ -135,6 +170,12 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); */ void jitter_buffer_tick(JitterBuffer *jitter); +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + /** Used like the ioctl function to control the jitter buffer parameters * * @param jitter Jitter buffer state @@ -148,45 +189,8 @@ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, /* @} */ -/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex - * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size - * to maintain good quality and low latency. This is a simplified version that works only - * with Speex, but is much easier to use. - * @{ -*/ - -/** Speex jitter-buffer state. Never use it directly! */ -typedef struct SpeexJitter { - SpeexBits current_packet; /**< Current Speex packet */ - int valid_bits; /**< True if Speex bits are valid */ - JitterBuffer *packets; /**< Generic jitter buffer state */ - void *dec; /**< Pointer to Speex decoder */ - spx_int32_t frame_size; /**< Frame size of Speex decoder */ -} SpeexJitter; - -/** Initialise jitter buffer - * - * @param jitter State of the Speex jitter buffer - * @param decoder Speex decoder to call - * @param sampling_rate Sampling rate used by the decoder -*/ -void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); - -/** Destroy jitter buffer */ -void speex_jitter_destroy(SpeexJitter *jitter); - -/** Put one packet into the jitter buffer */ -void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); - -/** Get one packet from the jitter buffer */ -void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); - -/** Get pointer timestamp of jitter buffer */ -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); - #ifdef __cplusplus } #endif -/* @} */ #endif diff --git a/include/speex/speex_preprocess.h b/include/speex/speex_preprocess.h index 59b0aab..a0d3aa3 100644 --- a/include/speex/speex_preprocess.h +++ b/include/speex/speex_preprocess.h @@ -178,6 +178,10 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** 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 + #ifdef __cplusplus } #endif diff --git a/include/speex/speex_stereo.h b/include/speex/speex_stereo.h index 45da338..a259713 100644 --- a/include/speex/speex_stereo.h +++ b/include/speex/speex_stereo.h @@ -46,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)] */ @@ -56,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); diff --git a/include/speex/speex_types.h b/include/speex/speex_types.h index c746d4f..852fed8 100644 --- a/include/speex/speex_types.h +++ b/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 <sys/types.h> typedef int16_t spx_int16_t; diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am index ff6d4bc..8dec1b5 100644 --- a/libspeex/Makefile.am +++ b/libspeex/Makefile.am @@ -6,28 +6,31 @@ EXTRA_DIST=echo_diagnostic.m INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) @OGG_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 filterbank.c resample.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 filterbank.h +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 + +libspeexdsp_la_SOURCES = preprocess.c smallft.c \ + jitter.c mdf.c fftwrap.c kiss_fft.c _kiss_fft_guts.h kiss_fft.h \ + kiss_fftr.c kiss_fftr.h filterbank.c resample.c buffer.c + +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 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 testenc_SOURCES = testenc.c @@ -37,6 +40,6 @@ testenc_wb_LDADD = libspeex.la testenc_uwb_SOURCES = testenc_uwb.c testenc_uwb_LDADD = libspeex.la testdenoise_SOURCES = testdenoise.c -testdenoise_LDADD = libspeex.la +testdenoise_LDADD = libspeexdsp.la testecho_SOURCES = testecho.c -testecho_LDADD = libspeex.la +testecho_LDADD = libspeexdsp.la diff --git a/libspeex/_kiss_fft_guts.h b/libspeex/_kiss_fft_guts.h index 526a73b..6571e79 100644 --- a/libspeex/_kiss_fft_guts.h +++ b/libspeex/_kiss_fft_guts.h @@ -45,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 diff --git a/libspeex/arch.h b/libspeex/arch.h index e2d731a..7679aea 100644 --- a/libspeex/arch.h +++ b/libspeex/arch.h @@ -35,6 +35,45 @@ #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 @@ -68,6 +107,7 @@ 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) @@ -111,9 +151,6 @@ 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 @@ -194,4 +231,11 @@ typedef float spx_word32_t; #endif + + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + + #endif diff --git a/libspeex/bits.c b/libspeex/bits.c index 5c4cb0e..311e812 100644 --- a/libspeex/bits.c +++ b/libspeex/bits.c @@ -37,7 +37,8 @@ #endif #include <speex/speex_bits.h> -#include "misc.h" +#include "arch.h" +#include "os_support.h" /* Maximum size of the bit-stream (for fixed-size allocation) */ #ifndef MAX_CHARS_PER_FRAME @@ -67,6 +68,20 @@ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) speex_bits_reset(bits); } +void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size) +{ + bits->chars = (char*)buff; + bits->buf_size = buf_size; + + bits->owner=0; + + bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR; + bits->charPtr=0; + bits->bitPtr=0; + bits->overflow=0; + +} + void speex_bits_destroy(SpeexBits *bits) { if (bits->owner) diff --git a/libspeex/buffer.c b/libspeex/buffer.c new file mode 100644 index 0000000..2f94430 --- /dev/null +++ b/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 <speex/speex_buffer.h> + +struct SpeexBuffer_ { + char *data; + int size; + int read_ptr; + int write_ptr; + int available; +}; + +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; +} + +void speex_buffer_destroy(SpeexBuffer *st) +{ + speex_free(st->data); + speex_free(st); +} + +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_move(st->data + st->write_ptr, data, end1 - st->write_ptr); + if (end > st->size) + { + end -= st->size; + speex_move(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; +} + +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_move(). 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; +} + +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_move(data, st->data + st->read_ptr, end1 - st->read_ptr); + + if (end > st->size) + { + end -= st->size; + speex_move(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; +} + +int speex_buffer_get_available(SpeexBuffer *st) +{ + return st->available; +} + +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/libspeex/cb_search.c b/libspeex/cb_search.c index cab2b71..0d9f295 100644 --- a/libspeex/cb_search.c +++ b/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" @@ -359,7 +361,11 @@ int update_target /*"erase" nbest list*/ for (j=0;j<N;j++) ndist[j]=VERY_LARGE32; - + /* This is not strictly necessary, but it provides an additonal safety + to prevent crashes in case something goes wrong in the previous + steps (e.g. NaNs) */ + for (j=0;j<N;j++) + best_nind[j] = best_ntarget[j] = 0; /*For all n-bests of previous subvector*/ for (j=0;j<N;j++) { @@ -397,6 +403,7 @@ int update_target best_nind[n] = best_nind[n-1]; best_ntarget[n] = best_ntarget[n-1]; } + /* n is equal to m here, so they're interchangeable */ ndist[m] = err; best_nind[n] = best_index[k]; best_ntarget[n] = j; diff --git a/libspeex/cb_search.h b/libspeex/cb_search.h index fd5c110..7687b45 100644 --- a/libspeex/cb_search.h +++ b/libspeex/cb_search.h @@ -36,7 +36,7 @@ #define CB_SEARCH_H #include <speex/speex_bits.h> -#include "misc.h" +#include "arch.h" /** Split codebook parameters. */ typedef struct split_cb_params { diff --git a/libspeex/fftwrap.c b/libspeex/fftwrap.c index 35e2d05..0b462c2 100644 --- a/libspeex/fftwrap.c +++ b/libspeex/fftwrap.c @@ -40,7 +40,8 @@ #define USE_KISS_FFT -#include "misc.h" +#include "arch.h" +#include "os_support.h" #define MAX_FFT_SIZE 2048 diff --git a/libspeex/fftwrap.h b/libspeex/fftwrap.h index 826b38e..dfaf489 100644 --- a/libspeex/fftwrap.h +++ b/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/libspeex/filterbank.c b/libspeex/filterbank.c index 187d5ee..e2fb71d 100644 --- a/libspeex/filterbank.c +++ b/libspeex/filterbank.c @@ -36,9 +36,10 @@ #endif #include "filterbank.h" -#include "misc.h" +#include "arch.h" #include <math.h> #include "math_approx.h" +#include "os_support.h" #ifdef FIXED_POINT @@ -59,7 +60,7 @@ FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type) int id1; int id2; df = DIV32(SHL32(sampling,15),MULT16_16(2,len)); - max_mel = toBARK(EXTRACT16(MULT16_16_Q15(QCONST16(.5f,15),sampling))); + max_mel = toBARK(EXTRACT16(sampling/2)); mel_interval = PDIV32(max_mel,banks-1); bank = (FilterBank*)speex_alloc(sizeof(FilterBank)); diff --git a/libspeex/filterbank.h b/libspeex/filterbank.h index 5ded6b9..3e889a2 100644 --- a/libspeex/filterbank.h +++ b/libspeex/filterbank.h @@ -34,7 +34,7 @@ #ifndef FILTERBANK_H #define FILTERBANK_H -#include "misc.h" +#include "arch.h" typedef struct { int *bank_left; diff --git a/libspeex/filters.c b/libspeex/filters.c index 48b4753..36ef4f6 100644 --- a/libspeex/filters.c +++ b/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 <math.h> @@ -474,7 +474,7 @@ void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1 } /* Re-synthesised a signal from the QMF low-band and high-band signals */ -void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack) +void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack) /* assumptions: all odd x[i] are zero -- well, actually they are left out of the array now N and M are multiples of 4 */ diff --git a/libspeex/filters.h b/libspeex/filters.h index b363a9a..e3a5980 100644 --- a/libspeex/filters.h +++ b/libspeex/filters.h @@ -35,7 +35,7 @@ #ifndef FILTERS_H #define FILTERS_H -#include "misc.h" +#include "arch.h" spx_word16_t compute_rms(const spx_sig_t *x, int len); spx_word16_t compute_rms16(const spx_word16_t *x, int len); @@ -59,7 +59,7 @@ void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_m void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack); -void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word32_t *mem1, spx_word32_t *mem2, char *stack); +void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack); void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack); void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack); diff --git a/libspeex/filters_arm4.h b/libspeex/filters_arm4.h index 9138610..886caed 100644 --- a/libspeex/filters_arm4.h +++ b/libspeex/filters_arm4.h @@ -33,9 +33,8 @@ */ #define OVERRIDE_NORMALIZE16 -int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len) +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) { - int i; spx_sig_t max_val=1; int sig_shift; int dead1, dead2, dead3, dead4, dead5, dead6; diff --git a/libspeex/jitter.c b/libspeex/jitter.c index 2b64453..0bf609b 100644 --- a/libspeex/jitter.c +++ b/libspeex/jitter.c @@ -32,66 +32,260 @@ */ +/* +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 <speex/speex.h> #include <speex/speex_bits.h> #include <speex/speex_jitter.h> +#include "os_support.h" #ifndef NULL #define NULL 0 #endif -#define LATE_BINS 15 -#define MAX_MARGIN 30 /**< Number of bins in margin histogram */ - #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) +#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) + +#define MAX_TIMINGS 20 +#define MAX_BUFFERS 3 +#define TOP_DELAY 20 + +/** 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_int16_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 (pos<tb->filled && 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*sizeof(tb->timing[0])); + speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0])); + } + /* Insert */ + tb->timing[pos] = timing; + tb->counts[pos] = tb->curr_count; + + tb->curr_count++; + if (tb->filled<MAX_TIMINGS) + tb->filled++; +} + + + /** 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) */ - - 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 */ - - 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 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 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 */ + 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() */ + + 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;i<MAX_BUFFERS;i++) + tot_count += tb[i].curr_count; + if (tot_count==0) + return 0; + + /* Compute cost for one lost packet */ + if (jitter->latency_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;i<MAX_BUFFERS;i++) + pos[i] = 0; + + /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late + for the current settings) */ + for (i=0;i<TOP_DELAY;i++) + { + int j; + int next=-1; + int latest = 32767; + /* Pick latest amoung all sub-windows */ + for (j=0;j<MAX_BUFFERS;j++) + { + if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) + { + next = j; + latest = tb[j].timing[pos[j]]; + } + } + if (next != -1) + { + spx_int32_t cost; + + if (i==0) + worst = latest; + best = latest; + latest = ROUND_DOWN(latest, jitter->delay_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+=2; + } + } + + 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) +JitterBuffer *jitter_buffer_init(void) { JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); if (jitter) { int i; + spx_int32_t tmp; for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) - jitter->buf[i]=NULL; - jitter->tick_size = tick; - jitter->buffer_margin = 1; + jitter->packets[i].data=NULL; + jitter->delay_step = 1; + jitter->concealment_size = 1; + /*FIXME: Should this be 0 or 1?*/ + jitter->buffer_margin = 0; jitter->late_cutoff = 50; + jitter->destroy = NULL; + jitter->latency_tradeoff = 0; + tmp = 4; + jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); jitter_buffer_reset(jitter); } return jitter; @@ -103,22 +297,27 @@ void jitter_buffer_reset(JitterBuffer *jitter) int i; for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (jitter->buf[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;i<MAX_MARGIN;i++) + jitter->buffered = 0; + jitter->auto_tradeoff = 32000; + + for (i=0;i<MAX_BUFFERS;i++) { - jitter->shortterm_margin[i] = 0; - jitter->longterm_margin[i] = 0; + tb_init(&jitter->_tb[i]); + jitter->timeBuffers[i] = &jitter->_tb[i]; } /*fprintf (stderr, "reset\n");*/ } @@ -130,17 +329,52 @@ void jitter_buffer_destroy(JitterBuffer *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;i<MAX_BUFFERS;i++) + { + for (j=0;j<jitter->timeBuffers[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) { int i,j; - spx_int32_t arrival_margin; + int late; /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ + + /* Syncing on the first packet to arrive */ if (jitter->reset_state) { jitter->reset_state=0; jitter->pointer_timestamp = packet->timestamp; - jitter->current_timestamp = packet->timestamp; + jitter->next_stop = packet->timestamp; /*fprintf(stderr, "reset to %d\n", timestamp);*/ } @@ -148,167 +382,120 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ - if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp)) + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) { /*fprintf (stderr, "cleaned (not played)\n");*/ - 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; } } - /*Find an empty slot in the buffer*/ - for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + /*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 (LT32(packet->timestamp, jitter->next_stop)) { - if (jitter->buf[i]==NULL) - break; + update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); + late = 1; + } else { + late = 0; } - - /*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) + + /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ + if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) { - int earliest=jitter->timestamp[0]; - i=0; - for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) + + /*Find an empty slot in the buffer*/ + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (!jitter->buf[i] || LT32(jitter->timestamp[j],earliest)) + if (jitter->packets[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;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) { - earliest = jitter->timestamp[j]; - i=j; + if (!jitter->packets[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; + 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);*/ } - speex_free(jitter->buf[i]); - jitter->buf[i]=NULL; - if (jitter->lost_count>20) + + /* Copy packet in buffer */ + if (jitter->destroy) { - jitter_buffer_reset(jitter); + jitter->packets[i].data = packet->data; + } else { + jitter->packets[i].data=(char*)speex_alloc(packet->len); + for (j=0;j<packet->len;j++) + jitter->packets[i].data[j]=packet->data[j]; } - /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ + jitter->packets[i].timestamp=packet->timestamp; + jitter->packets[i].span=packet->span; + jitter->packets[i].len=packet->len; + jitter->packets[i].user_data=packet->user_data; + if (late) + jitter->arrival[i] = 0; + else + jitter->arrival[i] = jitter->next_stop; } - /* Copy packet in buffer */ - jitter->buf[i]=(char*)speex_alloc(packet->len); - for (j=0;j<packet->len;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. - The arrival margin is how much in advance (or late) the packet it */ - arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->current_timestamp))/jitter->tick_size - jitter->buffer_margin; - if (arrival_margin >= -jitter->late_cutoff) - { - /* Here we compute the histogram based on the time of arrival of the packet. - This is based on a (first-order) recursive average. We keep both a short-term - histogram and a long-term histogram */ - spx_int32_t int_margin; - /* First, apply the "damping" of the recursive average to all bins */ - for (i=0;i<MAX_MARGIN;i++) - { - jitter->shortterm_margin[i] *= .98; - jitter->longterm_margin[i] *= .995; - } - /* What histogram bin the packet should be counted in */ - int_margin = LATE_BINS + arrival_margin; - if (int_margin>MAX_MARGIN-1) - int_margin = MAX_MARGIN-1; - if (int_margin<0) - int_margin = 0; - /* Add the packet to the right bin */ - jitter->shortterm_margin[int_margin] += .02; - jitter->longterm_margin[int_margin] += .005; - } else { - /* Packet has arrived *way* too late, we pretty much consider it lost and not take it into account in the histogram */ - /*fprintf (stderr, "way too late = %d\n", arrival_margin);*/ - if (jitter->lost_count>20) - { - jitter_buffer_reset(jitter); - } - } -#if 0 /* Enable to check how much is being buffered */ - if (rand()%1000==0) - { - int count = 0; - for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) - { - if (jitter->buf[j]) - count++; - } - fprintf (stderr, "buffer_size = %d\n", count); - } -#endif } /** Get one packet from the jitter buffer */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) { int i; unsigned int 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 incomplete = 0; + spx_int16_t opt; - if (jitter->interp_requested) + jitter->last_returned_timestamp = jitter->pointer_timestamp; + + if (jitter->interp_requested != 0) { - jitter->interp_requested = 0; if (start_offset) *start_offset = 0; packet->timestamp = jitter->pointer_timestamp; - packet->span = jitter->tick_size; - jitter->pointer_timestamp += jitter->tick_size; + 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; - return JITTER_BUFFER_MISSING; - } - 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);*/ + /*fprintf (stderr, "Deferred interpolate\n");*/ + + jitter->interp_requested = 0; + + jitter->buffered = packet->span - desired_span; - /* 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; - /* Count the proportion of packets that are late */ - for (i=0;i<LATE_BINS;i++) - { - late_ratio_short += jitter->shortterm_margin[i]; - late_ratio_long += jitter->longterm_margin[i]; - } - /* Count the proportion of packets that are just on time */ - ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; - ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; - early_ratio_short = early_ratio_long = 0; - /* Count the proportion of packets that are early */ - for (i=LATE_BINS+1;i<MAX_MARGIN;i++) - { - early_ratio_short += jitter->shortterm_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);*/ + return JITTER_BUFFER_MISSING; } - /* Searching for the packet that fits best */ /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (jitter->buf[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; } @@ -317,7 +504,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (jitter->buf[i] && LE32(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; } } @@ -327,7 +514,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (jitter->buf[i] && LE32(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; } } @@ -342,12 +529,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { /* check if packet starts within current chunk */ - if (jitter->buf[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; } @@ -357,31 +544,52 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { 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) { + + /* 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); + } + + + /* FIXME: Check for potential overflow */ + packet->len = jitter->packets[i].len; /* Copy packet */ - for (j=0;j<packet->len;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; + } else { + for (j=0;j<packet->len;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 = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)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]; + *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; + + packet->timestamp = jitter->packets[i].timestamp; + jitter->last_returned_timestamp = packet->timestamp; + + packet->span = jitter->packets[i].span; + 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 = *start_offset + packet->span - desired_span; + if (incomplete) return JITTER_BUFFER_INCOMPLETE; else @@ -390,41 +598,81 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 /* 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; - /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ - if (late_ratio_short > .1 || late_ratio_long > .03) + opt = compute_opt_delay(jitter); + + /* Should we force an increase in the buffer or just do normal interpolation? */ + if (opt < 0) { - /* 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--) - { - jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; - jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; - } - 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");*/ + /* 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->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; + /*fprintf (stderr, "Normal loss\n");*/ } + jitter->buffered = packet->span - desired_span; return JITTER_BUFFER_MISSING; } +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) +{ + int i, j; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[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;j<packet->len;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->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; + } +} + /** Get pointer timestamp of jitter buffer */ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) { @@ -433,85 +681,44 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) void jitter_buffer_tick(JitterBuffer *jitter) { - jitter->current_timestamp += jitter->tick_size; + if (jitter->buffered >= 0) + { + jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; + } else { + jitter->next_stop = jitter->pointer_timestamp; + speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered); + } + jitter->buffered = 0; +} + +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) +{ + if (jitter->buffered < 0) + speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered); + jitter->next_stop = jitter->pointer_timestamp - rem; } /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) { - int i; - float late_ratio_short; - float late_ratio_long; - float ontime_ratio_short; - float ontime_ratio_long; - float early_ratio_short; - float early_ratio_long; - - 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);*/ - - /* FIXME: This should be only what remaining of the current tick */ - late_ratio_short = 0; - late_ratio_long = 0; - /* Count the proportion of packets that are late */ - for (i=0;i<LATE_BINS;i++) - { - late_ratio_short += jitter->shortterm_margin[i]; - late_ratio_long += jitter->longterm_margin[i]; - } - /* Count the proportion of packets that are just on time */ - ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; - ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; - early_ratio_short = early_ratio_long = 0; - /* Count the proportion of packets that are early */ - for (i=LATE_BINS+1;i<MAX_MARGIN;i++) - { - early_ratio_short += jitter->shortterm_margin[i]; - early_ratio_long += jitter->longterm_margin[i]; - } + spx_int16_t opt = compute_opt_delay(jitter); + /*fprintf(stderr, "opt adjustment is %d ", opt);*/ - /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ - if (late_ratio_short > .1 || late_ratio_long > .03) + if (opt < 0) { - /* 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--) - { - jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; - jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; - } - jitter->shortterm_margin[0] = 0; - jitter->longterm_margin[0] = 0; - jitter->pointer_timestamp -= jitter->tick_size; - jitter->current_timestamp -= jitter->tick_size; - jitter->interp_requested = 1; - return JITTER_BUFFER_ADJUST_INTERPOLATE; - - } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8) + 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) { - /* Many frames arriving early */ - jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; - jitter->longterm_margin[0] += jitter->longterm_margin[1]; - for (i=1;i<MAX_MARGIN-1;i++) - { - jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1]; - jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; - } - 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; - return JITTER_BUFFER_ADJUST_DROP; + shift_timings(jitter, -opt); + jitter->pointer_timestamp += opt; + /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ } - return JITTER_BUFFER_ADJUST_OK; + return opt; } /* Used like the ioctl function to control the jitter buffer parameters */ @@ -530,13 +737,45 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) count = 0; for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { - if (jitter->buf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i])) + if (jitter->packets[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; @@ -544,84 +783,3 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) return 0; } - - -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; - - if (jitter->valid_bits) - { - /* 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); - } 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;i<jitter->frame_size;i++) - out[i]=0; - } - } - jitter_buffer_update_delay(jitter->packets, &packet, NULL); - jitter_buffer_tick(jitter->packets); -} - -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter) -{ - return jitter_buffer_get_pointer_timestamp(jitter->packets); -} diff --git a/libspeex/kiss_fft.c b/libspeex/kiss_fft.c index 775a257..62904cd 100644 --- a/libspeex/kiss_fft.c +++ b/libspeex/kiss_fft.c @@ -19,7 +19,8 @@ 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. @@ -86,7 +87,7 @@ static void kf_bfly4( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, - const size_t m, + int m, int N, int mm ) @@ -290,7 +291,7 @@ static void kf_bfly_generic( /*CHECKBUF(scratchbuf,nscratchbuf,p);*/ if (p>17) - speex_error("KissFFT: max radix supported is 17"); + speex_fatal("KissFFT: max radix supported is 17"); for ( u=0; u<m; ++u ) { k=u; @@ -505,7 +506,7 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout, { if (fin == fout) { - speex_error("In-place FFT not supported"); + 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,sizeof(kiss_fft_cpx)*st->nfft);*/ diff --git a/libspeex/kiss_fft.h b/libspeex/kiss_fft.h index 54627e7..fa3f2c6 100644 --- a/libspeex/kiss_fft.h +++ b/libspeex/kiss_fft.h @@ -3,7 +3,7 @@ #include <stdlib.h> #include <math.h> -#include "misc.h" +#include "arch.h" #ifdef __cplusplus extern "C" { @@ -32,7 +32,7 @@ extern "C" { #ifdef FIXED_POINT -#include "misc.h" +#include "arch.h" # define kiss_fft_scalar spx_int16_t #else # ifndef kiss_fft_scalar diff --git a/libspeex/kiss_fftr.c b/libspeex/kiss_fftr.c index 392945c..f6275b8 100644 --- a/libspeex/kiss_fftr.c +++ b/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" @@ -84,7 +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_error("kiss fft usage error: improper alloc\n"); + speex_fatal("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; @@ -138,7 +139,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar * int k, ncfft; if (st->substate->inverse == 0) { - speex_error ("kiss fft usage error: improper alloc\n"); + speex_fatal("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; @@ -177,7 +178,7 @@ void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar spx_word32_t f1kr, f1ki, twr, twi; if ( st->substate->inverse) { - speex_error("kiss fft usage error: improper alloc\n"); + speex_fatal("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; @@ -263,7 +264,7 @@ void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scala int k, ncfft; if (st->substate->inverse == 0) { - speex_error ("kiss fft usage error: improper alloc\n"); + speex_fatal ("kiss fft usage error: improper alloc\n"); } ncfft = st->substate->nfft; diff --git a/libspeex/lbr_48k_tables.c b/libspeex/lbr_48k_tables.c deleted file mode 100644 index d4d80dc..0000000 --- a/libspeex/lbr_48k_tables.c +++ /dev/null @@ -1,678 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: lbr_48k_tables.c - - 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 - - -const int dummy_epic_48k_variable=0; -#ifdef EPIC_48K - -const signed char gain_cdbk_ulbr[256] = { --31, -48, -30, 10, --19, -10, -18, 25, --33, -22, -45, 12, --5, -56, -43, 31, --30, -56, -3, 28, --59, -17, -52, 31, --41, -60, -58, 32, --64, -47, -22, 29, --30, -31, -31, 2, --29, -14, -31, 11, --22, -37, -58, 21, --31, -44, 13, 29, --37, 0, 1, 35, --46, -55, -35, 20, --56, -14, -53, 32, --8, 1, -36, 31, --29, -15, -27, 13, --29, -39, -28, 7, --43, -5, 3, 37, --51, -27, -54, 23, -10, -46, -36, 30, -3, -3, -42, 37, --27, 16, -22, 32, --34, -52, 13, 34, --31, -21, -28, 8, --34, -45, -40, 12, --20, -48, 4, 32, --40, -27, 16, 31, --6, 11, -44, 41, --35, 12, -5, 37, -19, -33, -37, 29, --29, 18, -32, 27, --29, -23, -19, 13, -16, -47, -28, 34, --34, -30, 17, 27, --20, 2, -26, 26, --38, -40, -36, 9, -15, -14, -40, 37, --39, 14, -9, 38, --15, 25, -39, 41, --26, 19, -32, 29, --39, 17, -14, 37, -10, -36, -26, 26, -14, -13, -40, 37, --29, -21, -12, 17, --8, 19, -39, 41, --36, -18, 15, 33, --32, -38, -38, 6, --19, 4, -23, 29, --38, -7, 11, 37, -9, -10, -39, 35, --37, 24, -19, 37, --34, -5, -8, 27, --20, 23, -41, 38, --4, 17, -31, 39, --17, -26, -26, 14, --24, 28, -36, 36, --7, 15, -39, 40, --42, 16, -11, 40, --29, 14, -6, 38, --36, 28, -27, 35, --21, 5, -26, 27, -11, -9, -39, 37, --38, -7, 13, 38 -}; - - -const signed char exc_12_32_table[384] = { -34, 55, 9, 55, 4, 44, -2, 25, 4, -6, 13, -22, -20, 26, -13, -56, -37, 18, 5, 28, 4, 10, 6, -7, -37, -24, -31, 22, 12, -6, -4, -7, 2, 0, -3, -2, --16, -13, -1, 9, -2, 4, 6, 5, -3, 3, 8, -1, --1, -6, -2, -1, 8, 24, 19, 33, -73, -53, 6, -18, -14, 7, 11, 8, -33, -94, -5, 7, 0, 44, 1, 19, --9, -7, -34, -16, 8, 2, 5, 0, 3, 1, -2, 3, --22, 6, -2, 12, 16, 30, 39, 25, 25, 2, 10, -2, --1, -40, -6, -51, -5, -48, -9, -33, -14, -1, -24, 15, -104, 39, 12, -9, -20, -12, -30, -10, -31, -7, -30, -8, --71, -53, -4, -11, 9, -10, 7, -10, 10, -1, 11, 8, -24, 14, 6, -3, 10, 8, 8, 11, -6, 11, 0, -2, --6, -2, 1, -1, -3, 8, -41, 27, 57, -7, 11, -16, --61, 50, 10, -10, 4, -13, 14, -7, 1, 5, -4, 4, -0, 2, -1, -2, -1, 1, 1, 0, -1, -1, -2, -3, --3, -15, 69, 60, 10, -10, -10, -29, -21, -7, -16, 2, -24, -32, 24, -18, -14, -2, -11, 11, -6, 10, 1, 3, -24, -10, 14, 18, -13, 17, -16, 4, -3, -21, -3, -11, --19, 12, -14, 26, 20, -9, 24, -15, 18, 1, -32, -2, --1, 8, -3, 4, 11, -47, 7, 46, -4, -10, -10, -2, --24, 29, -33, 6, -20, -3, 0, -12, 5, -30, 8, -13, -28, 9, 5, -11, 0, -14, -13, -22, -12, -8, -4, 1, --6, 28, 45, -18, -31, -5, 1, 2, 1, 5, 0, -3, --19, -10, 10, 27, 8, -16, -28, -9, 2, -5, 8, -1, -100, -49, 4, -43, 25, -7, 1, 9, -13, 13, -18, 13, --1, -1, 0, 2, -2, -8, 9, -46, -7, 70, 23, 7, --103, 20, 8, 42, -5, 21, -4, 4, 1, -8, 16, -8, -3, 3, 8, 4, 7, -3, -3, -4, 9, 6, 2, 13, -6, 3, -15, 11, -43, 31, 40, -13, 12, -21, -2, -3, --10, -9, 16, -35, 31, -3, -12, 8, -34, 7, 12, 22, --3, -4, -7, -12, 24, 53, -19, -43, 4, -3, -4, 6, --18, -30, -58, -17, -11, 17, 23, 34, 30, 28, 28, 15, -}; - - -const signed char cdbk_lsp_vlbr[5120]={ -23, 34, 108, 100, 102, 82, 69, 48, 52, 25, -0, -37, -55, -78, -111, -79, 58, 57, 45, 32, -27, -9, -12, -14, -41, -29, -17, -41, 44, 35, --24, -68, -72, 61, 100, 73, 100, 80, 70, 37, -12, -5, 22, 11, -10, -40, -33, -17, 19, 12, --20, -57, -94, -92, 56, 71, 48, 31, 22, -5, -41, 28, 6, -6, -12, -39, -18, -16, -30, -23, -65, 54, 41, 28, 23, 9, 26, 18, 22, 6, -17, -16, -33, -54, -87, -79, 8, -8, 44, 35, --20, -62, -78, 22, 78, 47, 44, 33, 26, 14, -8, 1, 45, 47, 72, 68, 55, 31, 36, 17, --27, -68, -86, -65, -10, 23, 8, -22, -31, 25, --4, -38, -55, -68, -96, -118, -39, 30, 28, 31, --21, -66, -47, 99, 91, 68, 78, 56, 64, 36, -33, 22, 13, -13, -36, -22, 44, 37, 54, 33, --31, -76, -106, -100, -5, 21, 7, -17, 13, 48, --26, -65, -84, -84, -46, 67, 97, 66, 58, 31, --20, -52, -32, -20, 3, 16, 27, 40, 54, 29, --6, -35, -56, -64, -8, -31, -36, 21, 26, -3, -32, 23, 1, -23, -19, -44, -45, -7, 10, -10, --24, -55, 2, 67, 72, 85, 90, 74, 77, 45, --21, -58, -45, -49, 16, 34, 13, -15, -16, 16, -8, -31, -34, -61, -83, 10, 24, 8, 56, 25, --8, -49, -74, -95, -123, -77, 6, 40, 46, 42, --21, -60, -59, -34, -12, 27, 8, -19, -48, -17, --25, -66, -78, -73, -81, -16, 14, 0, -2, 33, -78, 79, 69, 49, 44, 32, 50, 44, 46, 22, -24, 9, -4, -18, -37, -56, 22, 34, 22, 11, --19, -59, -85, -41, 46, 72, 60, 33, 29, -3, --21, -66, -70, 65, 92, 57, 61, 41, 40, 23, --4, -41, -60, -72, -102, -106, 4, 56, 57, 31, --5, -48, -62, -91, -109, 1, 76, 54, 72, 39, --21, -61, -86, -46, -34, -39, 42, 25, 15, 12, -5, -16, -36, -56, 5, 18, 11, 13, 52, 23, -12, -6, 30, 40, 59, 40, 27, 8, 19, 6, -25, 8, -9, -19, -25, -53, -40, -38, -46, -4, --17, -59, -83, 2, 58, 29, 18, -2, -17, -5, --35, -80, -111, -117, -41, -9, 14, 23, 36, 56, -48, 67, 93, 71, 77, 91, 110, 95, 83, 47, --25, -62, -97, -93, 76, 96, 73, 52, 61, 28, --9, -55, -46, 49, 33, 8, 1, -25, 28, 23, --10, -47, -60, -45, -62, -58, 56, 57, 48, 28, -34, 12, -9, 0, 34, 4, 6, 11, 3, -18, -21, -9, -16, -13, -39, -41, 14, -8, 33, 28, --7, -49, -61, 15, 34, 3, 2, -13, -28, -17, --14, -50, -46, -65, -76, -13, -10, -29, -30, 22, --28, -68, -97, -98, -8, 38, 36, 26, 25, 15, -6, -33, -9, 1, -28, -11, -19, -24, 61, 36, --15, -60, -19, 81, 58, 52, 42, 28, 66, 36, --15, -52, -71, -15, 11, -13, 38, 28, 11, -4, -34, 1, -9, -27, -57, -19, 36, 6, 14, 0, --1, -43, -14, 16, -12, -5, -14, -29, -33, -32, --13, -57, -75, -100, -111, 1, 2, 13, 48, 33, -12, 16, 100, 85, 69, 49, 40, 29, 46, 23, --4, -26, -41, -44, -7, -26, -39, -27, 18, 0, --4, -47, -51, 17, 7, -19, 13, -10, -16, 9, --24, -63, -93, -53, 25, 14, 73, 51, 35, 8, --34, -77, -106, -83, -51, -47, 2, 12, 41, 53, --13, -47, -67, -44, 42, 20, 24, 33, 21, -3, -11, -15, -29, -51, -79, -88, 22, 56, 43, 20, -11, -22, -37, -1, 61, 40, 28, 24, 22, -6, --3, -33, -50, -66, -93, -100, -16, -16, 3, 41, --18, -58, -82, -5, 95, 78, 56, 39, 30, 1, --6, -47, -28, -26, -36, 49, 55, 51, 71, 35, --6, -50, -42, -4, -32, -1, -1, -18, 67, 40, --23, -63, -56, -48, -32, 0, -14, -43, -46, 25, --17, -61, -63, 13, -1, 28, 23, 10, 67, 36, -45, 92, 124, 111, 108, 86, 77, 56, 57, 28, -50, 35, 13, 3, -2, -32, 3, 14, 6, -8, -12, -17, -24, -42, -67, -23, 67, 49, 64, 38, --21, -60, -90, -45, 32, 6, 7, -3, -15, 9, --16, -62, -73, 50, 46, 18, 7, -13, 63, 39, -19, -16, -19, 20, 5, -15, 16, -9, 5, 8, --11, -46, -42, -39, -55, -68, -62, -27, -18, 23, --23, -61, -67, -71, -29, 44, 32, 10, -15, -12, --6, -45, -43, -40, -67, -22, 42, 19, 61, 38, -9, -13, -38, -37, 40, 30, 15, 9, 11, -16, -0, -18, -29, -34, -17, -44, -50, -3, 47, 15, --3, -46, -26, 20, -10, 16, 20, -2, 43, 18, --23, -46, 46, 91, 99, 100, 99, 79, 72, 42, --1, -44, -33, -36, -56, 22, 17, 4, 71, 37, -0, -38, -49, 0, -1, -30, -21, -35, -44, -6, --32, -74, -101, -98, -14, -21, -23, 7, 26, 45, -8, -28, -44, -63, -96, -84, 34, 21, 13, 23, -10, -24, -38, -17, -29, -53, -16, -41, -14, 23, --19, -61, -76, -12, 97, 99, 79, 60, 59, 25, -5, -11, -26, -54, -26, -8, -13, 3, 25, 4, -17, 16, 4, -24, -1, 42, 60, 63, 70, 37, -10, -27, -22, -43, -62, -7, -16, 10, 75, 40, --26, -64, -96, -106, -3, 73, 73, 46, 55, 29, --2, -45, -43, 45, 46, 17, 37, 10, 30, 32, -21, -2, -18, -28, -47, -63, -38, -56, -3, 27, --17, -48, -9, 9, 3, 28, 50, 58, 73, 44, -8, -14, -32, -56, -81, -106, -35, 41, 53, 26, -1, -38, -51, -66, -100, -61, 32, 17, 66, 42, -17, 5, -6, -21, -26, -52, -36, 23, 56, 22, -6, -20, -31, -22, -19, -48, 16, 38, 22, -2, --25, -67, -93, -51, 82, 62, 71, 69, 63, 35, --12, -51, -71, -60, -76, -91, -14, 41, 35, 20, --16, -31, 22, 32, 55, 80, 98, 91, 85, 49, --21, -63, -92, -6, 57, 27, 36, 11, 60, 39, --7, -45, -67, -81, -114, -110, 0, 24, 23, 45, --18, -55, -61, -56, -60, -64, -32, -2, 58, 36, --3, -33, -51, -24, 19, -10, -19, 4, 14, -15, --19, -59, -81, -12, 7, -12, 36, 16, 48, 36, -17, -13, -32, -49, -78, -95, -1, -3, -10, 25, -15, 5, 41, 59, 108, 101, 103, 81, 70, 35, --14, -52, -37, 15, 93, 83, 66, 50, 47, 15, --3, -31, -49, -52, -9, -31, -10, 37, 62, 27, --15, -56, -82, -17, 75, 56, 36, 22, 7, -16, --24, -63, -93, -84, 25, 94, 98, 65, 60, 31, --2, -45, -39, -61, -61, 48, 35, 32, 54, 18, --19, -51, -45, -57, -28, -8, 10, 14, 38, 26, --2, -46, -38, 45, 26, 22, 48, 21, 63, 40, --22, -61, -73, -75, -67, -31, 13, 18, 51, 34, --12, -2, -1, -17, -3, -27, -3, 6, -1, -15, --16, -59, -78, 10, 36, 9, 4, -18, 33, 22, --25, -62, -97, -107, 39, 87, 69, 46, 42, 12, -11, -7, -30, -36, 19, 2, -10, -7, -4, -24, -11, -8, 25, 28, 28, 5, -4, -10, 5, -2, --10, -48, -37, -17, -38, -9, -2, -19, -30, -22, --23, -61, -79, -81, -2, 15, -4, 17, 20, 2, -25, -14, -3, -10, -38, 1, 14, -14, -9, -27, -2, -18, -38, -36, -11, -39, -36, -28, -36, -11, -32, 59, 127, 124, 127, 108, 91, 68, 64, 34, -3, -32, -37, -10, -25, -46, 12, 1, -17, -24, --29, -69, -102, -100, 2, -7, 11, 14, 1, 31, -30, -6, -4, -16, -44, -5, 3, -9, 66, 40, --9, -45, -52, -5, 37, 19, 26, 6, 51, 32, --31, -73, -96, -45, -25, -37, -15, -16, 32, 39, -3, -15, 18, 21, 28, 33, 58, 58, 69, 42, --31, -73, -99, -99, -48, 14, 21, 5, 2, 39, -7, -35, -20, 29, 2, -8, -8, -28, 38, 26, --5, -39, -64, -36, 15, -15, -11, -21, -23, 5, --8, -51, -56, 15, -1, -14, -8, -31, 36, 22, --8, -53, -68, -98, -101, 42, 49, 38, 41, 12, -10, -27, -22, 4, -23, -21, 30, -1, 22, 26, --13, -56, -42, 31, 9, -1, -10, -2, 22, -4, -15, 8, 56, 57, 45, 55, 57, 46, 72, 44, --7, -53, -26, 53, 21, 17, 0, 0, 74, 41, -3, -18, -2, 0, 19, 17, 42, 36, 47, 26, -24, -7, -23, -34, -62, -60, 6, -22, 18, 25, --11, -42, -46, -61, -83, -99, -67, -11, 28, 39, -30, -3, -10, -1, -24, -30, -1, -28, 15, 18, -19, -15, -10, -6, -35, -26, 33, 10, 56, 39, --13, -53, -82, -42, 53, 37, 18, 10, -3, -21, --21, -60, -89, -46, 89, 94, 71, 46, 42, 9, --2, -34, -44, -46, -64, -84, -1, 37, 16, 0, --17, -51, -65, -64, -7, -17, -29, -11, 52, 27, -22, -15, -16, -39, -55, 26, 36, 21, 62, 28, --2, -26, -38, -49, -55, -80, -75, 8, 20, 9, --6, -47, -61, -82, -103, -17, -15, -25, 53, 40, --8, -47, -66, -18, 56, 43, 25, 29, 39, 3, --27, -66, -86, -69, -50, -59, -34, -1, 19, 42, -3, -20, 2, 21, 72, 57, 52, 36, 31, 7, --12, -49, -61, -13, -1, -33, 5, 37, 26, 2, --27, -69, -92, -62, 2, 43, 88, 67, 64, 36, -0, -40, -4, -6, -20, 43, 33, 25, 50, 20, -14, -20, -30, -44, -73, -37, -24, -47, 26, 20, -31, 53, 111, 118, 127, 126, 121, 99, 85, 46, --14, -45, -51, -39, 24, 5, -6, 17, 46, 14, --4, -43, -45, -70, -63, 8, 14, 58, 78, 39, --8, -47, -66, -84, -114, -55, 10, -8, 32, 40, -28, 22, 42, 26, 8, -21, -16, -6, 22, 10, -24, 10, 34, 31, 35, 31, 46, 39, 59, 36, --4, -43, -62, -10, 20, -14, 2, 14, -6, -19, --21, -62, -89, -22, 62, 33, 30, 16, 15, 15, -0, -22, -31, -45, -58, -80, -66, 13, 68, 34, --16, -45, -6, 7, -6, -17, -14, -15, 2, 2, -10, -5, -22, -38, -40, -70, -60, -15, -23, 0, -22, -11, -22, -39, -67, -25, 30, 5, 58, 37, --21, -47, 6, 43, 37, 45, 65, 66, 73, 43, -2, -25, -40, -53, -72, -94, -35, 24, 9, 8, --3, 0, -3, -9, 4, -23, -10, 20, 43, 14, --2, -41, -60, -9, 57, 32, 17, 16, 6, -19, -1, -31, -36, -36, -54, -68, -77, -75, 21, 37, --19, -32, 79, 90, 92, 81, 67, 47, 52, 28, --6, -36, -57, -62, 27, 40, 21, 11, 9, -19, --10, -47, -49, -59, -74, -18, -14, -30, 25, 18, --23, -69, -82, 60, 66, 40, 75, 54, 65, 38, --19, -57, -92, -68, 66, 58, 34, 18, 1, -16, --29, -68, -99, -88, -37, -38, 13, 8, 5, 40, --22, -63, -75, 14, 15, 7, 75, 58, 59, 34, --23, -62, -82, -39, -31, -53, -27, 5, -3, 20, -13, -26, -20, 22, 2, -3, 35, 13, 54, 39, -32, 5, -13, -22, -45, -58, -1, -20, -19, 7, -30, 46, 70, 55, 89, 88, 91, 67, 56, 28, --13, -50, -63, -25, -28, -50, -23, -32, -34, 19, --13, -54, -65, -9, -20, -37, 29, 6, 11, 25, -0, -40, -55, -78, -107, -25, 47, 20, 34, 16, --20, -58, -96, -103, 38, 43, 27, 30, 15, -1, --16, -49, -52, -66, -80, -57, -44, -39, 6, 38, -0, -38, 5, 13, -8, 23, 24, 1, 7, -9, --18, -56, -64, -7, 38, 13, 11, 32, 28, 0, -14, -3, -20, -17, 4, -26, -34, -8, 19, -9, --23, -60, -83, -38, -8, -32, 11, 19, -1, -5, --5, -47, -12, 56, 38, 22, 18, -8, -5, -8, -18, -4, -24, -16, 27, 2, -6, 5, 25, -5, -13, 0, -19, -35, -23, -45, -59, -30, 19, 3, -19, -12, -23, 1, -7, -35, -14, -32, -23, 4, --23, -64, -67, -22, -27, -5, -5, -20, 20, 5, -20, 11, 83, 92, 85, 89, 69, 53, 80, 48, -15, -2, -21, -29, -18, -48, -52, -12, -11, -21, --6, -38, -55, -68, -9, 33, 22, 19, 25, -1, --8, -46, -49, -67, -64, 16, 8, -6, 32, 15, -3, -25, -46, -46, 39, 50, 34, 21, 46, 14, -8, -33, -37, -68, -82, 31, 34, 13, 19, -6, -33, 0, 5, -7, -32, 2, 22, -3, 35, 17, --23, -62, -91, -64, 6, 3, 36, 26, 7, -3, --12, -54, -60, 26, 46, 16, 30, 22, 8, -4, --23, -61, -40, 31, 58, 73, 88, 77, 74, 41, --2, -42, -49, 13, 5, -15, 22, -4, 26, 27, --13, -54, -39, 18, 2, -8, -12, 34, 56, 23, --20, -31, 27, 23, 24, 28, 39, 33, 47, 27, -36, 17, -4, -20, -30, -61, -8, 20, 0, -15, --10, -51, -72, -82, -111, -73, 34, 25, 19, 38, --10, -45, -63, -55, -46, -75, -45, 34, 34, 12, -6, -18, 29, 26, 7, -9, 0, 5, 38, 22, --7, -52, -16, 69, 43, 26, 23, 2, 51, 34, --12, -51, -59, -78, -88, 15, 20, 0, -14, 12, --3, -36, -59, -45, 60, 49, 28, 20, 16, -13, --28, -70, -90, 9, 67, 48, 90, 77, 70, 38, --10, -39, -58, -54, 15, -12, 3, 35, 27, -3, -12, -1, 28, 29, 55, 53, 80, 65, 51, 23, --17, -61, -39, 74, 56, 43, 75, 51, 58, 36, --30, -71, -93, -43, -29, -26, 4, -19, -14, 37, -3, -13, -31, -38, 11, -5, -22, -11, 43, 14, --25, -65, -80, -79, -71, 3, 37, 32, 20, 9, --20, -60, -77, -26, 18, 43, 44, 24, 22, -3, --4, -42, -22, -19, -45, -32, -35, -39, -46, 1, --25, -59, -27, -10, -7, -4, 7, 13, 25, 12, -8, -25, -32, -47, -74, -32, 27, 6, 25, 7, -41, 40, 62, 64, 64, 50, 54, 42, 49, 25, --21, -63, -88, -21, 16, -3, -4, -26, 57, 38, -8, -25, -34, 2, -8, -28, 2, -22, 12, 23, --19, -49, 10, 71, 84, 71, 66, 48, 42, 22, --20, -58, -89, -57, 62, 44, 33, 36, 25, -1, --22, -55, -27, 1, 43, 37, 46, 50, 51, 26, -1, -38, -46, 22, 34, 4, 20, -2, 3, 9, --4, -42, -49, -75, -89, -24, -25, 19, 71, 39, -5, -28, -45, -43, -63, -75, -17, -38, 14, 30, --4, -36, -62, -59, -29, -43, -4, -16, 11, 23, --19, -57, -82, -39, 26, 2, -2, 20, 11, -10, --28, -68, -92, -70, 9, -1, -15, -30, 11, 31, -1, -22, -41, -49, -30, -58, -48, 8, 4, -9, -38, 41, 108, 115, 96, 98, 103, 84, 86, 51, -15, 1, 58, 46, 26, 6, 16, 18, 41, 24, -4, -34, -14, -27, -42, 20, 18, 2, 23, 1, --22, -59, -83, -70, -22, -42, -26, 29, 29, 15, --14, -34, 11, -1, -21, -35, -3, 1, 29, 16, --16, -57, -78, -7, 17, -13, 8, -13, -6, 22, --22, -32, -21, -20, 20, -4, 10, 13, 12, -4, -8, -30, -30, -46, -71, -4, 3, -11, 4, -11, -16, 5, -15, -21, 3, -23, -25, -19, -28, -32, --28, -68, -98, -101, -34, 19, 71, 52, 49, 30, --18, -57, -82, -56, -56, -66, 15, 12, 1, 29, --21, -62, -76, -27, -33, -38, 18, 30, 54, 32, -3, -36, -10, -17, -34, -3, -8, 32, 63, 27, -1, -30, -44, -20, -13, -49, -25, 3, -14, -18, --26, -68, -80, -46, -28, 17, 42, 37, 58, 34, -30, 26, 57, 55, 49, 25, 16, 3, 24, 11, -35, 35, 67, 57, 60, 82, 114, 103, 93, 55, -18, -8, -23, -32, -53, -68, 15, 11, -6, -7, --2, -43, -29, 0, -28, -5, -5, -15, 25, -1, -4, -13, -35, -45, 14, -6, -2, 19, 16, -9, --30, -72, -93, -93, -73, -10, -15, 6, 30, 45, --23, -58, -50, -55, -74, -60, -23, 0, 6, 21, --4, -40, -63, -24, 7, -19, 4, -18, 27, 28, --12, 1, 88, 76, 74, 88, 93, 90, 80, 44, --13, -59, -43, 52, 27, 21, 15, 12, 42, 11, -22, -14, -17, -33, -57, -4, 5, -18, 40, 18, --3, -23, -43, -44, 8, -16, -14, -4, -20, -29, -35, 45, 75, 82, 111, 117, 125, 105, 89, 51, --3, -38, -57, -30, 79, 71, 48, 33, 33, 0, --17, -62, -57, 66, 67, 35, 29, 5, 22, 17, -3, -31, -34, -21, -44, -49, 42, 23, 24, 26, --23, -62, -74, -49, -30, -30, -37, -50, 9, 35, --17, -57, -71, -81, -45, 61, 58, 37, 31, 9, -3, -7, 28, 14, -2, 0, 40, 41, 58, 33, --11, -51, -74, -17, 40, 12, 8, 13, -4, -22, --16, -46, -31, -35, -49, -49, -26, -9, -7, -7, -17, -9, -24, -41, -68, -73, 38, 33, 19, 16, --15, -50, -47, -16, -24, -21, 59, 56, 53, 30, --14, -54, -57, 2, -17, -33, -34, -21, 4, -4, --23, -62, -93, -72, 48, 31, 21, 6, 3, 17, --18, -63, -79, 44, 68, 36, 45, 20, 57, 37, --29, -72, -99, -111, -86, -31, 7, 25, 39, 55, --14, -49, -53, -63, -80, -31, 24, 13, 1, -1, --9, -45, -55, -27, -31, -63, -23, 25, 13, -5, --20, -61, -80, 7, 44, 16, 54, 40, 32, 17, -24, 7, -8, -43, -62, -54, -11, 7, 35, 27, --12, -55, -59, -48, -69, -4, -1, -12, 68, 39, --12, -31, 52, 63, 53, 34, 29, 22, 36, 19, --26, -66, -97, -79, 50, 41, 40, 48, 54, 28, --2, -37, -41, -2, -11, -30, 29, 16, 4, -2, -40, 49, 56, 37, 39, 40, 64, 59, 67, 39, -11, -5, 20, 14, 25, 16, 25, 22, 37, 17, --3, -43, -46, -10, -35, -38, -35, -39, 67, 43, --7, -47, -33, -39, -60, -12, -18, 11, 43, 11, --25, -65, -91, -76, -91, -81, 0, 13, 34, 50, --9, -50, -52, 17, 0, -4, 43, 18, 63, 42, --8, -15, 15, 41, 56, 35, 51, 45, 51, 29, -0, -14, -24, -36, -43, -70, -39, 27, 33, 5, --25, -62, -81, -66, -12, -26, -16, -4, -13, 21, --29, -68, -60, -24, -3, 11, 18, 19, 30, 20, -1, -35, -42, -30, -57, -51, 13, -17, 3, 22, --8, -27, -12, -2, -7, -21, 36, 41, 34, 12, --17, -56, -62, -72, -73, -17, -26, 9, 16, 13, -11, -21, -37, -3, 16, -17, 1, -3, -18, -19, -15, -20, -19, -22, -49, -30, -7, -29, 3, -2, -17, -4, 11, 6, 51, 40, 36, 34, 48, 22, --19, -55, -29, 37, 68, 49, 45, 33, 42, 23, -7, -30, -22, 3, -22, -36, -36, -54, 20, 22, -20, 2, -15, -39, -59, -85, -10, 37, 21, 2, --15, -54, -77, -54, 74, 70, 48, 32, 51, 20, --25, -64, -70, -75, -52, 17, 6, -20, -30, 26, --13, -55, -15, 39, 16, 42, 30, 33, 62, 28, --21, -56, -30, -35, 6, 13, -4, -29, 33, 27, --17, -55, -75, -31, 3, -28, -26, 16, 18, -4, --13, -44, -60, -52, -9, -36, -38, 1, -9, -9, --12, -50, -77, -70, 43, 47, 28, 13, 43, 16, --13, -57, -80, -104, -113, -30, 43, 45, 52, 39, -3, -28, -42, -37, -58, -67, 23, 4, 38, 33, --21, -64, -74, -22, 43, 83, 81, 56, 62, 32, -34, 26, 23, 9, 14, 17, 26, 16, 37, 19, --5, -48, -49, -75, -65, 9, -6, 41, 45, 15, -32, 30, 63, 83, 90, 91, 100, 84, 85, 52, --19, -54, -68, -71, 11, 30, 13, 1, 63, 37, -44, 76, 99, 87, 117, 113, 103, 77, 64, 32, --16, -45, -12, 30, 27, 15, 57, 49, 42, 22, -9, -15, -31, -28, -36, -61, -13, -18, -33, -5, --12, -55, -8, 82, 64, 47, 42, 21, 27, 9, --15, -56, -74, -12, -19, -28, 7, -16, 53, 38, --7, -45, -64, -55, -74, -80, 35, 45, 24, 15, --25, -48, -34, -42, -6, -27, -9, 9, 13, -7, --25, -65, -84, -35, 30, 14, 24, 39, 48, 28, --22, -62, -86, -51, 64, 104, 94, 61, 62, 31, -16, -15, -25, -28, -55, -56, -10, -23, 52, 36, -10, -10, -22, -46, -71, -92, -45, -13, 16, 26, --22, -65, -84, 17, 85, 55, 66, 48, 55, 31, --1, -38, -33, -25, -49, -15, 18, -10, 41, 30, --3, -24, -47, -60, -30, -46, -17, -13, -27, 1, --7, -41, -61, -54, -50, -78, -28, 5, -2, 20, -17, -12, -27, -4, 8, -27, -5, 23, 14, -12, --36, -81, -111, -75, -17, -9, 9, 9, 39, 49, --13, -59, -54, 68, 51, 32, 35, 14, 64, 38, --11, -44, -69, -57, 11, -11, -5, 3, -16, -15, -34, 36, 41, 16, -8, -24, 11, 23, 48, 28, --17, -42, 8, 17, 45, 69, 71, 55, 49, 23, -3, -30, -46, -64, -95, -109, 2, 39, 19, 19, -25, -13, -7, 16, -11, -5, 8, -11, 52, 33, --8, -37, -57, -60, 13, 7, -14, -4, 20, -7, -7, -31, 9, 44, 20, 22, 29, 10, 52, 31, -3, -22, -36, -53, -80, -77, -35, -41, 54, 41, --21, -59, -87, -83, 12, 69, 57, 36, 32, 2, -6, -14, -34, -42, -4, -32, -27, 10, 4, -20, --11, -56, -59, 25, 8, -5, -9, -26, 68, 43, -22, 13, 40, 39, 73, 81, 95, 88, 82, 45, --18, -62, -79, 28, 60, 28, 29, 3, 23, 25, -6, -31, -39, -55, -85, -32, 7, -17, 48, 30, -7, -24, -42, -8, 39, 10, 7, 11, 1, -20, --1, -36, -26, -30, -48, 2, 46, 26, 35, 14, --17, -57, -56, -10, -4, 26, 22, 6, -4, -16, --18, -55, -59, -67, -86, -50, 3, 29, 29, 16, --25, -61, -33, 2, 26, 25, 23, 10, 24, 16, -26, 15, -8, -20, 6, -21, -16, 3, 0, -22, -13, -17, -26, -12, -31, -48, 15, -3, 1, 14, -4, -27, -33, -21, -29, -53, -52, -64, -42, 22, --11, -41, -42, -40, -42, -64, 0, 48, 50, 19, --13, -47, -42, -56, -50, 10, 3, -9, -30, -16, --4, -47, -12, 14, -13, 21, 13, 6, 73, 40, --15, -50, -63, -41, -31, -55, -60, -13, 28, 15, --6, -50, -56, -81, -95, 30, 29, 21, 71, 35, --14, -58, -65, 37, 40, 9, 18, -10, -4, 20, -31, 33, 79, 106, 119, 103, 100, 77, 64, 33, -14, 7, 56, 81, 97, 85, 85, 61, 45, 20, --24, -66, -74, -51, -17, 16, 5, -21, 22, 26, --1, -25, -38, -24, -2, -35, -26, 21, 34, 1, -20, 15, 75, 59, 39, 26, 48, 43, 50, 29, -26, 1, -15, -4, -9, -38, 9, 2, -9, -8, -20, 14, 19, 13, 2, -16, 24, 25, 19, 3, --8, -41, -58, -78, -109, -106, -27, 9, 53, 46, -17, 5, -13, -25, -24, -54, -20, 2, -21, -25, --11, -50, -48, 19, 10, -7, 46, 26, 24, 17, --28, -68, -69, -50, -49, -33, -7, 10, 20, 21, -4, -36, -21, 38, 19, 1, 25, -3, 20, 22, --18, -58, -87, -44, 82, 73, 49, 31, 19, -7, --21, -61, -78, -44, -58, -66, -9, -23, 10, 40, --25, -66, -76, -33, -33, 6, 16, -6, -21, 5, --27, -69, -77, 5, -2, -7, 6, 9, 24, 6, -1, -41, -41, -58, -79, 25, 69, 43, 68, 36, --28, -67, -85, -71, -34, 0, 14, 12, -2, 4, --2, -33, -55, -37, 37, 25, 6, 6, 29, -4, --8, -25, -11, -9, 40, 23, 17, 25, 37, 12, --21, -27, 52, 60, 47, 58, 76, 70, 69, 38, -23, 15, 22, -8, -32, -50, -10, 3, 31, 21, --10, -44, -67, -61, -29, -54, 8, 39, 21, 4, -31, 18, 30, 36, 46, 28, 50, 42, 35, 13, --21, -57, -24, -16, -15, 14, 3, -25, -17, 20, -23, 6, 24, 35, 90, 72, 64, 55, 55, 23, -7, -28, -42, -19, -36, -50, -15, -40, 29, 28, --21, -59, -66, -59, -6, 85, 83, 53, 54, 26, -2, -20, -42, -52, -27, -49, 5, 9, -9, -8, --18, -56, -84, -72, 24, 51, 32, 20, 13, -10, --13, -53, -64, -39, -63, -40, 24, 0, 34, 29, -0, -31, -45, -63, -90, -53, 3, -18, -9, 24, --13, -57, -71, 27, 19, -3, 25, -3, 45, 35, -12, -9, -26, -40, -51, -78, -24, 11, -9, -6, --12, -49, -45, -33, -50, -48, -46, -52, 2, 25, --14, -56, -84, -108, -122, -50, 4, 22, 42, 53, --6, -44, -54, -28, -41, -61, 19, 25, 6, 1, --32, -75, -95, -38, -1, -15, 7, 14, 23, 23, -11, 12, 37, 30, 38, 51, 80, 80, 82, 47, --19, -56, -69, -82, -98, -64, -29, 2, 28, 42, --18, -49, 3, 34, 41, 39, 32, 18, 21, 7, --8, 23, 39, 30, 30, 27, 41, 36, 44, 23, --16, -49, -69, -46, 1, -27, 41, 48, 35, 15, -6, -32, -36, 5, -17, -30, 2, -16, 51, 35, --23, -64, -91, -21, 71, 44, 52, 44, 40, 21, --22, -55, -40, -20, 62, 52, 38, 29, 27, 5, --27, -69, -75, -6, -8, 3, -2, -30, -42, 13, -2, -29, -42, -10, 29, 2, 15, 30, 26, 0, --27, -69, -85, -75, -54, -8, -14, -31, 16, 42, --2, -44, -54, -75, -101, -6, 4, -3, 32, 13, -7, -3, -22, -43, -14, -27, -24, -11, -14, -12, --18, -57, -85, -66, 47, 86, 75, 45, 42, 10, -18, 3, 39, 76, 80, 48, 48, 41, 44, 21, --13, -51, -73, -22, -15, -41, 3, -4, -22, 3, --10, -50, -63, -9, -23, -42, -6, -30, 11, 28, -15, -11, -29, -39, -57, -71, -23, -40, -33, 20, --2, -40, -48, -5, -21, -25, 31, 7, 53, 35, --19, -63, -72, 39, 34, 16, 37, 17, 54, 31, --18, -49, -28, -27, -40, -29, 4, 4, 19, 11, --1, -43, -41, 24, 15, -12, -4, -31, -4, 23, --11, -46, -79, -74, 34, 21, 9, 15, 3, -13, --16, -51, -56, -55, 8, 62, 50, 30, 43, 14, --1, -25, -27, -32, -46, -62, -66, -36, 53, 32, --12, -49, -77, -50, 2, -21, 23, 6, 14, 21, --5, -47, -58, -77, -105, -14, 30, 9, 73, 44, --24, -52, -4, 10, 13, 13, 27, 27, 42, 24, --10, -38, -27, -15, -24, -52, -53, 1, 14, -6, --17, -45, -13, 2, 19, 53, 83, 79, 76, 43, --21, -62, -86, -48, 40, 17, 14, -9, 40, 30, --1, -32, -51, -33, -3, -35, 2, 17, -2, -12, --21, -60, -85, -70, 33, 73, 58, 37, 67, 36, --1, -45, -39, 37, 17, 3, 18, -8, 53, 35, --8, -47, -65, -61, -87, -93, 9, 9, 2, 33, --13, -55, -56, -19, -29, 14, 17, 6, 55, 28, -5, 1, -7, -23, -26, -56, -39, 14, 11, -13, --28, -69, -89, -74, -83, -45, 1, 0, 16, 45, --3, 5, 91, 104, 119, 111, 97, 76, 72, 39, -19, 5, -12, -34, -41, -72, -67, 14, 21, 1, --17, -49, 15, 27, 13, 6, 2, 12, 27, 10, --10, -30, 18, 36, 93, 87, 87, 69, 58, 26, -37, 32, 64, 54, 53, 67, 78, 73, 80, 48, -48, 46, 38, 9, -1, 8, 47, 44, 58, 33, --23, -61, -88, -76, 27, 14, 9, 36, 36, 10, --24, -66, -88, -97, -55, 20, 19, 16, 52, 31, -4, -16, -1, -8, 2, 0, 15, 13, 29, 14, --9, -44, -66, -72, 8, 32, 37, 38, 46, 16, --22, -65, -62, 30, 22, 51, 57, 45, 68, 38, --4, -42, -53, -33, -54, -53, -4, -18, 62, 40, --5, -37, -61, -41, 35, 15, -2, -3, -12, -28, --18, -65, -55, 90, 80, 49, 44, 21, 59, 36, -5, -16, -31, -32, -37, -62, -19, -11, 9, 16, --22, -60, -67, -51, -61, -35, -5, -18, -27, 24, --18, -55, -39, -42, -40, 20, 25, 6, 6, 7, -0, -25, -42, -50, -59, -84, -31, -13, -22, 17, --32, -73, -100, -89, -21, -10, 18, 38, 31, 23, --15, -54, -57, -13, -18, -41, -32, 17, 50, 21, --16, -57, -71, -10, -8, -26, -38, -47, 42, 25, --17, -58, -82, -7, 33, 3, 30, 11, 13, 24, --23, -61, -97, -83, 82, 81, 57, 39, 31, 2, -26, 32, 104, 86, 62, 55, 77, 70, 74, 43, --8, -29, -33, -52, -74, -73, -17, 14, 39, 25, --21, -60, -68, -22, 43, 37, 51, 54, 64, 36, --5, -30, -50, -52, 22, 7, 10, 13, 0, -20, --15, -53, -61, -34, -50, -25, 15, 6, 0, -14, --10, -51, -60, 20, 77, 50, 34, 22, 8, -8, --8, -45, -52, -59, -76, -35, -43, -49, 47, 40, -41, 44, 53, 40, 41, 30, 38, 31, 46, 24, -19, 3, -15, -26, -16, -45, -13, 24, 18, -5, --3, -39, -54, -35, -49, -70, 2, -6, -19, 15, --13, -53, -36, 6, -3, 45, 50, 30, 33, 10, -15, -25, -16, -4, -32, 7, 23, 6, 67, 36, --21, -58, -87, -71, 10, -12, -16, 19, 10, 0, -9, -15, -6, 25, 31, 7, 30, 28, 20, 2, -2, -28, -42, -50, -67, -75, 12, 12, -4, 8, --17, -63, -58, 56, 49, 36, 60, 38, 37, 14, --13, -48, -38, -29, -44, -25, -20, -33, 38, 20, -2, -37, -42, -1, -18, -42, 3, -17, -19, 12, --20, -60, -73, -7, 12, -13, -22, -38, 4, 10, --8, -41, -63, -65, 42, 63, 45, 31, 31, 0, --4, -46, -38, -9, -35, 15, 50, 27, 67, 39, -3, -7, -13, -34, -51, -47, 9, 39, 54, 29, --29, -71, -89, -52, -39, -6, 3, 2, 38, 28, --14, -42, -13, -15, -19, 0, 20, 12, 37, 25, -11, -26, -24, -40, -65, -11, -13, -27, 65, 37, -0, -31, -46, -17, -21, -45, 11, -2, 25, 24, -51, 91, 102, 87, 85, 63, 57, 42, 48, 23, --4, -34, -56, -70, -10, -14, 4, 18, 3, -8, --23, -59, -39, -44, -42, -14, -10, -23, -4, 17, --2, 4, 35, 63, 69, 75, 82, 63, 78, 48, --17, -55, -60, -3, -4, -19, 4, -4, -18, -29, -2, -20, -36, -50, -32, -59, -16, 30, 16, -6, --12, -47, 24, 68, 45, 46, 41, 32, 65, 37, --4, -40, -54, -67, -96, -66, -9, -25, 42, 38, --15, 13, 58, 58, 84, 104, 119, 104, 89, 51, --15, -24, -9, -24, -27, -50, -7, 28, 29, 6, --7, -33, -35, -49, -65, -53, -37, -10, 33, 14, -31, 19, 46, 72, 67, 45, 83, 68, 63, 41, --14, -53, -59, -17, 55, 79, 64, 39, 43, 10, -}; - -const signed char cdbk_lsp2_vlbr[160]={ --20, -30, -24, 17, 7, -13, -21, 61, 56, 16, -12, 1, 10, 77, 32, 3, 7, 3, -25, -31, --4, 2, -36, -83, 18, 5, -5, 5, 11, 23, --2, -1, -11, -12, -20, -28, 68, 50, -17, -20, -5, 2, 1, 20, 17, 4, -52, -66, 36, 24, --4, -10, 7, -15, -32, 80, 37, 8, -13, -29, -33, 37, 28, 15, 8, 14, 35, 18, 50, 36, --4, -1, 4, -7, 3, 3, -11, -58, -75, 13, -13, 21, 24, -11, -12, -38, -72, 33, 15, -12, --44, -17, 83, 21, 2, 7, 0, 4, 0, -1, --25, -42, -51, 33, 20, 15, 30, -13, 9, 32, -6, 2, -8, 7, -38, -77, 6, -13, -7, 32, -48, 57, 32, -12, -10, -4, 2, -15, -29, -29, -2, 10, -9, -16, 79, 44, 7, 12, -5, -18, --23, -29, -35, -3, -3, -18, -34, -3, -39, -50, --5, -10, -8, -37, -76, 11, -4, -19, 30, 16, -}; - -#endif diff --git a/libspeex/lpc.h b/libspeex/lpc.h index d64df96..952ecdd 100644 --- a/libspeex/lpc.h +++ b/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/libspeex/lsp.h b/libspeex/lsp.h index 9d0345f..648652f 100644 --- a/libspeex/lsp.h +++ b/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/libspeex/ltp.h b/libspeex/ltp.h index bc050c6..1e435bc 100644 --- a/libspeex/ltp.h +++ b/libspeex/ltp.h @@ -33,7 +33,7 @@ */ #include <speex/speex_bits.h> -#include "misc.h" +#include "arch.h" /** LTP parameters. */ typedef struct { diff --git a/libspeex/math_approx.c b/libspeex/math_approx.c deleted file mode 100644 index 21af766..0000000 --- a/libspeex/math_approx.c +++ /dev/null @@ -1,291 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: math_approx.c - Various math approximation functions for Speex - - 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 "math_approx.h" -#include "misc.h" - -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; -} - -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 - -/* 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 - -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 - -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 - -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)))))))); -} - -spx_word16_t spx_cos_norm(spx_word32_t x) -{ - x = x&0x0001ffff; - if (x>SHL32(EXTEND32(1), 16)) - x = SUB32(SHL32(EXTEND32(1), 17),x); - if (x&0x00007fff) - { - if (x<SHL32(EXTEND32(1), 15)) - { - return _spx_cos_pi_2(EXTRACT16(x)); - } else { - return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x))); - } - } else { - if (x&0x0000ffff) - return 0; - else if (x&0x0001ffff) - return -32767; - else - return 32767; - } -} - -/* - K0 = 1 - K1 = log(2) - K2 = 3-4*log(2) - K3 = 3*log(2) - 2 -*/ -#define D0 16384 -#define D1 11356 -#define D2 3726 -#define D3 1301 -/* Input in Q11 format, output in Q16 */ -static spx_word32_t spx_exp2(spx_word16_t x) -{ - int integer; - spx_word16_t frac; - integer = SHR16(x,11); - if (integer>14) - return 0x7fffffff; - else if (integer < -15) - return 0; - frac = SHL16(x-SHL16(integer,11),3); - frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac)))))); - return VSHR32(EXTEND32(frac), -integer-2); -} - -/* Input in Q11 format, output in Q16 */ -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))))))); -} - -/* Input in Q15, output in Q14 */ -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 -spx_word16_t spx_cos(spx_word16_t x) -{ - if (x<SPX_PI_2) - { - x *= x; - return C1 + x*(C2+x*(C3+C4*x)); - } else { - x = M_PI-x; - x *= x; - return NEG16(C1 + x*(C2+x*(C3+C4*x))); - } -} - -#endif diff --git a/libspeex/math_approx.h b/libspeex/math_approx.h index 49cfda6..9ca8307 100644 --- a/libspeex/math_approx.h +++ b/libspeex/math_approx.h @@ -35,21 +35,9 @@ #ifndef MATH_APPROX_H #define MATH_APPROX_H -#include "misc.h" +#include "arch.h" -spx_word16_t spx_cos(spx_word16_t x); -spx_int16_t spx_ilog2(spx_uint32_t x); -spx_int16_t spx_ilog4(spx_uint32_t x); -#ifdef FIXED_POINT -spx_word16_t spx_sqrt(spx_word32_t x); -spx_word16_t spx_acos(spx_word16_t x); -spx_word32_t spx_exp(spx_word16_t x); -spx_word16_t spx_cos_norm(spx_word32_t x); - -/* Input in Q15, output in Q14 */ -spx_word16_t spx_atan(spx_word32_t x); - -#else +#ifndef FIXED_POINT #define spx_sqrt sqrt #define spx_acos acos @@ -57,6 +45,288 @@ spx_word16_t spx_atan(spx_word32_t x); #define spx_cos_norm(x) (cos((.5f*M_PI)*(x))) #define spx_atan atan +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 3.4642*std*ran.f; +} + + #endif + +static inline spx_int16_t spx_ilog2(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 16; + } + if (x>=256) + { + x >>= 8; + r += 8; + } + if (x>=16) + { + x >>= 4; + r += 4; + } + if (x>=4) + { + x >>= 2; + r += 2; + } + if (x>=2) + { + r += 1; + } + return r; +} + +static inline spx_int16_t spx_ilog4(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 8; + } + if (x>=256) + { + x >>= 8; + r += 4; + } + if (x>=16) + { + x >>= 4; + r += 2; + } + if (x>=4) + { + r += 1; + } + return r; +} + +#ifdef FIXED_POINT + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + spx_word32_t res; + *seed = 1664525 * *seed + 1013904223; + res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std); + return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14)); +} + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */ +/*#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4215*/ + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */ +#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4204 + +static inline spx_word16_t spx_sqrt(spx_word32_t x) +{ + int k; + spx_word32_t rt; + k = spx_ilog4(x)-6; + x = VSHR32(x, (k<<1)); + rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3))))))); + rt = VSHR32(rt,7-k); + return rt; +} + +/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */ + + +#define A1 16469 +#define A2 2242 +#define A3 1486 + +static inline spx_word16_t spx_acos(spx_word16_t x) +{ + int s=0; + spx_word16_t ret; + spx_word16_t sq; + if (x<0) + { + s=1; + x = NEG16(x); + } + x = SUB16(16384,x); + + x = x >> 1; + sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3)))))); + ret = spx_sqrt(SHL32(EXTEND32(sq),13)); + + /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/ + if (s) + ret = SUB16(25736,ret); + return ret; +} + + +#define K1 8192 +#define K2 -4096 +#define K3 340 +#define K4 -10 + +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + spx_word16_t x2; + + if (x<12868) + { + x2 = MULT16_16_P13(x,x); + return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } else { + x = SUB16(25736,x); + x2 = MULT16_16_P13(x,x); + return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x) +{ + spx_word16_t x2; + + x2 = MULT16_16_P15(x,x); + return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2)))))))); +} + +static inline spx_word16_t spx_cos_norm(spx_word32_t x) +{ + x = x&0x0001ffff; + if (x>SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17),x); + if (x&0x00007fff) + { + if (x<SHL32(EXTEND32(1), 15)) + { + return _spx_cos_pi_2(EXTRACT16(x)); + } else { + return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x))); + } + } else { + if (x&0x0000ffff) + return 0; + else if (x&0x0001ffff) + return -32767; + else + return 32767; + } +} + +/* + K0 = 1 + K1 = log(2) + K2 = 3-4*log(2) + K3 = 3*log(2) - 2 +*/ +#define D0 16384 +#define D1 11356 +#define D2 3726 +#define D3 1301 +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp2(spx_word16_t x) +{ + int integer; + spx_word16_t frac; + integer = SHR16(x,11); + if (integer>14) + return 0x7fffffff; + else if (integer < -15) + return 0; + frac = SHL16(x-SHL16(integer,11),3); + frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac)))))); + return VSHR32(EXTEND32(frac), -integer-2); +} + +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp(spx_word16_t x) +{ + if (x>21290) + return 0x7fffffff; + else if (x<-21290) + return 0; + else + return spx_exp2(MULT16_16_P14(23637,x)); +} +#define M1 32767 +#define M2 -21 +#define M3 -11943 +#define M4 4936 + +static inline spx_word16_t spx_atan01(spx_word16_t x) +{ + return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); +} + +#undef M1 +#undef M2 +#undef M3 +#undef M4 + +/* Input in Q15, output in Q14 */ +static inline spx_word16_t spx_atan(spx_word32_t x) +{ + if (x <= 32767) + { + return SHR16(spx_atan01(x),1); + } else { + int e = spx_ilog2(x); + if (e>=29) + return 25736; + x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14))); + return SUB16(25736, SHR16(spx_atan01(x),1)); + } +} +#else + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define C1 0.9999932946f +#define C2 -0.4999124376f +#define C3 0.0414877472f +#define C4 -0.0012712095f + + +#define SPX_PI_2 1.5707963268 +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + if (x<SPX_PI_2) + { + x *= x; + return C1 + x*(C2+x*(C3+C4*x)); + } else { + x = M_PI-x; + x *= x; + return NEG16(C1 + x*(C2+x*(C3+C4*x))); + } +} + +#endif + + #endif diff --git a/libspeex/mdf.c b/libspeex/mdf.c index 014ea25..d0262c7 100644 --- a/libspeex/mdf.c +++ b/libspeex/mdf.c @@ -69,11 +69,12 @@ #include "config.h" #endif -#include "misc.h" +#include "arch.h" #include "speex/speex_echo.h" #include "fftwrap.h" #include "pseudofloat.h" #include "math_approx.h" +#include "os_support.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -87,9 +88,6 @@ #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 /* 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 @@ -107,7 +105,7 @@ static const spx_float_t VAR_BACKTRACK = {16384, -12}; #else -static const spx_float_t MIN_LEAK = .0032f; +static const spx_float_t MIN_LEAK = .005f; /* Constants for the two-path filter */ static const spx_float_t VAR1_SMOOTH = .36f; @@ -367,7 +365,7 @@ static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, int P, s } for (i=0;i<M;i++) { - prop[i] += MULT16_16_Q15(QCONST16(.03f,15),max_sum); + prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum); prop_sum += EXTEND32(prop[i]); } for (i=0;i<M;i++) @@ -386,7 +384,7 @@ static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const sp { if (!(rFile && pFile && oFile)) { - speex_error("Dump files not open"); + speex_fatal("Dump files not open"); } fwrite(rec, sizeof(spx_int16_t), len, rFile); fwrite(play, sizeof(spx_int16_t), len, pFile); @@ -395,7 +393,7 @@ static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const sp #endif /** Creates a new echo canceller state */ -SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers) +SpeexEchoState *speex_echo_state_init(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)); @@ -406,10 +404,10 @@ SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic K=st->K; #ifdef DUMP_ECHO_CANCEL_DATA if (rFile || pFile || oFile) - speex_error("Opening dump files twice"); - rFile = fopen("aec_rec.sw", "w"); - pFile = fopen("aec_play.sw", "w"); - oFile = fopen("aec_out.sw", "w"); + 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; @@ -486,7 +484,7 @@ SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic } for (i=M-1;i>=0;i--) { - st->prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), st->prop[i]),sum); + st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum); } } @@ -577,7 +575,7 @@ void speex_echo_state_reset(SpeexEchoState *st) } /** Destroys an echo canceller state */ -void mc_echo_state_destroy(SpeexEchoState *st) +void speex_echo_state_destroy(SpeexEchoState *st) { spx_fft_destroy(st->fft_table); @@ -619,15 +617,14 @@ void mc_echo_state_destroy(SpeexEchoState *st) #endif } - -void mc_echo_capture2(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) +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) { - mc_echo_cancellation(st, rec, st->play_buf, out); + speex_echo_cancellation(st, rec, st->play_buf, out); st->play_buf_pos -= st->frame_size; for (i=0;i<st->play_buf_pos;i++) st->play_buf[i] = st->play_buf[i+st->frame_size]; @@ -643,7 +640,7 @@ void mc_echo_capture2(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *o } } -void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play) +void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play) { /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/ if (!st->play_buf_started) @@ -669,14 +666,14 @@ void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play) } } -/** Performs echo cancellation on a frame */ -void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout) +/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ +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) { - mc_echo_cancellation(st, in, far_end, out); + speex_echo_cancellation(st, in, far_end, out); } -/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ -void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out) +/** Performs echo cancellation on a frame */ +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; @@ -1120,7 +1117,7 @@ void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_i #endif /* We consider that the filter has had minimal adaptation if the following is true*/ - if (!st->adapted && st->sum_adapt > QCONST32(M,15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy)) + 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; } @@ -1219,7 +1216,7 @@ void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, in } -int mc_echo_ctl(SpeexEchoState *st, int request, void *ptr) +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) { switch(request) { diff --git a/libspeex/medfilter.c b/libspeex/medfilter.c index 83872e5..c061ea3 100644 --- a/libspeex/medfilter.c +++ b/libspeex/medfilter.c @@ -32,8 +32,12 @@ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "medfilter.h" -#include "misc.h" +#include "arch.h" MedianFilter *median_filter_new(int N) { diff --git a/libspeex/misc.c b/libspeex/misc.c deleted file mode 100644 index df44d86..0000000 --- a/libspeex/misc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (C) 2002-2005 Jean-Marc Valin - File: misc.c - Various utility routines for Speex - - 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 <stdlib.h> -#include <string.h> -#include <stdio.h> -#include "misc.h" - -#ifdef USER_MISC -#include "user_misc.h" -#endif - -#ifdef BFIN_ASM -#include "misc_bfin.h" -#endif - -#ifndef RELEASE -void print_vec(float *vec, int len, char *name) -{ - int i; - printf ("%s ", name); - for (i=0;i<len;i++) - printf (" %f", vec[i]); - printf ("\n"); -} -#endif - -#ifdef FIXED_DEBUG -long long spx_mips=0; -#endif - - -#ifndef OVERRIDE_SPEEX_ALLOC -void *speex_alloc (int size) -{ - return calloc(size,1); -} -#endif - -#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH -void *speex_alloc_scratch (int size) -{ - return calloc(size,1); -} -#endif - -#ifndef OVERRIDE_SPEEX_REALLOC -void *speex_realloc (void *ptr, int size) -{ - return realloc(ptr, size); -} -#endif - -#ifndef OVERRIDE_SPEEX_FREE -void speex_free (void *ptr) -{ - free(ptr); -} -#endif - -#ifndef OVERRIDE_SPEEX_FREE_SCRATCH -void speex_free_scratch (void *ptr) -{ - free(ptr); -} -#endif - -#ifndef OVERRIDE_SPEEX_MOVE -void *speex_move (void *dest, void *src, int n) -{ - return memmove(dest,src,n); -} -#endif - -#ifndef OVERRIDE_SPEEX_ERROR -void speex_error(const char *str) -{ - fprintf (stderr, "Fatal (internal) error: %s\n", str); - exit(1); -} -#endif - -#ifndef OVERRIDE_SPEEX_WARNING -void speex_warning(const char *str) -{ -#ifndef DISABLE_WARNINGS - fprintf (stderr, "warning: %s\n", str); -#endif -} -#endif - -#ifndef OVERRIDE_SPEEX_WARNING_INT -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 -void speex_notify(const char *str) -{ -#ifndef DISABLE_NOTIFICATIONS - fprintf (stderr, "notification: %s\n", str); -#endif -} -#endif - -#ifdef FIXED_POINT -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)); -} -#else -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 - -#ifndef OVERRIDE_SPEEX_PUTC -void _speex_putc(int ch, void *file) -{ - FILE *f = (FILE *)file; - fprintf(f, "%c", ch); -} -#endif diff --git a/libspeex/misc.h b/libspeex/misc.h deleted file mode 100644 index c6ea9e7..0000000 --- a/libspeex/misc.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file misc.h - @brief Various compatibility routines for Speex -*/ -/* - 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. -*/ - -#ifndef MISC_H -#define MISC_H - -#ifndef SPEEX_VERSION -#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ -#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ -#define SPEEX_MICRO_VERSION 13 /**< Micro Speex version. */ -#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ -#define SPEEX_VERSION "speex-1.2beta1" /**< Speex version string. */ -#endif - -/* A couple test to catch stupid option combinations */ -#ifdef FIXED_POINT - -#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 - -#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 - -#include "arch.h" - -#ifndef RELEASE -/** Print a named vector to stdout */ -void print_vec(float *vec, int len, char *name); -#endif - -/** Convert little endian */ -static inline spx_int32_t le_int(spx_int32_t i) -{ -#ifdef WORDS_BIGENDIAN - 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 -} - -/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */ -void *speex_alloc (int size); - -/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ -void *speex_alloc_scratch (int size); - -/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */ -void *speex_realloc (void *ptr, int size); - -/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */ -void speex_free (void *ptr); - -/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ -void speex_free_scratch (void *ptr); - -/** Speex wrapper for mem_move */ -void *speex_move (void *dest, void *src, int n); - -/** Abort with an error message to stderr (internal Speex error) */ -void speex_error(const char *str); - -/** Print warning message to stderr (programming error) */ -void speex_warning(const char *str); - -/** Print warning message with integer argument to stderr */ -void speex_warning_int(const char *str, int val); - -/** Print notification message to stderr */ -void speex_notify(const char *str); - -/** Generate a random number */ -spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed); - -/** Speex wrapper for putc */ -void _speex_putc(int ch, void *file); - -#endif diff --git a/libspeex/modes.c b/libspeex/modes.c index 9a1fe9c..33e031e 100644 --- a/libspeex/modes.c +++ b/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 <math.h> #ifndef NULL #define NULL 0 #endif -#define MAX_IN_SAMPLES 640 - -const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; /* Extern declarations for all codebooks we use here */ extern const signed char gain_cdbk_nb[]; extern const signed char gain_cdbk_lbr[]; -extern const signed char hexc_table[]; extern const signed char exc_5_256_table[]; extern const signed char exc_5_64_table[]; extern const signed char exc_8_128_table[]; extern const signed char exc_10_32_table[]; extern const signed char exc_10_16_table[]; extern const signed char exc_20_32_table[]; -extern const signed char hexc_10_32_table[]; /* Parameters for Long-Term Prediction (LTP)*/ @@ -150,29 +145,8 @@ 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 = { 0, @@ -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, @@ -384,285 +354,9 @@ 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*/ - 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}, - 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*/ - 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}, - 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, - QCONST16(.7,15), - 144 -}; - - -/* Special, non-standard 4.8 kbps mode */ -static const SpeexNBMode nb_48k_mode = { - 240, /*frameSize*/ - 48, /*subframeSize*/ - 10, /*lpcSize*/ - 17, /*pitchStart*/ - 144, /*pitchEnd*/ - 0.9, /*gamma1*/ - 0.6, /*gamma2*/ - .01, /*lag_factor*/ - QCONST16(.0003,15), /*lpc_floor*/ - 1, - {NULL, NULL, &nb_48k_submode, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, - 2, - {2,2,2,2,2,2,2,2,2,2,2} -}; - - -/* Default mode for narrowband */ -const SpeexMode speex_nb_48k_mode = { - &nb_48k_mode, - nb_mode_query, - "narrowband 4.8 kbps", - 1000, - 4, - &nb_encoder_init, - &nb_encoder_destroy, - &nb_encode, - &nb_decoder_init, - &nb_decoder_destroy, - &nb_decode, - &nb_encoder_ctl, - &nb_decoder_ctl, -}; - - -#endif int speex_mode_query(const SpeexMode *mode, int request, void *ptr) { return mode->query(mode->mode, request, ptr); } -const SpeexMode * speex_lib_get_mode (int mode) -{ -#ifdef EPIC_48K - if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode; -#endif - - if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL; - - return speex_mode_list[mode]; -} diff --git a/libspeex/modes.h b/libspeex/modes.h index 5bf1971..26e2d86 100644 --- a/libspeex/modes.h +++ b/libspeex/modes.h @@ -38,7 +38,7 @@ #include <speex/speex.h> #include <speex/speex_bits.h> -#include "misc.h" +#include "arch.h" #define NB_SUBMODES 16 #define NB_SUBMODE_BITS 4 @@ -98,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) */ @@ -123,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 */ @@ -142,10 +137,8 @@ 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 */ spx_word16_t folding_gain; @@ -153,7 +146,9 @@ typedef struct SpeexSBMode { 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/libspeex/modes_wb.c b/libspeex/modes_wb.c new file mode 100644 index 0000000..4b575b2 --- /dev/null +++ b/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 <math.h> +#include "os_support.h" + + +#ifndef NULL +#define NULL 0 +#endif + +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 +}; + + +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; +} + + +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 + +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/libspeex/nb_celp.c b/libspeex/nb_celp.c index 1828aed..b1d8592 100644 --- a/libspeex/nb_celp.c +++ b/libspeex/nb_celp.c @@ -45,8 +45,9 @@ #include "vq.h" #include <speex/speex_bits.h> #include "vbr.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" +#include "os_support.h" #include <speex/speex_callbacks.h> #ifdef VORBIS_PSYCHO @@ -107,6 +108,7 @@ const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f}; #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;i<st->lpcSize+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;i<st->lpcSize;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)); @@ -191,6 +185,7 @@ void *nb_encoder_init(const SpeexMode *m) 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,21 @@ 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; + st->abr_drift = 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 +225,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 +234,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 +274,7 @@ 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; @@ -355,8 +350,11 @@ 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]; @@ -393,19 +391,6 @@ 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; @@ -419,28 +404,9 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) 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=SHR32(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 @@ -461,6 +427,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) #endif /*VBR stuff*/ +#ifndef DISABLE_VBR if (st->vbr && (st->vbr_enabled||st->vad_enabled)) { float lsp_dist=0; @@ -572,22 +539,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*/ @@ -626,35 +587,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) { @@ -664,13 +596,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)); } @@ -695,10 +633,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) #endif -#ifdef EPIC_48K - } -#endif - /* Special case for first frame */ if (st->first) @@ -724,15 +658,6 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) spx_word16_t *exc; 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; @@ -787,18 +712,15 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) /*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;i<st->subframeSize;i++) - real_exc[i] = sw[i] = st->winBuf[i]; - } else { - for (i=0;i<st->subframeSize;i++) - real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)]; - } + for (i=0;i<st->subframeSize;i++) + real_exc[i] = sw[i] = st->winBuf[i]; + } else { + for (i=0;i<st->subframeSize;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); @@ -845,7 +767,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) exc[i]=0; /* 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 */ @@ -874,30 +796,14 @@ 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 */ for (i=0;i<st->subframeSize;i++) innov[i]=0; @@ -944,7 +850,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) signal_div(target, target, ener, st->subframeSize); /* Quantize innovation */ - if (SUBMODE(innovation_quant)) + speex_assert (SUBMODE(innovation_quant)); { /* Codebook search */ SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, @@ -980,11 +886,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) { st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize); } - } else { - speex_error("No fixed codebook"); } - for (i=0;i<st->subframeSize;i++) sw[i] = exc[i]; /* Final signal synthesis from excitation */ @@ -1015,9 +918,11 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) 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); } @@ -1053,9 +958,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"*/ @@ -1101,7 +1003,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; } @@ -1195,7 +1097,9 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack) 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; @@ -1215,10 +1119,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] = {0, 0}; - int ol_pitch_id=0; -#endif + spx_word16_t *out = (spx_word16_t*)vout; VARDECL(spx_lsp_t *interp_qlsp); @@ -1240,9 +1141,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 { @@ -1254,7 +1152,8 @@ 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_notify("Invalid mode encountered. The stream is corrupted."); @@ -1269,7 +1168,8 @@ 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_notify("Invalid mode encountered. The stream is corrupted."); @@ -1313,9 +1213,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) /* Get the sub-mode that was used */ st->submodeID = m; -#ifdef EPIC_48K - } -#endif } } @@ -1330,10 +1227,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) ALLOC(lpc, st->lpcSize, spx_coef_t); 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;i<st->frameSize;i++) @@ -1381,23 +1275,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) { @@ -1408,7 +1285,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 */ @@ -1422,9 +1299,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) 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); @@ -1452,16 +1326,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) 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 */ @@ -1477,7 +1341,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) exc[i]=0; /*Adaptive codebook contribution*/ - if (SUBMODE(ltp_unquant)) + speex_assert (SUBMODE(ltp_unquant)); { int pit_min, pit_max; /* Handle pitch constraints if any */ @@ -1510,22 +1374,11 @@ 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); + 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 /* 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. */ @@ -1542,8 +1395,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 */ @@ -1567,16 +1418,14 @@ 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); /* 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 + /* Decode second codebook (only for some modes) */ if (SUBMODE(double_codebook)) { @@ -1599,39 +1448,40 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) for (i=0;i<st->subframeSize;i++) innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT)); } - } else { - speex_error("No fixed codebook"); } /*Vocoder mode*/ if (st->submodeID==1) { - float g=ol_pitch_coef*GAIN_SCALING_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; for (i=0;i<st->subframeSize;i++) exc[i]=0; while (st->voc_offset<st->subframeSize) { + /* 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]=sqrt(1.0*ol_pitch); + 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; - - g=.5+2*(g-.6); - if (g<0) - g=0; - if (g>1) - g=1; + for (i=0;i<st->subframeSize;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); + 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 = .95*st->voc_mean + .05*exc[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; } } @@ -1720,6 +1570,14 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) /*for (i=0;i<st->frameSize;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;i<st->lpcSize;i++) st->old_qlsp[i] = qlsp[i]; @@ -1759,7 +1617,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: @@ -1807,12 +1666,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); @@ -1864,7 +1726,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr) st->bounded_pitch = 1; st->first = 1; for (i=0;i<st->lpcSize;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;i<st->lpcSize;i++) st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; for (i=0;i<st->frameSize+st->max_pitch+1;i++) @@ -1890,12 +1752,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; @@ -1919,9 +1783,11 @@ int nb_encoder_ctl(void *state, int request, void *ptr) ((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_rms_save = (spx_word16_t*)ptr; break; @@ -2013,7 +1879,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; diff --git a/libspeex/nb_celp.h b/libspeex/nb_celp.h index 1ebf717..14c776f 100644 --- a/libspeex/nb_celp.h +++ b/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 */ @@ -97,7 +92,8 @@ typedef struct EncState { 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_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_word16_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/libspeex/os_support.h b/libspeex/os_support.h new file mode 100644 index 0000000..7703461 --- /dev/null +++ b/libspeex/os_support.h @@ -0,0 +1,162 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: os_support.h + This is the (tiny) OS abstraction layer. Aside from math.h, this is the + only place where system headers are allowed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OS_SUPPORT_H +#define OS_SUPPORT_H + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +/** 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 + +/** Print warning message with integer argument to stderr */ +#ifndef OVERRIDE_SPEEX_MOVE +static inline void *speex_move (void *dest, void *src, int n) +{ + return memmove(dest,src,n); +} +#endif + +/** Print warning message with integer argument to stderr */ +#ifndef OVERRIDE_SPEEX_MOVE +static inline void *speex_memset (void *s, int c, int n) +{ + return memset(s,c,n); +} +#endif + + +#ifndef OVERRIDE_SPEEX_FATAL +static inline void _speex_fatal(const char *str, const char *file, int line) +{ + fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); + exit(1); +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING +static inline void speex_warning(const char *str) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING_INT +static inline void speex_warning_int(const char *str, int val) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s %d\n", str, val); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_NOTIFY +static inline void speex_notify(const char *str) +{ +#ifndef DISABLE_NOTIFICATIONS + fprintf (stderr, "notification: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_PUTC +/** Speex wrapper for putc */ +static inline void _speex_putc(int ch, void *file) +{ + FILE *f = (FILE *)file; + fprintf(f, "%c", ch); +} +#endif + +#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__); +#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}} + +#ifndef RELEASE +static inline void print_vec(float *vec, int len, char *name) +{ + int i; + printf ("%s ", name); + for (i=0;i<len;i++) + printf (" %f", vec[i]); + printf ("\n"); +} +#endif + +#endif + diff --git a/libspeex/preprocess.c b/libspeex/preprocess.c index b5caf4b..d94a75a 100644 --- a/libspeex/preprocess.c +++ b/libspeex/preprocess.c @@ -62,10 +62,11 @@ #include <math.h> #include "speex/speex_preprocess.h" #include "speex/speex_echo.h" -#include "misc.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 @@ -215,7 +216,7 @@ struct SpeexPreprocessState_ { spx_word32_t *S; /**< Smoothed power spectrum */ spx_word32_t *Smin; /**< See Cohen paper */ spx_word32_t *Stmp; /**< See Cohen paper */ - int *update_prob; /**< Propability of speech presence for noise update */ + int *update_prob; /**< Probability of speech presence for noise update */ spx_word16_t *zeta; /**< Smoothed a priori SNR */ spx_word32_t *echo_noise; @@ -276,7 +277,7 @@ static void conj_window(spx_word16_t *w, int len) x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */ } x = MULT16_16_Q14(QCONST16(1.271903f,14), x); - tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(QCONST32(x,2)))); + tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2)))); if (inv) tmp=SUB16(Q15_ONE,tmp); w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15)); @@ -737,6 +738,8 @@ int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x) 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)); @@ -1064,14 +1067,14 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) break; case SPEEX_PREPROCESS_SET_AGC_LEVEL: - st->agc_level = (*(float*)ptr); + 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_LEVEL: - (*(float*)ptr) = st->agc_level; + (*(spx_int32_t*)ptr) = st->agc_level; break; case SPEEX_PREPROCESS_SET_AGC_INCREMENT: st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); @@ -1110,30 +1113,34 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) 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: - *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); - st->speech_prob_start = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); + *(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: (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); break; case SPEEX_PREPROCESS_SET_PROB_CONTINUE: - *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); - st->speech_prob_continue = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); + *(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: (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); @@ -1163,6 +1170,11 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) case SPEEX_PREPROCESS_GET_ECHO_STATE: ptr = (void*)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; +#endif default: speex_warning_int("Unknown speex_preprocess_ctl request: ", request); diff --git a/libspeex/pseudofloat.h b/libspeex/pseudofloat.h index a6c4762..fa841a0 100644 --- a/libspeex/pseudofloat.h +++ b/libspeex/pseudofloat.h @@ -44,7 +44,8 @@ #ifndef PSEUDOFLOAT_H #define PSEUDOFLOAT_H -#include "misc.h" +#include "arch.h" +#include "os_support.h" #include "math_approx.h" #include <math.h> diff --git a/libspeex/quant_lsp.c b/libspeex/quant_lsp.c index d907b98..e624d1a 100644 --- a/libspeex/quant_lsp.c +++ b/libspeex/quant_lsp.c @@ -35,12 +35,13 @@ #endif #include "quant_lsp.h" +#include "os_support.h" #include <math.h> #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -#include "misc.h" +#include "arch.h" #ifdef BFIN_ASM #include "quant_lsp_bfin.h" @@ -304,11 +305,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits) #ifdef DISABLE_WIDEBAND void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) { - speex_error("Wideband and Ultra-wideband are disabled"); + speex_fatal("Wideband and Ultra-wideband are disabled"); } #else extern const signed char high_lsp_cdbk[]; @@ -382,66 +383,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) #endif - -#ifdef EPIC_48K - -extern const signed char cdbk_lsp_vlbr[5120]; -extern const signed char cdbk_lsp2_vlbr[160]; - -void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) -{ - int i; - int id; - spx_word16_t quant_weight[10]; - - for (i=0;i<order;i++) - qlsp[i]=lsp[i]; - - compute_quant_weights(qlsp, quant_weight, order); - - for (i=0;i<order;i++) - qlsp[i]=SUB16(qlsp[i],LSP_SCALING*(.25*i+.3125)); -#ifndef FIXED_POINT - for (i=0;i<order;i++) - qlsp[i] = qlsp[i]*LSP_SCALE; -#endif - - id = lsp_quant(qlsp, cdbk_lsp_vlbr, 512, order); - speex_bits_pack(bits, id, 9); - - for (i=0;i<order;i++) - qlsp[i]*=4; - - id = lsp_weight_quant(qlsp, quant_weight, cdbk_lsp2_vlbr, 16, 10); - speex_bits_pack(bits, id, 4); - -#ifdef FIXED_POINT - for (i=0;i<order;i++) - qlsp[i]=PSHR16(qlsp[i],2); -#else - for (i=0;i<order;i++) - qlsp[i]=qlsp[i]*0.00097655; -#endif - - for (i=0;i<order;i++) - qlsp[i]=lsp[i]-qlsp[i]; -} - -void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits) -{ - int i, id; - for (i=0;i<order;i++) - lsp[i]=LSP_SCALING*(.25*i+.3125); - - - id=speex_bits_unpack_unsigned(bits, 9); - for (i=0;i<10;i++) - lsp[i] += LSP_SCALING*0.0039062*cdbk_lsp_vlbr[id*10+i]; - - id=speex_bits_unpack_unsigned(bits, 4); - for (i=0;i<10;i++) - lsp[i] += LSP_SCALING*0.00097655*cdbk_lsp2_vlbr[id*10+i]; - -} - -#endif diff --git a/libspeex/quant_lsp.h b/libspeex/quant_lsp.h index c6d5bb3..3bf4d40 100644 --- a/libspeex/quant_lsp.h +++ b/libspeex/quant_lsp.h @@ -36,7 +36,7 @@ #define QUANT_LSP_H #include <speex/speex_bits.h> -#include "misc.h" +#include "arch.h" #define MAX_LSP_SIZE 20 @@ -71,13 +71,4 @@ void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) /* Decodes high-band LSPs */ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits); -#ifdef EPIC_48K -/* Quantizes narrowband LSPs with 14 bits */ -void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits); - -/* Decodes quantized narrowband LSPs (14 bits) */ -void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits); -#endif - - #endif diff --git a/libspeex/resample.c b/libspeex/resample.c index 7135a29..6ca7f2e 100644 --- a/libspeex/resample.c +++ b/libspeex/resample.c @@ -37,17 +37,23 @@ - Low memory requirement - Good *perceptual* quality (and not best SNR) - The code is working, but it's in a very early stage, so it may have - artifacts, noise or subliminal messages from satan. Also, the API - isn't stable and I can actually promise that I *will* change the API - some time in the future. + 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. -TODO list: - - Variable calculation resolution depending on quality setting - - Single vs double in float mode - - 16-bit vs 32-bit (sinc only) in fixed-point mode - - Make sure the filter update works even when changing params - after only a few samples procesed + 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 @@ -64,7 +70,8 @@ static void speex_free (void *ptr) {free(ptr);} #else /* OUTSIDE_SPEEX */ #include "speex/speex_resampler.h" -#include "misc.h" +#include "arch.h" +#include "os_support.h" #endif /* OUTSIDE_SPEEX */ #include <math.h> @@ -84,6 +91,7 @@ static void speex_free (void *ptr) {free(ptr);} #define OVERSAMPLE 8 #define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) #ifndef NULL #define NULL 0 @@ -576,10 +584,10 @@ static void update_filter(SpeexResamplerState *st) } for (i=0;i<st->den_rate;i++) { - spx_uint32_t j; + spx_int32_t j; for (j=0;j<st->filt_len;j++) { - st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + 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 @@ -615,6 +623,10 @@ static void update_filter(SpeexResamplerState *st) 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; @@ -633,7 +645,7 @@ static void update_filter(SpeexResamplerState *st) /*speex_warning("reinit filter");*/ } else if (st->filt_len > old_length) { - spx_uint32_t i; + spx_int32_t i; /* Increase the filter length */ /*speex_warning("increase filter size");*/ int old_alloc_size = st->mem_alloc_size; @@ -642,32 +654,55 @@ static void update_filter(SpeexResamplerState *st) st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); st->mem_alloc_size = st->filt_len-1; } - for (i=0;i<st->nb_channels;i++) + for (i=st->nb_channels-1;i>=0;i--) { - spx_uint32_t j; - /* Copy data going backward */ - for (j=0;j<old_length-1;j++) - st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*old_alloc_size+(old_length-2-j)]; - /* Then put zeros for lack of anything better */ - for (;j<st->filt_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 - old_length)/2; + 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;j<st->magic_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;j<olen-1;j++) + st->mem[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 (;j<st->filt_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;j<st->filt_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 */ - /*speex_warning("decrease filter size (unimplemented)");*/ - /* Adjust last_sample (which will likely end up negative) */ - /*st->last_sample += (st->filt_len - old_length)/2;*/ + /* 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;i<st->nb_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;j<st->filt_len-1+st->magic_samples[i];j++) + for (j=0;j<st->filt_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; } } @@ -756,15 +791,19 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t /* Handle the case where we have samples left from a reduction in filter length */ if (st->magic_samples[channel_index]) { + int istride_save; spx_uint32_t tmp_in_len; spx_uint32_t tmp_magic; + + istride_save = st->in_stride; tmp_in_len = st->magic_samples[channel_index]; tmp_out_len = *out_len; - /* FIXME: Need to handle the case where the out array is too small */ /* magic_samples needs to be set to zero to avoid infinite recursion */ tmp_magic = st->magic_samples[channel_index]; st->magic_samples[channel_index] = 0; + st->in_stride = 1; speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len); + st->in_stride = istride_save; /*speex_warning_int("extra samples:", tmp_out_len);*/ /* If we couldn't process all "magic" input samples, save the rest for next time */ if (tmp_in_len < tmp_magic) @@ -774,7 +813,8 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t for (i=0;i<st->magic_samples[channel_index];i++) mem[N-1+i]=mem[N-1+i+tmp_in_len]; } - out += tmp_out_len; + out += tmp_out_len*st->out_stride; + *out_len -= tmp_out_len; } /* Call the right resampler through the function ptr */ @@ -919,11 +959,13 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const flo { 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;i<st->nb_channels;i++) { + *out_len = bak_len; speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); } st->in_stride = istride_save; @@ -931,15 +973,18 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const flo return RESAMPLER_ERR_SUCCESS; } + 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;i<st->nb_channels;i++) { + *out_len = bak_len; speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); } st->in_stride = istride_save; @@ -960,16 +1005,19 @@ void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, sp 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) { - int fact; + 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<=sqrt(IMAX(in_rate, out_rate));fact++) + for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) { while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) { @@ -978,6 +1026,17 @@ int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_nu } } + if (old_den > 0) + { + for (i=0;i<st->nb_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; diff --git a/libspeex/sb_celp.c b/libspeex/sb_celp.c index 50b9824..619512c 100644 --- a/libspeex/sb_celp.c +++ b/libspeex/sb_celp.c @@ -35,7 +35,6 @@ #include <math.h> #include "sb_celp.h" -#include "stdlib.h" #include "filters.h" #include "lpc.h" #include "lsp.h" @@ -44,8 +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. */ @@ -61,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 @@ -179,6 +183,7 @@ static const float h0[64] = { #endif +extern const spx_word16_t lag_window[]; extern const spx_word16_t lpc_window[]; @@ -210,7 +215,6 @@ void *sb_encoder_init(const SpeexMode *m) 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; @@ -221,7 +225,6 @@ 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; @@ -234,9 +237,7 @@ void *sb_encoder_init(const SpeexMode *m) st->window= lpc_window; - st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - for (i=0;i<st->lpcSize+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)); @@ -250,10 +251,9 @@ void *sb_encoder_init(const SpeexMode *m) st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); for (i=0;i<st->lpcSize;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); +#ifndef DISABLE_VBR st->vbr_quality = 8; st->vbr_enabled = 0; st->vbr_max = 0; @@ -261,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); @@ -285,8 +286,6 @@ void sb_encoder_destroy(void *state) speex_free(st->h0_mem); speex_free(st->h1_mem); - speex_free(st->lagWindow); - speex_free(st->old_lsp); speex_free(st->old_qlsp); speex_free(st->interp_qlpc); @@ -339,6 +338,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) /* 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 */ @@ -346,6 +346,8 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) e_low = compute_rms16(low, st->frame_size); e_high = compute_rms16(high, st->frame_size); } +#endif /* #ifndef DISABLE_VBR */ + 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*/ @@ -421,6 +423,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits) } } +#ifndef DISABLE_VBR /* VBR code */ if ((st->vbr_enabled || st->vad_enabled) && !dtx) { @@ -497,6 +500,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) { @@ -787,8 +791,8 @@ void *sb_decoder_init(const SpeexMode *m) st->first=1; - 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->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->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t)); @@ -1130,6 +1134,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); @@ -1144,6 +1149,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; @@ -1161,6 +1168,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; @@ -1191,6 +1200,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; @@ -1253,7 +1264,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) int i; st->first = 1; for (i=0;i<st->lpcSize;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;i<st->lpcSize;i++) st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; for (i=0;i<QMF_ORDER;i++) @@ -1277,6 +1288,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); @@ -1308,6 +1320,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; @@ -1332,9 +1345,11 @@ int sb_encoder_ctl(void *state, int request, void *ptr) ((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_rms_save = (spx_word16_t*)ptr; break; @@ -1441,7 +1456,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; diff --git a/libspeex/sb_celp.h b/libspeex/sb_celp.h index a0dc3af..e8c3761 100644 --- a/libspeex/sb_celp.h +++ b/libspeex/sb_celp.h @@ -50,9 +50,7 @@ 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 */ @@ -62,7 +60,7 @@ typedef struct SBEncState { spx_word16_t *h0_mem, *h1_mem; const spx_word16_t *window; /**< LPC analysis window */ - spx_word16_t *lagWindow; /**< Auto-correlation window */ + 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_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ @@ -74,6 +72,7 @@ typedef struct SBEncState { 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) */ @@ -84,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; @@ -109,7 +109,7 @@ typedef struct SBDecState { int lpc_enh_enabled; char *stack; - spx_word32_t *g0_mem, *g1_mem; + spx_word16_t *g0_mem, *g1_mem; spx_word16_t *excBuf; spx_lsp_t *old_qlsp; diff --git a/libspeex/smallft.c b/libspeex/smallft.c index 269549d..5c26d01 100644 --- a/libspeex/smallft.c +++ b/libspeex/smallft.c @@ -34,7 +34,8 @@ #include <math.h> #include "smallft.h" -#include "misc.h" +#include "arch.h" +#include "os_support.h" static void drfti1(int n, float *wa, int *ifac){ static int ntryh[4] = { 4,2,3,5 }; diff --git a/libspeex/speex.c b/libspeex/speex.c index 846e021..78e1a7a 100644 --- a/libspeex/speex.c +++ b/libspeex/speex.c @@ -38,6 +38,7 @@ #include "modes.h" #include <math.h> +#include "os_support.h" #ifndef NULL #define NULL 0 @@ -83,6 +84,7 @@ int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out) #ifdef FIXED_POINT +#ifndef DISABLE_FLOAT_API int speex_encode(void *state, float *in, SpeexBits *bits) { int i; @@ -100,6 +102,7 @@ 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) { @@ -108,6 +111,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) return (mode)->enc(state, in, bits); } +#ifndef DISABLE_FLOAT_API int speex_decode(void *state, SpeexBits *bits, float *out) { int i, ret; @@ -119,6 +123,7 @@ 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) { @@ -208,29 +213,6 @@ 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) diff --git a/libspeex/speex_callbacks.c b/libspeex/speex_callbacks.c index 682322e..d1158b2 100644 --- a/libspeex/speex_callbacks.c +++ b/libspeex/speex_callbacks.c @@ -37,7 +37,8 @@ #endif #include <speex/speex_callbacks.h> -#include "misc.h" +#include "arch.h" +#include "os_support.h" int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) { @@ -95,6 +96,7 @@ int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data return 0; } +#ifndef DISABLE_VBR int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) { spx_int32_t vbr; @@ -102,6 +104,7 @@ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) 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) { @@ -111,6 +114,7 @@ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) return 0; } +#ifndef DISABLE_VBR int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) { float qual; @@ -118,7 +122,7 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da 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) { diff --git a/libspeex/speex_header.c b/libspeex/speex_header.c index 8e10851..2efb3e3 100644 --- a/libspeex/speex_header.c +++ b/libspeex/speex_header.c @@ -35,14 +35,31 @@ #include "config.h" #endif -#include "misc.h" +#include "arch.h" #include <speex/speex_header.h> #include <speex/speex.h> +#include "os_support.h" #ifndef NULL #define NULL 0 #endif +/** Convert little endian */ +static inline spx_int32_t le_int(spx_int32_t i) +{ +#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) + spx_uint32_t ui, ret; + ui = i; + ret = ui>>24; + ret |= (ui>>8)&0x0000ff00; + ret |= (ui<<8)&0x00ff0000; + ret |= (ui<<24); + return ret; +#else + return i; +#endif +} + #define ENDIAN_SWITCH(x) {x=le_int(x);} diff --git a/libspeex/stack_alloc.h b/libspeex/stack_alloc.h index cb048fa..f9056b4 100644 --- a/libspeex/stack_alloc.h +++ b/libspeex/stack_alloc.h @@ -36,11 +36,15 @@ #define STACK_ALLOC_H #ifdef USE_ALLOCA -#ifdef WIN32 -#include <malloc.h> -#else -#include <alloca.h> -#endif +# ifdef WIN32 +# include <malloc.h> +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# include <stdlib.h> +# endif +# endif #endif /** diff --git a/libspeex/stereo.c b/libspeex/stereo.c index f18387e..bc6e1ba 100644 --- a/libspeex/stereo.c +++ b/libspeex/stereo.c @@ -35,12 +35,76 @@ #include <speex/speex_stereo.h> #include <speex/speex_callbacks.h> +#include "math_approx.h" #include "vq.h" #include <math.h> +#include "os_support.h" + +typedef struct RealSpeexStereoState { + spx_word32_t balance; /**< Left/right balance info */ + spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ + spx_word32_t smooth_left; /**< Smoothed left channel gain */ + spx_word32_t smooth_right; /**< Smoothed right channel gain */ + spx_uint32_t reserved1; /**< Reserved for future use */ + spx_int32_t reserved2; /**< Reserved for future use */ +} RealSpeexStereoState; + /*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ +#ifndef FIXED_POINT static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; +static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f}; +#else +static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384}; +static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696}; +static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104, + 134, 172, 221, 284, 364, 468, 600, 771, + 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696, + 7314, 9392, 12059, 15484, 19882, 25529, 32766}; +#endif + +/* 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 +SpeexStereoState *speex_stereo_state_init() +{ + SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState)); + speex_stereo_state_reset(stereo); + return stereo; +} + +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 +} + +void speex_stereo_state_destroy(SpeexStereoState *stereo) +{ + speex_free(stereo); +} + +#ifndef DISABLE_FLOAT_API void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) { int i, tmp; @@ -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) { int i, tmp; - float e_left=0, e_right=0, e_tot=0; - float balance, e_ratio; + spx_word32_t e_left=0, e_right=0, e_tot=0; + spx_word32_t balance, e_ratio; + spx_word32_t largest, smallest; + int balance_id; +#ifdef FIXED_POINT + int shift; +#endif + + /* In band marker */ + speex_bits_pack(bits, 14, 5); + /* Stereo marker */ + speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); + for (i=0;i<frame_size;i++) { - e_left += ((float)data[2*i])*data[2*i]; - e_right += ((float)data[2*i+1])*data[2*i+1]; + e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8); + e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8); +#ifdef FIXED_POINT + /* I think this is actually unbiased */ + data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1); +#else data[i] = .5*(((float)data[2*i])+data[2*i+1]); - e_tot += ((float)data[i])*data[i]; +#endif + e_tot += SHR32(MULT16_16(data[i],data[i]),8); } - balance=(e_left+1)/(e_right+1); - e_ratio = e_tot/(1+e_left+e_right); - - /*Quantization*/ - speex_bits_pack(bits, 14, 5); - speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); - - balance=4*log(balance); - - /*Pack sign*/ - if (balance>0) + if (e_left > e_right) + { speex_bits_pack(bits, 0, 1); - else + largest = e_left; + smallest = e_right; + } else { speex_bits_pack(bits, 1, 1); - balance=floor(.5+fabs(balance)); - if (balance>30) - balance=31; + largest = e_right; + smallest = e_left; + } + + /* Balance quantization */ +#ifdef FIXED_POINT + shift = spx_ilog2(largest)-15; + largest = VSHR32(largest, shift-4); + smallest = VSHR32(smallest, shift); + balance = DIV32(largest, ADD32(smallest, 1)); + if (balance > 32767) + balance = 32767; + balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); +#else + balance=(largest+1.)/(smallest+1.); + balance=4*log(balance); + balance_id=floor(.5+fabs(balance)); + if (balance_id>30) + balance_id=31; +#endif - speex_bits_pack(bits, (int)balance, 5); + speex_bits_pack(bits, balance_id, 5); + + /* "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 - /*Quantize energy ratio*/ - tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); + 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 +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; - 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)); + + /* 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_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); } } +#endif /* #ifndef DISABLE_FLOAT_API */ -void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo) +void speex_decode_stereo_int(spx_int16_t *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; - 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)); + + /* 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); } } 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/libspeex/testecho.c b/libspeex/testecho.c index 60d76d5..01b4539 100644 --- a/libspeex/testecho.c +++ b/libspeex/testecho.c @@ -7,7 +7,6 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <unistd.h> #include "speex/speex_echo.h" #include "speex/speex_preprocess.h" @@ -17,37 +16,38 @@ int main(int argc, char **argv) { - int echo_fd, ref_fd, e_fd; + 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 = mc_echo_state_init(NN, TAIL, 1, 1); - den = speex_preprocess_state_init(NN, 8000); - int tmp = 8000; - mc_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp); + st = speex_echo_state_init(NN, TAIL, 1, 1); + 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); - mc_echo_cancellation(st, ref_buf, echo_buf, e_buf); + 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); - write(e_fd, e_buf, NN*2); + fwrite(e_buf, sizeof(short), NN, e_fd); } - mc_echo_state_destroy(st); + 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/libspeex/testenc.c b/libspeex/testenc.c index eabd02c..44c132f 100644 --- a/libspeex/testenc.c +++ b/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/libspeex/testenc_uwb.c b/libspeex/testenc_uwb.c index e9bf18a..503b64d 100644 --- a/libspeex/testenc_uwb.c +++ b/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/libspeex/testenc_wb.c b/libspeex/testenc_wb.c index 8e515cb..3f13184 100644 --- a/libspeex/testenc_wb.c +++ b/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<FRAME_SIZE;i++) - in_float[i]=in_short[i]; speex_bits_reset(&bits); speex_encode_int(st, in_short, &bits); diff --git a/libspeex/vbr.c b/libspeex/vbr.c index d24ec0f..5b7dd9b 100644 --- a/libspeex/vbr.c +++ b/libspeex/vbr.c @@ -45,17 +45,18 @@ #define MIN_ENERGY 6000 #define NOISE_POW .3 +#ifndef DISABLE_VBR const float vbr_nb_thresh[9][11]={ {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */ - { 3.5f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */ + { 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */ {10.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, 9.0f, 8.0f, 7.0f, 6.5f, 6.0f, 5.0f, 4.0f, 2.0f}, /* 11 kbps */ - {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 9.0f, 8.0f, 7.0f, 6.5f, 5.0f, 3.0f}, /* 15 kbps */ - {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 6.5f, 4.0f}, /* 18 kbps */ - {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f}, /* 24 kbps */ - { 8.0f, 5.0f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 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 */ }; @@ -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/libspeex/vbr.h b/libspeex/vbr.h index 34e1d4c..ff1e3e4 100644 --- a/libspeex/vbr.h +++ b/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/libspeex/vorbis_psy.c b/libspeex/vorbis_psy.c index 6aac56f..ec32c6e 100644 --- a/libspeex/vorbis_psy.c +++ b/libspeex/vorbis_psy.c @@ -35,7 +35,7 @@ #ifdef VORBIS_PSYCHO -#include "misc.h" +#include "arch.h" #include "smallft.h" #include "lpc.h" #include "vorbis_psy.h" diff --git a/libspeex/vorbis_psy.h b/libspeex/vorbis_psy.h index fbdb7c5..6871057 100644 --- a/libspeex/vorbis_psy.h +++ b/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/libspeex/vq.c b/libspeex/vq.c index d40133f..609f124 100644 --- a/libspeex/vq.c +++ b/libspeex/vq.c @@ -36,7 +36,7 @@ #include "vq.h" #include "stack_alloc.h" -#include "misc.h" +#include "arch.h" #ifdef _USE_SSE #include <xmmintrin.h> @@ -70,29 +70,6 @@ int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries) return i; } -/*Finds the index of the entry in a codebook that best matches the input*/ -int vq_index(float *in, const float *codebook, int len, int entries) -{ - int i,j; - float min_dist=0; - int best_index=0; - for (i=0;i<entries;i++) - { - float dist=0; - for (j=0;j<len;j++) - { - float tmp = in[j]-*codebook++; - dist += tmp*tmp; - } - if (i==0 || dist<min_dist) - { - min_dist=dist; - best_index=i; - } - } - return best_index; -} - #ifndef OVERRIDE_VQ_NBEST /*Finds the indices of the n-best entries in a codebook*/ diff --git a/libspeex/vq.h b/libspeex/vq.h index 7ca8197..5a4ced2 100644 --- a/libspeex/vq.h +++ b/libspeex/vq.h @@ -35,12 +35,11 @@ #ifndef VQ_H #define VQ_H -#include "misc.h" +#include "arch.h" int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries); int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries); -int vq_index(float *in, const float *codebook, int len, int entries); #ifdef _USE_SSE #include <xmmintrin.h> void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack); diff --git a/libspeex/window.c b/libspeex/window.c index 65b1917..ac042d4 100644 --- a/libspeex/window.c +++ b/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,6 +68,10 @@ 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.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, diff --git a/regression-fixes/1-resampler_unsigned_fix.patch b/regression-fixes/1-resampler_unsigned_fix.patch new file mode 100644 index 0000000..99a4c8a --- /dev/null +++ b/regression-fixes/1-resampler_unsigned_fix.patch @@ -0,0 +1,17 @@ +diff --git a/libspeex/resample.c b/libspeex/resample.c +index 4403f78..48ffcef 100644 +--- a/libspeex/resample.c ++++ b/libspeex/resample.c +@@ -561,10 +561,10 @@ static void update_filter(SpeexResamplerState *st) + } + for (i=0;i<st->den_rate;i++) + { +- spx_uint32_t j; ++ spx_int32_t j; + for (j=0;j<st->filt_len;j++) + { +- st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); ++ 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 diff --git a/regressions b/regressions new file mode 100644 index 0000000..2a17631 --- /dev/null +++ b/regressions @@ -0,0 +1,4 @@ +1: 723f644e09333a0230383eae4af1f3aa3e46e1c3 (r12736): broke resampler badly +Changed the sign of a bunch of parameters in the API. Tons of signed/unsigned changes in the code as a consequence of that. Hopefully this will be the last change to the API. +Fixed: 2007-08-11 + diff --git a/speexclient/compile.sh b/speexclient/compile.sh index 54e16fc..fe93af5 100755 --- a/speexclient/compile.sh +++ b/speexclient/compile.sh @@ -1,3 +1,2 @@ #!/bin/sh -echo gcc -Wall speexclient.c alsa_device.c -o speexclient -lspeex -lasound -lm -gcc -Wall speexclient.c alsa_device.c -o speexclient -lspeex -lasound -lm +gcc -Wall -I../include speex_jitter_buffer.c speexclient.c alsa_device.c -o speexclient -lspeex -lspeexdsp -lasound -lm diff --git a/speexclient/speex_jitter_buffer.c b/speexclient/speex_jitter_buffer.c new file mode 100644 index 0000000..6f779b7 --- /dev/null +++ b/speexclient/speex_jitter_buffer.c @@ -0,0 +1,90 @@ +#include <speex/speex_jitter.h> +#include "speex_jitter_buffer.h" + +#ifndef NULL +#define NULL 0 +#endif + + +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, spx_int16_t *out, int *current_timestamp) +{ + int i; + int ret; + spx_int32_t activity; + char data[2048]; + JitterBufferPacket packet; + packet.data = data; + + if (jitter->valid_bits) + { + /* 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, jitter->frame_size, 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); + } 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;i<jitter->frame_size;i++) + out[i]=0; + } + } + speex_decoder_ctl(jitter->dec, SPEEX_GET_ACTIVITY, &activity); + if (activity < 30) + jitter_buffer_update_delay(jitter->packets, &packet, NULL); + jitter_buffer_tick(jitter->packets); +} + +int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter) +{ + return jitter_buffer_get_pointer_timestamp(jitter->packets); +} diff --git a/speexclient/speex_jitter_buffer.h b/speexclient/speex_jitter_buffer.h new file mode 100644 index 0000000..098462a --- /dev/null +++ b/speexclient/speex_jitter_buffer.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_jitter_buffer.h + @brief Adaptive jitter buffer for Speex packets only +*/ + +#include <speex/speex_jitter.h> +#include <speex/speex.h> + +/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. This is a simplified version that works only + * with Speex, but is much easier to use. + * @{ +*/ + +/** Speex jitter-buffer state. Never use it directly! */ +typedef struct SpeexJitter { + SpeexBits current_packet; /**< Current Speex packet */ + int valid_bits; /**< True if Speex bits are valid */ + JitterBuffer *packets; /**< Generic jitter buffer state */ + void *dec; /**< Pointer to Speex decoder */ + spx_int32_t frame_size; /**< Frame size of Speex decoder */ +} SpeexJitter; + +/** Initialise jitter buffer + * + * @param jitter State of the Speex jitter buffer + * @param decoder Speex decoder to call + * @param sampling_rate Sampling rate used by the decoder +*/ +void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); + +/** Destroy jitter buffer */ +void speex_jitter_destroy(SpeexJitter *jitter); + +/** Put one packet into the jitter buffer */ +void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); + +/** Get one packet from the jitter buffer */ +void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); + +/** Get pointer timestamp of jitter buffer */ +int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); + +#ifdef __cplusplus +} +#endif + +/* @} */ diff --git a/speexclient/speexclient.c b/speexclient/speexclient.c index 60d5764..cb375c9 100644 --- a/speexclient/speexclient.c +++ b/speexclient/speexclient.c @@ -51,6 +51,7 @@ #include <speex/speex_jitter.h> #include <speex/speex_preprocess.h> #include <speex/speex_echo.h> +#include "speex_jitter_buffer.h" #include <sched.h> diff --git a/speexdsp.pc.in b/speexdsp.pc.in new file mode 100644 index 0000000..328a866 --- /dev/null +++ b/speexdsp.pc.in @@ -0,0 +1,14 @@ +# 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: +Conflicts: +Libs: -L${libdir} -lspeexdsp -lm +Cflags: -I${includedir} diff --git a/src/Makefile.am b/src/Makefile.am index 1ef61b2..9997271 100644 --- a/src/Makefile.am +++ b/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,7 +17,7 @@ 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 \ +speexenc_LDADD = $(top_builddir)/libspeex/libspeex.la $(top_builddir)/libspeex/libspeexdsp.la \ $(OGG_LIBS) speexdec_SOURCES = speexdec.c wav_io.c diff --git a/src/speexdec.c b/src/speexdec.c index 94a63c1..b8252b5 100644 --- a/src/speexdec.c +++ b/src/speexdec.c @@ -48,8 +48,6 @@ #include <ogg/ogg.h> #if defined WIN32 || defined _WIN32 -#include <windows.h> -#include "getopt_win.h" #include "wave_out.h" /* We need the following two to set stdout to binary */ #include <io.h> @@ -84,7 +82,6 @@ #include <speex/speex_header.h> #include <speex/speex_stereo.h> #include <speex/speex_callbacks.h> -#include "wav_io.h" #define MAX_FRAME_SIZE 2000 @@ -289,13 +286,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 +318,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 +331,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,6 +352,7 @@ 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); diff --git a/src/speexenc.c b/src/speexenc.c index e251b9b..52f7117 100644 --- a/src/speexenc.c +++ b/src/speexenc.c @@ -53,7 +53,6 @@ #include <speex/speex_preprocess.h> #if defined WIN32 || defined _WIN32 -#include "getopt_win.h" /* We need the following two to set stdout to binary */ #include <io.h> #include <fcntl.h> @@ -182,13 +181,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 +319,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 +333,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); @@ -949,6 +956,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 +976,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/src/wav_io.h b/src/wav_io.h index ab04e1b..0755763 100644 --- a/src/wav_io.h +++ b/src/wav_io.h @@ -35,7 +35,7 @@ #include <stdio.h> #include "speex/speex_types.h" -#ifdef WORDS_BIGENDIAN +#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 @@ -46,7 +46,7 @@ /** Convert little endian */ static inline spx_int32_t le_int(spx_int32_t i) { -#ifdef WORDS_BIGENDIAN +#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) spx_uint32_t ui, ret; ui = i; ret = ui>>24; diff --git a/win32/Makefile.am b/win32/Makefile.am index 0823f46..084ace2 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -5,4 +5,4 @@ SUBDIRS = libspeex speexenc speexdec VS2003 VS2005
-EXTRA_DIST = speex.iss config.h
+EXTRA_DIST = speex.iss config.h libspeex.def libspeexdsp.def
diff --git a/win32/VS2003/Makefile.am b/win32/VS2003/Makefile.am index d4698d7..15479c3 100644 --- a/win32/VS2003/Makefile.am +++ b/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/win32/VS2003/libspeex.sln b/win32/VS2003/libspeex.sln new file mode 100644 index 0000000..4693b1a --- /dev/null +++ b/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/win32/VS2003/libspeex/Makefile.am b/win32/VS2003/libspeex/Makefile.am index 35cf918..5de466c 100644 --- a/win32/VS2003/libspeex/Makefile.am +++ b/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/win32/VS2003/libspeex/libspeex.vcproj b/win32/VS2003/libspeex/libspeex.vcproj index daa6216..92d0e7e 100644 --- a/win32/VS2003/libspeex/libspeex.vcproj +++ b/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"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="$(OutDir)/libspeex.lib"/>
+ OutputFile="../../../lib/libspeex.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -69,13 +69,13 @@ FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H; USE_ALLOCA"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
UsePrecompiledHeader="0"
- WarningLevel="4"
+ WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"
CompileAs="1"
@@ -84,7 +84,7 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="$(OutDir)/libspeex.lib"/>
+ OutputFile="../../../lib/libspeex.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -105,7 +105,7 @@ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
- Name="Release_SSE|Win32"
+ Name="Release_Static_SSE|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
@@ -120,10 +120,10 @@ FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
+ PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
@@ -136,7 +136,7 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="$(OutDir)/libspeex.lib"/>
+ OutputFile="../../../lib/libspeex.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -157,59 +157,7 @@ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
- Name="Release_SSE2|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="3"
- GlobalOptimizations="TRUE"
- InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="TRUE"
- FavorSizeOrSpeed="1"
- OptimizeForProcessor="3"
- AdditionalIncludeDirectories="..\..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableEnhancedInstructionSet="2"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"
- CompileAs="1"
- DisableSpecificWarnings="4244;4305;4311;4100;4127"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/libspeex.lib"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release_Dynamic|Win32"
+ Name="Release_Dynamic_SSE|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
@@ -222,15 +170,16 @@ InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
- OptimizeForProcessor="2"
+ OptimizeForProcessor="3"
AdditionalIncludeDirectories="..\..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
+ PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
- WarningLevel="4"
+ WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"
CompileAs="1"
@@ -239,10 +188,12 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- ModuleDefinitionFile="libspeex.def"
+ OutputFile="../../../bin/libspeex.dll"
+ ModuleDefinitionFile="..\..\libspeex.def"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- OptimizeForWindows98="1"/>
+ OptimizeForWindows98="1"
+ ImportLibrary="../../../lib/libspeex.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -315,12 +266,6 @@ RelativePath="..\..\..\libspeex\high_lsp_tables.c">
</File>
<File
- RelativePath="..\..\..\libspeex\jitter.c">
- </File>
- <File
- RelativePath=".\libspeex.def">
- </File>
- <File
RelativePath="..\..\..\libspeex\lpc.c">
</File>
<File
@@ -333,25 +278,13 @@ RelativePath="..\..\..\libspeex\ltp.c">
</File>
<File
- RelativePath="..\..\..\libspeex\math_approx.c">
- </File>
- <File
- RelativePath="..\..\..\libspeex\mdf.c">
- </File>
- <File
- RelativePath="..\..\..\libspeex\medfilter.c">
- </File>
- <File
- RelativePath="..\..\..\libspeex\misc.c">
- </File>
- <File
RelativePath="..\..\..\libspeex\modes.c">
</File>
<File
- RelativePath="..\..\..\libspeex\nb_celp.c">
+ RelativePath="..\..\..\libspeex\modes_wb.c">
</File>
<File
- RelativePath="..\..\..\libspeex\preprocess.c">
+ RelativePath="..\..\..\libspeex\nb_celp.c">
</File>
<File
RelativePath="..\..\..\libspeex\quant_lsp.c">
@@ -360,9 +293,6 @@ RelativePath="..\..\..\libspeex\sb_celp.c">
</File>
<File
- RelativePath="..\..\..\libspeex\smallft.c">
- </File>
- <File
RelativePath="..\..\..\libspeex\speex.c">
</File>
<File
@@ -380,16 +310,22 @@ <File
RelativePath="..\..\..\libspeex\vq.c">
</File>
+ <File
+ RelativePath="..\..\..\libspeex\window.c">
+ </File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
+ RelativePath="..\..\..\libspeex\arch.h">
+ </File>
+ <File
RelativePath="..\..\..\libspeex\cb_search.h">
</File>
<File
- RelativePath="..\..\config.h">
+ RelativePath="..\..\..\libspeex\cb_search_sse.h">
</File>
<File
RelativePath="..\..\..\libspeex\filters.h">
@@ -398,6 +334,12 @@ RelativePath="..\..\..\libspeex\filters_sse.h">
</File>
<File
+ RelativePath="..\..\..\libspeex\fixed_debug.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\fixed_generic.h">
+ </File>
+ <File
RelativePath="..\..\..\libspeex\lpc.h">
</File>
<File
@@ -413,43 +355,47 @@ RelativePath="..\..\..\libspeex\math_approx.h">
</File>
<File
- RelativePath="..\..\..\libspeex\misc.h">
- </File>
- <File
RelativePath="..\..\..\libspeex\modes.h">
</File>
<File
RelativePath="..\..\..\libspeex\nb_celp.h">
</File>
<File
+ RelativePath="..\..\..\libspeex\os_support.h">
+ </File>
+ <File
RelativePath="..\..\..\libspeex\quant_lsp.h">
</File>
<File
RelativePath="..\..\..\libspeex\sb_celp.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex.h">
+ RelativePath="..\..\..\libspeex\stack_alloc.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_bits.h">
+ RelativePath="..\..\..\libspeex\vbr.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_callbacks.h">
+ RelativePath="..\..\..\libspeex\vq.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_echo.h">
+ RelativePath="..\..\..\libspeex\vq_sse.h">
</File>
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ Filter="">
<File
- RelativePath="..\..\..\include\speex\speex_header.h">
+ RelativePath="..\..\..\include\speex\speex.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_jitter.h">
+ RelativePath="..\..\..\include\speex\speex_bits.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_noglobals.h">
+ RelativePath="..\..\..\include\speex\speex_callbacks.h">
</File>
<File
- RelativePath="..\..\..\include\speex\speex_preprocess.h">
+ RelativePath="..\..\..\include\speex\speex_header.h">
</File>
<File
RelativePath="..\..\..\include\speex\speex_stereo.h">
@@ -457,15 +403,6 @@ <File
RelativePath="..\..\..\include\speex\speex_types.h">
</File>
- <File
- RelativePath="..\..\..\libspeex\stack_alloc.h">
- </File>
- <File
- RelativePath="..\..\..\libspeex\vbr.h">
- </File>
- <File
- RelativePath="..\..\..\libspeex\vq.h">
- </File>
</Filter>
<Filter
Name="Resource Files"
@@ -473,7 +410,10 @@ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
- RelativePath=".\ReadMe.txt">
+ RelativePath="..\..\config.h">
+ </File>
+ <File
+ RelativePath="..\..\libspeex.def">
</File>
</Files>
<Globals>
diff --git a/win32/VS2003/libspeexdsp/Makefile.am b/win32/VS2003/libspeexdsp/Makefile.am new file mode 100644 index 0000000..796fefc --- /dev/null +++ b/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/win32/VS2003/libspeexdsp/libspeexdsp.vcproj b/win32/VS2003/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 0000000..59205db --- /dev/null +++ b/win32/VS2003/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,342 @@ +<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="libspeexdsp"
+ ProjectGUID="{03207781-0D1C-4DB3-A71D-45C608F28DBD}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="../../../lib/libspeexdsp.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ DisableSpecificWarnings="4244;4305;4311;4100;4127"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="../../../lib/libspeexdsp.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_Dynamic_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="3"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ DisableSpecificWarnings="4244;4305;4311;4100;4127"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../../../bin/libspeexdsp.dll"
+ ModuleDefinitionFile="..\..\libspeexdsp.def"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ ImportLibrary="../../../lib/libspeexdsp.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_Static_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="3"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ DisableSpecificWarnings="4244;4305;4311;4100;4127"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="../../../lib/libspeexdsp.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\buffer.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\fftwrap.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\filterbank.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\jitter.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\kiss_fft.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\kiss_fftr.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\mdf.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\preprocess.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\resample.c">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\smallft.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\..\..\libspeex\_kiss_fft_guts.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\arch.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\fftwrap.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\filterbank.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\fixed_debug.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\fixed_generic.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\kiss_fft.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\kiss_fftr.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\math_approx.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\os_support.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\pseudofloat.h">
+ </File>
+ <File
+ RelativePath="..\..\..\libspeex\smallft.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ Filter="">
+ <File
+ RelativePath="..\..\..\include\speex\speex.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_bits.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_buffer.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_echo.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_jitter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_preprocess.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_resampler.h">
+ </File>
+ <File
+ RelativePath="..\..\..\include\speex\speex_types.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\config.h">
+ </File>
+ <File
+ RelativePath="..\..\libspeexdsp.def">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/speexdec/speexdec.vcproj b/win32/VS2003/speexdec/speexdec.vcproj index a390be4..d950422 100644 --- a/win32/VS2003/speexdec/speexdec.vcproj +++ b/win32/VS2003/speexdec/speexdec.vcproj @@ -19,11 +19,11 @@ <Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@@ -33,9 +33,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexdec.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexdec.exe"
LinkIncremental="2"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
SubSystem="1"
@@ -76,11 +77,11 @@ EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -91,9 +92,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexdec.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexdec.exe"
LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
@@ -136,11 +138,11 @@ EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
@@ -152,70 +154,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexdec.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release_SSE2|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="3"
- GlobalOptimizations="TRUE"
- InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="TRUE"
- FavorSizeOrSpeed="1"
- OptimizeForProcessor="3"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableEnhancedInstructionSet="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"
- CompileAs="1"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexdec.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexdec.exe"
LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
diff --git a/win32/VS2003/speexenc/speexenc.vcproj b/win32/VS2003/speexenc/speexenc.vcproj index 4893cc9..68ef494 100644 --- a/win32/VS2003/speexenc/speexenc.vcproj +++ b/win32/VS2003/speexenc/speexenc.vcproj @@ -19,11 +19,11 @@ <Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@@ -33,9 +33,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexenc.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexenc.exe"
LinkIncremental="2"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
SubSystem="1"
@@ -76,11 +77,11 @@ EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H: USE_ALLOCA"
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -91,9 +92,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexenc.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexenc.exe"
LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
@@ -136,11 +138,11 @@ EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
+ AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
StringPooling="TRUE"
ExceptionHandling="FALSE"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="0"
@@ -152,70 +154,10 @@ Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexenc.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release_SSE2|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="3"
- GlobalOptimizations="TRUE"
- InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="TRUE"
- FavorSizeOrSpeed="1"
- OptimizeForProcessor="3"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include;..\..\..\libspeex;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableEnhancedInstructionSet="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"
- CompileAs="1"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/speexenc.exe"
+ AdditionalDependencies="winmm.lib libogg.lib"
+ OutputFile="../../../bin/speexenc.exe"
LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\..\libogg\lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
@@ -258,6 +200,9 @@ RelativePath="..\..\..\src\getopt1.c">
</File>
<File
+ RelativePath="..\..\..\src\skeleton.c">
+ </File>
+ <File
RelativePath="..\..\..\src\speexenc.c">
</File>
<File
@@ -275,6 +220,9 @@ RelativePath="..\..\..\src\getopt_win.h">
</File>
<File
+ RelativePath="..\..\..\src\skeleton.h">
+ </File>
+ <File
RelativePath="..\..\..\src\wav_io.h">
</File>
<File
diff --git a/win32/VS2003/tests/Makefile.am b/win32/VS2003/tests/Makefile.am new file mode 100644 index 0000000..47918c6 --- /dev/null +++ b/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/win32/VS2003/tests/testdenoise.vcproj b/win32/VS2003/tests/testdenoise.vcproj new file mode 100644 index 0000000..730df77 --- /dev/null +++ b/win32/VS2003/tests/testdenoise.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testdenoise"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testdenoise.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testdenoise.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testdenoise.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testdenoise.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/tests/testecho.vcproj b/win32/VS2003/tests/testecho.vcproj new file mode 100644 index 0000000..0d12166 --- /dev/null +++ b/win32/VS2003/tests/testecho.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testecho"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testecho.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testecho.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testecho.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testecho.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/tests/testenc.vcproj b/win32/VS2003/tests/testenc.vcproj new file mode 100644 index 0000000..42488f0 --- /dev/null +++ b/win32/VS2003/tests/testenc.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testenc"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testenc.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/tests/testenc_uwb.vcproj b/win32/VS2003/tests/testenc_uwb.vcproj new file mode 100644 index 0000000..3178b52 --- /dev/null +++ b/win32/VS2003/tests/testenc_uwb.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testenc_uwb"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_uwb.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_uwb.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_uwb.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testenc_uwb.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/tests/testenc_wb.vcproj b/win32/VS2003/tests/testenc_wb.vcproj new file mode 100644 index 0000000..472fc66 --- /dev/null +++ b/win32/VS2003/tests/testenc_wb.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testenc_wb"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_wb.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_wb.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testenc_wb.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testenc_wb.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2003/tests/testresample.vcproj b/win32/VS2003/tests/testresample.vcproj new file mode 100644 index 0000000..e4e08e4 --- /dev/null +++ b/win32/VS2003/tests/testresample.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="testresample"
+ ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testresample.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/speexenc.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testresample.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release_SSE|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\..\include;..\.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="1"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="../../../bin/testresample.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\..\libspeex\testresample.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/win32/VS2005/libspeex/libspeex.vcproj b/win32/VS2005/libspeex/libspeex.vcproj index 34565f7..3e66b7a 100644 --- a/win32/VS2005/libspeex/libspeex.vcproj +++ b/win32/VS2005/libspeex/libspeex.vcproj @@ -1486,10 +1486,6 @@ >
</File>
<File
- RelativePath="..\..\..\libspeex\medfilter.c"
- >
- </File>
- <File
RelativePath="..\..\..\libspeex\misc.c"
>
</File>
diff --git a/win32/config.h b/win32/config.h index 673f9dc..b46b9a9 100644 --- a/win32/config.h +++ b/win32/config.h @@ -1,3 +1,14 @@ +// 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
+#endif
diff --git a/win32/VS2003/libspeex/libspeex.def b/win32/libspeex.def index 511e148..e5f815f 100644 --- a/win32/VS2003/libspeex/libspeex.def +++ b/win32/libspeex.def @@ -3,27 +3,28 @@ EXPORTS ; -; speex_echo.h -; -speex_echo_state_init -speex_echo_state_destroy -speex_echo_cancel -speex_echo_state_reset - -; -; speex_preprocess.h +; speex.h ; -speex_preprocess_state_init -speex_preprocess_state_destroy -speex_preprocess -speex_preprocess_estimate_update -speex_preprocess_ctl +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 @@ -62,47 +63,13 @@ speex_header_to_packet speex_packet_to_header ; -; speex_jitter.h -; -speex_jitter_init -speex_jitter_destroy -speex_jitter_put -speex_jitter_get -speex_jitter_get_pointer_timestamp - -; -; speex_noglobals.h -; -;speex_mode_new -;speex_mode_destroy - - -; ; 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 - -; -; 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 - - - - diff --git a/win32/libspeex/Makefile.am b/win32/libspeex/Makefile.am index 9430c78..9cf4e85 100644 --- a/win32/libspeex/Makefile.am +++ b/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/win32/libspeex/libspeex.dsp b/win32/libspeex/libspeex.dsp index 47a8b5c..9cfa169 100644 --- a/win32/libspeex/libspeex.dsp +++ b/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,44 +281,52 @@ SOURCE=..\..\libspeex\sb_celp.h # End Source File
# Begin Source File
-SOURCE=..\..\libspeex\smallft.h
+SOURCE=..\..\libspeex\stack_alloc.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex.h
+SOURCE=..\..\libspeex\vbr.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_bits.h
+SOURCE=..\..\libspeex\vq.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_callbacks.h
+SOURCE=..\..\libspeex\vq_sse.h
# End Source File
+# End Group
+# Begin Group "Public Header Files"
+
+# PROP Default_Filter "*.h"
# Begin Source File
-SOURCE=..\..\libspeex\speex_denoise.h
+SOURCE=..\..\include\speex\speex.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_header.h
+SOURCE=..\..\include\speex\speex_bits.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_stereo.h
+SOURCE=..\..\include\speex\speex_callbacks.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\stack_alloc.h
+SOURCE=..\..\include\speex\speex_header.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\vbr.h
+SOURCE=..\..\include\speex\speex_stereo.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\vq.h
+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/win32/libspeex/libspeex.dsw b/win32/libspeex/libspeex.dsw index 9fb56fe..ff24f2a 100644 --- a/win32/libspeex/libspeex.dsw +++ b/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/win32/libspeex/libspeex_dynamic.dsp b/win32/libspeex/libspeex_dynamic.dsp index 5e00972..cd1945c 100644 --- a/win32/libspeex/libspeex_dynamic.dsp +++ b/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,44 +286,56 @@ SOURCE=..\..\libspeex\sb_celp.h # End Source File
# Begin Source File
-SOURCE=..\..\libspeex\smallft.h
+SOURCE=..\..\libspeex\stack_alloc.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex.h
+SOURCE=..\..\libspeex\vbr.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_bits.h
+SOURCE=..\..\libspeex\vq.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_callbacks.h
+SOURCE=..\..\libspeex\vq_sse.h
# End Source File
+# End Group
+# Begin Group "Public Header Files"
+
+# PROP Default_Filter "*.h"
# Begin Source File
-SOURCE=..\..\libspeex\speex_denoise.h
+SOURCE=..\..\include\speex\speex.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_header.h
+SOURCE=..\..\include\speex\speex_bits.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\speex_stereo.h
+SOURCE=..\..\include\speex\speex_callbacks.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\stack_alloc.h
+SOURCE=..\..\include\speex\speex_header.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\vbr.h
+SOURCE=..\..\include\speex\speex_stereo.h
# End Source File
# Begin Source File
-SOURCE=..\..\libspeex\vq.h
+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/win32/libspeex/libspeexdsp.dsp b/win32/libspeex/libspeexdsp.dsp new file mode 100644 index 0000000..0e39ada --- /dev/null +++ b/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/win32/libspeex/libspeexdsp_dynamic.dsp b/win32/libspeex/libspeexdsp_dynamic.dsp new file mode 100644 index 0000000..1a1a211 --- /dev/null +++ b/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/win32/libspeex/speex.def b/win32/libspeex/speex.def deleted file mode 100644 index 94098a8..0000000 --- a/win32/libspeex/speex.def +++ /dev/null @@ -1,72 +0,0 @@ -; -; speex.def -; -LIBRARY -NAME libspeex.dll -EXPORTS -; -speex_bits_advance @1 -speex_bits_destroy @2 -speex_bits_init @3 -speex_bits_init_buffer @4 -speex_bits_insert_terminator @5 -speex_bits_nbytes @6 -speex_bits_pack @7 -speex_bits_peek @8 -speex_bits_peek_unsigned @9 -speex_bits_read_from @10 -speex_bits_read_whole_bytes @11 -speex_bits_remaining @12 -speex_bits_reset @13 -speex_bits_rewind @14 -speex_bits_unpack_signed @15 -speex_bits_unpack_unsigned @16 -speex_bits_write @17 -speex_bits_write_whole_bytes @18 -speex_decode @19 -speex_decode_stereo @20 -speex_decoder_ctl @21 -speex_decoder_destroy @22 -speex_decoder_init @23 -speex_default_user_handler @24 -speex_encode @25 -speex_encode_stereo @26 -speex_encoder_ctl @27 -speex_encoder_destroy @28 -speex_encoder_init @29 -speex_header_to_packet @30 -speex_inband_handler @31 -speex_init_header @32 -speex_lib_ctl @33 -speex_mode_query @34 -speex_packet_to_header @35 -speex_std_char_handler @36 -speex_std_enh_request_handler @37 -speex_std_high_mode_request_handler @38 -speex_std_low_mode_request_handler @39 -speex_std_mode_request_handler @40 -speex_std_stereo_request_handler @41 -speex_std_vbr_quality_request_handler @42 -speex_std_vbr_request_handler @43 -speex_decode_int @44 -speex_decode_stereo_int @45 -speex_echo_cancel @46 -speex_echo_state_destroy @47 -speex_echo_state_init @48 -speex_echo_state_reset @49 -speex_encode_int @50 -speex_encode_stereo_int @51 -speex_jitter_destroy @52 -speex_jitter_get @53 -speex_jitter_get_pointer_timestamp @54 -speex_jitter_init @55 -speex_jitter_put @56 -speex_lib_get_mode @57 -speex_preprocess @58 -speex_preprocess_ctl @59 -speex_preprocess_estimate_update @60 -speex_preprocess_state_destroy @61 -speex_preprocess_state_init @62 -speex_nb_mode @63 DATA -speex_wb_mode @64 DATA -speex_uwb_mode @65 DATA diff --git a/win32/libspeexdsp.def b/win32/libspeexdsp.def new file mode 100644 index 0000000..bea3358 --- /dev/null +++ b/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/win32/speex.iss b/win32/speex.iss index 8f2a398..8f2a398 100755..100644 --- a/win32/speex.iss +++ b/win32/speex.iss diff --git a/win32/speexdec/speexdec.dsp b/win32/speexdec/speexdec.dsp index 64fcd46..10b732d 100644 --- a/win32/speexdec/speexdec.dsp +++ b/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/win32/speexdec/speexdec.dsw b/win32/speexdec/speexdec.dsw index 37f2d1f..a7de362 100644 --- a/win32/speexdec/speexdec.dsw +++ b/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/win32/speexenc/speexenc.dsp b/win32/speexenc/speexenc.dsp index 4b9dd89..eeae18e 100644 --- a/win32/speexenc/speexenc.dsp +++ b/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/win32/speexenc/speexenc.dsw b/win32/speexenc/speexenc.dsw index 55aa72d..d1e77b8 100644 --- a/win32/speexenc/speexenc.dsw +++ b/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
}}}
###############################################################################
|