diff options
Diffstat (limited to 'engine/voice_codecs/speex/source/libspeex')
56 files changed, 12099 insertions, 0 deletions
diff --git a/engine/voice_codecs/speex/source/libspeex/Makefile.am b/engine/voice_codecs/speex/source/libspeex/Makefile.am new file mode 100644 index 0000000..940bc37 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/Makefile.am @@ -0,0 +1,77 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# $Id: Makefile.am,v 1.49 2003/03/17 22:40:57 jm Exp $ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +lib_LTLIBRARIES = libspeex.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 \ + 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 + + +include_HEADERS = speex.h \ + speex_bits.h \ + speex_header.h \ + speex_callbacks.h \ + speex_stereo.h + +noinst_HEADERS = lsp.h \ + nb_celp.h \ + lpc.h \ + ltp.h \ + quant_lsp.h \ + cb_search.h \ + filters.h \ + stack_alloc.h \ + vq.h \ + modes.h \ + sb_celp.h \ + vbr.h \ + misc.h \ + ltp_sse.h \ + filters_sse.h \ + math_approx.h + + +libspeex_la_LDFLAGS = -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ + +noinst_PROGRAMS = testenc testenc_wb testenc_uwb + +testenc_SOURCES = testenc.c +testenc_LDADD = libspeex.la + +testenc_wb_SOURCES = testenc_wb.c +testenc_wb_LDADD = libspeex.la + +testenc_uwb_SOURCES = testenc_uwb.c +testenc_uwb_LDADD = libspeex.la diff --git a/engine/voice_codecs/speex/source/libspeex/Makefile.in b/engine/voice_codecs/speex/source/libspeex/Makefile.in new file mode 100644 index 0000000..b4e2a5f --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/Makefile.in @@ -0,0 +1,450 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# $Id: Makefile.am,v 1.49 2003/03/17 22:40:57 jm Exp $ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EXEEXT = @EXEEXT@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_INCLUDES = @OGG_INCLUDES@ +OGG_LDFLAGS = @OGG_LDFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +src = @src@ + +lib_LTLIBRARIES = libspeex.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 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 + + +include_HEADERS = speex.h speex_bits.h speex_header.h speex_callbacks.h speex_stereo.h + + +noinst_HEADERS = lsp.h nb_celp.h lpc.h ltp.h quant_lsp.h cb_search.h filters.h stack_alloc.h vq.h modes.h sb_celp.h vbr.h misc.h ltp_sse.h filters_sse.h math_approx.h + + +libspeex_la_LDFLAGS = -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ + +noinst_PROGRAMS = testenc testenc_wb testenc_uwb + +testenc_SOURCES = testenc.c +testenc_LDADD = libspeex.la + +testenc_wb_SOURCES = testenc_wb.c +testenc_wb_LDADD = libspeex.la + +testenc_uwb_SOURCES = testenc_uwb.c +testenc_uwb_LDADD = libspeex.la +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libspeex_la_LIBADD = +libspeex_la_OBJECTS = nb_celp.lo sb_celp.lo lpc.lo ltp.lo lsp.lo \ +quant_lsp.lo lsp_tables_nb.lo gain_table.lo gain_table_lbr.lo \ +cb_search.lo filters.lo bits.lo modes.lo vq.lo high_lsp_tables.lo \ +vbr.lo hexc_table.lo exc_5_256_table.lo exc_5_64_table.lo \ +exc_8_128_table.lo exc_10_32_table.lo exc_10_16_table.lo \ +exc_20_32_table.lo hexc_10_32_table.lo misc.lo speex_header.lo \ +speex_callbacks.lo math_approx.lo stereo.lo +noinst_PROGRAMS = testenc$(EXEEXT) testenc_wb$(EXEEXT) \ +testenc_uwb$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + +testenc_OBJECTS = testenc.$(OBJEXT) +testenc_DEPENDENCIES = libspeex.la +testenc_LDFLAGS = +testenc_wb_OBJECTS = testenc_wb.$(OBJEXT) +testenc_wb_DEPENDENCIES = libspeex.la +testenc_wb_LDFLAGS = +testenc_uwb_OBJECTS = testenc_uwb.$(OBJEXT) +testenc_uwb_DEPENDENCIES = libspeex.la +testenc_uwb_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(include_HEADERS) $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libspeex_la_SOURCES) $(testenc_SOURCES) $(testenc_wb_SOURCES) $(testenc_uwb_SOURCES) +OBJECTS = $(libspeex_la_OBJECTS) $(testenc_OBJECTS) $(testenc_wb_OBJECTS) $(testenc_uwb_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps libspeex/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libspeex.la: $(libspeex_la_OBJECTS) $(libspeex_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libspeex_la_LDFLAGS) $(libspeex_la_OBJECTS) $(libspeex_la_LIBADD) $(LIBS) + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +testenc$(EXEEXT): $(testenc_OBJECTS) $(testenc_DEPENDENCIES) + @rm -f testenc$(EXEEXT) + $(LINK) $(testenc_LDFLAGS) $(testenc_OBJECTS) $(testenc_LDADD) $(LIBS) + +testenc_wb$(EXEEXT): $(testenc_wb_OBJECTS) $(testenc_wb_DEPENDENCIES) + @rm -f testenc_wb$(EXEEXT) + $(LINK) $(testenc_wb_LDFLAGS) $(testenc_wb_OBJECTS) $(testenc_wb_LDADD) $(LIBS) + +testenc_uwb$(EXEEXT): $(testenc_uwb_OBJECTS) $(testenc_uwb_DEPENDENCIES) + @rm -f testenc_uwb$(EXEEXT) + $(LINK) $(testenc_uwb_LDFLAGS) $(testenc_uwb_OBJECTS) $(testenc_uwb_LDADD) $(LIBS) + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libspeex + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +bits.lo bits.o : bits.c speex_bits.h misc.h +cb_search.lo cb_search.o : cb_search.c cb_search.h speex_bits.h \ + filters.h stack_alloc.h vq.h misc.h +exc_10_16_table.lo exc_10_16_table.o : exc_10_16_table.c +exc_10_32_table.lo exc_10_32_table.o : exc_10_32_table.c +exc_20_32_table.lo exc_20_32_table.o : exc_20_32_table.c +exc_5_256_table.lo exc_5_256_table.o : exc_5_256_table.c +exc_5_64_table.lo exc_5_64_table.o : exc_5_64_table.c +exc_8_128_table.lo exc_8_128_table.o : exc_8_128_table.c +filters.lo filters.o : filters.c filters.h stack_alloc.h +gain_table.lo gain_table.o : gain_table.c +gain_table_lbr.lo gain_table_lbr.o : gain_table_lbr.c +hexc_10_32_table.lo hexc_10_32_table.o : hexc_10_32_table.c +hexc_table.lo hexc_table.o : hexc_table.c +high_lsp_tables.lo high_lsp_tables.o : high_lsp_tables.c +lpc.lo lpc.o : lpc.c lpc.h +lsp.lo lsp.o : lsp.c lsp.h stack_alloc.h +lsp_tables_nb.lo lsp_tables_nb.o : lsp_tables_nb.c +ltp.lo ltp.o : ltp.c ltp.h speex_bits.h stack_alloc.h filters.h +math_approx.lo math_approx.o : math_approx.c math_approx.h +misc.lo misc.o : misc.c misc.h +modes.lo modes.o : modes.c modes.h speex.h speex_bits.h ltp.h \ + quant_lsp.h cb_search.h sb_celp.h nb_celp.h speex_callbacks.h \ + vbr.h filters.h misc.h +nb_celp.lo nb_celp.o : nb_celp.c nb_celp.h modes.h speex.h speex_bits.h \ + speex_callbacks.h vbr.h filters.h lpc.h lsp.h ltp.h quant_lsp.h \ + cb_search.h stack_alloc.h vq.h misc.h +quant_lsp.lo quant_lsp.o : quant_lsp.c quant_lsp.h speex_bits.h +sb_celp.lo sb_celp.o : sb_celp.c sb_celp.h modes.h speex.h speex_bits.h \ + nb_celp.h speex_callbacks.h vbr.h filters.h lpc.h lsp.h \ + stack_alloc.h cb_search.h quant_lsp.h vq.h ltp.h misc.h +speex_callbacks.lo speex_callbacks.o : speex_callbacks.c \ + speex_callbacks.h speex.h speex_bits.h misc.h +speex_header.lo speex_header.o : speex_header.c speex_header.h misc.h \ + speex.h speex_bits.h +stereo.lo stereo.o : stereo.c speex_stereo.h speex_bits.h \ + speex_callbacks.h speex.h vq.h +testenc.o: testenc.c speex.h speex_bits.h speex_callbacks.h +testenc_uwb.o: testenc_uwb.c speex.h speex_bits.h +testenc_wb.o: testenc_wb.c speex.h speex_bits.h +vbr.lo vbr.o : vbr.c vbr.h +vq.lo vq.o : vq.c vq.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-noinstPROGRAMS \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \ + clean-noinstPROGRAMS clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-noinstPROGRAMS \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-noinstPROGRAMS maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool mostlyclean-noinstPROGRAMS \ +distclean-noinstPROGRAMS clean-noinstPROGRAMS \ +maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \ +install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/engine/voice_codecs/speex/source/libspeex/bits.c b/engine/voice_codecs/speex/source/libspeex/bits.c new file mode 100644 index 0000000..68285e0 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/bits.c @@ -0,0 +1,352 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_bits.c + + Handles bit packing/unpacking + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "speex_bits.h" +#include "misc.h" + +void speex_bits_init(SpeexBits *bits) +{ + int i; + bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME); + bits->buf_size = MAX_BYTES_PER_FRAME; + + for (i=0;i<bits->buf_size;i++) + bits->bytes[i]=0; + bits->nbBits=0; + bits->bytePtr=0; + bits->bitPtr=0; + bits->owner=1; + bits->overflow=0; +} + +void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) +{ + int i; + bits->bytes = (char*)buff; + bits->buf_size = buf_size; + + for (i=0;i<buf_size;i++) + bits->bytes[i]=0; + bits->nbBits=0; + bits->bytePtr=0; + bits->bitPtr=0; + bits->owner=0; + bits->overflow=0; +} + +void speex_bits_destroy(SpeexBits *bits) +{ + if (bits->owner) + speex_free(bits->bytes); + /* Will do something once the allocation is dynamic */ +} + +void speex_bits_reset(SpeexBits *bits) +{ + int i; + for (i=0;i<bits->buf_size;i++) + bits->bytes[i]=0; + bits->nbBits=0; + bits->bytePtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +void speex_bits_rewind(SpeexBits *bits) +{ + bits->bytePtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +void speex_bits_read_from(SpeexBits *bits, char *bytes, int len) +{ + int i; + if (len > bits->buf_size) + { + speex_warning_int("Packet if larger than allocated buffer: ", len); + if (bits->owner) + { + char *tmp = (char*)speex_realloc(bits->bytes, len); + if (tmp) + { + bits->buf_size=len; + bits->bytes=tmp; + } else { + len=bits->buf_size; + speex_warning("Could not resize input buffer: truncating input"); + } + } else { + speex_warning("Do not own input buffer: truncating input"); + len=bits->buf_size; + } + } + for (i=0;i<len;i++) + bits->bytes[i]=bytes[i]; + bits->nbBits=len<<3; + bits->bytePtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +static void speex_bits_flush(SpeexBits *bits) +{ + int i; + if (bits->bytePtr>0) + { + for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++) + bits->bytes[i-bits->bytePtr]=bits->bytes[i]; + } + bits->nbBits -= bits->bytePtr<<3; + bits->bytePtr=0; +} + +void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len) +{ + int i,pos; + + if ((bits->nbBits>>3)+len+1 > bits->buf_size) + { + speex_warning_int("Packet if larger than allocated buffer: ", len); + if (bits->owner) + { + char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1); + if (tmp) + { + bits->buf_size=(bits->nbBits>>3)+len+1; + bits->bytes=tmp; + } else { + len=bits->buf_size-(bits->nbBits>>3)-1; + speex_warning("Could not resize input buffer: truncating input"); + } + } else { + speex_warning("Do not own input buffer: truncating input"); + len=bits->buf_size; + } + } + + speex_bits_flush(bits); + pos=bits->nbBits>>3; + for (i=0;i<len;i++) + bits->bytes[pos+i]=bytes[i]; + bits->nbBits+=len<<3; +} + +int speex_bits_write(SpeexBits *bits, char *bytes, int max_len) +{ + int i; + if (max_len > ((bits->nbBits+7)>>3)) + max_len = ((bits->nbBits+7)>>3); + for (i=0;i<max_len;i++) + bytes[i]=bits->bytes[i]; + return max_len; +} + +int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len) +{ + int i; + if (max_len > ((bits->nbBits)>>3)) + max_len = ((bits->nbBits)>>3); + for (i=0;i<max_len;i++) + bytes[i]=bits->bytes[i]; + + if (bits->bitPtr>0) + bits->bytes[0]=bits->bytes[max_len]; + else + bits->bytes[0]=0; + for (i=1;i<((bits->nbBits)>>3)+1;i++) + bits->bytes[i]=0; + bits->bytePtr=0; + bits->nbBits &= 7; + return max_len; +} + + +void speex_bits_pack(SpeexBits *bits, int data, int nbBits) +{ + int i; + unsigned int d=data; + + if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size) + { + speex_warning("Buffer too small to pack bits"); + if (bits->owner) + { + char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1); + if (tmp) + { + for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++) + tmp[i]=0; + bits->buf_size=((bits->buf_size+5)*3)>>1; + bits->bytes=tmp; + } else { + speex_warning("Could not resize input buffer: not packing"); + return; + } + } else { + speex_warning("Do not own input buffer: not packing"); + return; + } + } + + while(nbBits) + { + int bit; + bit = (d>>(nbBits-1))&1; + bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr); + bits->bitPtr++; + + if (bits->bitPtr==8) + { + bits->bitPtr=0; + bits->bytePtr++; + } + bits->nbBits++; + nbBits--; + } +} + +int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) +{ + unsigned int d=speex_bits_unpack_unsigned(bits,nbBits); + /* If number is negative */ + if (d>>(nbBits-1)) + { + d |= (-1)<<nbBits; + } + return d; +} + +unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits) +{ + unsigned int d=0; + if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + while(nbBits) + { + d<<=1; + d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; + bits->bitPtr++; + if (bits->bitPtr==8) + { + bits->bitPtr=0; + bits->bytePtr++; + } + nbBits--; + } + return d; +} + +unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) +{ + unsigned int d=0; + int bitPtr, bytePtr; + char *bytes; + + if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + + bitPtr=bits->bitPtr; + bytePtr=bits->bytePtr; + bytes = bits->bytes; + while(nbBits) + { + d<<=1; + d |= (bytes[bytePtr]>>(7-bitPtr))&1; + bitPtr++; + if (bitPtr==8) + { + bitPtr=0; + bytePtr++; + } + nbBits--; + } + return d; +} + +int speex_bits_peek(SpeexBits *bits) +{ + if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; +} + +void speex_bits_advance(SpeexBits *bits, int n) +{ + int nbytes, nbits; + + if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return; + + nbytes = n >> 3; + nbits = n & 7; + + bits->bytePtr += nbytes; + bits->bitPtr += nbits; + + if (bits->bitPtr>7) + { + bits->bitPtr-=8; + bits->bytePtr++; + } +} + +int speex_bits_remaining(SpeexBits *bits) +{ + if (bits->overflow) + return -1; + else + return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr); +} + +int speex_bits_nbytes(SpeexBits *bits) +{ + return ((bits->nbBits+7)>>3); +} + +void speex_bits_insert_terminator(SpeexBits *bits) +{ + if (bits->bitPtr<7) + speex_bits_pack(bits, 0, 1); + while (bits->bitPtr<7) + speex_bits_pack(bits, 1, 1); +} diff --git a/engine/voice_codecs/speex/source/libspeex/cb_search.c b/engine/voice_codecs/speex/source/libspeex/cb_search.c new file mode 100644 index 0000000..785bb49 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/cb_search.c @@ -0,0 +1,387 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: cb_search.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. +*/ + + +#include "cb_search.h" +#include "filters.h" +#include "stack_alloc.h" +#include "vq.h" +#include "misc.h" + +void split_cb_search_shape_sign( +float target[], /* target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs for this subframe */ +float awk2[], /* Weighted LPCs for this subframe */ +void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +float *exc, +float *r, +SpeexBits *bits, +char *stack, +int complexity +) +{ + int i,j,k,m,n,q; + float *resp; + float *t, *e, *E, *r2; + float *tmp; + float *ndist, *odist; + int *itmp; + float **ot, **nt; + int **nind, **oind; + int *ind; + signed char *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + split_cb_params *params; + int N=2; + int *best_index; + float *best_dist; + int have_sign; + + N=complexity; + if (N>10) + N=10; + + ot=PUSH(stack, N, float*); + nt=PUSH(stack, N, float*); + oind=PUSH(stack, N, int*); + nind=PUSH(stack, N, int*); + + params = (split_cb_params *) par; + subvect_size = params->subvect_size; + nb_subvect = params->nb_subvect; + shape_cb_size = 1<<params->shape_bits; + shape_cb = params->shape_cb; + have_sign = params->have_sign; + resp = PUSH(stack, shape_cb_size*subvect_size, float); + t = PUSH(stack, nsf, float); + e = PUSH(stack, nsf, float); + r2 = PUSH(stack, nsf, float); + E = PUSH(stack, shape_cb_size, float); + ind = PUSH(stack, nb_subvect, int); + + tmp = PUSH(stack, 2*N*nsf, float); + for (i=0;i<N;i++) + { + ot[i]=tmp; + tmp += nsf; + nt[i]=tmp; + tmp += nsf; + } + + best_index = PUSH(stack, N, int); + best_dist = PUSH(stack, N, float); + ndist = PUSH(stack, N, float); + odist = PUSH(stack, N, float); + + itmp = PUSH(stack, 2*N*nb_subvect, int); + for (i=0;i<N;i++) + { + nind[i]=itmp; + itmp+=nb_subvect; + oind[i]=itmp; + itmp+=nb_subvect; + for (j=0;j<nb_subvect;j++) + nind[i][j]=oind[i][j]=-1; + } + + for (j=0;j<N;j++) + for (i=0;i<nsf;i++) + ot[j][i]=target[i]; + + for (i=0;i<nsf;i++) + t[i]=target[i]; + + /* Pre-compute codewords response and energy */ + for (i=0;i<shape_cb_size;i++) + { + float *res; + signed char *shape; + + res = resp+i*subvect_size; + shape = shape_cb+i*subvect_size; + + /* Compute codeword response using convolution with impulse response */ + for(j=0;j<subvect_size;j++) + { + res[j]=0; + for (k=0;k<=j;k++) + res[j] += 0.03125*shape[k]*r[j-k]; + } + + /* Compute codeword energy */ + E[i]=0; + for(j=0;j<subvect_size;j++) + E[i]+=res[j]*res[j]; + } + + for (j=0;j<N;j++) + odist[j]=0; + /*For all subvectors*/ + for (i=0;i<nb_subvect;i++) + { + /*"erase" nbest list*/ + for (j=0;j<N;j++) + ndist[j]=-1; + + /*For all n-bests of previous subvector*/ + for (j=0;j<N;j++) + { + float *x=ot[j]+subvect_size*i; + /*Find new n-best based on previous n-best j*/ + if (have_sign) + vq_nbest_sign(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist); + else + vq_nbest(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist); + + /*For all new n-bests*/ + for (k=0;k<N;k++) + { + float *ct; + float err=0; + ct = ot[j]; + /*update target*/ + + /*previous target*/ + for (m=i*subvect_size;m<(i+1)*subvect_size;m++) + t[m]=ct[m]; + + /* New code: update only enough of the target to calculate error*/ + { + int rind; + float *res; + float sign=1; + rind = best_index[k]; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + res = resp+rind*subvect_size; + if (sign>0) + for (m=0;m<subvect_size;m++) + t[subvect_size*i+m] -= res[m]; + else + for (m=0;m<subvect_size;m++) + t[subvect_size*i+m] += res[m]; + } + + /*compute error (distance)*/ + err=odist[j]; + for (m=i*subvect_size;m<(i+1)*subvect_size;m++) + err += t[m]*t[m]; + /*update n-best list*/ + if (err<ndist[N-1] || ndist[N-1]<-.5) + { + + /*previous target (we don't care what happened before*/ + for (m=(i+1)*subvect_size;m<nsf;m++) + t[m]=ct[m]; + /* New code: update the rest of the target only if it's worth it */ + for (m=0;m<subvect_size;m++) + { + float g; + int rind; + float sign=1; + rind = best_index[k]; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + + g=sign*0.03125*shape_cb[rind*subvect_size+m]; + q=subvect_size-m; + for (n=subvect_size*(i+1);n<nsf;n++,q++) + t[n] -= g*r[q]; + } + + + for (m=0;m<N;m++) + { + if (err < ndist[m] || ndist[m]<-.5) + { + for (n=N-1;n>m;n--) + { + for (q=(i+1)*subvect_size;q<nsf;q++) + nt[n][q]=nt[n-1][q]; + for (q=0;q<nb_subvect;q++) + nind[n][q]=nind[n-1][q]; + ndist[n]=ndist[n-1]; + } + for (q=(i+1)*subvect_size;q<nsf;q++) + nt[m][q]=t[q]; + for (q=0;q<nb_subvect;q++) + nind[m][q]=oind[j][q]; + nind[m][i]=best_index[k]; + ndist[m]=err; + break; + } + } + } + } + if (i==0) + break; + } + + /*update old-new data*/ + /* just swap pointers instead of a long copy */ + { + float **tmp2; + tmp2=ot; + ot=nt; + nt=tmp2; + } + for (j=0;j<N;j++) + for (m=0;m<nb_subvect;m++) + oind[j][m]=nind[j][m]; + for (j=0;j<N;j++) + odist[j]=ndist[j]; + } + + /*save indices*/ + for (i=0;i<nb_subvect;i++) + { + ind[i]=nind[0][i]; + speex_bits_pack(bits,ind[i],params->shape_bits+have_sign); + } + + /* Put everything back together */ + for (i=0;i<nb_subvect;i++) + { + int rind; + float sign=1; + rind = ind[i]; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j]; + } + /* Update excitation */ + for (j=0;j<nsf;j++) + exc[j]+=e[j]; + + /* Update target */ + syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack); + for (j=0;j<nsf;j++) + target[j]-=r2[j]; + +} + + +void split_cb_shape_sign_unquant( +float *exc, +void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack +) +{ + int i,j; + int *ind, *signs; + signed char *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + split_cb_params *params; + int have_sign; + + params = (split_cb_params *) par; + subvect_size = params->subvect_size; + nb_subvect = params->nb_subvect; + shape_cb_size = 1<<params->shape_bits; + shape_cb = params->shape_cb; + have_sign = params->have_sign; + + ind = PUSH(stack, nb_subvect, int); + signs = PUSH(stack, nb_subvect, int); + + /* Decode codewords and gains */ + for (i=0;i<nb_subvect;i++) + { + if (have_sign) + signs[i] = speex_bits_unpack_unsigned(bits, 1); + else + signs[i] = 0; + ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits); + } + /* Compute decoded excitation */ + for (i=0;i<nb_subvect;i++) + { + float s=1; + if (signs[i]) + s=-1; + for (j=0;j<subvect_size;j++) + exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j]; + } +} + +void noise_codebook_quant( +float target[], /* target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs for this subframe */ +float awk2[], /* Weighted LPCs for this subframe */ +void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +float *exc, +float *r, +SpeexBits *bits, +char *stack, +int complexity +) +{ + int i; + float *tmp=PUSH(stack, nsf, float); + residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack); + + for (i=0;i<nsf;i++) + exc[i]+=tmp[i]; + for (i=0;i<nsf;i++) + target[i]=0; + +} + + +void noise_codebook_unquant( +float *exc, +void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack +) +{ + speex_rand_vec(1, exc, nsf); +} diff --git a/engine/voice_codecs/speex/source/libspeex/cb_search.h b/engine/voice_codecs/speex/source/libspeex/cb_search.h new file mode 100644 index 0000000..dea5589 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/cb_search.h @@ -0,0 +1,95 @@ +/* Copyright (C) 2002 Jean-Marc Valin & David Rowe + File: cb_search.c + Overlapped codebook search + + 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 CB_SEARCH_H +#define CB_SEARCH_H + +#include "speex_bits.h" + +typedef struct split_cb_params { + int subvect_size; + int nb_subvect; + signed char *shape_cb; + int shape_bits; + int have_sign; +} split_cb_params; + + +void split_cb_search_shape_sign( +float target[], /* target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs for this subframe */ +float awk2[], /* Weighted LPCs for this subframe */ +void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +float *exc, +float *r, +SpeexBits *bits, +char *stack, +int complexity +); + +void split_cb_shape_sign_unquant( +float *exc, +void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack +); + + +void noise_codebook_quant( +float target[], /* target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs for this subframe */ +float awk2[], /* Weighted LPCs for this subframe */ +void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +float *exc, +float *r, +SpeexBits *bits, +char *stack, +int complexity +); + + +void noise_codebook_unquant( +float *exc, +void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack +); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/exc_10_16_table.c b/engine/voice_codecs/speex/source/libspeex/exc_10_16_table.c new file mode 100644 index 0000000..322ef38 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_10_16_table.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_10_16_table.c + Codebook for excitation in narrowband CELP mode (3200 bps) + + 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. +*/ + + +signed char exc_10_16_table[160] = { +22,39,14,44,11,35,-2,23,-4,6, +46,-28,13,-27,-23,12,4,20,-5,9, +37,-18,-23,23,0,9,-6,-20,4,-1, +-17,-5,-4,17,0,1,9,-2,1,2, +2,-12,8,-25,39,15,9,16,-55,-11, +9,11,5,10,-2,-60,8,13,-6,11, +-16,27,-47,-12,11,1,16,-7,9,-3, +-29,9,-14,25,-19,34,36,12,40,-10, +-3,-24,-14,-37,-21,-35,-2,-36,3,-6, +67,28,6,-17,-3,-12,-16,-15,-17,-7, +-59,-36,-13,1,7,1,2,10,2,11, +13,10,8,-2,7,3,5,4,2,2, +-3,-8,4,-5,6,7,-42,15,35,-2, +-46,38,28,-20,-9,1,7,-3,0,-2, +0,0,0,0,0,0,0,0,0,0, +-15,-28,52,32,5,-5,-17,-20,-10,-1}; diff --git a/engine/voice_codecs/speex/source/libspeex/exc_10_32_table.c b/engine/voice_codecs/speex/source/libspeex/exc_10_32_table.c new file mode 100644 index 0000000..75a8cb0 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_10_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_10_32_table.c + Codebook for excitation in narrowband CELP mode (4000 bps) + + 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. +*/ + + +signed char exc_10_32_table[320] = { +7,17,17,27,25,22,12,4,-3,0, +28,-36,39,-24,-15,3,-9,15,-5,10, +31,-28,11,31,-21,9,-11,-11,-2,-7, +-25,14,-22,31,4,-14,19,-12,14,-5, +4,-7,4,-5,9,0,-2,42,-47,-16, +1,8,0,9,23,-57,0,28,-11,6, +-31,55,-45,3,-5,4,2,-2,4,-7, +-3,6,-2,7,-3,12,5,8,54,-10, +8,-7,-8,-24,-25,-27,-14,-5,8,5, +44,23,5,-9,-11,-11,-13,-9,-12,-8, +-29,-8,-22,6,-15,3,-12,-1,-5,-3, +34,-1,29,-16,17,-4,12,2,1,4, +-2,-4,2,-1,11,-3,-52,28,30,-9, +-32,25,44,-20,-24,4,6,-1,0,0, +0,0,0,0,0,0,0,0,0,0, +-25,-10,22,29,13,-13,-22,-13,-4,0, +-4,-16,10,15,-36,-24,28,25,-1,-3, +66,-33,-11,-15,6,0,3,4,-2,5, +24,-20,-47,29,19,-2,-4,-1,0,-1, +-2,3,1,8,-11,5,5,-57,28,28, +0,-16,4,-4,12,-6,-1,2,-20,61, +-9,24,-22,-42,29,6,17,8,4,2, +-65,15,8,10,5,6,5,3,2,-2, +-3,5,-9,4,-5,23,13,23,-3,-63, +3,-5,-4,-6,0,-3,23,-36,-46,9, +5,5,8,4,9,-5,1,-3,10,1, +-6,10,-11,24,-47,31,22,-12,14,-10, +6,11,-7,-7,7,-31,51,-12,-6,7, +6,-17,9,-11,-20,52,-19,3,-6,-6, +-8,-5,23,-41,37,1,-21,10,-14,8, +7,5,-15,-15,23,39,-26,-33,7,2, +-32,-30,-21,-8,4,12,17,15,14,11}; diff --git a/engine/voice_codecs/speex/source/libspeex/exc_20_32_table.c b/engine/voice_codecs/speex/source/libspeex/exc_20_32_table.c new file mode 100644 index 0000000..76b0c94 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_20_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_20_32_table.c + Codebook for excitation in narrowband CELP mode (2000 bps) + + 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. +*/ + + +signed char exc_20_32_table[640] = { +12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5, +31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11, +42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2, +-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16, +0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10, +13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6, +-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2, +-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3, +27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1, +87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1, +-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5, +48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7, +-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1, +-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2, +-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2, +-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6, +-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2, +120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3, +30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1, +1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13, +3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2, +-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0, +-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2, +12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11, +17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3, +6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9, +-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7, +-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1, +7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12, +0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2}; diff --git a/engine/voice_codecs/speex/source/libspeex/exc_5_256_table.c b/engine/voice_codecs/speex/source/libspeex/exc_5_256_table.c new file mode 100644 index 0000000..1ceb2d4 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_5_256_table.c @@ -0,0 +1,290 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_5_256_table.c + Codebook for excitation in narrowband CELP mode (12800 bps) + + 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. +*/ + + +signed char exc_5_256_table[1280] = { +-8,-37,5,-43,5, +73,61,39,12,-3, +-61,-32,2,42,30, +-3,17,-27,9,34, +20,-1,-5,2,23, +-7,-46,26,53,-47, +20,-2,-33,-89,-51, +-64,27,11,15,-34, +-5,-56,25,-9,-1, +-29,1,40,67,-23, +-16,16,33,19,7, +14,85,22,-10,-10, +-12,-7,-1,52,89, +29,11,-20,-37,-46, +-15,17,-24,-28,24, +2,1,0,23,-101, +23,14,-1,-23,-18, +9,5,-13,38,1, +-28,-28,4,27,51, +-26,34,-40,35,47, +54,38,-54,-26,-6, +42,-25,13,-30,-36, +18,41,-4,-33,23, +-32,-7,-4,51,-3, +17,-52,56,-47,36, +-2,-21,36,10,8, +-33,31,19,9,-5, +-40,10,-9,-21,19, +18,-78,-18,-5,0, +-26,-36,-47,-51,-44, +18,40,27,-2,29, +49,-26,2,32,-54, +30,-73,54,3,-5, +36,22,53,10,-1, +-84,-53,-29,-5,3, +-44,53,-51,4,22, +71,-35,-1,33,-5, +-27,-7,36,17,-23, +-39,16,-9,-55,-15, +-20,39,-35,6,-39, +-14,18,48,-64,-17, +-15,9,39,81,37, +-68,37,47,-21,-6, +-104,13,6,9,-2, +35,8,-23,18,42, +45,21,33,-5,-49, +9,-6,-43,-56,39, +2,-16,-25,87,1, +-3,-9,17,-25,-11, +-9,-1,10,2,-14, +-14,4,-1,-10,28, +-23,40,-32,26,-9, +26,4,-27,-23,3, +42,-60,1,49,-3, +27,10,-52,-40,-2, +18,45,-23,17,-44, +3,-3,17,-46,52, +-40,-47,25,75,31, +-49,53,30,-30,-32, +-36,38,-6,-15,-16, +54,-27,-48,3,38, +-29,-32,-22,-14,-4, +-23,-13,32,-39,9, +8,-45,-13,34,-16, +49,40,32,31,28, +23,23,32,47,59, +-68,8,62,44,25, +-14,-24,-65,-16,36, +67,-25,-38,-21,4, +-33,-2,42,5,-63, +40,11,26,-42,-23, +-61,79,-31,23,-20, +10,-32,53,-25,-36, +10,-26,-5,3,0, +-71,5,-10,-37,1, +-24,21,-54,-17,1, +-29,-25,-15,-27,32, +68,45,-16,-37,-18, +-5,1,0,-77,71, +-6,3,-20,71,-67, +29,-35,10,-30,19, +4,16,17,5,0, +-14,19,2,28,26, +59,3,2,24,39, +55,-50,-45,-18,-17, +33,-35,14,-1,1, +8,87,-35,-29,0, +-27,13,-7,23,-13, +37,-40,50,-35,14, +19,-7,-14,49,54, +-5,22,-2,-29,-8, +-27,38,13,27,48, +12,-41,-21,-15,28, +7,-16,-24,-19,-20, +11,-20,9,2,13, +23,-20,11,27,-27, +71,-69,8,2,-6, +22,12,16,16,9, +-16,-8,-17,1,25, +1,40,-37,-33,66, +94,53,4,-22,-25, +-41,-42,25,35,-16, +-15,57,31,-29,-32, +21,16,-60,45,15, +-1,7,57,-26,-47, +-29,11,8,15,19, +-105,-8,54,27,10, +-17,6,-12,-1,-10, +4,0,23,-10,31, +13,11,10,12,-64, +23,-3,-8,-19,16, +52,24,-40,16,10, +40,5,9,0,-13, +-7,-21,-8,-6,-7, +-21,59,16,-53,18, +-60,11,-47,14,-18, +25,-13,-24,4,-39, +16,-28,54,26,-67, +30,27,-20,-52,20, +-12,55,12,18,-16, +39,-14,-6,-26,56, +-88,-55,12,25,26, +-37,6,75,0,-34, +-81,54,-30,1,-7, +49,-23,-14,21,10, +-62,-58,-57,-47,-34, +15,-4,34,-78,31, +25,-11,7,50,-10, +42,-63,14,-36,-4, +57,55,57,53,42, +-42,-1,15,40,37, +15,25,-11,6,1, +31,-2,-6,-1,-7, +-64,34,28,30,-1, +3,21,0,-88,-12, +-56,25,-28,40,8, +-28,-14,9,12,2, +-6,-17,22,49,-6, +-26,14,28,-20,4, +-12,50,35,40,13, +-38,-58,-29,17,30, +22,60,26,-54,-39, +-12,58,-28,-63,10, +-21,-8,-12,26,-62, +6,-10,-11,-22,-6, +-7,4,1,18,2, +-70,11,14,4,13, +19,-24,-34,24,67, +17,51,-21,13,23, +54,-30,48,1,-13, +80,26,-16,-2,13, +-4,6,-30,29,-24, +73,-58,30,-27,20, +-2,-21,41,45,30, +-27,-3,-5,-18,-20, +-49,-3,-35,10,42, +-19,-67,-53,-11,9, +13,-15,-33,-51,-30, +15,7,25,-30,4, +28,-22,-34,54,-29, +39,-46,20,16,34, +-4,47,75,1,-44, +-55,-24,7,-1,9, +-42,50,-8,-36,41, +68,0,-4,-10,-23, +-15,-50,64,36,-9, +-27,12,25,-38,-47, +-37,32,-49,51,-36, +2,-4,69,-26,19, +7,45,67,46,13, +-63,46,15,-47,4, +-41,13,-6,5,-21, +37,26,-55,-7,33, +-1,-28,10,-17,-64, +-14,0,-36,-17,93, +-3,-9,-66,44,-21, +3,-12,38,-6,-13, +-12,19,13,43,-43, +-10,-12,6,-5,9, +-49,32,-5,2,4, +5,15,-16,10,-21, +8,-62,-8,64,8, +79,-1,-66,-49,-18, +5,40,-5,-30,-45, +1,-6,21,-32,93, +-18,-30,-21,32,21, +-18,22,8,5,-41, +-54,80,22,-10,-7, +-8,-23,-64,66,56, +-14,-30,-41,-46,-14, +-29,-37,27,-14,42, +-2,-9,-29,34,14, +33,-14,22,4,10, +26,26,28,32,23, +-72,-32,3,0,-14, +35,-42,-78,-32,6, +29,-18,-45,-5,7, +-33,-45,-3,-22,-34, +8,-8,4,-51,-25, +-9,59,-78,21,-5, +-25,-48,66,-15,-17, +-24,-49,-13,25,-23, +-64,-6,40,-24,-19, +-11,57,-33,-8,1, +10,-52,-54,28,39, +49,34,-11,-61,-41, +-43,10,15,-15,51, +30,15,-51,32,-34, +-2,-34,14,18,16, +1,1,-3,-3,1, +1,-18,6,16,48, +12,-5,-42,7,36, +48,7,-20,-10,7, +12,2,54,39,-38, +37,54,4,-11,-8, +-46,-10,5,-10,-34, +46,-12,29,-37,39, +36,-11,24,56,17, +14,20,25,0,-25, +-28,55,-7,-5,27, +3,9,-26,-8,6, +-24,-10,-30,-31,-34, +18,4,22,21,40, +-1,-29,-37,-8,-21, +92,-29,11,-3,11, +73,23,22,7,4, +-44,-9,-11,21,-13, +11,9,-78,-1,47, +114,-12,-37,-19,-5, +-11,-22,19,12,-30, +7,38,45,-21,-8, +-9,55,-45,56,-21, +7,17,46,-57,-87, +-6,27,31,31,7, +-56,-12,46,21,-5, +-12,36,3,3,-21, +43,19,12,-7,9, +-14,0,-9,-33,-91, +7,26,3,-11,64, +83,-31,-46,25,2, +9,5,2,2,-1, +20,-17,10,-5,-27, +-8,20,8,-19,16, +-21,-13,-31,5,5, +42,24,9,34,-20, +28,-61,22,11,-39, +64,-20,-1,-30,-9, +-20,24,-25,-24,-29, +22,-60,6,-5,41, +-9,-87,14,34,15, +-57,52,69,15,-3, +-102,58,16,3,6, +60,-75,-32,26,7, +-57,-27,-32,-24,-21, +-29,-16,62,-46,31, +30,-27,-15,7,15}; diff --git a/engine/voice_codecs/speex/source/libspeex/exc_5_64_table.c b/engine/voice_codecs/speex/source/libspeex/exc_5_64_table.c new file mode 100644 index 0000000..ec08abf --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_5_64_table.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_5_64_table.c + Codebook for excitation in narrowband CELP mode (9600 bps) + + 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. +*/ + + +signed char exc_5_64_table[320]={ +1,5,-15,49,-66, +-48,-4,50,-44,7, +37,16,-18,25,-26, +-26,-15,19,19,-27, +-47,28,57,5,-17, +-32,-41,68,21,-2, +64,56,8,-16,-13, +-26,-9,-16,11,6, +-39,25,-19,22,-31, +20,-45,55,-43,10, +-16,47,-40,40,-20, +-51,3,-17,-14,-15, +-24,53,-20,-46,46, +27,-68,32,3,-18, +-5,9,-31,16,-9, +-10,-1,-23,48,95, +47,25,-41,-32,-3, +15,-25,-55,36,41, +-27,20,5,13,14, +-22,5,2,-23,18, +46,-15,17,-18,-34, +-5,-8,27,-55,73, +16,2,-1,-17,40, +-78,33,0,2,19, +4,53,-16,-15,-16, +-28,-3,-13,49,8, +-7,-29,27,-13,32, +20,32,-61,16,14, +41,44,40,24,20, +7,4,48,-60,-77, +17,-6,-48,65,-15, +32,-30,-71,-10,-3, +-6,10,-2,-7,-29, +-56,67,-30,7,-5, +86,-6,-10,0,5, +-31,60,34,-38,-3, +24,10,-2,30,23, +24,-41,12,70,-43, +15,-17,6,13,16, +-13,8,30,-15,-8, +5,23,-34,-98,-4, +-13,13,-48,-31,70, +12,31,25,24,-24, +26,-7,33,-16,8, +5,-11,-14,-8,-65, +13,10,-2,-9,0, +-3,-68,5,35,7, +0,-31,-1,-17,-9, +-9,16,-37,-18,-1, +69,-48,-28,22,-21, +-11,5,49,55,23, +-86,-36,16,2,13, +63,-51,30,-11,13, +24,-18,-6,14,-19, +1,41,9,-5,27, +-36,-44,-34,-37,-21, +-26,31,-39,15,43, +5,-8,29,20,-8, +-20,-52,-28,-1,13, +26,-34,-10,-9,27, +-8,8,27,-66,4, +12,-22,49,10,-77, +32,-18,3,-38,12, +-3,-1,2,2,0}; diff --git a/engine/voice_codecs/speex/source/libspeex/exc_8_128_table.c b/engine/voice_codecs/speex/source/libspeex/exc_8_128_table.c new file mode 100644 index 0000000..e812a8d --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/exc_8_128_table.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_8_128_table.c + Codebook for excitation in narrowband CELP mode (7000 bps) + + 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. +*/ + + +signed char exc_8_128_table[1024] = { +-14,9,13,-32,2,-10,31,-10, +-8,-8,6,-4,-1,10,-64,23, +6,20,13,6,8,-22,16,34, +7,42,-49,-28,5,26,4,-15, +41,34,41,32,33,24,23,14, +8,40,34,4,-24,-41,-19,-15, +13,-13,33,-54,24,27,-44,33, +27,-15,-15,24,-19,14,-36,14, +-9,24,-12,-4,37,-5,16,-34, +5,10,33,-15,-54,-16,12,25, +12,1,2,0,3,-1,-4,-4, +11,2,-56,54,27,-20,13,-6, +-46,-41,-33,-11,-5,7,12,14, +-14,-5,8,20,6,3,4,-8, +-5,-42,11,8,-14,25,-2,2, +13,11,-22,39,-9,9,5,-45, +-9,7,-9,12,-7,34,-17,-102, +7,2,-42,18,35,-9,-34,11, +-5,-2,3,22,46,-52,-25,-9, +-94,8,11,-5,-5,-5,4,-7, +-35,-7,54,5,-32,3,24,-9, +-22,8,65,37,-1,-12,-23,-6, +-9,-28,55,-33,14,-3,2,18, +-60,41,-17,8,-16,17,-11,0, +-11,29,-28,37,9,-53,33,-14, +-9,7,-25,-7,-11,26,-32,-8, +24,-21,22,-19,19,-10,29,-14, +0,0,0,0,0,0,0,0, +-5,-52,10,41,6,-30,-4,16, +32,22,-27,-22,32,-3,-28,-3, +3,-35,6,17,23,21,8,2, +4,-45,-17,14,23,-4,-31,-11, +-3,14,1,19,-11,2,61,-8, +9,-12,7,-10,12,-3,-24,99, +-48,23,50,-37,-5,-23,0,8, +-14,35,-64,-5,46,-25,13,-1, +-49,-19,-15,9,34,50,25,11, +-6,-9,-16,-20,-32,-33,-32,-27, +10,-8,12,-15,56,-14,-32,33, +3,-9,1,65,-9,-9,-10,-2, +-6,-23,9,17,3,-28,13,-32, +4,-2,-10,4,-16,76,12,-52, +6,13,33,-6,4,-14,-9,-3, +1,-15,-16,28,1,-15,11,16, +9,4,-21,-37,-40,-6,22,12, +-15,-23,-14,-17,-16,-9,-10,-9, +13,-39,41,5,-9,16,-38,25, +46,-47,4,49,-14,17,-2,6, +18,5,-6,-33,-22,44,50,-2, +1,3,-6,7,7,-3,-21,38, +-18,34,-14,-41,60,-13,6,16, +-24,35,19,-13,-36,24,3,-17, +-14,-10,36,44,-44,-29,-3,3, +-54,-8,12,55,26,4,-2,-5, +2,-11,22,-23,2,22,1,-25, +-39,66,-49,21,-8,-2,10,-14, +-60,25,6,10,27,-25,16,5, +-2,-9,26,-13,-20,58,-2,7, +52,-9,2,5,-4,-15,23,-1, +-38,23,8,27,-6,0,-27,-7, +39,-10,-14,26,11,-45,-12,9, +-5,34,4,-35,10,43,-22,-11, +56,-7,20,1,10,1,-26,9, +94,11,-27,-14,-13,1,-11,0, +14,-5,-6,-10,-4,-15,-8,-41, +21,-5,1,-28,-8,22,-9,33, +-23,-4,-4,-12,39,4,-7,3, +-60,80,8,-17,2,-6,12,-5, +1,9,15,27,31,30,27,23, +61,47,26,10,-5,-8,-12,-13, +5,-18,25,-15,-4,-15,-11,12, +-2,-2,-16,-2,-6,24,12,11, +-4,9,1,-9,14,-45,57,12, +20,-35,26,11,-64,32,-10,-10, +42,-4,-9,-16,32,24,7,10, +52,-11,-57,29,0,8,0,-6, +17,-17,-56,-40,7,20,18,12, +-6,16,5,7,-1,9,1,10, +29,12,16,13,-2,23,7,9, +-3,-4,-5,18,-64,13,55,-25, +9,-9,24,14,-25,15,-11,-40, +-30,37,1,-19,22,-5,-31,13, +-2,0,7,-4,16,-67,12,66, +-36,24,-8,18,-15,-23,19,0, +-45,-7,4,3,-13,13,35,5, +13,33,10,27,23,0,-7,-11, +43,-74,36,-12,2,5,-8,6, +-33,11,-16,-14,-5,-7,-3,17, +-34,27,-16,11,-9,15,33,-31, +8,-16,7,-6,-7,63,-55,-17, +11,-1,20,-46,34,-30,6,9, +19,28,-9,5,-24,-8,-23,-2, +31,-19,-16,-5,-15,-18,0,26, +18,37,-5,-15,-2,17,5,-27, +21,-33,44,12,-27,-9,17,11, +25,-21,-31,-7,13,33,-8,-25, +-7,7,-10,4,-6,-9,48,-82, +-23,-8,6,11,-23,3,-3,49, +-29,25,31,4,14,16,9,-4, +-18,10,-26,3,5,-44,-9,9, +-47,-55,15,9,28,1,4,-3, +46,6,-6,-38,-29,-31,-15,-6, +3,0,14,-6,8,-54,-50,33, +-5,1,-14,33,-48,26,-4,-5, +-3,-5,-3,-5,-28,-22,77,55, +-1,2,10,10,-9,-14,-66,-49, +11,-36,-6,-20,10,-10,16,12, +4,-1,-16,45,-44,-50,31,-2, +25,42,23,-32,-22,0,11,20, +-40,-35,-40,-36,-32,-26,-21,-13, +52,-22,6,-24,-20,17,-5,-8, +36,-25,-11,21,-26,6,34,-8, +7,20,-3,5,-25,-8,18,-5, +-9,-4,1,-9,20,20,39,48, +-24,9,5,-65,22,29,4,3, +-43,-11,32,-6,9,19,-27,-10, +-47,-14,24,10,-7,-36,-7,-1, +-4,-5,-5,16,53,25,-26,-29, +-4,-12,45,-58,-34,33,-5,2, +-1,27,-48,31,-15,22,-5,4, +7,7,-25,-3,11,-22,16,-12, +8,-3,7,-11,45,14,-73,-19, +56,-46,24,-20,28,-12,-2,-1, +-36,-3,-33,19,-6,7,2,-15, +5,-31,-45,8,35,13,20,0, +-9,48,-13,-43,-3,-13,2,-5, +72,-68,-27,2,1,-2,-7,5, +36,33,-40,-12,-4,-5,23,19}; diff --git a/engine/voice_codecs/speex/source/libspeex/filters.c b/engine/voice_codecs/speex/source/libspeex/filters.c new file mode 100644 index 0000000..e924ef0 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/filters.c @@ -0,0 +1,292 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: filters.c + Various analysis/synthesis filters + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "filters.h" +#include "stack_alloc.h" +#include <math.h> + + +void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order) +{ + int i; + float tmp=1; + for (i=0;i<order+1;i++) + { + lpc_out[i] = tmp * lpc_in[i]; + tmp *= gamma; + } +} + +#ifdef _USE_SSE +#include "filters_sse.h" +#else +void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem) +{ + int i,j; + float xi,yi; + for (i=0;i<N;i++) + { + xi=x[i]; + y[i] = num[0]*xi + mem[0]; + yi=y[i]; + for (j=0;j<ord-1;j++) + { + mem[j] = mem[j+1] + num[j+1]*xi - den[j+1]*yi; + } + mem[ord-1] = num[ord]*xi - den[ord]*yi; + } +} + + +void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem) +{ + int i,j; + for (i=0;i<N;i++) + { + y[i] = x[i] + mem[0]; + for (j=0;j<ord-1;j++) + { + mem[j] = mem[j+1] - den[j+1]*y[i]; + } + mem[ord-1] = - den[ord]*y[i]; + } +} +#endif + +void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem) +{ + int i,j; + float xi; + for (i=0;i<N;i++) + { + xi=x[i]; + y[i] = num[0]*xi + mem[0]; + for (j=0;j<ord-1;j++) + { + mem[j] = mem[j+1] + num[j+1]*xi; + } + mem[ord-1] = num[ord]*xi; + } +} + +void syn_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack) +{ + int i; + float *mem = PUSH(stack,ord, float); + for (i=0;i<ord;i++) + mem[i]=0; + filter_mem2(xx, awk1, ak, y, N, ord, mem); + for (i=0;i<ord;i++) + mem[i]=0; + iir_mem2(y, awk2, y, N, ord, mem); +} + +void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack) +{ + int i; + float *mem = PUSH(stack,ord, float); + for (i=0;i<ord;i++) + mem[i]=0; + filter_mem2(xx, ak, awk1, y, N, ord, mem); + for (i=0;i<ord;i++) + mem[i]=0; + fir_mem2(y, awk2, y, N, ord, mem); +} + + +void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack) +{ + int i,j,k,M2; + float *a; + float *x; + float *x2; + + a = PUSH(stack, M, float); + x = PUSH(stack, N+M-1, float); + x2=x+M-1; + M2=M>>1; + for (i=0;i<M;i++) + a[M-i-1]=aa[i]; + for (i=0;i<M-1;i++) + x[i]=mem[M-i-2]; + for (i=0;i<N;i++) + x[i+M-1]=xx[i]; + for (i=0,k=0;i<N;i+=2,k++) + { + y1[k]=0; + y2[k]=0; + for (j=0;j<M2;j++) + { + y1[k]+=a[j]*(x[i+j]+x2[i-j]); + y2[k]-=a[j]*(x[i+j]-x2[i-j]); + j++; + y1[k]+=a[j]*(x[i+j]+x2[i-j]); + y2[k]+=a[j]*(x[i+j]-x2[i-j]); + } + } + for (i=0;i<M-1;i++) + mem[i]=xx[N-i-1]; +} + +/* By segher */ +void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack) + /* assumptions: + all odd x[i] are zero -- well, actually they are left out of the array now + N and M are multiples of 4 */ +{ + int i, j; + float *xx=PUSH(stack, M+N-1, float); + + for (i = 0; i < N/2; i++) + xx[2*i] = x[N/2-1-i]; + for (i = 0; i < M - 1; i += 2) + xx[N+i] = mem[i+1]; + + for (i = 0; i < N; i += 4) { + float y0, y1, y2, y3; + float x0; + + y0 = y1 = y2 = y3 = 0.f; + x0 = xx[N-4-i]; + + for (j = 0; j < M; j += 4) { + float x1; + float a0, a1; + + a0 = a[j]; + a1 = a[j+1]; + x1 = xx[N-2+j-i]; + + y0 += a0 * x1; + y1 += a1 * x1; + y2 += a0 * x0; + y3 += a1 * x0; + + a0 = a[j+2]; + a1 = a[j+3]; + x0 = xx[N+j-i]; + + y0 += a0 * x0; + y1 += a1 * x0; + y2 += a0 * x1; + y3 += a1 * x1; + } + y[i] = y0; + y[i+1] = y1; + y[i+2] = y2; + y[i+3] = y3; + } + + for (i = 0; i < M - 1; i += 2) + mem[i+1] = xx[i]; +} + + +void comp_filter_mem_init (CombFilterMem *mem) +{ + mem->last_pitch=0; + mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0; + mem->smooth_gain=1; +} + +void comb_filter( +float *exc, /*decoded excitation*/ +float *new_exc, /*enhanced excitation*/ +float *ak, /*LPC filter coefs*/ +int p, /*LPC order*/ +int nsf, /*sub-frame size*/ +int pitch, /*pitch period*/ +float *pitch_gain, /*pitch gain (3-tap)*/ +float comb_gain, /*gain of comb filter*/ +CombFilterMem *mem +) +{ + int i; + float exc_energy=0, new_exc_energy=0; + float gain; + float step; + float fact; + /*Compute excitation energy prior to enhancement*/ + for (i=0;i<nsf;i++) + exc_energy+=exc[i]*exc[i]; + + /*Some gain adjustment is pitch is too high or if unvoiced*/ + { + float g=0; + g = .5*fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2] + + mem->last_pitch_gain[0] + mem->last_pitch_gain[1] + mem->last_pitch_gain[2]); + if (g>1.3) + comb_gain*=1.3/g; + if (g<.5) + comb_gain*=2*g; + } + step = 1.0/nsf; + fact=0; + /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/ + for (i=0;i<nsf;i++) + { + fact += step; + + new_exc[i] = exc[i] + comb_gain * fact * ( + pitch_gain[0]*exc[i-pitch+1] + + pitch_gain[1]*exc[i-pitch] + + pitch_gain[2]*exc[i-pitch-1] + ) + + comb_gain * (1-fact) * ( + mem->last_pitch_gain[0]*exc[i-mem->last_pitch+1] + + mem->last_pitch_gain[1]*exc[i-mem->last_pitch] + + mem->last_pitch_gain[2]*exc[i-mem->last_pitch-1] + ); + } + + mem->last_pitch_gain[0] = pitch_gain[0]; + mem->last_pitch_gain[1] = pitch_gain[1]; + mem->last_pitch_gain[2] = pitch_gain[2]; + mem->last_pitch = pitch; + + /*Gain after enhancement*/ + for (i=0;i<nsf;i++) + new_exc_energy+=new_exc[i]*new_exc[i]; + + /*Compute scaling factor and normalize energy*/ + gain = sqrt(exc_energy)/sqrt(.1+new_exc_energy); + if (gain < .5) + gain=.5; + if (gain>1) + gain=1; + + for (i=0;i<nsf;i++) + { + mem->smooth_gain = .96*mem->smooth_gain + .04*gain; + new_exc[i] *= mem->smooth_gain; + } +} diff --git a/engine/voice_codecs/speex/source/libspeex/filters.h b/engine/voice_codecs/speex/source/libspeex/filters.h new file mode 100644 index 0000000..ad6dc02 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/filters.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: filters.h + Various analysis/synthesis filters + + 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 FILTERS_H +#define FILTERS_H + + +typedef struct CombFilterMem { + int last_pitch; + float last_pitch_gain[3]; + float smooth_gain; +} CombFilterMem; + + +void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack); +void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack); + + +void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem); +void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem); +void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem); + +/* Apply bandwidth expansion on LPC coef */ +void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order); + + + +/* FIR filter */ +void fir_decim_mem(float *x, float *a, float *y, int N, int M, float *mem); + +void syn_percep_zero(float *x, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); + +void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); + +void comp_filter_mem_init (CombFilterMem *mem); + +void comb_filter( +float *exc, /*decoded excitation*/ +float *new_exc, /*enhanced excitation*/ +float *ak, /*LPC filter coefs*/ +int p, /*LPC order*/ +int nsf, /*sub-frame size*/ +int pitch, /*pitch period*/ +float *pitch_gain, /*pitch gain (3-tap)*/ +float comb_gain, /*gain of comb filter*/ +CombFilterMem *mem +); + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/filters_sse.h b/engine/voice_codecs/speex/source/libspeex/filters_sse.h new file mode 100644 index 0000000..3fba6c8 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/filters_sse.h @@ -0,0 +1,289 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: filters.c + Various analysis/synthesis filters + + 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. +*/ + +void filter_mem2(float *x, float *_num, float *_den, float *y, int N, int ord, float *_mem) +{ + float __num[20], __den[20], __mem[20]; + float *num, *den, *mem; + int i; + + num = (float*)(((int)(__num+4))&0xfffffff0)-1; + den = (float*)(((int)(__den+4))&0xfffffff0)-1; + mem = (float*)(((int)(__mem+4))&0xfffffff0)-1; + for (i=0;i<=10;i++) + num[i]=den[i]=0; + for (i=0;i<10;i++) + mem[i]=0; + + for (i=0;i<ord+1;i++) + { + num[i]=_num[i]; + den[i]=_den[i]; + } + for (i=0;i<ord;i++) + mem[i]=_mem[i]; + for (i=0;i<N;i+=4) + { + + __asm__ __volatile__ + ( + "\tmovss (%1), %%xmm0\n" + "\tmovss (%0), %%xmm1\n" + "\taddss %%xmm0, %%xmm1\n" + "\tmovss %%xmm1, (%2)\n" + "\tshufps $0x00, %%xmm0, %%xmm0\n" + "\tshufps $0x00, %%xmm1, %%xmm1\n" + + "\tmovaps 4(%3), %%xmm2\n" + "\tmovaps 4(%4), %%xmm3\n" + "\tmulps %%xmm0, %%xmm2\n" + "\tmulps %%xmm1, %%xmm3\n" + "\tmovaps 20(%3), %%xmm4\n" + "\tmulps %%xmm0, %%xmm4\n" + "\taddps 4(%0), %%xmm2\n" + "\tmovaps 20(%4), %%xmm5\n" + "\tmulps %%xmm1, %%xmm5\n" + "\taddps 20(%0), %%xmm4\n" + "\tsubps %%xmm3, %%xmm2\n" + "\tmovups %%xmm2, (%0)\n" + "\tsubps %%xmm5, %%xmm4\n" + "\tmovups %%xmm4, 16(%0)\n" + + "\tmovss 36(%3), %%xmm2\n" + "\tmulss %%xmm0, %%xmm2\n" + "\tmovss 36(%4), %%xmm3\n" + "\tmulss %%xmm1, %%xmm3\n" + "\taddss 36(%0), %%xmm2\n" + "\tmovss 40(%3), %%xmm4\n" + "\tmulss %%xmm0, %%xmm4\n" + "\tmovss 40(%4), %%xmm5\n" + "\tmulss %%xmm1, %%xmm5\n" + "\tsubss %%xmm3, %%xmm2\n" + "\tmovss %%xmm2, 32(%0) \n" + "\tsubss %%xmm5, %%xmm4\n" + "\tmovss %%xmm4, 36(%0)\n" + + + + "\tmovss 4(%1), %%xmm0\n" + "\tmovss (%0), %%xmm1\n" + "\taddss %%xmm0, %%xmm1\n" + "\tmovss %%xmm1, 4(%2)\n" + "\tshufps $0x00, %%xmm0, %%xmm0\n" + "\tshufps $0x00, %%xmm1, %%xmm1\n" + + "\tmovaps 4(%3), %%xmm2\n" + "\tmovaps 4(%4), %%xmm3\n" + "\tmulps %%xmm0, %%xmm2\n" + "\tmulps %%xmm1, %%xmm3\n" + "\tmovaps 20(%3), %%xmm4\n" + "\tmulps %%xmm0, %%xmm4\n" + "\taddps 4(%0), %%xmm2\n" + "\tmovaps 20(%4), %%xmm5\n" + "\tmulps %%xmm1, %%xmm5\n" + "\taddps 20(%0), %%xmm4\n" + "\tsubps %%xmm3, %%xmm2\n" + "\tmovups %%xmm2, (%0)\n" + "\tsubps %%xmm5, %%xmm4\n" + "\tmovups %%xmm4, 16(%0)\n" + + "\tmovss 36(%3), %%xmm2\n" + "\tmulss %%xmm0, %%xmm2\n" + "\tmovss 36(%4), %%xmm3\n" + "\tmulss %%xmm1, %%xmm3\n" + "\taddss 36(%0), %%xmm2\n" + "\tmovss 40(%3), %%xmm4\n" + "\tmulss %%xmm0, %%xmm4\n" + "\tmovss 40(%4), %%xmm5\n" + "\tmulss %%xmm1, %%xmm5\n" + "\tsubss %%xmm3, %%xmm2\n" + "\tmovss %%xmm2, 32(%0) \n" + "\tsubss %%xmm5, %%xmm4\n" + "\tmovss %%xmm4, 36(%0)\n" + + + + "\tmovss 8(%1), %%xmm0\n" + "\tmovss (%0), %%xmm1\n" + "\taddss %%xmm0, %%xmm1\n" + "\tmovss %%xmm1, 8(%2)\n" + "\tshufps $0x00, %%xmm0, %%xmm0\n" + "\tshufps $0x00, %%xmm1, %%xmm1\n" + + "\tmovaps 4(%3), %%xmm2\n" + "\tmovaps 4(%4), %%xmm3\n" + "\tmulps %%xmm0, %%xmm2\n" + "\tmulps %%xmm1, %%xmm3\n" + "\tmovaps 20(%3), %%xmm4\n" + "\tmulps %%xmm0, %%xmm4\n" + "\taddps 4(%0), %%xmm2\n" + "\tmovaps 20(%4), %%xmm5\n" + "\tmulps %%xmm1, %%xmm5\n" + "\taddps 20(%0), %%xmm4\n" + "\tsubps %%xmm3, %%xmm2\n" + "\tmovups %%xmm2, (%0)\n" + "\tsubps %%xmm5, %%xmm4\n" + "\tmovups %%xmm4, 16(%0)\n" + + "\tmovss 36(%3), %%xmm2\n" + "\tmulss %%xmm0, %%xmm2\n" + "\tmovss 36(%4), %%xmm3\n" + "\tmulss %%xmm1, %%xmm3\n" + "\taddss 36(%0), %%xmm2\n" + "\tmovss 40(%3), %%xmm4\n" + "\tmulss %%xmm0, %%xmm4\n" + "\tmovss 40(%4), %%xmm5\n" + "\tmulss %%xmm1, %%xmm5\n" + "\tsubss %%xmm3, %%xmm2\n" + "\tmovss %%xmm2, 32(%0) \n" + "\tsubss %%xmm5, %%xmm4\n" + "\tmovss %%xmm4, 36(%0)\n" + + + + "\tmovss 12(%1), %%xmm0\n" + "\tmovss (%0), %%xmm1\n" + "\taddss %%xmm0, %%xmm1\n" + "\tmovss %%xmm1, 12(%2)\n" + "\tshufps $0x00, %%xmm0, %%xmm0\n" + "\tshufps $0x00, %%xmm1, %%xmm1\n" + + "\tmovaps 4(%3), %%xmm2\n" + "\tmovaps 4(%4), %%xmm3\n" + "\tmulps %%xmm0, %%xmm2\n" + "\tmulps %%xmm1, %%xmm3\n" + "\tmovaps 20(%3), %%xmm4\n" + "\tmulps %%xmm0, %%xmm4\n" + "\taddps 4(%0), %%xmm2\n" + "\tmovaps 20(%4), %%xmm5\n" + "\tmulps %%xmm1, %%xmm5\n" + "\taddps 20(%0), %%xmm4\n" + "\tsubps %%xmm3, %%xmm2\n" + "\tmovups %%xmm2, (%0)\n" + "\tsubps %%xmm5, %%xmm4\n" + "\tmovups %%xmm4, 16(%0)\n" + + "\tmovss 36(%3), %%xmm2\n" + "\tmulss %%xmm0, %%xmm2\n" + "\tmovss 36(%4), %%xmm3\n" + "\tmulss %%xmm1, %%xmm3\n" + "\taddss 36(%0), %%xmm2\n" + "\tmovss 40(%3), %%xmm4\n" + "\tmulss %%xmm0, %%xmm4\n" + "\tmovss 40(%4), %%xmm5\n" + "\tmulss %%xmm1, %%xmm5\n" + "\tsubss %%xmm3, %%xmm2\n" + "\tmovss %%xmm2, 32(%0) \n" + "\tsubss %%xmm5, %%xmm4\n" + "\tmovss %%xmm4, 36(%0)\n" + + : : "r" (mem), "r" (x+i), "r" (y+i), "r" (num), "r" (den) + : "memory" ); + + } + for (i=0;i<ord;i++) + _mem[i]=mem[i]; + +} + + +void iir_mem2(float *x, float *_den, float *y, int N, int ord, float *_mem) +{ + float __den[20], __mem[20]; + float *den, *mem; + int i; + + den = (float*)(((int)(__den+4))&0xfffffff0)-1; + mem = (float*)(((int)(__mem+4))&0xfffffff0)-1; + for (i=0;i<=10;i++) + den[i]=0; + for (i=0;i<10;i++) + mem[i]=0; + for (i=0;i<ord+1;i++) + { + den[i]=_den[i]; + } + for (i=0;i<ord;i++) + mem[i]=_mem[i]; + + for (i=0;i<N;i++) + { +#if 0 + y[i] = x[i] + mem[0]; + for (j=0;j<ord-1;j++) + { + mem[j] = mem[j+1] - den[j+1]*y[i]; + } + mem[ord-1] = - den[ord]*y[i]; +#else + __asm__ __volatile__ + ( + "\tmovss (%1), %%xmm0\n" + "\tmovss (%0), %%xmm1\n" + "\taddss %%xmm0, %%xmm1\n" + "\tmovss %%xmm1, (%2)\n" + "\tshufps $0x00, %%xmm0, %%xmm0\n" + "\tshufps $0x00, %%xmm1, %%xmm1\n" + + + "\tmovaps 4(%3), %%xmm2\n" + "\tmovaps 20(%3), %%xmm3\n" + "\tmulps %%xmm1, %%xmm2\n" + "\tmulps %%xmm1, %%xmm3\n" + "\tmovss 36(%3), %%xmm4\n" + "\tmovss 40(%3), %%xmm5\n" + "\tmulss %%xmm1, %%xmm4\n" + "\tmulss %%xmm1, %%xmm5\n" + "\tmovaps 4(%0), %%xmm6\n" + "\tsubps %%xmm2, %%xmm6\n" + "\tmovups %%xmm6, (%0)\n" + "\tmovaps 20(%0), %%xmm7\n" + "\tsubps %%xmm3, %%xmm7\n" + "\tmovups %%xmm7, 16(%0)\n" + + + "\tmovss 36(%0), %%xmm7\n" + "\tsubss %%xmm4, %%xmm7\n" + "\tmovss %%xmm7, 32(%0) \n" + "\txorps %%xmm2, %%xmm2\n" + "\tsubss %%xmm5, %%xmm2\n" + "\tmovss %%xmm2, 36(%0)\n" + + : : "r" (mem), "r" (x+i), "r" (y+i), "r" (den) + : "memory" ); +#endif + } + for (i=0;i<ord;i++) + _mem[i]=mem[i]; + +} + diff --git a/engine/voice_codecs/speex/source/libspeex/gain_table.c b/engine/voice_codecs/speex/source/libspeex/gain_table.c new file mode 100644 index 0000000..b1a2a7d --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/gain_table.c @@ -0,0 +1,160 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: gain_table.c + Codebook for 3-tap pitch prediction gain (128 entries) + + 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. +*/ + +signed char gain_cdbk_nb[384] = { +-32,-32,-32, +-28,-67,-5, +-42,-6,-32, +-57,-10,-54, +-16,27,-41, +19,-19,-40, +-45,24,-21, +-8,-14,-18, +1,14,-58, +-18,-88,-39, +-38,21,-18, +-19,20,-43, +10,17,-48, +-52,-58,-13, +-44,-1,-11, +-12,-11,-34, +14,0,-46, +-37,-35,-34, +-25,44,-30, +6,-4,-63, +-31,43,-41, +-23,30,-43, +-43,26,-14, +-33,1,-13, +-13,18,-37, +-46,-73,-45, +-36,24,-25, +-36,-11,-20, +-25,12,-18, +-36,-69,-59, +-45,6,8, +-22,-14,-24, +-1,13,-44, +-39,-48,-26, +-32,31,-37, +-33,15,-46, +-24,30,-36, +-41,31,-23, +-50,22,-4, +-22,2,-21, +-17,30,-34, +-7,-60,-28, +-38,42,-28, +-44,-11,21, +-16,8,-44, +-39,-55,-43, +-11,-35,26, +-9,0,-34, +-8,121,-81, +7,-16,-22, +-37,33,-31, +-27,-7,-36, +-34,70,-57, +-37,-11,-48, +-40,17,-1, +-33,6,-6, +-9,0,-20, +-21,69,-33, +-29,33,-31, +-55,12,-1, +-33,27,-22, +-50,-33,-47, +-50,54,51, +-1,-5,-44, +-4,22,-40, +-39,-66,-25, +-33,1,-26, +-24,-23,-25, +-11,21,-45, +-25,-45,-19, +-43,105,-16, +5,-21,1, +-16,11,-33, +-13,-99,-4, +-37,33,-15, +-25,37,-63, +-36,24,-31, +-53,-56,-38, +-41,-4,4, +-33,13,-30, +49,52,-94, +-5,-30,-15, +1,38,-40, +-23,12,-36, +-17,40,-47, +-37,-41,-39, +-49,34,0, +-18,-7,-4, +-16,17,-27, +30,5,-62, +4,48,-68, +-43,11,-11, +-18,19,-15, +-23,-62,-39, +-42,10,-2, +-21,-13,-13, +-9,13,-47, +-23,-62,-24, +-44,60,-21, +-18,-3,-52, +-22,22,-36, +-75,57,16, +-19,3,10, +-29,23,-38, +-5,-62,-51, +-51,40,-18, +-42,13,-24, +-34,14,-20, +-56,-75,-26, +-26,32,15, +-26,17,-29, +-7,28,-52, +-12,-30,5, +-5,-48,-5, +2,2,-43, +21,16,16, +-25,-45,-32, +-43,18,-10, +9,0,-1, +-1,7,-30, +19,-48,-4, +-28,25,-29, +-22,0,-31, +-32,17,-10, +-64,-41,-62, +-52,15,16, +-30,-22,-32, +-7,9,-38}; diff --git a/engine/voice_codecs/speex/source/libspeex/gain_table_lbr.c b/engine/voice_codecs/speex/source/libspeex/gain_table_lbr.c new file mode 100644 index 0000000..1d6291a --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/gain_table_lbr.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: gain_table_lbr.c + Codebook for 3-tap pitch prediction gain (32 entries) + + 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. +*/ + +signed char gain_cdbk_lbr[96] = { +-32,-32,-32, +-31,-58,-16, +-41,-24,-43, +-56,-22,-55, +-13,33,-41, +-4,-39,-9, +-41,15,-12, +-8,-15,-12, +1,2,-44, +-22,-66,-42, +-38,28,-23, +-21,14,-37, +0,21,-50, +-53,-71,-27, +-37,-1,-19, +-19,-5,-28, +6,65,-44, +-33,-48,-33, +-40,57,-14, +-17,4,-45, +-31,38,-33, +-23,28,-40, +-43,29,-12, +-34,13,-23, +-16,15,-27, +-14,-82,-15, +-31,25,-32, +-21,5,-5, +-47,-63,-51, +-46,12,3, +-28,-17,-29, +-10,14,-40}; diff --git a/engine/voice_codecs/speex/source/libspeex/hexc_10_32_table.c b/engine/voice_codecs/speex/source/libspeex/hexc_10_32_table.c new file mode 100644 index 0000000..39ff1f9 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/hexc_10_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: hexc_10_32_table.c + Codebook for high-band excitation in SB-CELP mode (4000 bps) + + 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. +*/ + +signed char hexc_10_32_table[320] = { +-3, -2, -1, 0, -4, 5, 35, -40, -9, 13, +-44, 5, -27, -1, -7, 6, -11, 7, -8, 7, +19, -14, 15, -4, 9, -10, 10, -8, 10, -9, +-1, 1, 0, 0, 2, 5, -18, 22, -53, 50, +1, -23, 50, -36, 15, 3, -13, 14, -10, 6, +1, 5, -3, 4, -2, 5, -32, 25, 5, -2, +-1, -4, 1, 11, -29, 26, -6, -15, 30, -18, +0, 15, -17, 40, -41, 3, 9, -2, -2, 3, +-3, -1, -5, 2, 21, -6, -16, -21, 23, 2, +60, 15, 16, -16, -9, 14, 9, -1, 7, -9, +0, 1, 1, 0, -1, -6, 17, -28, 54, -45, +-1, 1, -1, -6, -6, 2, 11, 26, -29, -2, +46, -21, 34, 12, -23, 32, -23, 16, -10, 3, +66, 19, -20, 24, 7, 11, -3, 0, -3, -1, +-50, -46, 2, -18, -3, 4, -1, -2, 3, -3, +-19, 41, -36, 9, 11, -24, 21, -16, 9, -3, +-25, -3, 10, 18, -9, -2, -5, -1, -5, 6, +-4, -3, 2, -26, 21, -19, 35, -15, 7, -13, +17, -19, 39, -43, 48, -31, 16, -9, 7, -2, +-5, 3, -4, 9, -19, 27, -55, 63, -35, 10, +26, -44, -2, 9, 4, 1, -6, 8, -9, 5, +-8, -1, -3, -16, 45, -42, 5, 15, -16, 10, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +-16, 24, -55, 47, -38, 27, -19, 7, -3, 1, +16, 27, 20, -19, 18, 5, -7, 1, -5, 2, +-6, 8, -22, 0, -3, -3, 8, -1, 7, -8, +1, -3, 5, 0, 17, -48, 58, -52, 29, -7, +-2, 3, -10, 6, -26, 58, -31, 1, -6, 3, +93, -29, 39, 3, 17, 5, 6, -1, -1, -1, +27, 13, 10, 19, -7, -34, 12, 10, -4, 9, +-76, 9, 8, -28, -2, -11, 2, -1, 3, 1, +-83, 38, -39, 4, -16, -6, -2, -5, 5, -2, +}; diff --git a/engine/voice_codecs/speex/source/libspeex/hexc_table.c b/engine/voice_codecs/speex/source/libspeex/hexc_table.c new file mode 100644 index 0000000..d7b2f51 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/hexc_table.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: hexc_table.c + Codebook for high-band excitation in SB-CELP mode (8000 bps with sign) + + 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. +*/ + +signed char hexc_table[1024] = { +-24, 21, -20, 5, -5, -7, 14, -10, +2, -27, 16, -20, 0, -32, 26, 19, +8, -11, -41, 31, 28, -27, -32, 34, +42, 34, -17, 22, -10, 13, -29, 18, +-12, -26, -24, 11, 22, 5, -5, -5, +54, -68, -43, 57, -25, 24, 4, 4, +26, -8, -12, -17, 54, 30, -45, 1, +10, -15, 18, -41, 11, 68, -67, 37, +-16, -24, -16, 38, -22, 6, -29, 30, +66, -27, 5, 7, -16, 13, 2, -12, +-7, -3, -20, 36, 4, -28, 9, 3, +32, 48, 26, 39, 3, 0, 7, -21, +-13, 5, -82, -7, 73, -20, 34, -9, +-5, 1, -1, 10, -5, -10, -1, 9, +1, -9, 10, 0, -14, 11, -1, -2, +-1, 11, 20, 96, -81, -22, -12, -9, +-58, 9, 24, -30, 26, -35, 27, -12, +13, -18, 56, -59, 15, -7, 23, -15, +-1, 6, -25, 14, -22, -20, 47, -11, +16, 2, 38, -23, -19, -30, -9, 40, +-11, 5, 4, -6, 8, 26, -21, -11, +131, 4, 1, 6, -9, 2, -7, -2, +-3, 7, -5, 10, -19, 7, -106, 91, +-3, 9, -4, 21, -8, 26, -80, 8, +1, -2, -10, -17, -17, -27, 32, 71, +6, -29, 11, -23, 54, -38, 29, -22, +39, 87, -31, -12, -20, 3, -2, -2, +2, 20, 0, -1, -35, 27, 9, -6, +-12, 3, -12, -6, 13, 1, 14, -22, +-59, -15, -17, -25, 13, -7, 7, 3, +0, 1, -7, 6, -3, 61, -37, -23, +-23, -29, 38, -31, 27, 1, -8, 2, +-27, 23, -26, 36, -34, 5, 24, -24, +-6, 7, 3, -59, 78, -62, 44, -16, +1, 6, 0, 17, 8, 45, 0, -110, +6, 14, -2, 32, -77, -56, 62, -3, +3, -13, 4, -16, 102, -15, -36, -1, +9, -113, 6, 23, 0, 9, 9, 5, +-8, -1, -14, 5, -12, 121, -53, -27, +-8, -9, 22, -13, 3, 2, -3, 1, +-2, -71, 95, 38, -19, 15, -16, -5, +71, 10, 2, -32, -13, -5, 15, -1, +-2, -14, -85, 30, 29, 6, 3, 2, +0, 0, 0, 0, 0, 0, 0, 0, +2, -65, -56, -9, 18, 18, 23, -14, +-2, 0, 12, -29, 26, -12, 1, 2, +-12, -64, 90, -6, 4, 1, 5, -5, +-110, -3, -31, 22, -29, 9, 0, 8, +-40, -5, 21, -5, -5, 13, 10, -18, +40, 1, 35, -20, 30, -28, 11, -6, +19, 7, 14, 18, -64, 9, -6, 16, +51, 68, 8, 16, 12, -8, 0, -9, +20, -22, 25, 7, -4, -13, 41, -35, +93, -18, -54, 11, -1, 1, -9, 4, +-66, 66, -31, 20, -22, 25, -23, 11, +10, 9, 19, 15, 11, -5, -31, -10, +-23, -28, -6, -6, -3, -4, 5, 3, +-28, 22, -11, -42, 25, -25, -16, 41, +34, 47, -6, 2, 42, -19, -22, 5, +-39, 32, 6, -35, 22, 17, -30, 8, +-26, -11, -11, 3, -12, 33, 33, -37, +21, -1, 6, -4, 3, 0, -5, 5, +12, -12, 57, 27, -61, -3, 20, -17, +2, 0, 4, 0, -2, -33, -58, 81, +-23, 39, -10, -5, 2, 6, -7, 5, +4, -3, -2, -13, -23, -72, 107, 15, +-5, 0, -7, -3, -6, 5, -4, 15, +47, 12, -31, 25, -16, 8, 22, -25, +-62, -56, -18, 14, 28, 12, 2, -11, +74, -66, 41, -20, -7, 16, -20, 16, +-8, 0, -16, 4, -19, 92, 12, -59, +-14, -39, 49, -25, -16, 23, -27, 19, +-3, -33, 19, 85, -29, 6, -7, -10, +16, -7, -12, 1, -6, 2, 4, -2, +64, 10, -25, 41, -2, -31, 15, 0, +110, 50, 69, 35, 28, 19, -10, 2, +-43, -49, -56, -15, -16, 10, 3, 12, +-1, -8, 1, 26, -12, -1, 7, -11, +-27, 41, 25, 1, -11, -18, 22, -7, +-1, -47, -8, 23, -3, -17, -7, 18, +-125, 59, -5, 3, 18, 1, 2, 3, +27, -35, 65, -53, 50, -46, 37, -21, +-28, 7, 14, -37, -5, -5, 12, 5, +-8, 78, -19, 21, -6, -16, 8, -7, +5, 2, 7, 2, 10, -6, 12, -60, +44, 11, -36, -32, 31, 0, 2, -2, +2, 1, -3, 7, -10, 17, -21, 10, +6, -2, 19, -2, 59, -38, -86, 38, +8, -41, -30, -45, -33, 7, 15, 28, +29, -7, 24, -40, 7, 7, 5, -2, +9, 24, -23, -18, 6, -29, 30, 2, +28, 49, -11, -46, 10, 43, -13, -9, +-1, -3, -7, -7, -17, -6, 97, -33, +-21, 3, 5, 1, 12, -43, -8, 28, +7, -43, -7, 17, -20, 19, -1, 2, +-13, 9, 54, 34, 9, -28, -11, -9, +-17, 110, -59, 44, -26, 0, 3, -12, +-47, 73, -34, -43, 38, -33, 16, -5, +-46, -4, -6, -2, -25, 19, -29, 28, +-13, 5, 14, 27, -40, -43, 4, 32, +-13, -2, -35, -4, 112, -42, 9, -12, +37, -28, 17, 14, -19, 35, -39, 23, +3, -14, -1, -57, -5, 94, -9, 3, +-39, 5, 30, -10, -32, 42, -13, -14, +-97, -63, 30, -9, 1, -7, 12, 5, +20, 17, -9, -36, -30, 25, 47, -9, +-15, 12, -22, 98, -8, -50, 15, -27, +21, -16, -11, 2, 12, -10, 10, -3, +33, 36, -96, 0, -17, 31, -9, 9, +3, -20, 13, -11, 8, -4, 10, -10, +9, 1, 112, -70, -27, 5, -21, 2, +-57, -3, -29, 10, 19, -21, 21, -10, +-66, -3, 91, -35, 30, -12, 0, -7, +59, -28, 26, 2, 14, -18, 1, 1, +11, 17, 20, -54, -59, 27, 4, 29, +32, 5, 19, 12, -4, 1, 7, -10, +5, -2, 10, 0, 23, -5, 28, -104, +46, 11, 16, 3, 29, 1, -8, -14, +1, 7, -50, 88, -62, 26, 8, -17, +-14, 50, 0, 32, -12, -3, -27, 18, +-8, -5, 8, 3, -20, -11, 37, -12, +9, 33, 46, -101, -1, -4, 1, 6, +-1, 28, -42, -15, 16, 5, -1, -2, +-55, 85, 38, -9, -4, 11, -2, -9, +-6, 3, -20, -10, -77, 89, 24, -3, +-104, -57, -26, -31, -20, -6, -9, 14, +20, -23, 46, -15, -31, 28, 1, -15, +-2, 6, -2, 31, 45, -76, 23, -25, +}; diff --git a/engine/voice_codecs/speex/source/libspeex/high_lsp_tables.c b/engine/voice_codecs/speex/source/libspeex/high_lsp_tables.c new file mode 100644 index 0000000..90bea7a --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/high_lsp_tables.c @@ -0,0 +1,163 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: high_lsp_tables.c + Codebooks for high-band LSPs in SB-CELP mode + + 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. +*/ + +signed char high_lsp_cdbk[512]={ +39,12,-14,-20,-29,-61,-67,-76, +-32,-71,-67,68,77,46,34,5, +-13,-48,-46,-72,-81,-84,-60,-58, +-40,-28,82,93,68,45,29,3, +-19,-47,-28,-43,-35,-30,-8,-13, +-39,-91,-91,-123,-96,10,10,-6, +-18,-55,-60,-91,-56,-36,-27,-16, +-48,-75,40,28,-10,-28,35,9, +37,19,1,-20,-31,-41,-18,-25, +-35,-68,-80,45,27,-1,47,13, +0,-29,-35,-57,-50,-79,-73,-38, +-19,5,35,14,-10,-23,16,-8, +5,-24,-40,-62,-23,-27,-22,-16, +-18,-46,-72,-77,43,21,33,1, +-80,-70,-70,-64,-56,-52,-39,-33, +-31,-38,-19,-19,-15,32,33,-2, +7,-15,-15,-24,-23,-33,-41,-56, +-24,-57,5,89,64,41,27,5, +-9,-47,-60,-97,-97,-124,-20,-9, +-44,-73,31,29,-4,64,48,7, +-35,-57,0,-3,-26,-47,-3,-6, +-40,-76,-79,-48,12,81,55,10, +9,-24,-43,-73,-57,-69,16,5, +-28,-53,18,29,20,0,-4,-11, +6,-13,23,7,-17,-35,-37,-37, +-30,-68,-63,6,24,-9,-14,3, +21,-13,-27,-57,-49,-80,-24,-41, +-5,-16,-5,1,45,25,12,-7, +3,-15,-6,-16,-15,-8,6,-13, +-42,-81,-80,-87,14,1,-10,-3, +-43,-69,-46,-24,-28,-29,36,6, +-43,-56,-12,12,54,79,43,9, +54,22,2,8,-12,-43,-46,-52, +-38,-69,-89,-5,75,38,33,5, +-13,-53,-62,-87,-89,-113,-99,-55, +-34,-37,62,55,33,16,21,-2, +-17,-46,-29,-38,-38,-48,-39,-42, +-36,-75,-72,-88,-48,-30,21,2, +-15,-57,-64,-98,-84,-76,25,1, +-46,-80,-12,18,-7,3,34,6, +38,31,23,4,-1,20,14,-15, +-43,-78,-91,-24,14,-3,54,16, +0,-27,-28,-44,-56,-83,-92,-89, +-3,34,56,41,36,22,20,-8, +-7,-35,-42,-62,-49,3,12,-10, +-50,-87,-96,-66,92,70,38,9, +-70,-71,-62,-42,-39,-43,-11,-7, +-50,-79,-58,-50,-31,32,31,-6, +-4,-25,7,-17,-38,-70,-58,-27, +-43,-83,-28,59,36,20,31,2, +-27,-71,-80,-109,-98,-75,-33,-32, +-31,-2,33,15,-6,43,33,-5, +0,-22,-10,-27,-34,-49,-11,-20, +-41,-91,-100,-121,-39,57,41,10, +-19,-50,-38,-59,-60,-70,-18,-20, +-8,-31,-8,-15,1,-14,-26,-25, +33,21,32,17,1,-19,-19,-26, +-58,-81,-35,-22,45,30,11,-11, +3,-26,-48,-87,-67,-83,-58,3, +-1,-26,-20,44,10,25,39,5, +-9,-35,-27,-38,7,10,4,-9, +-42,-85,-102,-127,52,44,28,10, +-47,-61,-40,-39,-17,-1,-10,-33, +-42,-74,-48,21,-4,70,52,10}; + + +signed char high_lsp_cdbk2[512]={ +-36,-62,6,-9,-10,-14,-56,23, +1,-26,23,-48,-17,12,8,-7, +23,29,-36,-28,-6,-29,-17,-5, +40,23,10,10,-46,-13,36,6, +4,-30,-29,62,32,-32,-1,22, +-14,1,-4,-22,-45,2,54,4, +-30,-57,-59,-12,27,-3,-31,8, +-9,5,10,-14,32,66,19,9, +2,-25,-37,23,-15,18,-38,-31, +5,-9,-21,15,0,22,62,30, +15,-12,-14,-46,77,21,33,3, +34,29,-19,50,2,11,9,-38, +-12,-37,62,1,-15,54,32,6, +2,-24,20,35,-21,2,19,24, +-13,55,4,9,39,-19,30,-1, +-21,73,54,33,8,18,3,15, +6,-19,-47,6,-3,-48,-50,1, +26,20,8,-23,-50,65,-14,-55, +-17,-31,-37,-28,53,-1,-17,-53, +1,57,11,-8,-25,-30,-37,64, +5,-52,-45,15,23,31,15,14, +-25,24,33,-2,-44,-56,-18,6, +-21,-43,4,-12,17,-37,20,-10, +34,15,2,15,55,21,-11,-31, +-6,46,25,16,-9,-25,-8,-62, +28,17,20,-32,-29,26,30,25, +-19,2,-16,-17,26,-51,2,50, +42,19,-66,23,29,-2,3,19, +-19,-37,32,15,6,30,-34,13, +11,-5,40,31,10,-42,4,-9, +26,-9,-70,17,-2,-23,20,-22, +-55,51,-24,-31,22,-22,15,-13, +3,-10,-28,-16,56,4,-63,11, +-18,-15,-18,-38,-35,16,-7,34, +-1,-21,-49,-47,9,-37,7,8, +69,55,20,6,-33,-45,-10,-9, +6,-9,12,71,15,-3,-42,-7, +-24,32,-35,-2,-42,-17,-5,0, +-2,-33,-54,13,-12,-34,47,23, +19,55,7,-8,74,31,14,16, +-23,-26,19,12,-18,-49,-28,-31, +-20,2,-14,-20,-47,78,40,13, +-23,-11,21,-6,18,1,47,5, +38,35,32,46,22,8,13,16, +-14,18,51,19,40,39,11,-26, +-1,-17,47,2,-53,-15,31,-22, +38,21,-15,-16,5,-33,53,15, +-38,86,11,-3,-24,49,13,-4, +-11,-18,28,20,-12,-27,-26,35, +-25,-35,-3,-20,-61,30,10,-55, +-12,-22,-52,-54,-14,19,-32,-12, +45,15,-8,-48,-9,11,-32,8, +-16,-34,-13,51,18,38,-2,-32, +-17,22,-2,-18,-28,-70,59,27, +-28,-19,-10,-20,-9,-9,-8,-21, +21,-8,35,-2,45,-3,-9,12, +0,30,7,-39,43,27,-38,-91, +30,26,19,-55,-4,63,14,-17, +13,9,13,2,7,4,6,61, +72,-1,-17,29,-1,-22,-17,8, +-28,-37,63,44,41,3,2,14, +9,-6,75,-8,-7,-12,-15,-12, +13,9,-4,30,-22,-65,15,0, +-45,4,-4,1,5,22,11,23}; diff --git a/engine/voice_codecs/speex/source/libspeex/libspeex.opt b/engine/voice_codecs/speex/source/libspeex/libspeex.opt Binary files differnew file mode 100644 index 0000000..3a9f5b9 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/libspeex.opt diff --git a/engine/voice_codecs/speex/source/libspeex/lpc.c b/engine/voice_codecs/speex/source/libspeex/lpc.c new file mode 100644 index 0000000..9aec141 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/lpc.c @@ -0,0 +1,119 @@ +/* + Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Any use of this software is permitted provided that this notice is not + removed and that neither the authors nor the Technische Universitaet Berlin + are deemed to have made any representations as to the suitability of this + software for any purpose nor are held responsible for any defects of + this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + + As a matter of courtesy, the authors request to be informed about uses + this software has found, about bugs in this software, and about any + improvements that may be of general interest. + + Berlin, 28.11.1994 + Jutta Degener + Carsten Bormann + + + Code slightly modified by Jean-Marc Valin + + Speex License: + + 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. +*/ + + + +/* LPC- and Reflection Coefficients + * + * The next two functions calculate linear prediction coefficients + * and/or the related reflection coefficients from the first P_MAX+1 + * values of the autocorrelation function. + */ + +/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959. + */ + +#include "lpc.h" + +float /* returns minimum mean square error */ +wld( + float * lpc, /* [0...p-1] LPC coefficients */ + const float * ac, /* in: [0...p] autocorrelation values */ + float * ref, /* out: [0...p-1] reflection coef's */ + int p + ) +{ + int i, j; float r, error = ac[0]; + + if (ac[0] == 0) { + for (i = 0; i < p; i++) ref[i] = 0; return 0; } + + for (i = 0; i < p; i++) { + + /* Sum up this iteration's reflection coefficient. + */ + r = -ac[i + 1]; + for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j]; + ref[i] = r /= error; + + /* Update LPC coefficients and total error. + */ + lpc[i] = r; + for (j = 0; j < i/2; j++) { + float tmp = lpc[j]; + lpc[j] += r * lpc[i-1-j]; + lpc[i-1-j] += r * tmp; + } + if (i % 2) lpc[j] += lpc[j] * r; + + error *= 1.0 - r * r; + } + return error; +} + + +/* Compute the autocorrelation + * ,--, + * ac(i) = > x(n) * x(n-i) for all n + * `--' + * for lags between 0 and lag-1, and x == 0 outside 0...n-1 + */ +void _spx_autocorr( + const float * x, /* in: [0...n-1] samples x */ + float *ac, /* out: [0...lag-1] ac values */ + int lag, int n) +{ + float d; int i; + while (lag--) { + for (i = lag, d = 0; i < n; i++) d += x[i] * x[i-lag]; + ac[lag] = d; + } +} diff --git a/engine/voice_codecs/speex/source/libspeex/lpc.h b/engine/voice_codecs/speex/source/libspeex/lpc.h new file mode 100644 index 0000000..e3f70b5 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/lpc.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: lpc.h + Functions for LPC (Linear Prediction Coefficients) analysis + + 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 LPC_H +#define LPC_H + +void _spx_autocorr( + const float * x, /* in: [0...n-1] samples x */ + float *ac, /* out: [0...lag-1] ac values */ + int lag, int n); + +float /* returns minimum mean square error */ +wld( + float * lpc, /* [0...p-1] LPC coefficients */ + const float * ac, /* in: [0...p] autocorrelation values */ + float * ref, /* out: [0...p-1] reflection coef's */ + int p + ); + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/lsp.c b/engine/voice_codecs/speex/source/libspeex/lsp.c new file mode 100644 index 0000000..1af762c --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/lsp.c @@ -0,0 +1,328 @@ +/*---------------------------------------------------------------------------*\ +Original copyright + FILE........: AKSLSPD.C + TYPE........: Turbo C + COMPANY.....: Voicetronix + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + +Modified by Jean-Marc Valin + + This file contains functions for converting Linear Prediction + Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the + LSP coefficients are not in radians format but in the x domain of the + unit circle. + + Speex License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <math.h> +#include "lsp.h" +#include "stack_alloc.h" + + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cheb_poly_eva() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function evaluates a series of Chebyshev polynomials + +\*---------------------------------------------------------------------------*/ + + + +static float cheb_poly_eva(float *coef,float x,int m,char *stack) +/* float coef[] coefficients of the polynomial to be evaluated */ +/* float x the point where polynomial is to be evaluated */ +/* int m order of the polynomial */ +{ + int i; + float *T,sum; + int m2=m>>1; + + /* Allocate memory for Chebyshev series formulation */ + T=PUSH(stack, m2+1, float); + + /* Initialise values */ + T[0]=1; + T[1]=x; + + /* Evaluate Chebyshev series formulation using iterative approach */ + /* Evaluate polynomial and return value also free memory space */ + sum = coef[m2] + coef[m2-1]*x; + x *= 2; + for(i=2;i<=m2;i++) + { + T[i] = x*T[i-1] - T[i-2]; + sum += coef[m2-i] * T[i]; + } + + return sum; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lpc_to_lsp() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LPC coefficients to LSP + coefficients. + +\*---------------------------------------------------------------------------*/ + + +int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack) +/* float *a lpc coefficients */ +/* int lpcrdr order of LPC coefficients (10) */ +/* float *freq LSP frequencies in the x domain */ +/* int nb number of sub-intervals (4) */ +/* float delta grid spacing interval (0.02) */ + + +{ + + float psuml,psumr,psumm,temp_xr,xl,xr,xm=0; + float temp_psumr/*,temp_qsumr*/; + int i,j,m,flag,k; + float *Q; /* ptrs for memory allocation */ + float *P; + float *px; /* ptrs of respective P'(z) & Q'(z) */ + float *qx; + float *p; + float *q; + float *pt; /* ptr used for cheb_poly_eval() + whether P' or Q' */ + int roots=0; /* DR 8/2/94: number of roots found */ + flag = 1; /* program is searching for a root when, + 1 else has found one */ + m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */ + + + /* Allocate memory space for polynomials */ + Q = PUSH(stack, (m+1), float); + P = PUSH(stack, (m+1), float); + + /* determine P'(z)'s and Q'(z)'s coefficients where + P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ + + px = P; /* initialise ptrs */ + qx = Q; + p = px; + q = qx; + *px++ = 1.0; + *qx++ = 1.0; + for(i=1;i<=m;i++){ + *px++ = a[i]+a[lpcrdr+1-i]-*p++; + *qx++ = a[i]-a[lpcrdr+1-i]+*q++; + } + px = P; + qx = Q; + for(i=0;i<m;i++){ + *px = 2**px; + *qx = 2**qx; + px++; + qx++; + } + px = P; /* re-initialise ptrs */ + qx = Q; + + /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). + Keep alternating between the two polynomials as each zero is found */ + + xr = 0; /* initialise xr to zero */ + xl = 1.0; /* start at point xl = 1 */ + + + for(j=0;j<lpcrdr;j++){ + if(j%2) /* determines whether P' or Q' is eval. */ + pt = qx; + else + pt = px; + + psuml = cheb_poly_eva(pt,xl,lpcrdr,stack); /* evals poly. at xl */ + flag = 1; + while(flag && (xr >= -1.0)){ + float dd; + /* Modified by JMV to provide smaller steps around x=+-1 */ + dd=(delta*(1-.9*xl*xl)); + if (fabs(psuml)<.2) + dd *= .5; + + xr = xl - dd; /* interval spacing */ + psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */ + temp_psumr = psumr; + temp_xr = xr; + + /* if no sign change increment xr and re-evaluate poly(xr). Repeat til + sign change. + if a sign change has occurred the interval is bisected and then + checked again for a sign change which determines in which + interval the zero lies in. + If there is no sign change between poly(xm) and poly(xl) set interval + between xm and xr else set interval between xl and xr and repeat till + root is located within the specified limits */ + + if((psumr*psuml)<0.0){ + roots++; + + psumm=psuml; + for(k=0;k<=nb;k++){ + xm = (xl+xr)/2; /* bisect the interval */ + psumm=cheb_poly_eva(pt,xm,lpcrdr,stack); + if(psumm*psuml>0.){ + psuml=psumm; + xl=xm; + } + else{ + psumr=psumm; + xr=xm; + } + } + + /* once zero is found, reset initial interval to xr */ + freq[j] = (xm); + xl = xm; + flag = 0; /* reset flag for next search */ + } + else{ + psuml=temp_psumr; + xl=temp_xr; + } + } + } + return(roots); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lsp_to_lpc() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + lsp_to_lpc: This function converts LSP coefficients to LPC + coefficients. + +\*---------------------------------------------------------------------------*/ + + +void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack) +/* float *freq array of LSP frequencies in the x domain */ +/* float *ak array of LPC coefficients */ +/* int lpcrdr order of LPC coefficients */ + + +{ + int i,j; + float xout1,xout2,xin1,xin2; + float *Wp; + float *pw,*n1,*n2,*n3,*n4=NULL; + int m = lpcrdr/2; + + Wp = PUSH(stack, 4*m+2, float); + pw = Wp; + + /* initialise contents of array */ + + for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ + *pw++ = 0.0; + } + + /* Set pointers up */ + + pw = Wp; + xin1 = 1.0; + xin2 = 1.0; + + /* reconstruct P(z) and Q(z) by cascading second order + polynomials in form 1 - 2xz(-1) +z(-2), where x is the + LSP coefficient */ + + for(j=0;j<=lpcrdr;j++){ + int i2=0; + for(i=0;i<m;i++,i2+=2){ + n1 = pw+(i*4); + n2 = n1 + 1; + n3 = n2 + 1; + n4 = n3 + 1; + xout1 = xin1 - 2*(freq[i2]) * *n1 + *n2; + xout2 = xin2 - 2*(freq[i2+1]) * *n3 + *n4; + *n2 = *n1; + *n4 = *n3; + *n1 = xin1; + *n3 = xin2; + xin1 = xout1; + xin2 = xout2; + } + xout1 = xin1 + *(n4+1); + xout2 = xin2 - *(n4+2); + ak[j] = (xout1 + xout2)*0.5; + *(n4+1) = xin1; + *(n4+2) = xin2; + + xin1 = 0.0; + xin2 = 0.0; + } + +} + +/*Added by JMV + Makes sure the LSPs are stable*/ +void lsp_enforce_margin(float *lsp, int len, float margin) +{ + int i; + if (lsp[0]<margin) + lsp[0]=margin; + if (lsp[len-1]>M_PI-margin) + lsp[len-1]=M_PI-margin; + for (i=1;i<len-1;i++) + { + if (lsp[i]<lsp[i-1]+margin) + lsp[i]=lsp[i-1]+margin; + + if (lsp[i]>lsp[i+1]-margin) + lsp[i]= .5* (lsp[i] + lsp[i+1]-margin); + } +} diff --git a/engine/voice_codecs/speex/source/libspeex/lsp.h b/engine/voice_codecs/speex/source/libspeex/lsp.h new file mode 100644 index 0000000..2540495 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/lsp.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------*\ +Original Copyright + FILE........: AK2LSPD.H + TYPE........: Turbo C header file + COMPANY.....: Voicetronix + AUTHOR......: James Whitehall + DATE CREATED: 21/11/95 + +Modified by Jean-Marc Valin + + This file contains functions for converting Linear Prediction + Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the + LSP coefficients are not in radians format but in the x domain of the + unit circle. + +\*---------------------------------------------------------------------------*/ +/* Speex License: + + 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 __AK2LSPD__ +#define __AK2LSPD__ + +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta, char *stack); +void lsp_to_lpc(float *freq, float *ak, int lpcrdr, char *stack); + +/*Added by JMV*/ +void lsp_enforce_margin(float *lsp, int len, float margin); + + +#endif /* __AK2LSPD__ */ diff --git a/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c b/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c new file mode 100644 index 0000000..a68ce99 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c @@ -0,0 +1,360 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: lsp_tables_nb.c + Codebooks for LSPs in narrowband CELP mode + + 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. +*/ + +signed char cdbk_nb[640]={ +30,19,38,34,40,32,46,43,58,43, +5,-18,-25,-40,-33,-55,-52,20,34,28, +-20,-63,-97,-92,61,53,47,49,53,75, +-14,-53,-77,-79,0,-3,-5,19,22,26, +-9,-53,-55,66,90,72,85,68,74,52, +-4,-41,-58,-31,-18,-31,27,32,30,18, +24,3,8,5,-12,-3,26,28,74,63, +-2,-39,-67,-77,-106,-74,59,59,73,65, +44,40,71,72,82,83,98,88,89,60, +-6,-31,-47,-48,-13,-39,-9,7,2,79, +-1,-39,-60,-17,87,81,65,50,45,19, +-21,-67,-91,-87,-41,-50,7,18,39,74, +10,-31,-28,39,24,13,23,5,56,45, +29,10,-5,-13,-11,-35,-18,-8,-10,-8, +-25,-71,-77,-21,2,16,50,63,87,87, +5,-32,-40,-51,-68,0,12,6,54,34, +5,-12,32,52,68,64,69,59,65,45, +14,-16,-31,-40,-65,-67,41,49,47,37, +-11,-52,-75,-84,-4,57,48,42,42,33, +-11,-51,-68,-6,13,0,8,-8,26,32, +-23,-53,0,36,56,76,97,105,111,97, +-1,-28,-39,-40,-43,-54,-44,-40,-18,35, +16,-20,-19,-28,-42,29,47,38,74,45, +3,-29,-48,-62,-80,-104,-33,56,59,59, +10,17,46,72,84,101,117,123,123,106, +-7,-33,-49,-51,-70,-67,-27,-31,70,67, +-16,-62,-85,-20,82,71,86,80,85,74, +-19,-58,-75,-45,-29,-33,-18,-25,45,57, +-12,-42,-5,12,28,36,52,64,81,82, +13,-9,-27,-28,22,3,2,22,26,6, +-6,-44,-51,2,15,10,48,43,49,34, +-19,-62,-84,-89,-102,-24,8,17,61,68, +39,24,23,19,16,-5,12,15,27,15, +-8,-44,-49,-60,-18,-32,-28,52,54,62, +-8,-48,-77,-70,66,101,83,63,61,37, +-12,-50,-75,-64,33,17,13,25,15,77, +1,-42,-29,72,64,46,49,31,61,44, +-8,-47,-54,-46,-30,19,20,-1,-16,0, +16,-12,-18,-9,-26,-27,-10,-22,53,45, +-10,-47,-75,-82,-105,-109,8,25,49,77, +50,65,114,117,124,118,115,96,90,61, +-9,-45,-63,-60,-75,-57,8,11,20,29, +0,-35,-49,-43,40,47,35,40,55,38, +-24,-76,-103,-112,-27,3,23,34,52,75, +8,-29,-43,12,63,38,35,29,24,8, +25,11,1,-15,-18,-43,-7,37,40,21, +-20,-56,-19,-19,-4,-2,11,29,51,63, +-2,-44,-62,-75,-89,30,57,51,74,51, +50,46,68,64,65,52,63,55,65,43, +18,-9,-26,-35,-55,-69,3,6,8,17, +-15,-61,-86,-97,1,86,93,74,78,67, +-1,-38,-66,-48,48,39,29,25,17,-1, +13,13,29,39,50,51,69,82,97,98, +-2,-36,-46,-27,-16,-30,-13,-4,-7,-4, +25,-5,-11,-6,-25,-21,33,12,31,29, +-8,-38,-52,-63,-68,-89,-33,-1,10,74, +-2,-15,59,91,105,105,101,87,84,62, +-7,-33,-50,-35,-54,-47,25,17,82,81, +-13,-56,-83,21,58,31,42,25,72,65, +-24,-66,-91,-56,9,-2,21,10,69,75, +2,-24,11,22,25,28,38,34,48,33, +7,-29,-26,17,15,-1,14,0,-2,0, +-6,-41,-67,6,-2,-9,19,2,85,74, +-22,-67,-84,-71,-50,3,11,-9,2,62}; + +signed char cdbk_nb_low1[320]={ +-34,-52,-15,45,2, +23,21,52,24,-33, +-9,-1,9,-44,-41, +-13,-17,44,22,-17, +-6,-4,-1,22,38, +26,16,2,50,27, +-35,-34,-9,-41,6, +0,-16,-34,51,8, +-14,-31,-49,15,-33, +45,49,33,-11,-37, +-62,-54,45,11,-5, +-72,11,-1,-12,-11, +24,27,-11,-43,46, +43,33,-12,-9,-1, +1,-4,-23,-57,-71, +11,8,16,17,-8, +-20,-31,-41,53,48, +-16,3,65,-24,-8, +-23,-32,-37,-32,-49, +-10,-17,6,38,5, +-9,-17,-46,8,52, +3,6,45,40,39, +-7,-6,-34,-74,31, +8,1,-16,43,68, +-11,-19,-31,4,6, +0,-6,-17,-16,-38, +-16,-30,2,9,-39, +-16,-1,43,-10,48, +3,3,-16,-31,-3, +62,68,43,13,3, +-10,8,20,-56,12, +12,-2,-18,22,-15, +-40,-36,1,7,41, +0,1,46,-6,-62, +-4,-12,-2,-11,-83, +-13,-2,91,33,-10, +0,4,-11,-16,79, +32,37,14,9,51, +-21,-28,-56,-34,0, +21,9,-26,11,28, +-42,-54,-23,-2,-15, +31,30,8,-39,-66, +-39,-36,31,-28,-40, +-46,35,40,22,24, +33,48,23,-34,14, +40,32,17,27,-3, +25,26,-13,-61,-17, +11,4,31,60,-6, +-26,-41,-64,13,16, +-26,54,31,-11,-23, +-9,-11,-34,-71,-21, +-34,-35,55,50,29, +-22,-27,-50,-38,57, +33,42,57,48,26, +11,0,-49,-31,26, +-4,-14,5,78,37, +17,0,-49,-12,-23, +26,14,2,2,-43, +-17,-12,10,-8,-4, +8,18,12,-6,20, +-12,-6,-13,-25,34, +15,40,49,7,8, +13,20,20,-19,-22, +-2,-8,2,51,-51}; + +signed char cdbk_nb_low2[320]={ +-6,53,-21,-24,4, +26,17,-4,-37,25, +17,-36,-13,31,3, +-6,27,15,-10,31, +28,26,-10,-10,-40, +16,-7,15,13,41, +-9,0,-4,50,-6, +-7,14,38,22,0, +-48,2,1,-13,-19, +32,-3,-60,11,-17, +-1,-24,-34,-1,35, +-5,-27,28,44,13, +25,15,42,-11,15, +51,35,-36,20,8, +-4,-12,-29,19,-47, +49,-15,-4,16,-29, +-39,14,-30,4,25, +-9,-5,-51,-14,-3, +-40,-32,38,5,-9, +-8,-4,-1,-22,71, +-3,14,26,-18,-22, +24,-41,-25,-24,6, +23,19,-10,39,-26, +-27,65,45,2,-7, +-26,-8,22,-12,16, +15,16,-35,-5,33, +-21,-8,0,23,33, +34,6,21,36,6, +-7,-22,8,-37,-14, +31,38,11,-4,-3, +-39,-32,-8,32,-23, +-6,-12,16,20,-28, +-4,23,13,-52,-1, +22,6,-33,-40,-6, +4,-62,13,5,-26, +35,39,11,2,57, +-11,9,-20,-28,-33, +52,-5,-6,-2,22, +-14,-16,-48,35,1, +-58,20,13,33,-1, +-74,56,-18,-22,-31, +12,6,-14,4,-2, +-9,-47,10,-3,29, +-17,-5,61,14,47, +-12,2,72,-39,-17, +92,64,-53,-51,-15, +-30,-38,-41,-29,-28, +27,9,36,9,-35, +-42,81,-21,20,25, +-16,-5,-17,-35,21, +15,-28,48,2,-2, +9,-19,29,-40,30, +-18,-18,18,-16,-57, +15,-20,-12,-15,-37, +-15,33,-39,21,-22, +-13,35,11,13,-38, +-63,29,23,-27,32, +18,3,-26,42,33, +-64,-66,-17,16,56, +2,36,3,31,21, +-41,-39,8,-57,14, +37,-2,19,-36,-19, +-23,-29,-16,1,-3, +-8,-10,31,64,-65}; + +signed char cdbk_nb_high1[320]={ +-26,-8,29,21,4, +19,-39,33,-7,-36, +56,54,48,40,29, +-4,-24,-42,-66,-43, +-60,19,-2,37,41, +-10,-37,-60,-64,18, +-22,77,73,40,25, +4,19,-19,-66,-2, +11,5,21,14,26, +-25,-86,-4,18,1, +26,-37,10,37,-1, +24,-12,-59,-11,20, +-6,34,-16,-16,42, +19,-28,-51,53,32, +4,10,62,21,-12, +-34,27,4,-48,-48, +-50,-49,31,-7,-21, +-42,-25,-4,-43,-22, +59,2,27,12,-9, +-6,-16,-8,-32,-58, +-16,-29,-5,41,23, +-30,-33,-46,-13,-10, +-38,52,52,1,-17, +-9,10,26,-25,-6, +33,-20,53,55,25, +-32,-5,-42,23,21, +66,5,-28,20,9, +75,29,-7,-42,-39, +15,3,-23,21,6, +11,1,-29,14,63, +10,54,26,-24,-51, +-49,7,-23,-51,15, +-66,1,60,25,10, +0,-30,-4,-15,17, +19,59,40,4,-5, +33,6,-22,-58,-70, +-5,23,-6,60,44, +-29,-16,-47,-29,52, +-19,50,28,16,35, +31,36,0,-21,6, +21,27,22,42,7, +-66,-40,-8,7,19, +46,0,-4,60,36, +45,-7,-29,-6,-32, +-39,2,6,-9,33, +20,-51,-34,18,-6, +19,6,11,5,-19, +-29,-2,42,-11,-45, +-21,-55,57,37,2, +-14,-67,-16,-27,-38, +69,48,19,2,-17, +20,-20,-16,-34,-17, +-25,-61,10,73,45, +16,-40,-64,-17,-29, +-22,56,17,-39,8, +-11,8,-25,-18,-13, +-19,8,54,57,36, +-17,-26,-4,6,-21, +40,42,-4,20,31, +53,10,-34,-53,31, +-17,35,0,15,-6, +-20,-63,-73,22,25, +29,17,8,-29,-39, +-69,18,15,-15,-5}; + +signed char cdbk_nb_high2[320]={ +11,47,16,-9,-46, +-32,26,-64,34,-5, +38,-7,47,20,2, +-73,-99,-3,-45,20, +70,-52,15,-6,-7, +-82,31,21,47,51, +39,-3,9,0,-41, +-7,-15,-54,2,0, +27,-31,9,-45,-22, +-38,-24,-24,8,-33, +23,5,50,-36,-17, +-18,-51,-2,13,19, +43,12,-15,-12,61, +38,38,7,13,0, +6,-1,3,62,9, +27,22,-33,38,-35, +-9,30,-43,-9,-32, +-1,4,-4,1,-5, +-11,-8,38,31,11, +-10,-42,-21,-37,1, +43,15,-13,-35,-19, +-18,15,23,-26,59, +1,-21,53,8,-41, +-50,-14,-28,4,21, +25,-28,-40,5,-40, +-41,4,51,-33,-8, +-8,1,17,-60,12, +25,-41,17,34,43, +19,45,7,-37,24, +-15,56,-2,35,-10, +48,4,-47,-2,5, +-5,-54,5,-3,-33, +-10,30,-2,-44,-24, +-38,9,-9,42,4, +6,-56,44,-16,9, +-40,-26,18,-20,10, +28,-41,-21,-4,13, +-18,32,-30,-3,37, +15,22,28,50,-40, +3,-29,-64,7,51, +-19,-11,17,-27,-40, +-64,24,-12,-7,-27, +3,37,48,-1,2, +-9,-38,-34,46,1, +27,-6,19,-13,26, +10,34,20,25,40, +50,-6,-7,30,9, +-24,0,-23,71,-61, +22,58,-34,-4,2, +-49,-33,25,30,-8, +-6,-16,77,2,38, +-8,-35,-6,-30,56, +78,31,33,-20,13, +-39,20,22,4,21, +-8,4,-6,10,-83, +-41,9,-25,-43,15, +-7,-12,-34,-39,-37, +-33,19,30,16,-33, +42,-25,25,-68,44, +-15,-11,-4,23,50, +14,4,-39,-43,20, +-30,60,9,-20,7, +16,19,-33,37,29, +16,-35,7,38,-27}; diff --git a/engine/voice_codecs/speex/source/libspeex/ltp.c b/engine/voice_codecs/speex/source/libspeex/ltp.c new file mode 100644 index 0000000..f95d215 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/ltp.c @@ -0,0 +1,548 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: ltp.c + Long-Term Prediction functions + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <math.h> +#include "ltp.h" +#include "stack_alloc.h" +#include "filters.h" +#include "speex_bits.h" + +#ifdef _USE_SSE +#include "ltp_sse.h" +#else +static float inner_prod(float *x, float *y, int len) +{ + int i; + float sum1=0,sum2=0,sum3=0,sum4=0; + for (i=0;i<len;) + { + sum1 += x[i]*y[i]; + sum2 += x[i+1]*y[i+1]; + sum3 += x[i+2]*y[i+2]; + sum4 += x[i+3]*y[i+3]; + i+=4; + } + return sum1+sum2+sum3+sum4; +} +#endif + +/*Original, non-optimized version*/ +/*static float inner_prod(float *x, float *y, int len) +{ + int i; + float sum=0; + for (i=0;i<len;i++) + sum += x[i]*y[i]; + return sum; +} +*/ + + +void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack) +{ + int i,j,k; + /*float corr=0;*/ + /*float energy;*/ + float *best_score; + float e0; + float *corr, *energy, *score; + + best_score = PUSH(stack,N, float); + corr = PUSH(stack,end-start+1, float); + energy = PUSH(stack,end-start+2, float); + score = PUSH(stack,end-start+1, float); + for (i=0;i<N;i++) + { + best_score[i]=-1; + gain[i]=0; + } + energy[0]=inner_prod(sw-start, sw-start, len); + e0=inner_prod(sw, sw, len); + for (i=start;i<=end;i++) + { + /* Update energy for next pitch*/ + energy[i-start+1] = energy[i-start] + sw[-i-1]*sw[-i-1] - sw[-i+len-1]*sw[-i+len-1]; + } + for (i=start;i<=end;i++) + { + corr[i-start]=0; + score[i-start]=0; + } + + for (i=start;i<=end;i++) + { + /* Compute correlation*/ + corr[i-start]=inner_prod(sw, sw-i, len); + score[i-start]=corr[i-start]*corr[i-start]/(energy[i-start]+1); + } + for (i=start;i<=end;i++) + { + if (score[i-start]>best_score[N-1]) + { + float g1, g; + g1 = corr[i-start]/(energy[i-start]+10); + g = sqrt(g1*corr[i-start]/(e0+10)); + if (g>g1) + g=g1; + if (g<0) + g=0; + for (j=0;j<N;j++) + { + if (score[i-start] > best_score[j]) + { + for (k=N-1;k>j;k--) + { + best_score[k]=best_score[k-1]; + pitch[k]=pitch[k-1]; + gain[k] = gain[k-1]; + } + best_score[j]=score[i-start]; + pitch[j]=i; + gain[j]=g; + break; + } + } + } + } + +} + + + + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +float pitch_gain_search_3tap( +float target[], /* Target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Excitation */ +void *par, +int pitch, /* Pitch value */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int *cdbk_index +) +{ + int i,j; + float *tmp, *tmp2; + float *x[3]; + float *e[3]; + float corr[3]; + float A[3][3]; + float gain[3]; + int gain_cdbk_size; + signed char *gain_cdbk; + float err1,err2; + + ltp_params *params; + params = (ltp_params*) par; + gain_cdbk=params->gain_cdbk; + gain_cdbk_size=1<<params->gain_bits; + tmp = PUSH(stack, 3*nsf, float); + tmp2 = PUSH(stack, 3*nsf, float); + + x[0]=tmp; + x[1]=tmp+nsf; + x[2]=tmp+2*nsf; + + e[0]=tmp2; + e[1]=tmp2+nsf; + e[2]=tmp2+2*nsf; + + for (i=2;i>=0;i--) + { + int pp=pitch+1-i; + for (j=0;j<nsf;j++) + { + if (j-pp<0) + e[i][j]=exc2[j-pp]; + else if (j-pp-pitch<0) + e[i][j]=exc2[j-pp-pitch]; + else + e[i][j]=0; + } + + if (i==2) + syn_percep_zero(e[i], ak, awk1, awk2, x[i], nsf, p, stack); + else { + for (j=0;j<nsf-1;j++) + x[i][j+1]=x[i+1][j]; + x[i][0]=0; + for (j=0;j<nsf;j++) + x[i][j]+=e[i][0]*r[j]; + } + } + + for (i=0;i<3;i++) + corr[i]=inner_prod(x[i],target,nsf); + + for (i=0;i<3;i++) + for (j=0;j<=i;j++) + A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); + + { + float C[9]; + signed char *ptr=gain_cdbk; + int best_cdbk=0; + float best_sum=0; + C[0]=corr[2]; + C[1]=corr[1]; + C[2]=corr[0]; + C[3]=A[1][2]; + C[4]=A[0][1]; + C[5]=A[0][2]; + C[6]=A[2][2]; + C[7]=A[1][1]; + C[8]=A[0][0]; + + for (i=0;i<gain_cdbk_size;i++) + { + float sum=0; + float g0,g1,g2; + ptr = gain_cdbk+3*i; + g0=0.015625*ptr[0]+.5; + g1=0.015625*ptr[1]+.5; + g2=0.015625*ptr[2]+.5; + + sum += C[0]*g0; + sum += C[1]*g1; + sum += C[2]*g2; + sum -= C[3]*g0*g1; + sum -= C[4]*g2*g1; + sum -= C[5]*g2*g0; + sum -= .5*C[6]*g0*g0; + sum -= .5*C[7]*g1*g1; + sum -= .5*C[8]*g2*g2; + + /* If 1, force "safe" pitch values to handle packet loss better */ + if (0) { + float tot = fabs(ptr[1]); + if (ptr[0]>0) + tot+=ptr[0]; + if (ptr[2]>0) + tot+=ptr[2]; + if (tot>1) + continue; + } + + if (sum>best_sum || i==0) + { + best_sum=sum; + best_cdbk=i; + } + } + gain[0] = 0.015625*gain_cdbk[best_cdbk*3] + .5; + gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5; + gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5; + + *cdbk_index=best_cdbk; + } + + for (i=0;i<nsf;i++) + exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i]; + + err1=0; + err2=0; + for (i=0;i<nsf;i++) + err1+=target[i]*target[i]; + for (i=0;i<nsf;i++) + err2+=(target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]) + * (target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]); + + return err2; +} + + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +int pitch_search_3tap( +float target[], /* Target vector */ +float *sw, +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Excitation */ +void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int complexity +) +{ + int i,j; + int cdbk_index, pitch=0, best_gain_index=0; + float *best_exc; + int best_pitch=0; + float err, best_err=-1; + int N; + ltp_params *params; + int *nbest; + float *gains; + + N=complexity; + if (N>10) + N=10; + + nbest=PUSH(stack, N, int); + gains = PUSH(stack, N, float); + params = (ltp_params*) par; + + if (N==0 || end<start) + { + speex_bits_pack(bits, 0, params->pitch_bits); + speex_bits_pack(bits, 0, params->gain_bits); + for (i=0;i<nsf;i++) + exc[i]=0; + return start; + } + + best_exc=PUSH(stack,nsf, float); + + if (N>end-start+1) + N=end-start+1; + open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack); + for (i=0;i<N;i++) + { + pitch=nbest[i]; + for (j=0;j<nsf;j++) + exc[j]=0; + err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf, + bits, stack, exc2, r, &cdbk_index); + if (err<best_err || best_err<0) + { + for (j=0;j<nsf;j++) + best_exc[j]=exc[j]; + best_err=err; + best_pitch=pitch; + best_gain_index=cdbk_index; + } + } + + /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ + speex_bits_pack(bits, best_pitch-start, params->pitch_bits); + speex_bits_pack(bits, best_gain_index, params->gain_bits); + /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ + for (i=0;i<nsf;i++) + exc[i]=best_exc[i]; + + return pitch; +} + +void pitch_unquant_3tap( +float exc[], /* Excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +float *gain_val, +SpeexBits *bits, +char *stack, +int count_lost, +int subframe_offset, +float last_pitch_gain) +{ + int i; + int pitch; + int gain_index; + float gain[3]; + signed char *gain_cdbk; + ltp_params *params; + params = (ltp_params*) par; + gain_cdbk=params->gain_cdbk; + + pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); + pitch += start; + gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); + /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ + gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5; + gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5; + gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5; + + if (count_lost && pitch > subframe_offset) + { + float gain_sum; + + if (1) { + float tmp = count_lost < 4 ? last_pitch_gain : 0.4 * last_pitch_gain; + if (tmp>.95) + tmp=.95; + gain_sum = fabs(gain[1]); + if (gain[0]>0) + gain_sum += gain[0]; + else + gain_sum -= .5*gain[0]; + if (gain[2]>0) + gain_sum += gain[2]; + else + gain_sum -= .5*gain[2]; + if (gain_sum > tmp) { + float fact = tmp/gain_sum; + for (i=0;i<3;i++) + gain[i]*=fact; + + } + + } + + if (0) { + gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]); + if (gain_sum>.95) { + float fact = .95/gain_sum; + for (i=0;i<3;i++) + gain[i]*=fact; + } + } + } + + *pitch_val = pitch; + /**gain_val = gain[0]+gain[1]+gain[2];*/ + gain_val[0]=gain[0]; + gain_val[1]=gain[1]; + gain_val[2]=gain[2]; + + { + float *e[3]; + float *tmp2; + tmp2=PUSH(stack, 3*nsf, float); + e[0]=tmp2; + e[1]=tmp2+nsf; + e[2]=tmp2+2*nsf; + + for (i=0;i<3;i++) + { + int j; + int pp=pitch+1-i; +#if 0 + for (j=0;j<nsf;j++) + { + if (j-pp<0) + e[i][j]=exc[j-pp]; + else if (j-pp-pitch<0) + e[i][j]=exc[j-pp-pitch]; + else + e[i][j]=0; + } +#else + { + int tmp1, tmp3; + tmp1=nsf; + if (tmp1>pp) + tmp1=pp; + for (j=0;j<tmp1;j++) + e[i][j]=exc[j-pp]; + tmp3=nsf; + if (tmp3>pp+pitch) + tmp3=pp+pitch; + for (j=tmp1;j<tmp3;j++) + e[i][j]=exc[j-pp-pitch]; + for (j=tmp3;j<nsf;j++) + e[i][j]=0; + } +#endif + } + for (i=0;i<nsf;i++) + exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i]; + } +} + + +/** Forced pitch delay and gain */ +int forced_pitch_quant( +float target[], /* Target vector */ +float *sw, +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Excitation */ +void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int complexity +) +{ + int i; + if (pitch_coef>.99) + pitch_coef=.99; + for (i=0;i<nsf;i++) + { + exc[i]=exc[i-start]*pitch_coef; + } + return start; +} + +/** Unquantize forced pitch delay and gain */ +void forced_pitch_unquant( +float exc[], /* Excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +float *gain_val, +SpeexBits *bits, +char *stack, +int count_lost, +int subframe_offset, +float last_pitch_gain) +{ + int i; + /*pitch_coef=.9;*/ + if (pitch_coef>.99) + pitch_coef=.99; + for (i=0;i<nsf;i++) + { + exc[i]=exc[i-start]*pitch_coef; + } + *pitch_val = start; + gain_val[0]=gain_val[2]=0; + gain_val[1] = pitch_coef; +} diff --git a/engine/voice_codecs/speex/source/libspeex/ltp.h b/engine/voice_codecs/speex/source/libspeex/ltp.h new file mode 100644 index 0000000..7af6790 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/ltp.h @@ -0,0 +1,138 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: ltp.h + Long-Term Prediction functions + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "speex_bits.h" + + +typedef struct ltp_params { + signed char *gain_cdbk; + int gain_bits; + int pitch_bits; +} ltp_params; + + +void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack); + + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +int pitch_search_3tap( +float target[], /* Target vector */ +float *sw, +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Overlapping codebook */ +void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int complexity +); + +/*Unquantize adaptive codebook and update pitch contribution*/ +void pitch_unquant_3tap( +float exc[], /* Excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +float *gain_val, +SpeexBits *bits, +char *stack, +int lost, +int subframe_offset, +float last_pitch_gain +); + +float pitch_gain_search_3tap( +float target[], /* Target vector */ +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Excitation */ +void *par, +int pitch, /* Pitch value */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int *cdbk_index +); + + +/** Forced pitch delay and gain */ +int forced_pitch_quant( +float target[], /* Target vector */ +float *sw, +float ak[], /* LPCs for this subframe */ +float awk1[], /* Weighted LPCs #1 for this subframe */ +float awk2[], /* Weighted LPCs #2 for this subframe */ +float exc[], /* Excitation */ +void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +float *exc2, +float *r, +int complexity +); + +/** Unquantize forced pitch delay and gain */ +void forced_pitch_unquant( +float exc[], /* Excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +float pitch_coef, /* Voicing (pitch) coefficient */ +void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +float *gain_val, +SpeexBits *bits, +char *stack, +int lost, +int subframe_offset, +float last_pitch_gain +); diff --git a/engine/voice_codecs/speex/source/libspeex/ltp_sse.h b/engine/voice_codecs/speex/source/libspeex/ltp_sse.h new file mode 100644 index 0000000..c8d484a --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/ltp_sse.h @@ -0,0 +1,95 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: ltp.c + Lont-Term Prediction functions + + 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. +*/ + + +static float inner_prod(float *a, float *b, int len) +{ + float sum; + __asm__ __volatile__ ( + "\tpush %%eax\n" + "\tpush %%edi\n" + "\tpush %%ecx\n" + "\txorps %%xmm3, %%xmm3\n" + "\txorps %%xmm4, %%xmm4\n" + + "\tsub $20, %%ecx\n" + +".mul20_loop%=:\n" + + "\tmovups (%%eax), %%xmm0\n" + "\tmovups (%%edi), %%xmm1\n" + "\tmulps %%xmm0, %%xmm1\n" + + "\tmovups 16(%%eax), %%xmm5\n" + "\tmovups 16(%%edi), %%xmm6\n" + "\tmulps %%xmm5, %%xmm6\n" + "\taddps %%xmm1, %%xmm3\n" + + "\tmovups 32(%%eax), %%xmm0\n" + "\tmovups 32(%%edi), %%xmm1\n" + "\tmulps %%xmm0, %%xmm1\n" + "\taddps %%xmm6, %%xmm4\n" + + "\tmovups 48(%%eax), %%xmm5\n" + "\tmovups 48(%%edi), %%xmm6\n" + "\tmulps %%xmm5, %%xmm6\n" + "\taddps %%xmm1, %%xmm3\n" + + "\tmovups 64(%%eax), %%xmm0\n" + "\tmovups 64(%%edi), %%xmm1\n" + "\tmulps %%xmm0, %%xmm1\n" + "\taddps %%xmm6, %%xmm4\n" + "\taddps %%xmm1, %%xmm3\n" + + + "\tadd $80, %%eax\n" + "\tadd $80, %%edi\n" + + "\tsub $20, %%ecx\n" + + "\tjae .mul20_loop%=\n" + + "\taddps %%xmm4, %%xmm3\n" + + "\tmovhlps %%xmm3, %%xmm4\n" + "\taddps %%xmm4, %%xmm3\n" + "\tmovaps %%xmm3, %%xmm4\n" + "\tshufps $0x55, %%xmm4, %%xmm4\n" + "\taddss %%xmm4, %%xmm3\n" + "\tmovss %%xmm3, (%%edx)\n" + + "\tpop %%ecx\n" + "\tpop %%edi\n" + "\tpop %%eax\n" + : : "a" (a), "D" (b), "c" (len), "d" (&sum) : "memory"); + return sum; +} diff --git a/engine/voice_codecs/speex/source/libspeex/math_approx.c b/engine/voice_codecs/speex/source/libspeex/math_approx.c new file mode 100644 index 0000000..748d619 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/math_approx.c @@ -0,0 +1,105 @@ +/* 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. +*/ + +#include <math.h> +#include "math_approx.h" + +#ifdef SLOW_TRIG + +float cos_sin[102] = { + 1.00000000, 0.00000000, + 0.99804751, 0.06245932, + 0.99219767, 0.12467473, + 0.98247331, 0.18640330, + 0.96891242, 0.24740396, + 0.95156795, 0.30743851, + 0.93050762, 0.36627253, + 0.90581368, 0.42367626, + 0.87758256, 0.47942554, + 0.84592450, 0.53330267, + 0.81096312, 0.58509727, + 0.77283495, 0.63460708, + 0.73168887, 0.68163876, + 0.68768556, 0.72600866, + 0.64099686, 0.76754350, + 0.59180508, 0.80608111, + 0.54030231, 0.84147098, + 0.48668967, 0.87357494, + 0.43117652, 0.90226759, + 0.37397963, 0.92743692, + 0.31532236, 0.94898462, + 0.25543377, 0.96682656, + 0.19454771, 0.98089306, + 0.13290194, 0.99112919, + 0.07073720, 0.99749499, + 0.00829623, 0.99996559, + -0.05417714, 0.99853134, + -0.11643894, 0.99319785, + -0.17824606, 0.98398595, + -0.23935712, 0.97093160, + -0.29953351, 0.95408578, + -0.35854022, 0.93351428, + -0.41614684, 0.90929743, + -0.47212841, 0.88152979, + -0.52626633, 0.85031979, + -0.57834920, 0.81578931, + -0.62817362, 0.77807320, + -0.67554504, 0.73731872, + -0.72027847, 0.69368503, + -0.76219923, 0.64734252, + -0.80114362, 0.59847214, + -0.83695955, 0.54726475, + -0.86950718, 0.49392030, + -0.89865940, 0.43864710, + -0.92430238, 0.38166099, + -0.94633597, 0.32318451, + -0.96467415, 0.26344599, + -0.97924529, 0.20267873, + -0.98999250, 0.14112001, + -0.99687381, 0.07901022, + -0.99986235, 0.01659189 +}; + +float speex_cos(float x) +{ + int ind; + float delta; + ind = (int)floor(x*16+.5); + delta = x-0.062500*ind; + ind <<= 1; + return cos_sin[ind] - delta*(cos_sin[ind+1] + + .5*delta*(cos_sin[ind] - + .3333333*delta*cos_sin[ind+1])); +} + +#endif + diff --git a/engine/voice_codecs/speex/source/libspeex/math_approx.h b/engine/voice_codecs/speex/source/libspeex/math_approx.h new file mode 100644 index 0000000..c917ffd --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/math_approx.h @@ -0,0 +1,39 @@ +/* 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. +*/ + +#ifndef MATH_APPROX_H +#define MATH_APPROX_H + +float speex_cos(float x); + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/misc.c b/engine/voice_codecs/speex/source/libspeex/misc.c new file mode 100644 index 0000000..f84e0f6 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/misc.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: mics.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. +*/ + +#include "misc.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#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 + +unsigned int be_int(unsigned int i) +{ + unsigned int ret=i; +#ifndef WORDS_BIGENDIAN + ret = i>>24; + ret += (i>>8)&0x0000ff00; + ret += (i<<8)&0x00ff0000; + ret += (i<<24); +#endif + return ret; +} + +unsigned int le_int(unsigned int i) +{ + unsigned int ret=i; +#ifdef WORDS_BIGENDIAN + ret = i>>24; + ret += (i>>8)&0x0000ff00; + ret += (i<<8)&0x00ff0000; + ret += (i<<24); +#endif + return ret; +} + +unsigned short be_short(unsigned short s) +{ + unsigned short ret=s; +#ifndef WORDS_BIGENDIAN + ret = s>>8; + ret += s<<8; +#endif + return ret; +} + +unsigned short le_short(unsigned short s) +{ + unsigned short ret=s; +#ifdef WORDS_BIGENDIAN + ret = s>>8; + ret += s<<8; +#endif + return ret; +} + +void *speex_alloc (int size) +{ + return calloc(size,1); +} + +void *speex_realloc (void *ptr, int size) +{ + return realloc(ptr, size); +} + +void speex_free (void *ptr) +{ + free(ptr); +} + +void *speex_move (void *dest, void *src, int n) +{ + return memmove(dest,src,n); +} + +void speex_error(char *str) +{ + fprintf (stderr, "Fatal error: %s\n", str); + exit(1); +} + +void speex_warning(char *str) +{ + fprintf (stderr, "warning: %s\n", str); +} + +void speex_warning_int(char *str, int val) +{ + fprintf (stderr, "warning: %s %d\n", str, val); +} + +void speex_rand_vec(float std, float *data, int len) +{ + int i; + for (i=0;i<len;i++) + data[i]+=3*std*((((float)rand())/RAND_MAX)-.5); +} + +float speex_rand(float std) +{ + return 3*std*((((float)rand())/RAND_MAX)-.5); +} + +void _speex_putc(int ch, void *file) +{ + FILE *f = (FILE *)file; + fputc(ch, f); +} diff --git a/engine/voice_codecs/speex/source/libspeex/misc.h b/engine/voice_codecs/speex/source/libspeex/misc.h new file mode 100644 index 0000000..d128da8 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/misc.h @@ -0,0 +1,83 @@ +/* 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 VERSION +#define VERSION "speex-1.0" +#endif + +/*Disable some warnings on VC++*/ +#ifdef _MSC_VER +#pragma warning(disable : 4244) +#pragma warning(disable : 4305) +#endif + +#ifndef RELEASE +void print_vec(float *vec, int len, char *name); +#endif + +unsigned int be_int(unsigned int i); +unsigned int le_int(unsigned int i); + + +unsigned short be_short(unsigned short s); +unsigned short le_short(unsigned short s); + +/** 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); + +/** 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); + +/** Speex wrapper for mem_move */ +void *speex_move (void *dest, void *src, int n); + +void speex_error(char *str); + +void speex_warning(char *str); + +void speex_warning_int(char *str, int val); + +void speex_rand_vec(float std, float *data, int len); + +float speex_rand(float std); + +void _speex_putc(int ch, void *file); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/modes.c b/engine/voice_codecs/speex/source/libspeex/modes.c new file mode 100644 index 0000000..b525872 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/modes.c @@ -0,0 +1,650 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: modes.c + + Describes the different 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. + +*/ + +#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 "misc.h" + +#ifndef NULL +#define NULL 0 +#endif + +SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; + +/* Extern declarations for all codebooks we use here */ +extern signed char gain_cdbk_nb[]; +extern signed char gain_cdbk_lbr[]; +extern signed char hexc_table[]; +extern signed char exc_5_256_table[]; +extern signed char exc_5_64_table[]; +extern signed char exc_8_128_table[]; +extern signed char exc_10_32_table[]; +extern signed char exc_10_16_table[]; +extern signed char exc_20_32_table[]; +extern signed char hexc_10_32_table[]; + +static int nb_mode_query(void *mode, int request, void *ptr); +static int wb_mode_query(void *mode, int request, void *ptr); + +/* Parameters for Long-Term Prediction (LTP)*/ +static ltp_params ltp_params_nb = { + gain_cdbk_nb, + 7, + 7 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static ltp_params ltp_params_vlbr = { + gain_cdbk_lbr, + 5, + 0 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static ltp_params ltp_params_lbr = { + gain_cdbk_lbr, + 5, + 7 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static ltp_params ltp_params_med = { + gain_cdbk_lbr, + 5, + 7 +}; + +/* Split-VQ innovation parameters for very low bit-rate narrowband */ +static split_cb_params split_cb_nb_vlbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + exc_10_16_table, /*shape_cb*/ + 4, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters for very low bit-rate narrowband */ +static split_cb_params split_cb_nb_ulbr = { + 20, /*subvect_size*/ + 2, /*nb_subvect*/ + exc_20_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters for low bit-rate narrowband */ +static split_cb_params split_cb_nb_lbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + exc_10_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + + +/* Split-VQ innovation parameters narrowband */ +static split_cb_params split_cb_nb = { + 5, /*subvect_size*/ + 8, /*nb_subvect*/ + exc_5_64_table, /*shape_cb*/ + 6, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters narrowband */ +static split_cb_params split_cb_nb_med = { + 8, /*subvect_size*/ + 5, /*nb_subvect*/ + exc_8_128_table, /*shape_cb*/ + 7, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation for low-band wideband */ +static split_cb_params split_cb_sb = { + 5, /*subvect_size*/ + 8, /*nb_subvect*/ + exc_5_256_table, /*shape_cb*/ + 8, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation for high-band wideband */ +static 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 split_cb_params split_cb_high_lbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + hexc_10_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + +/* 2150 bps "vocoder-like" mode for comfort noise */ +static SpeexSubmode nb_submode1 = { + 0, + 1, + 0, + 0, + /* LSP quantization */ + lsp_quant_lbr, + lsp_unquant_lbr, + /* No pitch quantization */ + forced_pitch_quant, + forced_pitch_unquant, + NULL, + /* No innovation quantization (noise only) */ + noise_codebook_quant, + noise_codebook_unquant, + NULL, + .7, .7, -1, + 43 +}; + +/* 3.95 kbps very low bit-rate mode */ +static SpeexSubmode nb_submode8 = { + 0, + 1, + 0, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*No pitch quantization*/ + forced_pitch_quant, + forced_pitch_unquant, + NULL, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_ulbr, + + 0.7, 0.5, .65, + 79 +}; + +/* 5.95 kbps very low bit-rate mode */ +static SpeexSubmode nb_submode2 = { + 0, + 0, + 0, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*No pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_vlbr, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_vlbr, + + 0.7, 0.5, .55, + 119 +}; + +/* 8 kbps low bit-rate mode */ +static SpeexSubmode nb_submode3 = { + -1, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_lbr, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_lbr, + + 0.7, 0.55, .45, + 160 +}; + +/* 11 kbps medium bit-rate mode */ +static SpeexSubmode nb_submode4 = { + -1, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_med, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_med, + + 0.7, 0.63, .35, + 220 +}; + +/* 15 kbps high bit-rate mode */ +static SpeexSubmode nb_submode5 = { + -1, + 0, + 3, + 0, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb, + + 0.7, 0.65, .25, + 300 +}; + +/* 18.2 high bit-rate mode */ +static SpeexSubmode nb_submode6 = { + -1, + 0, + 3, + 0, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_sb, + + 0.68, 0.65, .1, + 364 +}; + +/* 24.6 kbps high bit-rate mode */ +static SpeexSubmode nb_submode7 = { + -1, + 0, + 3, + 1, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + <p_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb, + + 0.65, 0.65, -1, + 492 +}; + + +/* Default mode for narrowband */ +static SpeexNBMode nb_mode = { + 160, /*frameSize*/ + 40, /*subframeSize*/ + 10, /*lpcSize*/ + 640, /*bufSize*/ + 17, /*pitchStart*/ + 144, /*pitchEnd*/ + 0.9, /*gamma1*/ + 0.6, /*gamma2*/ + .01, /*lag_factor*/ + 1.0001, /*lpc_floor*/ + 0.0, /*preemph*/ + {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, + {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7} +}; + + +/* Default mode for narrowband */ +SpeexMode speex_nb_mode = { + &nb_mode, + nb_mode_query, + "narrowband", + 0, + 4, + &nb_encoder_init, + &nb_encoder_destroy, + &nb_encode, + &nb_decoder_init, + &nb_decoder_destroy, + &nb_decode, + &nb_encoder_ctl, + &nb_decoder_ctl, +}; + + +/* Wideband part */ + +static 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, + + .75, .75, -1, + 36 +}; + + +static 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, + &split_cb_high_lbr, + + .85, .6, -1, + 112 +}; + + +static 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, + &split_cb_high, + + .75, .7, -1, + 192 +}; + +static 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, + &split_cb_high, + + .75, .75, -1, + 352 +}; + + +/* Split-band wideband CELP mode*/ +static SpeexSBMode sb_wb_mode = { + &speex_nb_mode, + 160, /*frameSize*/ + 40, /*subframeSize*/ + 8, /*lpcSize*/ + 640, /*bufSize*/ + .9, /*gamma1*/ + 0.6, /*gamma2*/ + .002, /*lag_factor*/ + 1.0001, /*lpc_floor*/ + 0.0, /*preemph*/ + 0.9, + {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, + 3, + {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7}, + {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4}, + vbr_hb_thresh, + 5 +}; + + +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 SpeexSBMode sb_uwb_mode = { + &speex_wb_mode, + 320, /*frameSize*/ + 80, /*subframeSize*/ + 8, /*lpcSize*/ + 1280, /*bufSize*/ + .9, /*gamma1*/ + 0.6, /*gamma2*/ + .002, /*lag_factor*/ + 1.0001, /*lpc_floor*/ + 0.0, /*preemph*/ + 0.7, + {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, + 1, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + vbr_uhb_thresh, + 2 +}; + + +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, +}; + + + + +void *speex_encoder_init(SpeexMode *mode) +{ + return mode->enc_init(mode); +} + +void *speex_decoder_init(SpeexMode *mode) +{ + return mode->dec_init(mode); +} + +void speex_encoder_destroy(void *state) +{ + (*((SpeexMode**)state))->enc_destroy(state); +} + +int speex_encode(void *state, float *in, SpeexBits *bits) +{ + return (*((SpeexMode**)state))->enc(state, in, bits); +} + +void speex_decoder_destroy(void *state) +{ + (*((SpeexMode**)state))->dec_destroy(state); +} + +int speex_decode(void *state, SpeexBits *bits, float *out) +{ + return (*((SpeexMode**)state))->dec(state, bits, out); +} + + +int speex_encoder_ctl(void *state, int request, void *ptr) +{ + return (*((SpeexMode**)state))->enc_ctl(state, request, ptr); +} + +int speex_decoder_ctl(void *state, int request, void *ptr) +{ + return (*((SpeexMode**)state))->dec_ctl(state, request, ptr); +} + + + +static int nb_mode_query(void *mode, int request, void *ptr) +{ + SpeexNBMode *m = (SpeexNBMode*)mode; + + switch (request) + { + case SPEEX_MODE_FRAME_SIZE: + *((int*)ptr)=m->frameSize; + break; + case SPEEX_SUBMODE_BITS_PER_FRAME: + if (*((int*)ptr)==0) + *((int*)ptr) = NB_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 nb_mode_query request: ", request); + return -1; + } + return 0; +} + +static int wb_mode_query(void *mode, int request, void *ptr) +{ + SpeexSBMode *m = (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_mode_query(SpeexMode *mode, int request, void *ptr) +{ + return mode->query(mode->mode, request, ptr); +} diff --git a/engine/voice_codecs/speex/source/libspeex/modes.h b/engine/voice_codecs/speex/source/libspeex/modes.h new file mode 100644 index 0000000..0a94357 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/modes.h @@ -0,0 +1,146 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file modes.h + @brief Describes the different 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. + +*/ + +#ifndef MODES_H +#define MODES_H + +#include "speex.h" +#include "speex_bits.h" + + +#define NB_SUBMODES 16 +#define NB_SUBMODE_BITS 4 + +#define SB_SUBMODES 8 +#define SB_SUBMODE_BITS 3 + + +/** Quantizes LSPs */ +typedef void (*lsp_quant_func)(float *, float *, int, SpeexBits *); + +/** Decodes quantized LSPs */ +typedef void (*lsp_unquant_func)(float *, int, SpeexBits *); + + +/** Long-term predictor quantization */ +typedef int (*ltp_quant_func)(float *, float *, float *, float *, + float *, float *, void *, int, int, float, + int, int, SpeexBits*, char *, float *, float *, int); + +/** Long-term un-quantize */ +typedef void (*ltp_unquant_func)(float *, int, int, float, void *, int, int *, + float *, SpeexBits*, char*, int, int, float); + + +/** Innovation quantization function */ +typedef void (*innovation_quant_func)(float *, float *, float *, float *, void *, int, int, + float *, float *, SpeexBits *, char *, int); + +/** Innovation unquantization function */ +typedef void (*innovation_unquant_func)(float *, void *, int, SpeexBits*, char *); + +/** Description of a Speex sub-mode (wither narrowband or wideband */ +typedef struct SpeexSubmode { + int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/ + int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */ + int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */ + int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/ + /*LSP functions*/ + lsp_quant_func lsp_quant; /**< LSP quantization function */ + lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ + + /*Lont-term predictor functions*/ + ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ + ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ + void *ltp_params; /**< Pitch parameters (options) */ + + /*Quantization of innovation*/ + innovation_quant_func innovation_quant; /**< Innovation quantization */ + innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */ + void *innovation_params; /**< Innovation quantization parameters*/ + + /*Synthesis filter enhancement*/ + float lpc_enh_k1; /**< Enhancer constant */ + float lpc_enh_k2; /**< Enhancer constant */ + float comb_gain; /**< Gain of enhancer comb filter */ + + int bits_per_frame; /**< Number of bits per frame after encoding*/ +} SpeexSubmode; + +/** Struct defining the encoding/decoding mode*/ +typedef struct SpeexNBMode { + 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; /**< Size of signal buffer to use in encoder */ + int pitchStart; /**< Smallest pitch value allowed */ + int pitchEnd; /**< Largest pitch value allowed */ + + float gamma1; /**< Perceptual filter parameter #1 */ + float gamma2; /**< Perceptual filter parameter #2 */ + float lag_factor; /**< Lag-windowing parameter */ + float lpc_floor; /**< Noise floor for LPC analysis */ + float preemph; /**< Pre-emphasis */ + + 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 */ +} SpeexNBMode; + + +/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */ +typedef struct SpeexSBMode { + SpeexMode *nb_mode; /**< Embedded narrowband mode */ + 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 */ + float gamma1; /**< Perceptual filter parameter #1 */ + float gamma2; /**< Perceptual filter parameter #1 */ + float lag_factor; /**< Lag-windowing parameter */ + float lpc_floor; /**< Noise floor for LPC analysis */ + float preemph; /**< Pre-emphasis */ + float folding_gain; + + SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */ + int defaultSubmode; /**< Default sub-mode to use when encoding */ + int low_quality_map[11]; /**< Mode corresponding to each quality setting */ + int quality_map[11]; /**< Mode corresponding to each quality setting */ + float (*vbr_thresh)[11]; + int nb_modes; +} SpeexSBMode; + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/nb_celp.c b/engine/voice_codecs/speex/source/libspeex/nb_celp.c new file mode 100644 index 0000000..837d2f5 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/nb_celp.c @@ -0,0 +1,1715 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: nb_celp.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. +*/ + +#include <math.h> +#include "nb_celp.h" +#include "lpc.h" +#include "lsp.h" +#include "ltp.h" +#include "quant_lsp.h" +#include "cb_search.h" +#include "filters.h" +#include "stack_alloc.h" +#include "vq.h" +#include "speex_bits.h" +#include "vbr.h" +#include "misc.h" +#include "speex_callbacks.h" + +#ifdef SLOW_TRIG +#include "math_approx.h" +#define cos speex_cos +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define SUBMODE(x) st->submodes[st->submodeID]->x + +float exc_gain_quant_scal3[8]={-2.794750, -1.810660, -1.169850, -0.848119, -0.587190, -0.329818, -0.063266, 0.282826}; + +float exc_gain_quant_scal1[2]={-0.35, 0.05}; + +#define sqr(x) ((x)*(x)) + +void *nb_encoder_init(SpeexMode *m) +{ + EncState *st; + SpeexNBMode *mode; + int i; + + mode=(SpeexNBMode *)m->mode; + st = (EncState*)speex_alloc(sizeof(EncState)+8000*sizeof(float)); + if (!st) + return NULL; + + st->stack = ((char*)st) + sizeof(EncState); + + st->mode=m; + + st->frameSize = mode->frameSize; + st->windowSize = st->frameSize*3/2; + st->nbSubframes=mode->frameSize/mode->subframeSize; + st->subframeSize=mode->subframeSize; + st->lpcSize = mode->lpcSize; + st->bufSize = mode->bufSize; + st->gamma1=mode->gamma1; + 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->preemph = mode->preemph; + + st->submodes=mode->submodes; + st->submodeID=st->submodeSelect=mode->defaultSubmode; + st->pre_mem=0; + st->pre_mem2=0; + st->bounded_pitch = 1; + + /* Allocating input buffer */ + st->inBuf = PUSH(st->stack, st->bufSize, float); + st->frame = st->inBuf + st->bufSize - st->windowSize; + /* Allocating excitation buffer */ + st->excBuf = PUSH(st->stack, st->bufSize, float); + st->exc = st->excBuf + st->bufSize - st->windowSize; + st->swBuf = PUSH(st->stack, st->bufSize, float); + st->sw = st->swBuf + st->bufSize - st->windowSize; + + st->exc2Buf = PUSH(st->stack, st->bufSize, float); + st->exc2 = st->exc2Buf + st->bufSize - st->windowSize; + + st->innov = PUSH(st->stack, st->frameSize, float); + + /* Asymmetric "pseudo-Hamming" window */ + { + int part1, part2; + part1 = st->subframeSize*7/2; + part2 = st->subframeSize*5/2; + st->window = PUSH(st->stack, st->windowSize, float); + for (i=0;i<part1;i++) + st->window[i]=.54-.46*cos(M_PI*i/part1); + for (i=0;i<part2;i++) + st->window[part1+i]=.54+.46*cos(M_PI*i/part2); + } + /* Create the window for autocorrelation (lag-windowing) */ + st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); + for (i=0;i<st->lpcSize+1;i++) + st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + + st->autocorr = PUSH(st->stack, st->lpcSize+1, float); + + st->buf2 = PUSH(st->stack, st->windowSize, float); + + st->lpc = PUSH(st->stack, st->lpcSize+1, float); + st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); + st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); + st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); + st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); + + st->lsp = PUSH(st->stack, st->lpcSize, float); + st->qlsp = PUSH(st->stack, st->lpcSize, float); + st->old_lsp = PUSH(st->stack, st->lpcSize, float); + st->old_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_lsp = PUSH(st->stack, st->lpcSize, float); + st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); + st->rc = PUSH(st->stack, st->lpcSize, float); + st->first = 1; + for (i=0;i<st->lpcSize;i++) + { + st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); + } + + st->mem_sp = PUSH(st->stack, st->lpcSize, float); + st->mem_sw = PUSH(st->stack, st->lpcSize, float); + st->mem_sw_whole = PUSH(st->stack, st->lpcSize, float); + st->mem_exc = PUSH(st->stack, st->lpcSize, float); + + st->pi_gain = PUSH(st->stack, st->nbSubframes, float); + + st->pitch = PUSH(st->stack, st->nbSubframes, int); + + st->vbr = PUSHS(st->stack, VBRState); + vbr_init(st->vbr); + st->vbr_quality = 8; + st->vbr_enabled = 0; + st->vad_enabled = 0; + st->dtx_enabled = 0; + st->abr_enabled = 0; + st->abr_drift = 0; + + st->complexity=2; + st->sampling_rate=8000; + st->dtx_count=0; + + return st; +} + +void nb_encoder_destroy(void *state) +{ + EncState *st=(EncState *)state; + /* Free all allocated memory */ + + vbr_destroy(st->vbr); + + /*Free state memory... should be last*/ + speex_free(st); +} + +int nb_encode(void *state, float *in, SpeexBits *bits) +{ + EncState *st; + int i, sub, roots; + int ol_pitch; + float ol_pitch_coef; + float ol_gain; + float *res, *target, *mem; + char *stack; + float *syn_resp; + float lsp_dist=0; + float *orig; + + st=(EncState *)state; + stack=st->stack; + + /* Copy new data in input buffer */ + speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + st->inBuf[st->bufSize-st->frameSize] = in[0] - st->preemph*st->pre_mem; + for (i=1;i<st->frameSize;i++) + st->inBuf[st->bufSize-st->frameSize+i] = in[i] - st->preemph*in[i-1]; + st->pre_mem = in[st->frameSize-1]; + + /* Move signals 1 frame towards the past */ + speex_move(st->exc2Buf, st->exc2Buf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + speex_move(st->swBuf, st->swBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + + + /* Window for analysis */ + for (i=0;i<st->windowSize;i++) + st->buf2[i] = st->frame[i] * st->window[i]; + + /* Compute auto-correlation */ + _spx_autocorr(st->buf2, st->autocorr, st->lpcSize+1, st->windowSize); + + st->autocorr[0] += 10; /* prevents NANs */ + st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ + + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;i<st->lpcSize+1;i++) + st->autocorr[i] *= st->lagWindow[i]; + + /* Levinson-Durbin */ + wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); + st->lpc[0]=1; + + /* LPC to LSPs (x-domain) transform */ + roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); + /* Check if we found all the roots */ + if (roots==st->lpcSize) + { + /* LSP x-domain to angle domain*/ + for (i=0;i<st->lpcSize;i++) + st->lsp[i] = acos(st->lsp[i]); + } else { + /* Search again if we can afford it */ + if (st->complexity>1) + roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.05, stack); + if (roots==st->lpcSize) + { + /* LSP x-domain to angle domain*/ + for (i=0;i<st->lpcSize;i++) + st->lsp[i] = acos(st->lsp[i]); + } else { + /*If we can't find all LSP's, do some damage control and use previous filter*/ + for (i=0;i<st->lpcSize;i++) + { + st->lsp[i]=st->old_lsp[i]; + } + } + } + + + lsp_dist=0; + for (i=0;i<st->lpcSize;i++) + lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]); + + /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */ + { + if (st->first) + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = st->lsp[i]; + else + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = .375*st->old_lsp[i] + .625*st->lsp[i]; + + lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); + + /* Compute interpolated LPCs (unquantized) for whole frame*/ + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = cos(st->interp_lsp[i]); + lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); + + + /*Open-loop pitch*/ + if (!st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) || + SUBMODE(lbr_pitch) != -1) + { + int nol_pitch[6]; + float nol_pitch_coef[6]; + + bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); + bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); + + filter_mem2(st->frame, st->bw_lpc1, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole); + + open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, + nol_pitch, nol_pitch_coef, 6, stack); + ol_pitch=nol_pitch[0]; + ol_pitch_coef = nol_pitch_coef[0]; + /*Try to remove pitch multiples*/ + for (i=1;i<6;i++) + { + if ((nol_pitch_coef[i]>.85*ol_pitch_coef) && + (fabs(nol_pitch[i]-ol_pitch/2.0)<=1 || fabs(nol_pitch[i]-ol_pitch/3.0)<=1 || + fabs(nol_pitch[i]-ol_pitch/4.0)<=1 || fabs(nol_pitch[i]-ol_pitch/5.0)<=1)) + { + /*ol_pitch_coef=nol_pitch_coef[i];*/ + ol_pitch = nol_pitch[i]; + } + } + /*if (ol_pitch>50) + ol_pitch/=2;*/ + /*ol_pitch_coef = sqrt(ol_pitch_coef);*/ + } else { + ol_pitch=0; + ol_pitch_coef=0; + } + /*Compute "real" excitation*/ + fir_mem2(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc); + + /* Compute open-loop excitation gain */ + ol_gain=0; + for (i=0;i<st->frameSize;i++) + ol_gain += st->exc[i]*st->exc[i]; + + ol_gain=sqrt(1+ol_gain/st->frameSize); + } + + /*VBR stuff*/ + if (st->vbr && (st->vbr_enabled||st->vad_enabled)) + { + + if (st->abr_enabled) + { + float qual_change=0; + if (st->abr_drift2 * st->abr_drift > 0) + { + /* Only adapt if long-term and short-term drift are the same sign */ + qual_change = -.00001*st->abr_drift/(1+st->abr_count); + if (qual_change>.05) + qual_change=.05; + if (qual_change<-.05) + qual_change=-.05; + } + st->vbr_quality += qual_change; + if (st->vbr_quality>10) + st->vbr_quality=10; + if (st->vbr_quality<0) + st->vbr_quality=0; + } + + st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, ol_pitch_coef); + /*if (delta_qual<0)*/ + /* delta_qual*=.1*(3+st->vbr_quality);*/ + if (st->vbr_enabled) + { + int mode; + int choice=0; + float min_diff=100; + mode = 8; + while (mode) + { + int v1; + float thresh; + v1=(int)floor(st->vbr_quality); + if (v1==10) + thresh = vbr_nb_thresh[mode][v1]; + else + thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1]; + if (st->relative_quality > thresh && + st->relative_quality-thresh<min_diff) + { + choice = mode; + min_diff = st->relative_quality-thresh; + } + mode--; + } + mode=choice; + if (mode==0) + { + if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) + { + mode=1; + st->dtx_count=1; + } else { + mode=0; + st->dtx_count++; + } + } else { + st->dtx_count=0; + } + + speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); + + if (st->abr_enabled) + { + int bitrate; + speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); + st->abr_drift+=(bitrate-st->abr_enabled); + st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); + st->abr_count += 1.0; + } + + } else { + /*VAD only case*/ + int mode; + if (st->relative_quality<2) + { + if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) + { + st->dtx_count=1; + mode=1; + } else { + mode=0; + st->dtx_count++; + } + } else { + st->dtx_count = 0; + mode=st->submodeSelect; + } + /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ + st->submodeID=mode; + } + } else { + st->relative_quality = -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); + + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + for (i=0;i<st->frameSize;i++) + st->exc[i]=st->exc2[i]=st->sw[i]=0; + + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=0; + st->first=1; + st->bounded_pitch = 1; + + /* Final signal synthesis from excitation */ + iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); + + in[0] = st->frame[0] + st->preemph*st->pre_mem2; + for (i=1;i<st->frameSize;i++) + in[i]=st->frame[i] + st->preemph*in[i-1]; + st->pre_mem2=in[st->frameSize-1]; + + return 0; + + } + + /* LSP Quantization */ + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = st->lsp[i]; + } + + + /*Quantize LSPs*/ +#if 1 /*0 for unquantized*/ + SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); +#else + for (i=0;i<st->lpcSize;i++) + st->qlsp[i]=st->lsp[i]; +#endif + + /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ + if (SUBMODE(lbr_pitch)!=-1) + { + speex_bits_pack(bits, ol_pitch-st->min_pitch, 7); + } + + if (SUBMODE(forced_pitch_gain)) + { + int quant; + quant = (int)floor(.5+15*ol_pitch_coef); + if (quant>15) + quant=15; + if (quant<0) + quant=0; + speex_bits_pack(bits, quant, 4); + ol_pitch_coef=0.066667*quant; + } + + + /*Quantize and transmit open-loop excitation gain*/ + { + int qe = (int)(floor(3.5*log(ol_gain))); + if (qe<0) + qe=0; + if (qe>31) + qe=31; + ol_gain = exp(qe/3.5); + speex_bits_pack(bits, qe, 5); + } + + /* Special case for first frame */ + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + } + + /* Filter response */ + res = PUSH(stack, st->subframeSize, float); + /* Target signal */ + target = PUSH(stack, st->subframeSize, float); + syn_resp = PUSH(stack, st->subframeSize, float); + mem = PUSH(stack, st->lpcSize, float); + orig = PUSH(stack, st->frameSize, float); + for (i=0;i<st->frameSize;i++) + orig[i]=st->frame[i]; + + /* Loop on sub-frames */ + for (sub=0;sub<st->nbSubframes;sub++) + { + float tmp; + int offset; + float *sp, *sw, *exc, *exc2; + int pitch; + + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Original signal */ + sp=st->frame+offset; + /* Excitation */ + exc=st->exc+offset; + /* Weighted signal */ + sw=st->sw+offset; + + exc2=st->exc2+offset; + + + /* LSP interpolation (quantized and unquantized) */ + tmp = (1.0 + sub)/st->nbSubframes; + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; + + /* Make sure the filters are stable */ + lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); + lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); + + /* Compute interpolated LPCs (quantized and unquantized) */ + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = cos(st->interp_lsp[i]); + lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); + + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = cos(st->interp_qlsp[i]); + lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + + /* Compute analysis filter gain at w=pi (for use in SB-CELP) */ + tmp=1; + st->pi_gain[sub]=0; + for (i=0;i<=st->lpcSize;i++) + { + st->pi_gain[sub] += tmp*st->interp_qlpc[i]; + tmp = -tmp; + } + + /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */ + bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); + if (st->gamma2>=0) + bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); + else + { + st->bw_lpc2[0]=1; + st->bw_lpc2[1]=-st->preemph; + for (i=2;i<=st->lpcSize;i++) + st->bw_lpc2[i]=0; + } + + /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) )*/ + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + exc[0]=1; + syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); + + /* Reset excitation */ + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + for (i=0;i<st->subframeSize;i++) + exc2[i]=0; + + /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); + + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); + + /* Compute weighted signal */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); + + /* Compute target signal */ + for (i=0;i<st->subframeSize;i++) + target[i]=sw[i]-res[i]; + + for (i=0;i<st->subframeSize;i++) + exc[i]=exc2[i]=0; + + /* If we have a long-term predictor (otherwise, something's wrong) */ + if (SUBMODE(ltp_quant)) + { + int pit_min, pit_max; + /* Long-term prediction */ + if (SUBMODE(lbr_pitch) != -1) + { + /* Low bit-rate pitch handling */ + int margin; + margin = SUBMODE(lbr_pitch); + if (margin) + { + if (ol_pitch < st->min_pitch+margin-1) + ol_pitch=st->min_pitch+margin-1; + if (ol_pitch > st->max_pitch-margin) + ol_pitch=st->max_pitch-margin; + pit_min = ol_pitch-margin+1; + pit_max = ol_pitch+margin; + } else { + pit_min=pit_max=ol_pitch; + } + } else { + pit_min = st->min_pitch; + pit_max = st->max_pitch; + } + + /* Force pitch to use only the current frame if needed */ + if (st->bounded_pitch && pit_max>offset) + pit_max=offset; + + /* Perform pitch search */ + pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, + st->lpcSize, st->subframeSize, bits, stack, + exc2, syn_resp, st->complexity); + + st->pitch[sub]=pitch; + } else { + speex_error ("No pitch prediction, what's wrong"); + } + + /* Update target for adaptive codebook contribution */ + syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, stack); + for (i=0;i<st->subframeSize;i++) + target[i]-=res[i]; + + + /* Quantization of innovation */ + { + float *innov; + float ener=0, ener_1; + + innov = st->innov+sub*st->subframeSize; + for (i=0;i<st->subframeSize;i++) + innov[i]=0; + + residue_percep_zero(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize, stack); + for (i=0;i<st->subframeSize;i++) + ener+=st->buf2[i]*st->buf2[i]; + ener=sqrt(.1+ener/st->subframeSize); + /*for (i=0;i<st->subframeSize;i++) + printf ("%f\n", st->buf2[i]/ener); + */ + + ener /= ol_gain; + + /* Calculate gain correction for the sub-frame (if any) */ + if (SUBMODE(have_subframe_gain)) + { + int qe; + ener=log(ener); + if (SUBMODE(have_subframe_gain)==3) + { + qe = vq_index(&ener, exc_gain_quant_scal3, 1, 8); + speex_bits_pack(bits, qe, 3); + ener=exc_gain_quant_scal3[qe]; + } else { + qe = vq_index(&ener, exc_gain_quant_scal1, 1, 2); + speex_bits_pack(bits, qe, 1); + ener=exc_gain_quant_scal1[qe]; + } + ener=exp(ener); + } else { + ener=1; + } + + ener*=ol_gain; + + /*printf ("%f %f\n", ener, ol_gain);*/ + + ener_1 = 1/ener; + + /* Normalize innovation */ + for (i=0;i<st->subframeSize;i++) + target[i]*=ener_1; + + /* Quantize innovation */ + if (SUBMODE(innovation_quant)) + { + /* Codebook search */ + SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov, syn_resp, bits, stack, st->complexity); + + /* De-normalize innovation and update excitation */ + for (i=0;i<st->subframeSize;i++) + innov[i]*=ener; + for (i=0;i<st->subframeSize;i++) + exc[i] += innov[i]; + } else { + speex_error("No fixed codebook"); + } + + /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + float *innov2 = PUSH(tmp_stack, st->subframeSize, float); + for (i=0;i<st->subframeSize;i++) + innov2[i]=0; + for (i=0;i<st->subframeSize;i++) + target[i]*=2.2; + SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov2, syn_resp, bits, tmp_stack, st->complexity); + for (i=0;i<st->subframeSize;i++) + innov2[i]*=ener*(1/2.2); + for (i=0;i<st->subframeSize;i++) + exc[i] += innov2[i]; + } + + for (i=0;i<st->subframeSize;i++) + target[i]*=ener; + + } + + /*Keep the previous memory*/ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + /* Final signal synthesis from excitation */ + iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); + + /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ + filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); + for (i=0;i<st->subframeSize;i++) + exc2[i]=exc[i]; + } + + /* Store the LSPs for interpolation in the next frame */ + if (st->submodeID>=1) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = st->lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + } + + if (st->submodeID==1) + { + if (st->dtx_count) + speex_bits_pack(bits, 15, 4); + else + speex_bits_pack(bits, 0, 4); + } + + /* The next frame will not be the first (Duh!) */ + st->first = 0; + + { + float ener=0, err=0; + float snr; + for (i=0;i<st->frameSize;i++) + { + ener+=st->frame[i]*st->frame[i]; + err += (st->frame[i]-orig[i])*(st->frame[i]-orig[i]); + } + snr = 10*log10((ener+1)/(err+1)); + /*printf ("%f %f %f\n", snr, ener, err);*/ + } + + /* Replace input by synthesized speech */ + in[0] = st->frame[0] + st->preemph*st->pre_mem2; + for (i=1;i<st->frameSize;i++) + in[i]=st->frame[i] + st->preemph*in[i-1]; + st->pre_mem2=in[st->frameSize-1]; + + if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) + st->bounded_pitch = 1; + else + st->bounded_pitch = 0; + + return 1; +} + + +void *nb_decoder_init(SpeexMode *m) +{ + DecState *st; + SpeexNBMode *mode; + int i; + + mode=(SpeexNBMode*)m->mode; + st = (DecState *)speex_alloc(sizeof(DecState)+4000*sizeof(float)); + st->mode=m; + + st->stack = ((char*)st) + sizeof(DecState); + + st->first=1; + /* Codec parameters, should eventually have several "modes"*/ + st->frameSize = mode->frameSize; + st->windowSize = st->frameSize*3/2; + st->nbSubframes=mode->frameSize/mode->subframeSize; + st->subframeSize=mode->subframeSize; + st->lpcSize = mode->lpcSize; + st->bufSize = mode->bufSize; + st->gamma1=mode->gamma1; + st->gamma2=mode->gamma2; + st->min_pitch=mode->pitchStart; + st->max_pitch=mode->pitchEnd; + st->preemph = mode->preemph; + + st->submodes=mode->submodes; + st->submodeID=mode->defaultSubmode; + + st->pre_mem=0; + st->lpc_enh_enabled=0; + + + st->inBuf = PUSH(st->stack, st->bufSize, float); + st->frame = st->inBuf + st->bufSize - st->windowSize; + st->excBuf = PUSH(st->stack, st->bufSize, float); + st->exc = st->excBuf + st->bufSize - st->windowSize; + for (i=0;i<st->bufSize;i++) + st->inBuf[i]=0; + for (i=0;i<st->bufSize;i++) + st->excBuf[i]=0; + st->innov = PUSH(st->stack, st->frameSize, float); + + st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); + st->qlsp = PUSH(st->stack, st->lpcSize, float); + st->old_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); + st->mem_sp = PUSH(st->stack, 5*st->lpcSize, float); + st->comb_mem = PUSHS(st->stack, CombFilterMem); + comp_filter_mem_init (st->comb_mem); + + st->pi_gain = PUSH(st->stack, st->nbSubframes, float); + st->last_pitch = 40; + st->count_lost=0; + st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0; + st->pitch_gain_buf_idx = 0; + + st->sampling_rate=8000; + st->last_ol_gain = 0; + + st->user_callback.func = &speex_default_user_handler; + st->user_callback.data = NULL; + for (i=0;i<16;i++) + st->speex_callbacks[i].func = NULL; + + st->voc_m1=st->voc_m2=st->voc_mean=0; + st->voc_offset=0; + st->dtx_enabled=0; + return st; +} + +void nb_decoder_destroy(void *state) +{ + DecState *st; + st=(DecState*)state; + + speex_free(state); +} + +#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a)))) + +static void nb_decode_lost(DecState *st, float *out, char *stack) +{ + int i, sub; + float *awk1, *awk2, *awk3; + float pitch_gain, fact, gain_med; + + fact = exp(-.04*st->count_lost*st->count_lost); + gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]); + if (gain_med < st->last_pitch_gain) + st->last_pitch_gain = gain_med; + + pitch_gain = st->last_pitch_gain; + if (pitch_gain>.95) + pitch_gain=.95; + + pitch_gain *= fact; + + /* Shift all buffers by one frame */ + speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + + awk1=PUSH(stack, (st->lpcSize+1), float); + awk2=PUSH(stack, (st->lpcSize+1), float); + awk3=PUSH(stack, (st->lpcSize+1), float); + + for (sub=0;sub<st->nbSubframes;sub++) + { + int offset; + float *sp, *exc; + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Original signal */ + sp=st->frame+offset; + /* Excitation */ + exc=st->exc+offset; + /* Excitation after post-filter*/ + + /* Calculate perceptually enhanced LPC filter */ + if (st->lpc_enh_enabled) + { + float r=.9; + + float k1,k2,k3; + if (st->submodes[st->submodeID] != NULL) + { + k1=SUBMODE(lpc_enh_k1); + k2=SUBMODE(lpc_enh_k2); + } else { + k1=k2=.7; + } + k3=(1-(1-r*k1)/(1-r*k2))/r; + if (!st->lpc_enh_enabled) + { + k1=k2; + k3=0; + } + bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); + bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); + bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); + } + + /* Make up a plausible excitation */ + /* THIS CAN BE IMPROVED */ + /*if (pitch_gain>.95) + pitch_gain=.95;*/ + { + float innov_gain=0; + for (i=0;i<st->frameSize;i++) + innov_gain += st->innov[i]*st->innov[i]; + innov_gain=sqrt(innov_gain/st->frameSize); + for (i=0;i<st->subframeSize;i++) + { +#if 0 + exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset]; + /*Just so it give the same lost packets as with if 0*/ + /*rand();*/ +#else + /*exc[i]=pitch_gain*exc[i-st->last_pitch] + fact*st->innov[i+offset];*/ + exc[i]=pitch_gain*exc[i-st->last_pitch] + + fact*sqrt(1-pitch_gain)*speex_rand(innov_gain); +#endif + } + } + for (i=0;i<st->subframeSize;i++) + sp[i]=exc[i]; + + /* Signal synthesis */ + if (st->lpc_enh_enabled) + { + filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, + st->mem_sp+st->lpcSize); + filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } else { + for (i=0;i<st->lpcSize;i++) + st->mem_sp[st->lpcSize+i] = 0; + iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } + } + + out[0] = st->frame[0] + st->preemph*st->pre_mem; + for (i=1;i<st->frameSize;i++) + out[i]=st->frame[i] + st->preemph*out[i-1]; + st->pre_mem=out[st->frameSize-1]; + + st->first = 0; + st->count_lost++; + st->pitch_gain_buf[st->pitch_gain_buf_idx++] = pitch_gain; + if (st->pitch_gain_buf_idx > 2) /* rollover */ + st->pitch_gain_buf_idx = 0; +} + +int nb_decode(void *state, SpeexBits *bits, float *out) +{ + DecState *st; + int i, sub; + int pitch; + float pitch_gain[3]; + float ol_gain=0; + int ol_pitch=0; + float ol_pitch_coef=0; + int best_pitch=40; + float best_pitch_gain=0; + int wideband; + int m; + char *stack; + float *awk1, *awk2, *awk3; + float pitch_average=0; + + st=(DecState*)state; + stack=st->stack; + + /* Check if we're in DTX mode*/ + if (!bits && st->dtx_enabled) + { + st->submodeID=0; + } else + { + /* If bits is NULL, consider the packet to be lost (what could we do anyway) */ + if (!bits) + { + nb_decode_lost(st, out, stack); + return 0; + } + + /* Search for next narrowband block (handle requests, skip wideband blocks) */ + do { + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) /* Skip wideband block (for compatibility) */ + { + 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); + if (advance < 0) + { + speex_warning ("Invalid wideband mode encountered. Corrupted stream?"); + return -2; + } + advance -= (SB_SUBMODE_BITS+1); + speex_bits_advance(bits, advance); + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) + { + advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); + speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); + if (advance < 0) + { + speex_warning ("Invalid wideband mode encountered: corrupted stream?"); + return -2; + } + advance -= (SB_SUBMODE_BITS+1); + speex_bits_advance(bits, advance); + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) + { + speex_warning ("More than to wideband layers found: corrupted stream?"); + return -2; + } + + } + } + + /* FIXME: Check for overflow */ + m = speex_bits_unpack_unsigned(bits, 4); + if (m==15) /* We found a terminator */ + { + return -1; + } else if (m==14) /* Speex in-band request */ + { + int ret = speex_inband_handler(bits, st->speex_callbacks, state); + if (ret) + return ret; + } else if (m==13) /* User in-band request */ + { + int ret = st->user_callback.func(bits, state, st->user_callback.data); + if (ret) + return ret; + } else if (m>8) /* Invalid mode */ + { + speex_warning("Invalid mode encountered: corrupted stream?"); + return -2; + } + + } while (m>8); + + /* Get the sub-mode that was used */ + st->submodeID = m; + + } + + /* Shift all buffers by one frame */ + speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + float *lpc; + lpc = PUSH(stack,11, float); + bw_lpc(.93, st->interp_qlpc, lpc, 10); + /*for (i=0;i<st->frameSize;i++) + st->exc[i]=0;*/ + { + float innov_gain=0; + float pgain=st->last_pitch_gain; + if (pgain>.6) + pgain=.6; + for (i=0;i<st->frameSize;i++) + innov_gain += st->innov[i]*st->innov[i]; + innov_gain=sqrt(innov_gain/st->frameSize); + for (i=0;i<st->frameSize;i++) + st->exc[i]=0; + speex_rand_vec(innov_gain, st->exc, st->frameSize); + } + + + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem2(st->exc, lpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); + + out[0] = st->frame[0] + st->preemph*st->pre_mem; + for (i=1;i<st->frameSize;i++) + out[i]=st->frame[i] + st->preemph*out[i-1]; + st->pre_mem=out[st->frameSize-1]; + st->count_lost=0; + return 0; + } + + /* Unquantize LSPs */ + SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); + + /*Damp memory if a frame was lost and the LSP changed too much*/ + if (st->count_lost) + { + float lsp_dist=0, fact; + for (i=0;i<st->lpcSize;i++) + lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]); + fact = .6*exp(-.2*lsp_dist); + for (i=0;i<2*st->lpcSize;i++) + st->mem_sp[i] *= fact; + } + + + /* Handle first frame and lost-packet case */ + if (st->first || st->count_lost) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + } + + /* Get open-loop pitch estimation for low bit-rate pitch coding */ + if (SUBMODE(lbr_pitch)!=-1) + { + ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); + } + + if (SUBMODE(forced_pitch_gain)) + { + int quant; + quant = speex_bits_unpack_unsigned(bits, 4); + ol_pitch_coef=0.066667*quant; + } + + /* Get global excitation gain */ + { + int qe; + qe = speex_bits_unpack_unsigned(bits, 5); + ol_gain = exp(qe/3.5); + } + + awk1=PUSH(stack, st->lpcSize+1, float); + awk2=PUSH(stack, st->lpcSize+1, float); + awk3=PUSH(stack, st->lpcSize+1, float); + + if (st->submodeID==1) + { + int extra; + extra = speex_bits_unpack_unsigned(bits, 4); + + if (extra==15) + st->dtx_enabled=1; + else + st->dtx_enabled=0; + } + if (st->submodeID>1) + st->dtx_enabled=0; + + /*Loop on subframes */ + for (sub=0;sub<st->nbSubframes;sub++) + { + int offset; + float *sp, *exc, tmp; + + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Original signal */ + sp=st->frame+offset; + /* Excitation */ + exc=st->exc+offset; + /* Excitation after post-filter*/ + + /* LSP interpolation (quantized and unquantized) */ + tmp = (1.0 + sub)/st->nbSubframes; + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; + + /* Make sure the LSP's are stable */ + lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); + + + /* Compute interpolated LPCs (unquantized) */ + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = cos(st->interp_qlsp[i]); + lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + + /* Compute enhanced synthesis filter */ + if (st->lpc_enh_enabled) + { + float r=.9; + + float k1,k2,k3; + k1=SUBMODE(lpc_enh_k1); + k2=SUBMODE(lpc_enh_k2); + k3=(1-(1-r*k1)/(1-r*k2))/r; + if (!st->lpc_enh_enabled) + { + k1=k2; + k3=0; + } + bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); + bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); + bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); + + } + + /* Compute analysis filter at w=pi */ + tmp=1; + st->pi_gain[sub]=0; + for (i=0;i<=st->lpcSize;i++) + { + st->pi_gain[sub] += tmp*st->interp_qlpc[i]; + tmp = -tmp; + } + + /* Reset excitation */ + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + + /*Adaptive codebook contribution*/ + if (SUBMODE(ltp_unquant)) + { + int pit_min, pit_max; + /* Handle pitch constraints if any */ + if (SUBMODE(lbr_pitch) != -1) + { + int margin; + margin = SUBMODE(lbr_pitch); + if (margin) + { +/* GT - need optimization? + if (ol_pitch < st->min_pitch+margin-1) + ol_pitch=st->min_pitch+margin-1; + if (ol_pitch > st->max_pitch-margin) + ol_pitch=st->max_pitch-margin; + pit_min = ol_pitch-margin+1; + pit_max = ol_pitch+margin; +*/ + pit_min = ol_pitch-margin+1; + if (pit_min < st->min_pitch) + pit_min = st->min_pitch; + pit_max = ol_pitch+margin; + if (pit_max > st->max_pitch) + pit_max = st->max_pitch; + } else { + pit_min = pit_max = ol_pitch; + } + } else { + pit_min = st->min_pitch; + pit_max = st->max_pitch; + } + + /* Pitch synthesis */ + SUBMODE(ltp_unquant)(exc, 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); + + /* If we had lost frames, check energy of last received frame */ + if (st->count_lost && ol_gain < st->last_ol_gain) + { + float fact = ol_gain/(st->last_ol_gain+1); + for (i=0;i<st->subframeSize;i++) + exc[i]*=fact; + } + + tmp = fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2]); + tmp = fabs(pitch_gain[1]); + if (pitch_gain[0]>0) + tmp += pitch_gain[0]; + else + tmp -= .5*pitch_gain[0]; + if (pitch_gain[2]>0) + tmp += pitch_gain[2]; + else + tmp -= .5*pitch_gain[0]; + + + pitch_average += tmp; + if (tmp>best_pitch_gain) + { + best_pitch = pitch; + best_pitch_gain = tmp; + /* best_pitch_gain = tmp*.9; + if (best_pitch_gain>.85) + best_pitch_gain=.85;*/ + } + } else { + speex_error("No pitch prediction, what's wrong"); + } + + /* Unquantize the innovation */ + { + int q_energy; + float ener; + float *innov; + + innov = st->innov+sub*st->subframeSize; + for (i=0;i<st->subframeSize;i++) + innov[i]=0; + + /* Decode sub-frame gain correction */ + if (SUBMODE(have_subframe_gain)==3) + { + q_energy = speex_bits_unpack_unsigned(bits, 3); + ener = ol_gain*exp(exc_gain_quant_scal3[q_energy]); + } else if (SUBMODE(have_subframe_gain)==1) + { + q_energy = speex_bits_unpack_unsigned(bits, 1); + ener = ol_gain*exp(exc_gain_quant_scal1[q_energy]); + } else { + ener = ol_gain; + } + + if (SUBMODE(innovation_unquant)) + { + /*Fixed codebook contribution*/ + SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack); + } else { + speex_error("No fixed codebook"); + } + + /* De-normalize innovation and update excitation */ + for (i=0;i<st->subframeSize;i++) + innov[i]*=ener; + + /*Vocoder mode*/ + if (st->submodeID==1) + { + float g=ol_pitch_coef; + + + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + while (st->voc_offset<st->subframeSize) + { + if (st->voc_offset>=0) + exc[st->voc_offset]=sqrt(1.0*ol_pitch); + 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++) + { + float exci=exc[i]; + exc[i]=.8*g*exc[i]*ol_gain + .6*g*st->voc_m1*ol_gain + .5*g*innov[i] - .5*g*st->voc_m2 + (1-g)*innov[i]; + st->voc_m1 = exci; + st->voc_m2=innov[i]; + st->voc_mean = .95*st->voc_mean + .05*exc[i]; + exc[i]-=st->voc_mean; + } + } else { + for (i=0;i<st->subframeSize;i++) + exc[i]+=innov[i]; + } + /* Decode second codebook (only for some modes) */ + if (SUBMODE(double_codebook)) + { + char *tmp_stack=stack; + float *innov2 = PUSH(tmp_stack, st->subframeSize, float); + for (i=0;i<st->subframeSize;i++) + innov2[i]=0; + SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, tmp_stack); + for (i=0;i<st->subframeSize;i++) + innov2[i]*=ener*(1/2.2); + for (i=0;i<st->subframeSize;i++) + exc[i] += innov2[i]; + } + + } + + for (i=0;i<st->subframeSize;i++) + sp[i]=exc[i]; + + /* Signal synthesis */ + if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0) + comb_filter(exc, sp, st->interp_qlpc, st->lpcSize, st->subframeSize, + pitch, pitch_gain, SUBMODE(comb_gain), st->comb_mem); + if (st->lpc_enh_enabled) + { + /* Use enhanced LPC filter */ + filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, + st->mem_sp+st->lpcSize); + filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } else { + /* Use regular filter */ + for (i=0;i<st->lpcSize;i++) + st->mem_sp[st->lpcSize+i] = 0; + iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } + } + + /*Copy output signal*/ + out[0] = st->frame[0] + st->preemph*st->pre_mem; + for (i=1;i<st->frameSize;i++) + out[i]=st->frame[i] + st->preemph*out[i-1]; + st->pre_mem=out[st->frameSize-1]; + + + /* Store the LSPs for interpolation in the next frame */ + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + + /* The next frame will not be the first (Duh!) */ + st->first = 0; + st->count_lost=0; + st->last_pitch = best_pitch; + st->last_pitch_gain = .25*pitch_average; + st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain; + if (st->pitch_gain_buf_idx > 2) /* rollover */ + st->pitch_gain_buf_idx = 0; + + st->last_ol_gain = ol_gain; + + return 0; +} + +int nb_encoder_ctl(void *state, int request, void *ptr) +{ + EncState *st; + st=(EncState*)state; + switch(request) + { + case SPEEX_GET_FRAME_SIZE: + (*(int*)ptr) = st->frameSize; + break; + case SPEEX_SET_LOW_MODE: + case SPEEX_SET_MODE: + st->submodeSelect = st->submodeID = (*(int*)ptr); + break; + case SPEEX_GET_LOW_MODE: + case SPEEX_GET_MODE: + (*(int*)ptr) = st->submodeID; + break; + case SPEEX_SET_VBR: + st->vbr_enabled = (*(int*)ptr); + break; + case SPEEX_GET_VBR: + (*(int*)ptr) = st->vbr_enabled; + break; + case SPEEX_SET_VAD: + st->vad_enabled = (*(int*)ptr); + break; + case SPEEX_GET_VAD: + (*(int*)ptr) = st->vad_enabled; + break; + case SPEEX_SET_DTX: + st->dtx_enabled = (*(int*)ptr); + break; + case SPEEX_GET_DTX: + (*(int*)ptr) = st->dtx_enabled; + break; + case SPEEX_SET_ABR: + st->abr_enabled = (*(int*)ptr); + st->vbr_enabled = 1; + { + int i=10, rate, target; + float vbr_qual; + target = (*(int*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + vbr_qual=i; + if (vbr_qual<0) + vbr_qual=0; + speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); + st->abr_count=0; + st->abr_drift=0; + st->abr_drift2=0; + } + + break; + case SPEEX_GET_ABR: + (*(int*)ptr) = st->abr_enabled; + break; + case SPEEX_SET_VBR_QUALITY: + st->vbr_quality = (*(float*)ptr); + break; + case SPEEX_GET_VBR_QUALITY: + (*(float*)ptr) = st->vbr_quality; + break; + case SPEEX_SET_QUALITY: + { + int quality = (*(int*)ptr); + if (quality < 0) + quality = 0; + if (quality > 10) + quality = 10; + st->submodeSelect = st->submodeID = ((SpeexNBMode*)(st->mode->mode))->quality_map[quality]; + } + break; + case SPEEX_SET_COMPLEXITY: + st->complexity = (*(int*)ptr); + if (st->complexity<1) + st->complexity=1; + break; + case SPEEX_GET_COMPLEXITY: + (*(int*)ptr) = st->complexity; + break; + case SPEEX_SET_BITRATE: + { + int i=10, rate, target; + target = (*(int*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + } + break; + case SPEEX_GET_BITRATE: + if (st->submodes[st->submodeID]) + (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; + else + (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; + break; + case SPEEX_SET_SAMPLING_RATE: + st->sampling_rate = (*(int*)ptr); + break; + case SPEEX_GET_SAMPLING_RATE: + (*(int*)ptr)=st->sampling_rate; + break; + case SPEEX_RESET_STATE: + { + int i; + st->bounded_pitch = 1; + st->first = 1; + for (i=0;i<st->lpcSize;i++) + st->lsp[i]=(M_PI*((float)(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->bufSize;i++) + st->excBuf[i]=st->swBuf[i]=st->inBuf[i]=st->exc2Buf[i]=0; + } + break; + case SPEEX_GET_PI_GAIN: + { + int i; + float *g = (float*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->frameSize;i++) + e[i]=st->exc[i]; + } + break; + case SPEEX_GET_INNOV: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->frameSize;i++) + e[i]=st->innov[i]; + } + break; + case SPEEX_GET_RELATIVE_QUALITY: + (*(float*)ptr)=st->relative_quality; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} + +int nb_decoder_ctl(void *state, int request, void *ptr) +{ + DecState *st; + st=(DecState*)state; + switch(request) + { + case SPEEX_GET_LOW_MODE: + case SPEEX_GET_MODE: + (*(int*)ptr) = st->submodeID; + break; + case SPEEX_SET_ENH: + st->lpc_enh_enabled = *((int*)ptr); + break; + case SPEEX_GET_ENH: + *((int*)ptr) = st->lpc_enh_enabled; + break; + case SPEEX_GET_FRAME_SIZE: + (*(int*)ptr) = st->frameSize; + break; + case SPEEX_GET_BITRATE: + if (st->submodes[st->submodeID]) + (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; + else + (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; + break; + case SPEEX_SET_SAMPLING_RATE: + st->sampling_rate = (*(int*)ptr); + break; + case SPEEX_GET_SAMPLING_RATE: + (*(int*)ptr)=st->sampling_rate; + break; + case SPEEX_SET_HANDLER: + { + SpeexCallback *c = (SpeexCallback*)ptr; + st->speex_callbacks[c->callback_id].func=c->func; + st->speex_callbacks[c->callback_id].data=c->data; + st->speex_callbacks[c->callback_id].callback_id=c->callback_id; + } + break; + case SPEEX_SET_USER_HANDLER: + { + SpeexCallback *c = (SpeexCallback*)ptr; + st->user_callback.func=c->func; + st->user_callback.data=c->data; + st->user_callback.callback_id=c->callback_id; + } + break; + case SPEEX_RESET_STATE: + { + int i; + for (i=0;i<2*st->lpcSize;i++) + st->mem_sp[i]=0; + for (i=0;i<st->bufSize;i++) + st->excBuf[i]=st->inBuf[i]=0; + } + break; + case SPEEX_GET_PI_GAIN: + { + int i; + float *g = (float*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->frameSize;i++) + e[i]=st->exc[i]; + } + break; + case SPEEX_GET_INNOV: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->frameSize;i++) + e[i]=st->innov[i]; + } + break; + case SPEEX_GET_DTX_STATUS: + *((int*)ptr) = st->dtx_enabled; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} diff --git a/engine/voice_codecs/speex/source/libspeex/nb_celp.h b/engine/voice_codecs/speex/source/libspeex/nb_celp.h new file mode 100644 index 0000000..7439f1c --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/nb_celp.h @@ -0,0 +1,202 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file nb_celp.h + @brief Narrowband CELP encoder/decoder +*/ +/* + 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 NB_CELP_H +#define NB_CELP_H + +#include "modes.h" +#include "speex_bits.h" +#include "speex_callbacks.h" +#include "vbr.h" +#include "filters.h" + +/**Structure representing the full state of the narrowband encoder*/ +typedef struct EncState { + SpeexMode *mode; /**< Mode corresponding to the state */ + int first; /**< Is this the first frame? */ + int frameSize; /**< Size of frames */ + int subframeSize; /**< Size of sub-frames */ + int nbSubframes; /**< Number of sub-frames */ + int windowSize; /**< Analysis (LPC) window length */ + int lpcSize; /**< LPC order */ + int bufSize; /**< Buffer size */ + int min_pitch; /**< Minimum pitch value allowed */ + int max_pitch; /**< Maximum pitch value allowed */ + + int safe_pitch; /**< Don't use too large values for pitch (in case we lose a packet) */ + int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */ + int ol_pitch; /**< Open-loop pitch */ + int ol_voiced; /**< Open-loop voiced/non-voiced decision */ + int *pitch; + float gamma1; /**< Perceptual filter: A(z/gamma1) */ + float gamma2; /**< Perceptual filter: A(z/gamma2) */ + float lag_factor; /**< Lag windowing Gaussian width */ + float lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ + float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ + float pre_mem; /**< 1-element memory for pre-emphasis */ + float pre_mem2; /**< 1-element memory for pre-emphasis */ + char *stack; /**< Pseudo-stack allocation for temporary memory */ + float *inBuf; /**< Input buffer (original signal) */ + float *frame; /**< Start of original frame */ + float *excBuf; /**< Excitation buffer */ + float *exc; /**< Start of excitation frame */ + float *exc2Buf; /**< "Pitch enhanced" excitation */ + float *exc2; /**< "Pitch enhanced" excitation */ + float *swBuf; /**< Weighted signal buffer */ + float *sw; /**< Start of weighted signal frame */ + float *innov; /**< Innovation for the frame */ + float *window; /**< Temporary (Hanning) window */ + float *buf2; /**< 2nd temporary buffer */ + float *autocorr; /**< auto-correlation */ + float *lagWindow; /**< Window applied to auto-correlation */ + float *lpc; /**< LPCs for current frame */ + float *lsp; /**< LSPs for current frame */ + float *qlsp; /**< Quantized LSPs for current frame */ + float *old_lsp; /**< LSPs for previous frame */ + float *old_qlsp; /**< Quantized LSPs for previous frame */ + float *interp_lsp; /**< Interpolated LSPs */ + float *interp_qlsp; /**< Interpolated quantized LSPs */ + float *interp_lpc; /**< Interpolated LPCs */ + float *interp_qlpc; /**< Interpolated quantized LPCs */ + float *bw_lpc1; /**< LPCs after bandwidth expansion by gamma1 for perceptual weighting*/ + float *bw_lpc2; /**< LPCs after bandwidth expansion by gamma2 for perceptual weighting*/ + float *rc; /**< Reflection coefficients */ + float *mem_sp; /**< Filter memory for signal synthesis */ + float *mem_sw; /**< Filter memory for perceptually-weighted signal */ + float *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/ + float *mem_exc; /**< Filter memory for excitation (whole frame) */ + float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ + + 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 */ + int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ + int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ + int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */ + int dtx_count; /**< Number of consecutive DTX frames */ + int abr_enabled; /**< ABR setting (in bps), 0 if off */ + float abr_drift; + float abr_drift2; + float abr_count; + int complexity; /**< Complexity setting (0-10 from least complex to most complex) */ + int sampling_rate; + + SpeexSubmode **submodes; /**< Sub-mode data */ + int submodeID; /**< Activated sub-mode */ + int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */ +} EncState; + +/**Structure representing the full state of the narrowband decoder*/ +typedef struct DecState { + SpeexMode *mode; /**< Mode corresponding to the state */ + int first; /**< Is this the first frame? */ + int count_lost; /**< Was the last frame lost? */ + int frameSize; /**< Size of frames */ + int subframeSize; /**< Size of sub-frames */ + int nbSubframes; /**< Number of sub-frames */ + int windowSize; /**< Analysis (LPC) window length */ + int lpcSize; /**< LPC order */ + int bufSize; /**< Buffer size */ + int min_pitch; /**< Minimum pitch value allowed */ + int max_pitch; /**< Maximum pitch value allowed */ + int sampling_rate; + float last_ol_gain; /**< Open-loop gain for previous frame */ + + + float gamma1; /**< Perceptual filter: A(z/gamma1) */ + float gamma2; /**< Perceptual filter: A(z/gamma2) */ + float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ + float pre_mem; /**< 1-element memory for pre-emphasis */ + char *stack; /**< Pseudo-stack allocation for temporary memory */ + float *inBuf; /**< Input buffer (original signal) */ + float *frame; /**< Start of original frame */ + float *excBuf; /**< Excitation buffer */ + float *exc; /**< Start of excitation frame */ + float *innov; /**< Innovation for the frame */ + float *qlsp; /**< Quantized LSPs for current frame */ + float *old_qlsp; /**< Quantized LSPs for previous frame */ + float *interp_qlsp; /**< Interpolated quantized LSPs */ + float *interp_qlpc; /**< Interpolated quantized LPCs */ + float *mem_sp; /**< Filter memory for synthesis signal */ + float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ + int last_pitch; /**< Pitch of last correctly decoded frame */ + float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */ + float pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */ + int pitch_gain_buf_idx; /**< Tail of the buffer */ + + SpeexSubmode **submodes; /**< Sub-mode data */ + int submodeID; /**< Activated sub-mode */ + int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */ + CombFilterMem *comb_mem; + SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS]; + + SpeexCallback user_callback; + + /*Vocoder data*/ + float voc_m1; + float voc_m2; + float voc_mean; + int voc_offset; + + int dtx_enabled; +} DecState; + +/** Initializes encoder state*/ +void *nb_encoder_init(SpeexMode *m); + +/** De-allocates encoder state resources*/ +void nb_encoder_destroy(void *state); + +/** Encodes one frame*/ +int nb_encode(void *state, float *in, SpeexBits *bits); + + +/** Initializes decoder state*/ +void *nb_decoder_init(SpeexMode *m); + +/** De-allocates decoder state resources*/ +void nb_decoder_destroy(void *state); + +/** Decodes one frame*/ +int nb_decode(void *state, SpeexBits *bits, float *out); + +/** ioctl-like function for controlling a narrowband encoder */ +int nb_encoder_ctl(void *state, int request, void *ptr); + +/** ioctl-like function for controlling a narrowband decoder */ +int nb_decoder_ctl(void *state, int request, void *ptr); + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/quant_lsp.c b/engine/voice_codecs/speex/source/libspeex/quant_lsp.c new file mode 100644 index 0000000..c9d797e --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/quant_lsp.c @@ -0,0 +1,311 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: quant_lsp.c + LSP vector quantization + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "quant_lsp.h" +#include <math.h> + +extern int lsp_nb_vqid[64]; +static float quant_weight[MAX_LSP_SIZE]; + +/* Note: x is modified*/ +static int lsp_quant(float *x, signed char *cdbk, int nbVec, int nbDim) +{ + int i,j; + float dist, tmp; + float best_dist=0; + int best_id=0; + signed char *ptr=cdbk; + for (i=0;i<nbVec;i++) + { + dist=0; + for (j=0;j<nbDim;j++) + { + tmp=(x[j]-*ptr++); + dist+=tmp*tmp; + } + if (dist<best_dist || i==0) + { + best_dist=dist; + best_id=i; + } + } + + for (j=0;j<nbDim;j++) + x[j] -= cdbk[best_id*nbDim+j]; + + return best_id; +} + +/* Note: x is modified*/ +static int lsp_weight_quant(float *x, float *weight, signed char *cdbk, int nbVec, int nbDim) +{ + int i,j; + float dist, tmp; + float best_dist=0; + int best_id=0; + signed char *ptr=cdbk; + for (i=0;i<nbVec;i++) + { + dist=0; + for (j=0;j<nbDim;j++) + { + tmp=(x[j]-*ptr++); + dist+=weight[j]*tmp*tmp; + } + if (dist<best_dist || i==0) + { + best_dist=dist; + best_id=i; + } + } + + for (j=0;j<nbDim;j++) + x[j] -= cdbk[best_id*nbDim+j]; + return best_id; +} + + +void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits) +{ + int i; + float tmp1, tmp2; + int id; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + quant_weight[0] = 1/(qlsp[1]-qlsp[0]); + quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]); + for (i=1;i<order-1;i++) + { +#if 1 + tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1])); + tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i])); +#else + tmp1 = 1/(qlsp[i]-qlsp[i-1]); + tmp2 = 1/(qlsp[i+1]-qlsp[i]); +#endif + quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2; + } + for (i=0;i<order;i++) + qlsp[i]-=(.25*i+.25); + for (i=0;i<order;i++) + qlsp[i]*=256; + + id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); + speex_bits_pack(bits, id, 6); + + for (i=0;i<5;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5); + speex_bits_pack(bits, id, 6); + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); + speex_bits_pack(bits, id, 6); + + for (i=5;i<10;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=.00097656; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits) +{ + int i, id; + for (i=0;i<order;i++) + lsp[i]=.25*i+.25; + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<10;i++) + lsp[i] += 0.0039062*cdbk_nb[id*10+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] += 0.0019531 * cdbk_nb_low1[id*5+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] += 0.00097656 * cdbk_nb_low2[id*5+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] += 0.0019531 * cdbk_nb_high1[id*5+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] += 0.00097656 * cdbk_nb_high2[id*5+i]; +} + + +void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits) +{ + int i; + float tmp1, tmp2; + int id; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + quant_weight[0] = 1/(qlsp[1]-qlsp[0]); + quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]); + for (i=1;i<order-1;i++) + { +#if 1 + tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1])); + tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i])); +#else + tmp1 = 1/(qlsp[i]-qlsp[i-1]); + tmp2 = 1/(qlsp[i+1]-qlsp[i]); +#endif + quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2; + } + + for (i=0;i<order;i++) + qlsp[i]-=(.25*i+.25); + for (i=0;i<order;i++) + qlsp[i]*=256; + + id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); + speex_bits_pack(bits, id, 6); + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=0.0019531; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits) +{ + int i, id; + for (i=0;i<order;i++) + lsp[i]=.25*i+.25; + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<10;i++) + lsp[i] += 0.0039062*cdbk_nb[id*10+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] += 0.0019531*cdbk_nb_low1[id*5+i]; + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] += 0.0019531*cdbk_nb_high1[id*5+i]; + +} + + +extern signed char high_lsp_cdbk[]; +extern signed char high_lsp_cdbk2[]; + + +void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *bits) +{ + int i; + float tmp1, tmp2; + int id; + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + quant_weight[0] = 1/(qlsp[1]-qlsp[0]); + quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]); + for (i=1;i<order-1;i++) + { + tmp1 = 1/(qlsp[i]-qlsp[i-1]); + tmp2 = 1/(qlsp[i+1]-qlsp[i]); + quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2; + } + + for (i=0;i<order;i++) + qlsp[i]-=(.3125*i+.75); + for (i=0;i<order;i++) + qlsp[i]*=256; + + id = lsp_quant(qlsp, high_lsp_cdbk, 64, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=0.0019531; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_high(float *lsp, int order, SpeexBits *bits) +{ + + int i, id; + for (i=0;i<order;i++) + lsp[i]=.3125*i+.75; + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<order;i++) + lsp[i] += 0.0039062*high_lsp_cdbk[id*order+i]; + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<order;i++) + lsp[i] += 0.0019531*high_lsp_cdbk2[id*order+i]; +} diff --git a/engine/voice_codecs/speex/source/libspeex/quant_lsp.h b/engine/voice_codecs/speex/source/libspeex/quant_lsp.h new file mode 100644 index 0000000..d678c39 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/quant_lsp.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: quant_lsp.h + LSP vector quantization + + 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 QUANT_LSP_H +#define QUANT_LSP_H + +#include "speex_bits.h" + +#define MAX_LSP_SIZE 20 + +#define NB_CDBK_SIZE 64 +#define NB_CDBK_SIZE_LOW1 64 +#define NB_CDBK_SIZE_LOW2 64 +#define NB_CDBK_SIZE_HIGH1 64 +#define NB_CDBK_SIZE_HIGH2 64 + +/*Narrowband codebooks*/ +extern signed char cdbk_nb[]; +extern signed char cdbk_nb_low1[]; +extern signed char cdbk_nb_low2[]; +extern signed char cdbk_nb_high1[]; +extern signed char cdbk_nb_high2[]; + +/* Quantizes narrowband LSPs with 30 bits */ +void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits); + +/* Decodes quantized narrowband LSPs */ +void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits); + +/* Quantizes low bit-rate narrowband LSPs with 18 bits */ +void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits); + +/* Decodes quantized low bit-rate narrowband LSPs */ +void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits); + +/* Quantizes high-band LSPs with 12 bits */ +void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *bits); + +/* Decodes high-band LSPs */ +void lsp_unquant_high(float *lsp, int order, SpeexBits *bits); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/sb_celp.c b/engine/voice_codecs/speex/source/libspeex/sb_celp.c new file mode 100644 index 0000000..ef280d2 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/sb_celp.c @@ -0,0 +1,1333 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: sb_celp.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. +*/ + + +#include <math.h> +#include "sb_celp.h" +#include "stdlib.h" +#include "filters.h" +#include "lpc.h" +#include "lsp.h" +#include "stack_alloc.h" +#include "cb_search.h" +#include "quant_lsp.h" +#include "vq.h" +#include "ltp.h" +#include "misc.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define sqr(x) ((x)*(x)) + +#define SUBMODE(x) st->submodes[st->submodeID]->x + +#define QMF_ORDER 64 +static float h0[64] = { + 3.596189e-05, -0.0001123515, + -0.0001104587, 0.0002790277, + 0.0002298438, -0.0005953563, + -0.0003823631, 0.00113826, + 0.0005308539, -0.001986177, + -0.0006243724, 0.003235877, + 0.0005743159, -0.004989147, + -0.0002584767, 0.007367171, + -0.0004857935, -0.01050689, + 0.001894714, 0.01459396, + -0.004313674, -0.01994365, + 0.00828756, 0.02716055, + -0.01485397, -0.03764973, + 0.026447, 0.05543245, + -0.05095487, -0.09779096, + 0.1382363, 0.4600981, + 0.4600981, 0.1382363, + -0.09779096, -0.05095487, + 0.05543245, 0.026447, + -0.03764973, -0.01485397, + 0.02716055, 0.00828756, + -0.01994365, -0.004313674, + 0.01459396, 0.001894714, + -0.01050689, -0.0004857935, + 0.007367171, -0.0002584767, + -0.004989147, 0.0005743159, + 0.003235877, -0.0006243724, + -0.001986177, 0.0005308539, + 0.00113826, -0.0003823631, + -0.0005953563, 0.0002298438, + 0.0002790277, -0.0001104587, + -0.0001123515, 3.596189e-05 +}; + +static float h1[64] = { + 3.596189e-05, 0.0001123515, + -0.0001104587, -0.0002790277, + 0.0002298438, 0.0005953563, + -0.0003823631, -0.00113826, + 0.0005308539, 0.001986177, + -0.0006243724, -0.003235877, + 0.0005743159, 0.004989147, + -0.0002584767, -0.007367171, + -0.0004857935, 0.01050689, + 0.001894714, -0.01459396, + -0.004313674, 0.01994365, + 0.00828756, -0.02716055, + -0.01485397, 0.03764973, + 0.026447, -0.05543245, + -0.05095487, 0.09779096, + 0.1382363, -0.4600981, + 0.4600981, -0.1382363, + -0.09779096, 0.05095487, + 0.05543245, -0.026447, + -0.03764973, 0.01485397, + 0.02716055, -0.00828756, + -0.01994365, 0.004313674, + 0.01459396, -0.001894714, + -0.01050689, 0.0004857935, + 0.007367171, 0.0002584767, + -0.004989147, -0.0005743159, + 0.003235877, 0.0006243724, + -0.001986177, -0.0005308539, + 0.00113826, 0.0003823631, + -0.0005953563, -0.0002298438, + 0.0002790277, 0.0001104587, + -0.0001123515, -3.596189e-05 +}; + +void *sb_encoder_init(SpeexMode *m) +{ + int i; + SBEncState *st; + SpeexSBMode *mode; + + st = (SBEncState*)speex_alloc(sizeof(SBEncState)+8000*sizeof(float)); + st->mode = m; + mode = (SpeexSBMode*)m->mode; + + st->stack = ((char*)st) + sizeof(SBEncState); + + st->st_low = speex_encoder_init(mode->nb_mode); + st->full_frame_size = 2*mode->frameSize; + st->frame_size = mode->frameSize; + st->subframeSize = mode->subframeSize; + st->nbSubframes = mode->frameSize/mode->subframeSize; + st->windowSize = st->frame_size*3/2; + st->lpcSize=mode->lpcSize; + st->bufSize=mode->bufSize; + + st->submodes=mode->submodes; + st->submodeSelect = st->submodeID=mode->defaultSubmode; + + i=9; + speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &i); + + st->lag_factor = mode->lag_factor; + st->lpc_floor = mode->lpc_floor; + st->gamma1=mode->gamma1; + st->gamma2=mode->gamma2; + st->first=1; + + st->x0d=PUSH(st->stack, st->frame_size, float); + st->x1d=PUSH(st->stack, st->frame_size, float); + st->high=PUSH(st->stack, st->full_frame_size, float); + st->y0=PUSH(st->stack, st->full_frame_size, float); + st->y1=PUSH(st->stack, st->full_frame_size, float); + + st->h0_mem=PUSH(st->stack, QMF_ORDER, float); + st->h1_mem=PUSH(st->stack, QMF_ORDER, float); + st->g0_mem=PUSH(st->stack, QMF_ORDER, float); + st->g1_mem=PUSH(st->stack, QMF_ORDER, float); + + st->buf=PUSH(st->stack, st->windowSize, float); + st->excBuf=PUSH(st->stack, st->bufSize, float); + st->exc = st->excBuf + st->bufSize - st->windowSize; + + st->res=PUSH(st->stack, st->frame_size, float); + st->sw=PUSH(st->stack, st->frame_size, float); + st->target=PUSH(st->stack, st->frame_size, float); + /*Asymmetric "pseudo-Hamming" window*/ + { + int part1, part2; + part1 = st->subframeSize*7/2; + part2 = st->subframeSize*5/2; + st->window = PUSH(st->stack, st->windowSize, float); + for (i=0;i<part1;i++) + st->window[i]=.54-.46*cos(M_PI*i/part1); + for (i=0;i<part2;i++) + st->window[part1+i]=.54+.46*cos(M_PI*i/part2); + } + + st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); + for (i=0;i<st->lpcSize+1;i++) + st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + + st->rc = PUSH(st->stack, st->lpcSize, float); + st->autocorr = PUSH(st->stack, st->lpcSize+1, float); + st->lpc = PUSH(st->stack, st->lpcSize+1, float); + st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); + st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); + st->lsp = PUSH(st->stack, st->lpcSize, float); + st->qlsp = PUSH(st->stack, st->lpcSize, float); + st->old_lsp = PUSH(st->stack, st->lpcSize, float); + st->old_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_lsp = PUSH(st->stack, st->lpcSize, float); + st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); + st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); + st->pi_gain = PUSH(st->stack, st->nbSubframes, float); + + st->mem_sp = PUSH(st->stack, st->lpcSize, float); + st->mem_sp2 = PUSH(st->stack, st->lpcSize, float); + st->mem_sw = PUSH(st->stack, st->lpcSize, float); + + st->vbr_quality = 8; + st->vbr_enabled = 0; + st->vad_enabled = 0; + st->abr_enabled = 0; + st->relative_quality=0; + + st->complexity=2; + speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); + st->sampling_rate*=2; + + return st; +} + +void sb_encoder_destroy(void *state) +{ + SBEncState *st=(SBEncState*)state; + + speex_encoder_destroy(st->st_low); + + speex_free(st); +} + + +int sb_encode(void *state, float *in, SpeexBits *bits) +{ + SBEncState *st; + int i, roots, sub; + char *stack; + float *mem, *innov, *syn_resp; + float *low_pi_gain, *low_exc, *low_innov; + SpeexSBMode *mode; + int dtx; + + st = (SBEncState*)state; + stack=st->stack; + mode = (SpeexSBMode*)(st->mode->mode); + + /* Compute the two sub-bands by filtering with h0 and h1*/ + qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); + + /* Encode the narrowband part*/ + speex_encode(st->st_low, st->x0d, bits); + + /* High-band buffering / sync with low band */ + for (i=0;i<st->windowSize-st->frame_size;i++) + st->high[i] = st->high[st->frame_size+i]; + for (i=0;i<st->frame_size;i++) + st->high[st->windowSize-st->frame_size+i]=st->x1d[i]; + + speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(float)); + + + low_pi_gain = PUSH(stack, st->nbSubframes, float); + low_exc = PUSH(stack, st->frame_size, float); + low_innov = PUSH(stack, st->frame_size, float); + speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); + speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); + speex_encoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); + + speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); + + if (dtx==0) + dtx=1; + else + dtx=0; + + /* Start encoding the high-band */ + for (i=0;i<st->windowSize;i++) + st->buf[i] = st->high[i] * st->window[i]; + + /* Compute auto-correlation */ + _spx_autocorr(st->buf, st->autocorr, st->lpcSize+1, st->windowSize); + + st->autocorr[0] += 1; /* prevents NANs */ + st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;i<st->lpcSize+1;i++) + st->autocorr[i] *= st->lagWindow[i]; + + /* Levinson-Durbin */ + wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); + st->lpc[0]=1; + + /* LPC to LSPs (x-domain) transform */ + roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); + if (roots!=st->lpcSize) + { + roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.02, stack); + if (roots!=st->lpcSize) { + /*If we can't find all LSP's, do some damage control and use a flat filter*/ + for (i=0;i<st->lpcSize;i++) + { + st->lsp[i]=cos(M_PI*((float)(i+1))/(st->lpcSize+1)); + } + } + } + + /* x-domain to angle domain*/ + for (i=0;i<st->lpcSize;i++) + st->lsp[i] = acos(st->lsp[i]); + + /* VBR code */ + if ((st->vbr_enabled || st->vad_enabled) && !dtx) + { + float e_low=0, e_high=0; + float ratio; + if (st->abr_enabled) + { + float qual_change=0; + if (st->abr_drift2 * st->abr_drift > 0) + { + /* Only adapt if long-term and short-term drift are the same sign */ + qual_change = -.00001*st->abr_drift/(1+st->abr_count); + if (qual_change>.1) + qual_change=.1; + if (qual_change<-.1) + qual_change=-.1; + } + st->vbr_quality += qual_change; + if (st->vbr_quality>10) + st->vbr_quality=10; + if (st->vbr_quality<0) + st->vbr_quality=0; + } + + + for (i=0;i<st->frame_size;i++) + { + e_low += st->x0d[i]* st->x0d[i]; + e_high += st->high[i]* st->high[i]; + } + ratio = log((1+e_high)/(1+e_low)); + speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); + if (ratio<-4) + ratio=-4; + if (ratio>2) + ratio=2; + /*if (ratio>-2)*/ + if (st->vbr_enabled) + { + int modeid; + modeid = mode->nb_modes-1; + st->relative_quality+=1.0*(ratio+2); + if (st->relative_quality<-1) + st->relative_quality=-1; + while (modeid) + { + int v1; + float thresh; + v1=(int)floor(st->vbr_quality); + if (v1==10) + thresh = mode->vbr_thresh[modeid][v1]; + else + thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] + + (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1]; + if (st->relative_quality >= thresh) + break; + modeid--; + } + speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); + if (st->abr_enabled) + { + int bitrate; + speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); + st->abr_drift+=(bitrate-st->abr_enabled); + st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); + st->abr_count += 1.0; + } + + } else { + /* VAD only */ + int modeid; + if (st->relative_quality<2.0) + modeid=1; + else + modeid=st->submodeSelect; + /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ + st->submodeID=modeid; + + } + /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ + } + + speex_bits_pack(bits, 1, 1); + if (dtx) + speex_bits_pack(bits, 0, SB_SUBMODE_BITS); + else + speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS); + + /* If null mode (no transmission), just set a couple things to zero*/ + if (dtx || st->submodes[st->submodeID] == NULL) + { + for (i=0;i<st->frame_size;i++) + st->exc[i]=st->sw[i]=0; + + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=0; + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp); + +#ifndef RELEASE + + /* Reconstruct the original */ + fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); + fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); + + for (i=0;i<st->full_frame_size;i++) + in[i]=2*(st->y0[i]-st->y1[i]); +#endif + + if (dtx) + return 0; + else + return 1; + } + + + /* LSP quantization */ + SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); + + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = st->lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + } + + mem=PUSH(stack, st->lpcSize, float); + syn_resp=PUSH(stack, st->subframeSize, float); + innov = PUSH(stack, st->subframeSize, float); + + for (sub=0;sub<st->nbSubframes;sub++) + { + float *exc, *sp, *res, *target, *sw, tmp, filter_ratio; + int offset; + float rl, rh, eh=0, el=0; + int fold; + + offset = st->subframeSize*sub; + sp=st->high+offset; + exc=st->exc+offset; + res=st->res+offset; + target=st->target+offset; + sw=st->sw+offset; + + /* LSP interpolation (quantized and unquantized) */ + tmp = (1.0 + sub)/st->nbSubframes; + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; + + lsp_enforce_margin(st->interp_lsp, st->lpcSize, .05); + lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); + + /* Compute interpolated LPCs (quantized and unquantized) */ + for (i=0;i<st->lpcSize;i++) + st->interp_lsp[i] = cos(st->interp_lsp[i]); + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = cos(st->interp_qlsp[i]); + + lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); + lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + + bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); + bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); + + /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band + filters */ + rl=rh=0; + tmp=1; + st->pi_gain[sub]=0; + for (i=0;i<=st->lpcSize;i++) + { + rh += tmp*st->interp_qlpc[i]; + tmp = -tmp; + st->pi_gain[sub]+=st->interp_qlpc[i]; + } + rl = low_pi_gain[sub]; + rl=1/(fabs(rl)+.01); + rh=1/(fabs(rh)+.01); + /* Compute ratio, will help predict the gain */ + filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); + + fold = filter_ratio<5; + /*printf ("filter_ratio %f\n", filter_ratio);*/ + fold=0; + + /* Compute "real excitation" */ + fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); + /* Compute energy of low-band and high-band excitation */ + for (i=0;i<st->subframeSize;i++) + eh+=sqr(exc[i]); + + if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ + float g; + /*speex_bits_pack(bits, 1, 1);*/ + for (i=0;i<st->subframeSize;i++) + el+=sqr(low_innov[offset+i]); + + /* Gain to use if we want to use the low-band excitation for high-band */ + g=eh/(.01+el); + g=sqrt(g); + + g *= filter_ratio; + /*print_vec(&g, 1, "gain factor");*/ + /* Gain quantization */ + { + int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001))); + /*speex_warning_int("tata", quant);*/ + if (quant<0) + quant=0; + if (quant>31) + quant=31; + speex_bits_pack(bits, quant, 5); + g= .1*exp(quant/9.4); + } + /*printf ("folding gain: %f\n", g);*/ + g /= filter_ratio; + + } else { + float gc, scale, scale_1; + + for (i=0;i<st->subframeSize;i++) + el+=sqr(low_exc[offset+i]); + /*speex_bits_pack(bits, 0, 1);*/ + + gc = sqrt(1+eh)*filter_ratio/sqrt((1+el)*st->subframeSize); + { + int qgc = (int)floor(.5+3.7*(log(gc)+2)); + if (qgc<0) + qgc=0; + if (qgc>15) + qgc=15; + speex_bits_pack(bits, qgc, 4); + gc = exp((1/3.7)*qgc-2); + } + + scale = gc*sqrt(1+el)/filter_ratio; + scale_1 = 1/scale; + + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + exc[0]=1; + syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); + + /* Reset excitation */ + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + + /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); + + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); + + /* Compute weighted signal */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); + + /* Compute target signal */ + for (i=0;i<st->subframeSize;i++) + target[i]=sw[i]-res[i]; + + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + + + for (i=0;i<st->subframeSize;i++) + target[i]*=scale_1; + + /* Reset excitation */ + for (i=0;i<st->subframeSize;i++) + innov[i]=0; + + /*print_vec(target, st->subframeSize, "\ntarget");*/ + SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov, syn_resp, bits, stack, (st->complexity+1)>>1); + /*print_vec(target, st->subframeSize, "after");*/ + + for (i=0;i<st->subframeSize;i++) + exc[i] += innov[i]*scale; + + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + float *innov2 = PUSH(tmp_stack, st->subframeSize, float); + for (i=0;i<st->subframeSize;i++) + innov2[i]=0; + for (i=0;i<st->subframeSize;i++) + target[i]*=2.5; + SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov2, syn_resp, bits, tmp_stack, (st->complexity+1)>>1); + for (i=0;i<st->subframeSize;i++) + innov2[i]*=scale*(1/2.5); + for (i=0;i<st->subframeSize;i++) + exc[i] += innov2[i]; + } + + } + + /*Keep the previous memory*/ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + /* Final signal synthesis from excitation */ + iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); + + /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ + filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); + } + + +#ifndef RELEASE + + /* Reconstruct the original */ + fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); + fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); + + for (i=0;i<st->full_frame_size;i++) + in[i]=2*(st->y0[i]-st->y1[i]); +#endif + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = st->lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + + st->first=0; + + return 1; +} + + + + + +void *sb_decoder_init(SpeexMode *m) +{ + SBDecState *st; + SpeexSBMode *mode; + st = (SBDecState*)speex_alloc(sizeof(SBDecState)+6000*sizeof(float)); + st->mode = m; + mode=(SpeexSBMode*)m->mode; + + st->stack = ((char*)st) + sizeof(SBDecState); + + + + st->st_low = speex_decoder_init(mode->nb_mode); + st->full_frame_size = 2*mode->frameSize; + st->frame_size = mode->frameSize; + st->subframeSize = mode->subframeSize; + st->nbSubframes = mode->frameSize/mode->subframeSize; + st->lpcSize=8; + speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); + st->sampling_rate*=2; + + st->submodes=mode->submodes; + st->submodeID=mode->defaultSubmode; + + st->first=1; + + + st->x0d=PUSH(st->stack, st->frame_size, float); + st->x1d=PUSH(st->stack, st->frame_size, float); + st->high=PUSH(st->stack, st->full_frame_size, float); + st->y0=PUSH(st->stack, st->full_frame_size, float); + st->y1=PUSH(st->stack, st->full_frame_size, float); + + st->h0_mem=PUSH(st->stack, QMF_ORDER, float); + st->h1_mem=PUSH(st->stack, QMF_ORDER, float); + st->g0_mem=PUSH(st->stack, QMF_ORDER, float); + st->g1_mem=PUSH(st->stack, QMF_ORDER, float); + + st->exc=PUSH(st->stack, st->frame_size, float); + + st->qlsp = PUSH(st->stack, st->lpcSize, float); + st->old_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); + st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); + + st->pi_gain = PUSH(st->stack, st->nbSubframes, float); + st->mem_sp = PUSH(st->stack, 2*st->lpcSize, float); + + st->lpc_enh_enabled=0; + + return st; +} + +void sb_decoder_destroy(void *state) +{ + SBDecState *st; + st = (SBDecState*)state; + speex_decoder_destroy(st->st_low); + + speex_free(state); +} + +static void sb_decode_lost(SBDecState *st, float *out, int dtx, char *stack) +{ + int i; + float *awk1, *awk2, *awk3; + int saved_modeid=0; + + if (dtx) + { + saved_modeid=st->submodeID; + st->submodeID=1; + } else { + bw_lpc(0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize); + } + + st->first=1; + + awk1=PUSH(stack, st->lpcSize+1, float); + awk2=PUSH(stack, st->lpcSize+1, float); + awk3=PUSH(stack, st->lpcSize+1, float); + + if (st->lpc_enh_enabled) + { + float r=.9; + + float k1,k2,k3; + if (st->submodes[st->submodeID] != NULL) + { + k1=SUBMODE(lpc_enh_k1); + k2=SUBMODE(lpc_enh_k2); + } else { + k1=k2=.7; + } + k3=(1-(1-r*k1)/(1-r*k2))/r; + k3=k1-k2; + if (!st->lpc_enh_enabled) + { + k1=k2; + k3=0; + } + bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); + bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); + bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); + /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ + } + + + /* Final signal synthesis from excitation */ + if (!dtx) + { + for (i=0;i<st->frame_size;i++) + st->exc[i] *= .9; + } + + for (i=0;i<st->frame_size;i++) + st->high[i]=st->exc[i]; + + if (st->lpc_enh_enabled) + { + /* Use enhanced LPC filter */ + filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize, + st->mem_sp+st->lpcSize); + filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, + st->mem_sp); + } else { + /* Use regular filter */ + for (i=0;i<st->lpcSize;i++) + st->mem_sp[st->lpcSize+i] = 0; + iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, + st->mem_sp); + } + + /*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/ + + /* Reconstruct the original */ + fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); + fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); + + for (i=0;i<st->full_frame_size;i++) + out[i]=2*(st->y0[i]-st->y1[i]); + + if (dtx) + { + st->submodeID=saved_modeid; + } + + return; +} + +int sb_decode(void *state, SpeexBits *bits, float *out) +{ + int i, sub; + SBDecState *st; + int wideband; + int ret; + char *stack; + float *low_pi_gain, *low_exc, *low_innov; + float *awk1, *awk2, *awk3; + int dtx; + SpeexSBMode *mode; + + st = (SBDecState*)state; + stack=st->stack; + mode = (SpeexSBMode*)(st->mode->mode); + + /* Decode the low-band */ + ret = speex_decode(st->st_low, bits, st->x0d); + + speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx); + + /* If error decoding the narrowband part, propagate error */ + if (ret!=0) + { + return ret; + } + + if (!bits) + { + sb_decode_lost(st, out, dtx, stack); + return 0; + } + + /*Check "wideband bit"*/ + if (speex_bits_remaining(bits)>0) + wideband = speex_bits_peek(bits); + else + wideband = 0; + if (wideband) + { + /*Regular wideband frame, read the submode*/ + wideband = speex_bits_unpack_unsigned(bits, 1); + st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); + } else + { + /*Was a narrowband frame, set "null submode"*/ + st->submodeID = 0; + } + if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL) + { + speex_warning("Invalid mode encountered: corrupted stream?"); + return -2; + } + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + if (dtx) + { + sb_decode_lost(st, out, 1, stack); + return 0; + } + + for (i=0;i<st->frame_size;i++) + st->exc[i]=0; + + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp); + + fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); + fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); + + for (i=0;i<st->full_frame_size;i++) + out[i]=2*(st->y0[i]-st->y1[i]); + + return 0; + + } + + for (i=0;i<st->frame_size;i++) + st->exc[i]=0; + + low_pi_gain = PUSH(stack, st->nbSubframes, float); + low_exc = PUSH(stack, st->frame_size, float); + low_innov = PUSH(stack, st->frame_size, float); + speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); + speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); + speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); + + SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); + + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + } + + awk1=PUSH(stack, st->lpcSize+1, float); + awk2=PUSH(stack, st->lpcSize+1, float); + awk3=PUSH(stack, st->lpcSize+1, float); + + for (sub=0;sub<st->nbSubframes;sub++) + { + float *exc, *sp, tmp, filter_ratio, el=0; + int offset; + float rl=0,rh=0; + + offset = st->subframeSize*sub; + sp=st->high+offset; + exc=st->exc+offset; + + /* LSP interpolation */ + tmp = (1.0 + sub)/st->nbSubframes; + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; + + lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); + + /* LSPs to x-domain */ + for (i=0;i<st->lpcSize;i++) + st->interp_qlsp[i] = cos(st->interp_qlsp[i]); + + /* LSP to LPC */ + lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + + + if (st->lpc_enh_enabled) + { + float r=.9; + + float k1,k2,k3; + k1=SUBMODE(lpc_enh_k1); + k2=SUBMODE(lpc_enh_k2); + k3=(1-(1-r*k1)/(1-r*k2))/r; + k3=k1-k2; + if (!st->lpc_enh_enabled) + { + k1=k2; + k3=0; + } + bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); + bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); + bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); + /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ + } + + + /* Calculate reponse ratio between the low and high filter in the middle + of the band (4000 Hz) */ + + tmp=1; + st->pi_gain[sub]=0; + for (i=0;i<=st->lpcSize;i++) + { + rh += tmp*st->interp_qlpc[i]; + tmp = -tmp; + st->pi_gain[sub]+=st->interp_qlpc[i]; + } + rl = low_pi_gain[sub]; + rl=1/(fabs(rl)+.01); + rh=1/(fabs(rh)+.01); + filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); + + + for (i=0;i<st->subframeSize;i++) + exc[i]=0; + if (!SUBMODE(innovation_unquant)) + { + float g; + int quant; + + for (i=0;i<st->subframeSize;i++) + el+=sqr(low_innov[offset+i]); + quant = speex_bits_unpack_unsigned(bits, 5); + g= exp(((float)quant-10)/8.0); + + /*printf ("unquant folding gain: %f\n", g);*/ + g /= filter_ratio; + + /* High-band excitation using the low-band excitation and a gain */ + for (i=0;i<st->subframeSize;i++) + exc[i]=mode->folding_gain*g*low_innov[offset+i]; + /*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/ + } else { + float gc, scale; + int qgc = speex_bits_unpack_unsigned(bits, 4); + for (i=0;i<st->subframeSize;i++) + el+=sqr(low_exc[offset+i]); + + + gc = exp((1/3.7)*qgc-2); + + scale = gc*sqrt(1+el)/filter_ratio; + + + SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, + bits, stack); + for (i=0;i<st->subframeSize;i++) + exc[i]*=scale; + + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + float *innov2 = PUSH(tmp_stack, st->subframeSize, float); + for (i=0;i<st->subframeSize;i++) + innov2[i]=0; + SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, + bits, tmp_stack); + for (i=0;i<st->subframeSize;i++) + innov2[i]*=scale*(1/2.5); + for (i=0;i<st->subframeSize;i++) + exc[i] += innov2[i]; + } + + } + + for (i=0;i<st->subframeSize;i++) + sp[i]=exc[i]; + if (st->lpc_enh_enabled) + { + /* Use enhanced LPC filter */ + filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, + st->mem_sp+st->lpcSize); + filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } else { + /* Use regular filter */ + for (i=0;i<st->lpcSize;i++) + st->mem_sp[st->lpcSize+i] = 0; + iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp); + } + /*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/ + + } + + fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); + fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); + + for (i=0;i<st->full_frame_size;i++) + out[i]=2*(st->y0[i]-st->y1[i]); + + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = st->qlsp[i]; + + st->first=0; + + return 0; +} + + +int sb_encoder_ctl(void *state, int request, void *ptr) +{ + SBEncState *st; + st=(SBEncState*)state; + switch(request) + { + case SPEEX_GET_FRAME_SIZE: + (*(int*)ptr) = st->full_frame_size; + break; + case SPEEX_SET_HIGH_MODE: + st->submodeSelect = st->submodeID = (*(int*)ptr); + break; + case SPEEX_SET_LOW_MODE: + speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr); + break; + case SPEEX_SET_DTX: + speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr); + break; + case SPEEX_GET_DTX: + speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr); + break; + case SPEEX_GET_LOW_MODE: + speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); + break; + case SPEEX_SET_MODE: + speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr); + break; + case SPEEX_SET_VBR: + st->vbr_enabled = (*(int*)ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr); + break; + case SPEEX_GET_VBR: + (*(int*)ptr) = st->vbr_enabled; + break; + case SPEEX_SET_VAD: + st->vad_enabled = (*(int*)ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr); + break; + case SPEEX_GET_VAD: + (*(int*)ptr) = st->vad_enabled; + break; + case SPEEX_SET_VBR_QUALITY: + { + int q; + float qual = (*(float*)ptr)+.6; + st->vbr_quality = (*(float*)ptr); + if (qual>10) + qual=10; + q=(int)floor(.5+*(float*)ptr); + if (q>10) + q=10; + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual); + speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q); + break; + } + case SPEEX_SET_ABR: + st->abr_enabled = (*(int*)ptr); + st->vbr_enabled = 1; + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled); + { + int i=10, rate, target; + float vbr_qual; + target = (*(int*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + vbr_qual=i; + if (vbr_qual<0) + vbr_qual=0; + speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); + st->abr_count=0; + st->abr_drift=0; + st->abr_drift2=0; + } + + break; + case SPEEX_GET_ABR: + (*(int*)ptr) = st->abr_enabled; + break; + case SPEEX_SET_QUALITY: + { + int nb_qual; + int quality = (*(int*)ptr); + if (quality < 0) + quality = 0; + if (quality > 10) + quality = 10; + st->submodeSelect = st->submodeID = ((SpeexSBMode*)(st->mode->mode))->quality_map[quality]; + nb_qual = ((SpeexSBMode*)(st->mode->mode))->low_quality_map[quality]; + speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual); + } + break; + case SPEEX_SET_COMPLEXITY: + speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr); + st->complexity = (*(int*)ptr); + if (st->complexity<1) + st->complexity=1; + break; + case SPEEX_GET_COMPLEXITY: + (*(int*)ptr) = st->complexity; + break; + case SPEEX_SET_BITRATE: + { + int i=10, rate, target; + target = (*(int*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + } + break; + case SPEEX_GET_BITRATE: + speex_encoder_ctl(st->st_low, request, ptr); + /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/ + if (st->submodes[st->submodeID]) + (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; + else + (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; + /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/ + break; + case SPEEX_SET_SAMPLING_RATE: + { + int tmp=(*(int*)ptr); + st->sampling_rate = tmp; + tmp>>=1; + speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); + } + break; + case SPEEX_GET_SAMPLING_RATE: + (*(int*)ptr)=st->sampling_rate; + break; + case SPEEX_RESET_STATE: + { + int i; + st->first = 1; + for (i=0;i<st->lpcSize;i++) + st->lsp[i]=(M_PI*((float)(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<st->bufSize;i++) + st->excBuf[i]=0; + for (i=0;i<QMF_ORDER;i++) + st->h0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; + } + break; + case SPEEX_GET_PI_GAIN: + { + int i; + float *g = (float*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->full_frame_size;i++) + e[i]=0; + for (i=0;i<st->frame_size;i++) + e[2*i]=2*st->exc[i]; + } + break; + case SPEEX_GET_INNOV: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->full_frame_size;i++) + e[i]=0; + for (i=0;i<st->frame_size;i++) + e[2*i]=2*st->exc[i]; + } + break; + case SPEEX_GET_RELATIVE_QUALITY: + (*(float*)ptr)=st->relative_quality; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} + +int sb_decoder_ctl(void *state, int request, void *ptr) +{ + SBDecState *st; + st=(SBDecState*)state; + switch(request) + { + case SPEEX_GET_LOW_MODE: + speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); + break; + case SPEEX_GET_FRAME_SIZE: + (*(int*)ptr) = st->full_frame_size; + break; + case SPEEX_SET_ENH: + speex_decoder_ctl(st->st_low, request, ptr); + st->lpc_enh_enabled = *((int*)ptr); + break; + case SPEEX_GET_BITRATE: + speex_decoder_ctl(st->st_low, request, ptr); + if (st->submodes[st->submodeID]) + (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; + else + (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; + break; + case SPEEX_SET_SAMPLING_RATE: + { + int tmp=(*(int*)ptr); + st->sampling_rate = tmp; + tmp>>=1; + speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); + } + break; + case SPEEX_GET_SAMPLING_RATE: + (*(int*)ptr)=st->sampling_rate; + break; + case SPEEX_SET_HANDLER: + speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr); + break; + case SPEEX_SET_USER_HANDLER: + speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr); + break; + case SPEEX_RESET_STATE: + { + int i; + for (i=0;i<2*st->lpcSize;i++) + st->mem_sp[i]=0; + for (i=0;i<QMF_ORDER;i++) + st->h0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; + } + break; + case SPEEX_GET_PI_GAIN: + { + int i; + float *g = (float*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->full_frame_size;i++) + e[i]=0; + for (i=0;i<st->frame_size;i++) + e[2*i]=2*st->exc[i]; + } + break; + case SPEEX_GET_INNOV: + { + int i; + float *e = (float*)ptr; + for (i=0;i<st->full_frame_size;i++) + e[i]=0; + for (i=0;i<st->frame_size;i++) + e[2*i]=2*st->exc[i]; + } + break; + case SPEEX_GET_DTX_STATUS: + speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr); + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} diff --git a/engine/voice_codecs/speex/source/libspeex/sb_celp.h b/engine/voice_codecs/speex/source/libspeex/sb_celp.h new file mode 100644 index 0000000..64b23ee --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/sb_celp.h @@ -0,0 +1,167 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file sb_celp.h + @brief Sub-band CELP mode used for wideband encoding +*/ +/* + 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 SB_CELP_H +#define SB_CELP_H + +#include "modes.h" +#include "speex_bits.h" +#include "nb_celp.h" + +/**Structure representing the full state of the sub-band encoder*/ +typedef struct SBEncState { + SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ + void *st_low; /**< State of the low-band (narrowband) encoder */ + int full_frame_size; /**< Length of full-band frames*/ + int frame_size; /**< Length of high-band frames*/ + int subframeSize; /**< Length of high-band sub-frames*/ + 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 */ + float lpc_floor; /**< Controls LPC analysis noise floor */ + float gamma1; /**< Perceptual weighting coef 1 */ + float gamma2; /**< Perceptual weighting coef 2 */ + + char *stack; /**< Temporary allocation stack */ + float *x0d, *x1d; /**< QMF filter signals*/ + float *high; /**< High-band signal (buffer) */ + float *y0, *y1; /**< QMF synthesis signals */ + float *h0_mem, *h1_mem, *g0_mem, *g1_mem; /**< QMF memories */ + + float *excBuf; /**< High-band excitation */ + float *exc; /**< High-band excitation (for QMF only)*/ + float *buf; /**< Temporary buffer */ + float *res; /**< Zero-input response (ringing) */ + float *sw; /**< Perceptually weighted signal */ + float *target; /**< Weighted target signal (analysis by synthesis) */ + float *window; /**< LPC analysis window */ + float *lagWindow; /**< Auto-correlation window */ + float *autocorr; /**< Auto-correlation (for LPC analysis) */ + float *rc; /**< Reflection coefficients (unused) */ + float *lpc; /**< LPC coefficients */ + float *lsp; /**< LSP coefficients */ + float *qlsp; /**< Quantized LSPs */ + float *old_lsp; /**< LSPs of previous frame */ + float *old_qlsp; /**< Quantized LSPs of previous frame */ + float *interp_lsp; /**< Interpolated LSPs for current sub-frame */ + float *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */ + float *interp_lpc; /**< Interpolated LPCs for current sub-frame */ + float *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ + float *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */ + float *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */ + + float *mem_sp; /**< Synthesis signal memory */ + float *mem_sp2; + float *mem_sw; /**< Perceptual signal memory */ + float *pi_gain; + + float vbr_quality; /**< Quality setting for VBR encoding */ + int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ + int abr_enabled; /**< ABR setting (in bps), 0 if off */ + float abr_drift; + float abr_drift2; + float abr_count; + int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ + float relative_quality; + + SpeexSubmode **submodes; + int submodeID; + int submodeSelect; + int complexity; + int sampling_rate; + +} SBEncState; + + +/**Structure representing the full state of the sub-band decoder*/ +typedef struct SBDecState { + SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ + void *st_low; /**< State of the low-band (narrowband) encoder */ + int full_frame_size; + int frame_size; + int subframeSize; + int nbSubframes; + int lpcSize; + int first; + int sampling_rate; + int lpc_enh_enabled; + + char *stack; + float *x0d, *x1d; + float *high; + float *y0, *y1; + float *h0_mem, *h1_mem, *g0_mem, *g1_mem; + + float *exc; + float *qlsp; + float *old_qlsp; + float *interp_qlsp; + float *interp_qlpc; + + float *mem_sp; + float *pi_gain; + + SpeexSubmode **submodes; + int submodeID; +} SBDecState; + + +/**Initializes encoder state*/ +void *sb_encoder_init(SpeexMode *m); + +/**De-allocates encoder state resources*/ +void sb_encoder_destroy(void *state); + +/**Encodes one frame*/ +int sb_encode(void *state, float *in, SpeexBits *bits); + + +/**Initializes decoder state*/ +void *sb_decoder_init(SpeexMode *m); + +/**De-allocates decoder state resources*/ +void sb_decoder_destroy(void *state); + +/**Decodes one frame*/ +int sb_decode(void *state, SpeexBits *bits, float *out); + +int sb_encoder_ctl(void *state, int request, void *ptr); + +int sb_decoder_ctl(void *state, int request, void *ptr); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex.h b/engine/voice_codecs/speex/source/libspeex/speex.h new file mode 100644 index 0000000..cafd0cd --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex.h @@ -0,0 +1,331 @@ +/* Copyright (C) 2002 Jean-Marc Valin*/ +/** + @file speex.h + @brief Describes the different 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. + +*/ + +#ifndef SPEEX_H +#define SPEEX_H + +#include "speex_bits.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Values allowed for *ctl() requests */ + +/** Set enhancement on/off (decoder only) */ +#define SPEEX_SET_ENH 0 +/** Get enhancement state (decoder only) */ +#define SPEEX_GET_ENH 1 + +/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/ +/** Obtain frame size used by encoder/decoder */ +#define SPEEX_GET_FRAME_SIZE 3 + +/** Set quality value */ +#define SPEEX_SET_QUALITY 4 +/** Get current quality setting */ +#define SPEEX_GET_QUALITY 5 + +/** Set sub-mode to use */ +#define SPEEX_SET_MODE 6 +/** Get current sub-mode in use */ +#define SPEEX_GET_MODE 7 + +/** Set low-band sub-mode to use (wideband only)*/ +#define SPEEX_SET_LOW_MODE 8 +/** Get current low-band mode in use (wideband only)*/ +#define SPEEX_GET_LOW_MODE 9 + +/** Set high-band sub-mode to use (wideband only)*/ +#define SPEEX_SET_HIGH_MODE 10 +/** Get current high-band mode in use (wideband only)*/ +#define SPEEX_GET_HIGH_MODE 11 + +/** Set VBR on (1) or off (0) */ +#define SPEEX_SET_VBR 12 +/** Get VBR status (1 for on, 0 for off) */ +#define SPEEX_GET_VBR 13 + +/** Set quality value for VBR encoding (0-10) */ +#define SPEEX_SET_VBR_QUALITY 14 +/** Get current quality value for VBR encoding (0-10) */ +#define SPEEX_GET_VBR_QUALITY 15 + +/** Set complexity of the encoder (0-10) */ +#define SPEEX_SET_COMPLEXITY 16 +/** Get current complexity of the encoder (0-10) */ +#define SPEEX_GET_COMPLEXITY 17 + +/** Set bit-rate used by the encoder (or lower) */ +#define SPEEX_SET_BITRATE 18 +/** Get current bit-rate used by the encoder or decoder */ +#define SPEEX_GET_BITRATE 19 + +/**Define a handler function for in-band Speex request*/ +#define SPEEX_SET_HANDLER 20 + +/**Define a handler function for in-band user-defined request*/ +#define SPEEX_SET_USER_HANDLER 22 + +/** Set sampling rate used in bit-rate computation */ +#define SPEEX_SET_SAMPLING_RATE 24 +/** Get sampling rate used in bit-rate computation */ +#define SPEEX_GET_SAMPLING_RATE 25 + +/** Reset the encoder/decoder memories to zero*/ +#define SPEEX_RESET_STATE 26 + +/** Get VBR info (mostly used internally) */ +#define SPEEX_GET_RELATIVE_QUALITY 29 + +/** Set VAD status (1 for on, 0 for off) */ +#define SPEEX_SET_VAD 30 + +/** Get VAD status (1 for on, 0 for off) */ +#define SPEEX_GET_VAD 31 + +/** Set Average Bit-Rate (ABR) to n bits per seconds */ +#define SPEEX_SET_ABR 32 +/** Get Average Bit-Rate (ABR) setting (in bps) */ +#define SPEEX_GET_ABR 33 + +/** Set DTX status (1 for on, 0 for off) */ +#define SPEEX_SET_DTX 34 +/** Get DTX status (1 for on, 0 for off) */ +#define SPEEX_GET_DTX 35 + + +/* Used internally, not to be used in applications */ +/** Used internally*/ +#define SPEEX_GET_PI_GAIN 100 +/** Used internally*/ +#define SPEEX_GET_EXC 101 +/** Used internally*/ +#define SPEEX_GET_INNOV 102 +/** Used internally*/ +#define SPEEX_GET_DTX_STATUS 103 + + +/* Preserving compatibility:*/ +/** Equivalent to SPEEX_SET_ENH */ +#define SPEEX_SET_PF 0 +/** Equivalent to SPEEX_GET_ENH */ +#define SPEEX_GET_PF 1 + + +/* Values allowed for mode queries */ +/** Query the frame size of a mode */ +#define SPEEX_MODE_FRAME_SIZE 0 + +/** Query the size of an encoded frame for a particular sub-mode */ +#define SPEEX_SUBMODE_BITS_PER_FRAME 1 + + +/** Number of defined modes in Speex */ +#define SPEEX_NB_MODES 3 + +struct SpeexMode; + + +/* Prototypes for mode function pointers */ + +/** Encoder state initialization function */ +typedef void *(*encoder_init_func)(struct SpeexMode *mode); + +/** Encoder state destruction function */ +typedef void (*encoder_destroy_func)(void *st); + +/** Main encoding function */ +typedef int (*encode_func)(void *state, float *in, SpeexBits *bits); + +/** Function for controlling the encoder options */ +typedef int (*encoder_ctl_func)(void *state, int request, void *ptr); + +/** Decoder state initialization function */ +typedef void *(*decoder_init_func)(struct SpeexMode *mode); + +/** Decoder state destruction function */ +typedef void (*decoder_destroy_func)(void *st); + +/** Main decoding function */ +typedef int (*decode_func)(void *state, SpeexBits *bits, float *out); + +/** Function for controlling the decoder options */ +typedef int (*decoder_ctl_func)(void *state, int request, void *ptr); + + +/** Query function for a mode */ +typedef int (*mode_query_func)(void *mode, int request, void *ptr); + +/** Struct defining a Speex mode */ +typedef struct SpeexMode { + /** Pointer to the low-level mode data */ + void *mode; + + /** Pointer to the mode query function */ + mode_query_func query; + + /** The name of the mode (you should not rely on this to identify the mode)*/ + char *modeName; + + /**ID of the mode*/ + int modeID; + + /**Version number of the bitstream (incremented every time we break + bitstream compatibility*/ + int bitstream_version; + + /** Pointer to encoder initialization function */ + encoder_init_func enc_init; + + /** Pointer to encoder destruction function */ + encoder_destroy_func enc_destroy; + + /** Pointer to frame encoding function */ + encode_func enc; + + /** Pointer to decoder initialization function */ + decoder_init_func dec_init; + + /** Pointer to decoder destruction function */ + decoder_destroy_func dec_destroy; + + /** Pointer to frame decoding function */ + decode_func dec; + + /** ioctl-like requests for encoder */ + encoder_ctl_func enc_ctl; + + /** ioctl-like requests for decoder */ + decoder_ctl_func dec_ctl; + +} SpeexMode; + +/** + * Returns a handle to a newly created Speex encoder state structure. For now, + * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes + * may be added. Note that for now if you have more than one channels to + * encode, you need one state per channel. + * + * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) + * @return A newly created encoder + */ +void *speex_encoder_init(SpeexMode *mode); + +/** Frees all resources associated to an existing Speex encoder state. + * @param state Encoder state to be destroyed */ +void speex_encoder_destroy(void *state); + +/** Uses an existing encoder state to encode one frame of speech pointed to by + "in". The encoded bit-stream is saved in "bits". + @param state Encoder state + @param in Frame that will be encoded with a +-2^16 range + @param bits Bit-stream where the data will be written + */ +int speex_encode(void *state, float *in, SpeexBits *bits); + +/** Used like the ioctl function to control the encoder parameters + * + * @param state Encoder state + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if frame needs not be transmitted (DTX only), 1 otherwise + */ +int speex_encoder_ctl(void *state, int request, void *ptr); + + +/** Returns a handle to a newly created decoder state structure. For now, + * the mode argument can be &nb_mode or &wb_mode . In the future, more modes + * may be added. Note that for now if you have more than one channels to + * decode, you need one state per channel. + * + * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) + * @return A newly created decoder state + */ +void *speex_decoder_init(SpeexMode *mode); + +/** Frees all resources associated to an existing decoder state. + * + * @param state State to be destroyed + */ +void speex_decoder_destroy(void *state); + +/** Uses an existing decoder state to decode one frame of speech from + * bit-stream bits. The output speech is saved written to out. + * + * @param state Decoder state + * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) + * @param out Where to write the decoded frame + * @return return status (0 for no error, -1 for end of stream, -2 other) + */ +int speex_decode(void *state, SpeexBits *bits, float *out); + +/** Used like the ioctl function to control the encoder parameters + * + * @param state Decoder state + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + * @return 0 for no error, 1 if a terminator is reached, 2 for another error + */ +int speex_decoder_ctl(void *state, int request, void *ptr); + + +/** Query function for mode information + * + * @param mode Speex mode + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + */ +int speex_mode_query(SpeexMode *mode, int request, void *ptr); + + +/** Default narrowband mode */ +extern SpeexMode speex_nb_mode; + +/** Default wideband mode */ +extern SpeexMode speex_wb_mode; + +/** Default "ultra-wideband" mode */ +extern SpeexMode speex_uwb_mode; + +/** List of all modes available */ +extern SpeexMode *speex_mode_list[SPEEX_NB_MODES]; + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_bits.h b/engine/voice_codecs/speex/source/libspeex/speex_bits.h new file mode 100644 index 0000000..b41fdad --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_bits.h @@ -0,0 +1,154 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_bits.h + @brief Handles bit packing/unpacking +*/ +/* + 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 BITS_H +#define BITS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Maximum size of the bit-stream (for fixed-size allocation) */ +#define MAX_BYTES_PER_FRAME 2000 + +/** Bit-packing data structure representing (part of) a bit-stream. */ +typedef struct SpeexBits { + char *bytes; /**< "raw" data */ + int nbBits; /**< Total number of bits stored in the stream*/ + int bytePtr; /**< Position of the byte "cursor" */ + int bitPtr; /**< Position of the bit "cursor" within the current byte */ + int owner; /**< Does the struct "own" the "raw" buffer (member "bytes") */ + int overflow;/**< Set to one if we try to read past the valid data */ + int buf_size;/**< Allocated size for buffer */ + int reserved1; /**< Reserved for future use */ + void *reserved2; /**< Reserved for future use */ +} SpeexBits; + +/** Initializes and allocates resources for a SpeexBits struct */ +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); + +/** 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); + +/** Resets bits to initial value (just after initialization, erasing content)*/ +void speex_bits_reset(SpeexBits *bits); + +/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */ +void speex_bits_rewind(SpeexBits *bits); + +/** Initializes the bit-stream from the data in an area of memory */ +void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); + +/** Append bytes to the bit-stream + * @param bits Bit-stream to operate on + * @param bytes pointer to the bytes what will be appended + * @param len Number of bytes of append + */ +void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); + +/** Write the content of a bit-stream to an area of memory */ +int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); + +/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ +int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len); + +/** Append bits to the bit-stream + * @param bits Bit-stream to operate on + * @param data Value to append as integer + * @param nbBits number of bits to consider in "data" + */ +void speex_bits_pack(SpeexBits *bits, int data, int nbBits); + +/** Interpret the next bits in the bit-stream as a signed integer + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to interpret + * @return A signed integer represented by the bits read + */ +int speex_bits_unpack_signed(SpeexBits *bits, int nbBits); + +/** Interpret the next bits in the bit-stream as an unsigned integer + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to interpret + * @return An unsigned integer represented by the bits read + */ +unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); + +/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full" + * + * @param bits Bit-stream to operate on + * @return Number of bytes in the stream + */ +int speex_bits_nbytes(SpeexBits *bits); + +/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */ +unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); + +/** Get the value of the next bit in the stream, without modifying the + * "cursor" position + * + * @param bits Bit-stream to operate on + */ +int speex_bits_peek(SpeexBits *bits); + +/** Advances the position of the "bit cursor" in the stream + * + * @param bits Bit-stream to operate on + * @param n Number of bits to advance + */ +void speex_bits_advance(SpeexBits *bits, int n); + +/** Returns the number of bits remaining to be read in a stream + * + * @param bits Bit-stream to operate on + */ +int speex_bits_remaining(SpeexBits *bits); + +/** Insert a terminator so that the data can be sent as a packet while auto-detecting + * the number of frames in each packet + * + * @param bits Bit-stream to operate on + */ +void speex_bits_insert_terminator(SpeexBits *bits); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c b/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c new file mode 100644 index 0000000..3b48696 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File speex_callbacks.c + Callback handling and in-band signalling + + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "speex_callbacks.h" +#include "misc.h" + +int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) +{ + int id; + SpeexCallback *callback; + /*speex_bits_advance(bits, 5);*/ + id=speex_bits_unpack_unsigned(bits, 4); + callback = callback_list+id; + + if (callback->func) + { + return callback->func(bits, state, callback->data); + } else + /*If callback is not registered, skip the right number of bits*/ + { + int adv; + if (id<2) + adv = 1; + else if (id<8) + adv = 4; + else if (id<10) + adv = 8; + else if (id<12) + adv = 16; + else if (id<14) + adv = 32; + else + adv = 64; + speex_bits_advance(bits, adv); + } + return 0; +} + +int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + int m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_MODE, &m); + return 0; +} + +int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + int m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m); + return 0; +} + +int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + int m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m); + return 0; +} + +int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) +{ + int vbr; + vbr = speex_bits_unpack_unsigned(bits, 1); + speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr); + return 0; +} + +int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) +{ + int enh; + enh = speex_bits_unpack_unsigned(bits, 1); + speex_decoder_ctl(data, SPEEX_SET_ENH, &enh); + return 0; +} + +int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) +{ + int qual; + qual = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual); + return 0; +} + + +int speex_std_char_handler(SpeexBits *bits, void *state, void *data) +{ + unsigned char ch; + ch = speex_bits_unpack_unsigned(bits, 8); + _speex_putc(ch, data); + return 0; +} + + + +/* Default handler for user callbacks: skip it */ +int speex_default_user_handler(SpeexBits *bits, void *state, void *data) +{ + int req_size = speex_bits_unpack_unsigned(bits, 4); + speex_bits_advance(bits, 5+8*req_size); + return 0; +} diff --git a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.h b/engine/voice_codecs/speex/source/libspeex/speex_callbacks.h new file mode 100644 index 0000000..f6334f2 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_callbacks.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2002 Jean-Marc Valin*/ +/** + @file speex_callbacks.h + @brief Describes callback handling and in-band signalling +*/ +/* + 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 SPEEX_CALLBACKS_H +#define SPEEX_CALLBACKS_H + +#include "speex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Total number of callbacks */ +#define SPEEX_MAX_CALLBACKS 16 + +/* Describes all the in-band requests */ + +/*These are 1-bit requests*/ +/** Request for perceptual enhancement (1 for on, 0 for off) */ +#define SPEEX_INBAND_ENH_REQUEST 0 +/** Reserved */ +#define SPEEX_INBAND_RESERVED1 1 + +/*These are 4-bit requests*/ +/** Request for a mode change */ +#define SPEEX_INBAND_MODE_REQUEST 2 +/** Request for a low mode change */ +#define SPEEX_INBAND_LOW_MODE_REQUEST 3 +/** Request for a high mode change */ +#define SPEEX_INBAND_HIGH_MODE_REQUEST 4 +/** Request for VBR (1 on, 0 off) */ +#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5 +/** Request to be sent acknowledge */ +#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6 +/** Request for VBR (1 for on, 0 for off) */ +#define SPEEX_INBAND_VBR_REQUEST 7 + +/*These are 8-bit requests*/ +/** Send a character in-band */ +#define SPEEX_INBAND_CHAR 8 +/** Intensity stereo information */ +#define SPEEX_INBAND_STEREO 9 + +/*These are 16-bit requests*/ +/** Transmit max bit-rate allowed */ +#define SPEEX_INBAND_MAX_BITRATE 10 + +/*These are 32-bit requests*/ +/** Acknowledge packet reception */ +#define SPEEX_INBAND_ACKNOWLEDGE 12 + +/** Callback function type */ +typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data); + +/** Callback information */ +typedef struct SpeexCallback { + int callback_id; /**< ID associated to the callback */ + speex_callback_func func; /**< Callback handler function */ + void *data; /**< Data that will be sent to the handler */ + void *reserved1; /**< Reserved for future use */ + int reserved2; /**< Reserved for future use */ +} SpeexCallback; + +/** Handle in-band request */ +int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state); + +/** Standard handler for mode request (change mode, no questions asked) */ +int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for high mode request (change high mode, no questions asked) */ +int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for in-band characters (write to stderr) */ +int speex_std_char_handler(SpeexBits *bits, void *state, void *data); + +/** Default handler for user-defined requests: in this case, just ignore */ +int speex_default_user_handler(SpeexBits *bits, void *state, void *data); + + + + +int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); + +int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); + +int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); + +int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_header.c b/engine/voice_codecs/speex/source/libspeex/speex_header.c new file mode 100644 index 0000000..7ee1ef3 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_header.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_header.c + Describes the Speex header + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "speex_header.h" +#include "misc.h" +#include "speex.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define ENDIAN_SWITCH(x) {x=le_int(x);} + + +/* +typedef struct SpeexHeader { + char speex_string[8]; + char speex_version[SPEEX_HEADER_VERSION_LENGTH]; + int speex_version_id; + int header_size; + int rate; + int mode; + int mode_bitstream_version; + int nb_channels; + int bitrate; + int frame_size; + int vbr; + int frames_per_packet; + int extra_headers; + int reserved1; + int reserved2; +} SpeexHeader; +*/ + +void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode *m) +{ + int i; + char *h="Speex "; + /* + strncpy(header->speex_string, "Speex ", 8); + strncpy(header->speex_version, VERSION, SPEEX_HEADER_VERSION_LENGTH-1); + header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0; + */ + for (i=0;i<8;i++) + header->speex_string[i]=h[i]; + for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && VERSION[i];i++) + header->speex_version[i]=VERSION[i]; + for (;i<SPEEX_HEADER_VERSION_LENGTH;i++) + header->speex_version[i]=0; + + header->speex_version_id = 1; + header->header_size = sizeof(SpeexHeader); + + header->rate = rate; + header->mode = m->modeID; + header->mode_bitstream_version = m->bitstream_version; + if (m->modeID<0) + speex_warning("This mode is meant to be used alone"); + header->nb_channels = nb_channels; + header->bitrate = -1; + speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size); + header->vbr = 0; + + header->frames_per_packet = 0; + header->extra_headers = 0; + header->reserved1 = 0; + header->reserved2 = 0; +} + +char *speex_header_to_packet(SpeexHeader *header, int *size) +{ + SpeexHeader *le_header; + le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); + + speex_move(le_header, header, sizeof(SpeexHeader)); + + /*Make sure everything is now little-endian*/ + ENDIAN_SWITCH(le_header->speex_version_id); + ENDIAN_SWITCH(le_header->header_size); + ENDIAN_SWITCH(le_header->rate); + ENDIAN_SWITCH(le_header->mode); + ENDIAN_SWITCH(le_header->mode_bitstream_version); + ENDIAN_SWITCH(le_header->nb_channels); + ENDIAN_SWITCH(le_header->bitrate); + ENDIAN_SWITCH(le_header->frame_size); + ENDIAN_SWITCH(le_header->vbr); + ENDIAN_SWITCH(le_header->frames_per_packet); + ENDIAN_SWITCH(le_header->extra_headers); + + *size = sizeof(SpeexHeader); + return (char *)le_header; +} + +SpeexHeader *speex_packet_to_header(char *packet, int size) +{ + int i; + SpeexHeader *le_header; + char *h = "Speex "; + for (i=0;i<8;i++) + if (packet[i]!=h[i]) + { + speex_warning ("This doesn't look like a Speex file"); + return NULL; + } + + /*FIXME: Do we allow larger headers?*/ + if (size < sizeof(SpeexHeader)) + { + speex_warning("Speex header too small"); + return NULL; + } + + le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); + + speex_move(le_header, packet, sizeof(SpeexHeader)); + + /*Make sure everything is converted correctly from little-endian*/ + ENDIAN_SWITCH(le_header->speex_version_id); + ENDIAN_SWITCH(le_header->header_size); + ENDIAN_SWITCH(le_header->rate); + ENDIAN_SWITCH(le_header->mode); + ENDIAN_SWITCH(le_header->mode_bitstream_version); + ENDIAN_SWITCH(le_header->nb_channels); + ENDIAN_SWITCH(le_header->bitrate); + ENDIAN_SWITCH(le_header->frame_size); + ENDIAN_SWITCH(le_header->vbr); + ENDIAN_SWITCH(le_header->frames_per_packet); + ENDIAN_SWITCH(le_header->extra_headers); + + return le_header; + +} diff --git a/engine/voice_codecs/speex/source/libspeex/speex_header.h b/engine/voice_codecs/speex/source/libspeex/speex_header.h new file mode 100644 index 0000000..8ded911 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_header.h @@ -0,0 +1,82 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_header.h + @brief Describes the Speex header +*/ +/* + 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 SPEEX_HEADER_H +#define SPEEX_HEADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct SpeexMode; + +/** Maximum number of characters for encoding the Speex version number in the header */ +#define SPEEX_HEADER_VERSION_LENGTH 20 + +/** Speex header info for file-based formats */ +typedef struct SpeexHeader { + char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */ + char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ + int speex_version_id; /**< Version for Speex (for checking compatibility) */ + int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ + int rate; /**< Sampling rate used */ + int mode; /**< Mode used (0 for narrowband, 1 for wideband) */ + int mode_bitstream_version; /**< Version ID of the bit-stream */ + int nb_channels; /**< Number of channels encoded */ + int bitrate; /**< Bit-rate used */ + int frame_size; /**< Size of frames */ + int vbr; /**< 1 for a VBR encoding, 0 otherwise */ + int frames_per_packet; /**< Number of frames stored per Ogg packet */ + int extra_headers; /**< Number of additional headers after the comments */ + int reserved1; /**< Reserved for future use, must be zero */ + int reserved2; /**< Reserved for future use, must be zero */ +} SpeexHeader; + +/** Initializes a SpeexHeader using basic information */ +void speex_init_header(SpeexHeader *header, int rate, int nb_channels, struct SpeexMode *m); + +/** Creates the header packet from the header itself (mostly involves endianness conversion) */ +char *speex_header_to_packet(SpeexHeader *header, int *size); + +/** Creates a SpeexHeader from a packet */ +SpeexHeader *speex_packet_to_header(char *packet, int size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_stereo.h b/engine/voice_codecs/speex/source/libspeex/speex_stereo.h new file mode 100644 index 0000000..3fbeb91 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/speex_stereo.h @@ -0,0 +1,62 @@ +/* Copyright (C) 2002 Jean-Marc Valin*/ +/** + @file speex_stereo.h + @brief Describes the handling for intensity stereo +*/ +/* + 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 STEREO_H +#define STEREO_H + +#include "speex_bits.h" + +/** State used for decoding (intensity) stereo information */ +typedef struct SpeexStereoState { + float balance; /**< Left/right balance info */ + float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ + float smooth_left; /**< Smoothed left channel gain */ + float smooth_right; /**< Smoothed right channel gain */ + float reserved1; /**< Reserved for future use */ + float reserved2; /**< Reserved for future use */ +} SpeexStereoState; + +/** Initialization value for a stereo state */ +#define SPEEX_STEREO_STATE_INIT {1,.5,1,1} + +/** 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); + +/** Transforms a mono frame into a stereo frame using intensity stereo info */ +void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo); + +/** Callback handler for intensity stereo info */ +int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/stack_alloc.h b/engine/voice_codecs/speex/source/libspeex/stack_alloc.h new file mode 100644 index 0000000..2390b69 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/stack_alloc.h @@ -0,0 +1,62 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: stack_alloc.h + + Temporary memory allocation on stack + + 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 STACK_ALLOC_H +#define STACK_ALLOC_H + +#if 0 + +/*Aligns the stack to a 'size' boundary */ +#define ALIGN(stack, size) (stack=(void*)((((int)stack)+((size)-1)) & (-(size)))) +/*Aligns the stack to a 'size' boundary minus k */ +#define ALIGN_1(stack, size, k) (stack=(void*)(((((int)stack)+((size)-1+(k))) & (-(size)))-(k))) + +/* Allocates 'size' elements of type 'type' on the stack */ +#define PUSH(stack, size, type) (ALIGN(stack,sizeof(type)),stack=(void*)(((int)stack)+((size)*sizeof(type))),(type*)(((int)stack)-((size)*sizeof(type)))) + + +#else + +/*Aligns the stack to a 'size' boundary */ +#define ALIGN(stack, size) ((stack) += ((size) - (int)(stack)) & ((size) - 1)) + +/* Allocates 'size' elements of type 'type' on the stack */ +#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) + +/* Allocates a struct stack */ +#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type)))) + + +#endif + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/stereo.c b/engine/voice_codecs/speex/source/libspeex/stereo.c new file mode 100644 index 0000000..e033ce5 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/stereo.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: stereo.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. +*/ + +#include "speex_stereo.h" +#include "speex_callbacks.h" +#include "vq.h" +#include <math.h> + +/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ +static float e_ratio_quant[4] = {.25, .315, .397, .5}; + +void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) +{ + int i, tmp; + float e_left=0, e_right=0, e_tot=0; + float balance, e_ratio; + for (i=0;i<frame_size;i++) + { + e_left += data[2*i]*data[2*i]; + e_right += data[2*i+1]*data[2*i+1]; + data[i] = .5*(data[2*i]+data[2*i+1]); + e_tot += data[i]*data[i]; + } + 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) + speex_bits_pack(bits, 0, 1); + else + speex_bits_pack(bits, 1, 1); + balance=floor(.5+fabs(balance)); + if (balance>30) + balance=31; + + speex_bits_pack(bits, (int)balance, 5); + + /*Quantize energy ratio*/ + tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); + speex_bits_pack(bits, tmp, 2); +} + +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; + + balance=stereo->balance; + e_ratio=stereo->e_ratio; + for (i=frame_size-1;i>=0;i--) + { + e_tot += data[i]*data[i]; + } + e_sum=e_tot/e_ratio; + e_left = e_sum*balance / (1+balance); + e_right = e_sum-e_left; + + e_left = sqrt(e_left/(e_tot+.01)); + e_right = sqrt(e_right/(e_tot+.01)); + + for (i=frame_size-1;i>=0;i--) + { + float ftmp=data[i]; + stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; + stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; + data[2*i] = stereo->smooth_left*ftmp; + data[2*i+1] = stereo->smooth_right*ftmp; + } +} + +int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) +{ + SpeexStereoState *stereo; + float sign=1; + int tmp; + + stereo = (SpeexStereoState*)data; + if (speex_bits_unpack_unsigned(bits, 1)) + sign=-1; + tmp = speex_bits_unpack_unsigned(bits, 5); + stereo->balance = exp(sign*.25*tmp); + + tmp = speex_bits_unpack_unsigned(bits, 2); + stereo->e_ratio = e_ratio_quant[tmp]; + + return 0; +} diff --git a/engine/voice_codecs/speex/source/libspeex/testenc.c b/engine/voice_codecs/speex/source/libspeex/testenc.c new file mode 100644 index 0000000..7033ef4 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/testenc.c @@ -0,0 +1,127 @@ +#include "speex.h" +#include <stdio.h> +#include <stdlib.h> +#include "speex_callbacks.h" + +#define FRAME_SIZE 160 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in[FRAME_SIZE]; + float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + int tmp; + int bitCount=0; + SpeexCallback callback; + + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=0; + st = speex_encoder_init(&speex_nb_mode); + dec = speex_decoder_init(&speex_nb_mode); + + callback.callback_id = SPEEX_INBAND_CHAR; + callback.func = speex_std_char_handler; + callback.data = stderr; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + callback.callback_id = SPEEX_INBAND_MODE_REQUEST; + callback.func = speex_std_mode_request_handler; + callback.data = st; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + tmp=0; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=8; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=1; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + + speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp); + fprintf (stderr, "frame size: %d\n", tmp); + + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "r"); + outFile = argv[2]; + fout = fopen(outFile, "w"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "w"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + for (i=0;i<FRAME_SIZE;i++) + bak[i]=input[i]=in[i]; + speex_bits_reset(&bits); + /* + speex_bits_pack(&bits, 14, 5); + speex_bits_pack(&bits, SPEEX_INBAND_CHAR, 4); + speex_bits_pack(&bits, 'A', 8); + + speex_bits_pack(&bits, 14, 5); + speex_bits_pack(&bits, SPEEX_INBAND_MODE_REQUEST, 4); + speex_bits_pack(&bits, 7, 4); + + speex_bits_pack(&bits, 15, 5); + speex_bits_pack(&bits, 2, 4); + speex_bits_pack(&bits, 0, 16); + */ + speex_encode(st, input, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + printf ("Encoding frame in %d bits\n", nbBits*8); + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + { + float enoise=0, esig=0, snr; + for (i=0;i<FRAME_SIZE;i++) + { + enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]); + esig += bak2[i]*bak2[i]; + } + snr = 10*log10((esig+1)/(enoise+1)); + printf ("real SNR = %f\n", snr); + } + speex_bits_rewind(&bits); + + speex_decode(dec, &bits, input); + + /* Save the bits here */ + for (i=0;i<FRAME_SIZE;i++) + { + if (input[i]>32000) + input[i]=32000; + else if (input[i]<-32000) + input[i]=-32000; + } + speex_bits_reset(&bits); + for (i=0;i<FRAME_SIZE;i++) + in[i]=(short)input[i]; + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=bak[i]; + fwrite(in, sizeof(short), FRAME_SIZE, fout); + } + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + return 1; +} diff --git a/engine/voice_codecs/speex/source/libspeex/testenc_uwb.c b/engine/voice_codecs/speex/source/libspeex/testenc_uwb.c new file mode 100644 index 0000000..9d83263 --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/testenc_uwb.c @@ -0,0 +1,106 @@ +#include "speex.h" +#include <stdio.h> +#include <stdlib.h> + +#define FRAME_SIZE 640 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in[FRAME_SIZE]; + float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + int tmp; + int bitCount=0; + + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=0; + st = speex_encoder_init(&speex_uwb_mode); + dec = speex_decoder_init(&speex_uwb_mode); + + tmp=0; + /*speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=10; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=3; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + tmp=3; + speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp); + tmp=6; + speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp); + */ + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "r"); + outFile = argv[2]; + fout = fopen(outFile, "w"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "w"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + for (i=0;i<FRAME_SIZE;i++) + bak[i]=input[i]=in[i]; + speex_bits_reset(&bits); + speex_encode(st, input, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + printf ("Encoding frame in %d bits\n", nbBits*8); + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + { + float enoise=0, esig=0, snr; + for (i=0;i<FRAME_SIZE;i++) + { + enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]); + esig += bak2[i]*bak2[i]; + } + snr = 10*log10((esig+1)/(enoise+1)); + printf ("real SNR = %f\n", snr); + } + speex_bits_rewind(&bits); + + speex_decode(dec, &bits, input); + + /* Save the bits here */ + for (i=0;i<FRAME_SIZE;i++) + { + if (input[i]>32000) + input[i]=32000; + else if (input[i]<-32000) + input[i]=-32000; + } + speex_bits_reset(&bits); + for (i=0;i<FRAME_SIZE;i++) + in[i]=(short)input[i]; + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=bak[i]; + fwrite(in, sizeof(short), FRAME_SIZE, fout); + } + + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + speex_bits_destroy(&bits); + fclose(fin); + fclose(fout); + return 1; +} diff --git a/engine/voice_codecs/speex/source/libspeex/testenc_wb.c b/engine/voice_codecs/speex/source/libspeex/testenc_wb.c new file mode 100644 index 0000000..31fe77c --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/testenc_wb.c @@ -0,0 +1,106 @@ +#include "speex.h" +#include <stdio.h> +#include <stdlib.h> + +#define FRAME_SIZE 320 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in[FRAME_SIZE]; + float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + int tmp; + int bitCount=0; + + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=0; + st = speex_encoder_init(&speex_wb_mode); + dec = speex_decoder_init(&speex_wb_mode); + + tmp=0; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=10; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=3; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + tmp=3; + speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp); + tmp=6; + speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp); + + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "r"); + outFile = argv[2]; + fout = fopen(outFile, "w"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "w"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + for (i=0;i<FRAME_SIZE;i++) + bak[i]=input[i]=in[i]; + speex_bits_reset(&bits); + speex_encode(st, input, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + printf ("Encoding frame in %d bits\n", nbBits*8); + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + { + float enoise=0, esig=0, snr; + for (i=0;i<FRAME_SIZE;i++) + { + enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]); + esig += bak2[i]*bak2[i]; + } + snr = 10*log10((esig+1)/(enoise+1)); + printf ("real SNR = %f\n", snr); + } + speex_bits_rewind(&bits); + + speex_decode(dec, &bits, input); + + /* Save the bits here */ + for (i=0;i<FRAME_SIZE;i++) + { + if (input[i]>32000) + input[i]=32000; + else if (input[i]<-32000) + input[i]=-32000; + } + speex_bits_reset(&bits); + for (i=0;i<FRAME_SIZE;i++) + in[i]=(short)input[i]; + for (i=0;i<FRAME_SIZE;i++) + bak2[i]=bak[i]; + fwrite(in, sizeof(short), FRAME_SIZE, fout); + } + + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + speex_bits_destroy(&bits); + fclose(fin); + fclose(fout); + return 1; +} diff --git a/engine/voice_codecs/speex/source/libspeex/vbr.c b/engine/voice_codecs/speex/source/libspeex/vbr.c new file mode 100644 index 0000000..b035dbc --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/vbr.c @@ -0,0 +1,268 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vbr.c + + VBR-related routines + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "vbr.h" +#include <math.h> + + +#define sqr(x) ((x)*(x)) + +#define MIN_ENERGY 6000 +#define NOISE_POW .3 + + +float vbr_nb_thresh[9][11]={ + {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */ + { 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */ + {10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */ + {11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */ + {11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */ + {11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */ + {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */ + {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */ + { 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */ +}; + + +float vbr_hb_thresh[5][11]={ + {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ + {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */ + {11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */ + {11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */ + {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */ +}; + +float vbr_uhb_thresh[2][11]={ + {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ + { 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */ +}; + +void vbr_init(VBRState *vbr) +{ + int i; + + vbr->average_energy=0; + vbr->last_energy=1; + vbr->accum_sum=0; + vbr->energy_alpha=.1; + vbr->soft_pitch=0; + vbr->last_pitch_coef=0; + vbr->last_quality=0; + + vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW); + vbr->noise_accum_count=.05; + vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; + vbr->consec_noise=0; + + + for (i=0;i<VBR_MEMORY_SIZE;i++) + vbr->last_log_energy[i] = log(MIN_ENERGY); +} + + +/* + This function should analyse the signal and decide how critical the + coding error will be perceptually. The following factors should be + taken into account: + + -Attacks (positive energy derivative) should be coded with more bits + + -Stationary voiced segments should receive more bits + + -Segments with (very) low absolute energy should receive less bits (maybe + only shaped noise?) + + -DTX for near-zero energy? + + -Stationary fricative segments should have less bits + + -Temporal masking: when energy slope is decreasing, decrease the bit-rate + + -Decrease bit-rate for males (low pitch)? + + -(wideband only) less bits in the high-band when signal is very + non-stationary (harder to notice high-frequency noise)??? + +*/ + +float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef) +{ + int i; + float ener=0, ener1=0, ener2=0; + float qual=7; + int va; + float log_energy; + float non_st=0; + float voicing; + float pow_ener; + + for (i=0;i<len>>1;i++) + ener1 += sig[i]*sig[i]; + + for (i=len>>1;i<len;i++) + ener2 += sig[i]*sig[i]; + ener=ener1+ener2; + + log_energy = log(ener+MIN_ENERGY); + for (i=0;i<VBR_MEMORY_SIZE;i++) + non_st += sqr(log_energy-vbr->last_log_energy[i]); + non_st = non_st/(30*VBR_MEMORY_SIZE); + if (non_st>1) + non_st=1; + + voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4); + vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener; + vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; + pow_ener = pow(ener,NOISE_POW); + if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY) + vbr->noise_accum = .05*pow_ener; + + if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level) + || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level) + || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level) + || (voicing<0 && non_st < .05)) + { + float tmp; + va = 0; + vbr->consec_noise++; + if (pow_ener > 3*vbr->noise_level) + tmp = 3*vbr->noise_level; + else + tmp = pow_ener; + if (vbr->consec_noise>=4) + { + vbr->noise_accum = .95*vbr->noise_accum + .05*tmp; + vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; + } + } else { + va = 1; + vbr->consec_noise=0; + } + + if (pow_ener < vbr->noise_level && ener>MIN_ENERGY) + { + vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener; + vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; + } + + /* Checking for very low absolute energy */ + if (ener < 30000) + { + qual -= .7; + if (ener < 10000) + qual-=.7; + if (ener < 3000) + qual-=.7; + } else { + float short_diff, long_diff; + short_diff = log((ener+1)/(1+vbr->last_energy)); + long_diff = log((ener+1)/(1+vbr->average_energy)); + /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/ + + if (long_diff<-5) + long_diff=-5; + if (long_diff>2) + long_diff=2; + + if (long_diff>0) + qual += .6*long_diff; + if (long_diff<0) + qual += .5*long_diff; + if (short_diff>0) + { + if (short_diff>5) + short_diff=5; + qual += .5*short_diff; + } + /* Checking for energy increases */ + if (ener2 > 1.6*ener1) + qual += .5; + } + vbr->last_energy = ener; + vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef; + qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4)); + + if (qual < vbr->last_quality) + qual = .5*qual + .5*vbr->last_quality; + if (qual<4) + qual=4; + if (qual>10) + qual=10; + + /* + if (vbr->consec_noise>=2) + qual-=1.3; + if (vbr->consec_noise>=5) + qual-=1.3; + if (vbr->consec_noise>=12) + qual-=1.3; + */ + if (vbr->consec_noise>=3) + qual=4; + + if (vbr->consec_noise) + qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3)); + if (qual<0) + qual=0; + + if (ener<60000) + { + if (vbr->consec_noise>2) + qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); + if (ener<10000&&vbr->consec_noise>2) + qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); + if (qual<0) + qual=0; + qual += .3*log(ener/60000.0); + } + if (qual<-1) + qual=-1; + + /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/ + + vbr->last_pitch_coef = pitch_coef; + vbr->last_quality = qual; + + for (i=VBR_MEMORY_SIZE-1;i>0;i--) + vbr->last_log_energy[i] = vbr->last_log_energy[i-1]; + vbr->last_log_energy[0] = log_energy; + + /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/ + + return qual; +} + +void vbr_destroy(VBRState *vbr) +{ +} diff --git a/engine/voice_codecs/speex/source/libspeex/vbr.h b/engine/voice_codecs/speex/source/libspeex/vbr.h new file mode 100644 index 0000000..405b47f --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/vbr.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vbr.h + + VBR-related routines + + 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 VBR_H +#define VBR_H + +#define VBR_MEMORY_SIZE 5 + +extern float vbr_nb_thresh[9][11]; +extern float vbr_hb_thresh[5][11]; +extern float vbr_uhb_thresh[2][11]; + +typedef struct VBRState { + float energy_alpha; + float average_energy; + float last_energy; + float last_log_energy[VBR_MEMORY_SIZE]; + float accum_sum; + float last_pitch_coef; + float soft_pitch; + float last_quality; + float noise_level; + float noise_accum; + float noise_accum_count; + int consec_noise; +} VBRState; + +void vbr_init(VBRState *vbr); + +float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef); + +void vbr_destroy(VBRState *vbr); + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/vq.c b/engine/voice_codecs/speex/source/libspeex/vq.c new file mode 100644 index 0000000..ed36f7d --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/vq.c @@ -0,0 +1,116 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vq.c + Vector quantization + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "vq.h" + +/*Finds the index of the entry in a codebook that best matches the input*/ +int vq_index(float *in, 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; +} + + +/*Finds the indices of the n-best entries in a codebook*/ +void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist) +{ + int i,j,k,used; + used = 0; + for (i=0;i<entries;i++) + { + float dist=.5*E[i]; + for (j=0;j<len;j++) + dist -= in[j]**codebook++; + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + } + } +} + +/*Finds the indices of the n-best entries in a codebook with sign*/ +void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist) +{ + int i,j,k, sign, used; + used=0; + for (i=0;i<entries;i++) + { + float dist=0; + for (j=0;j<len;j++) + dist -= in[j]**codebook++; + if (dist>0) + { + sign=1; + dist=-dist; + } else + { + sign=0; + } + dist += .5*E[i]; + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + if (sign) + nbest[k]+=entries; + } + } +} diff --git a/engine/voice_codecs/speex/source/libspeex/vq.h b/engine/voice_codecs/speex/source/libspeex/vq.h new file mode 100644 index 0000000..e82ba6c --- /dev/null +++ b/engine/voice_codecs/speex/source/libspeex/vq.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vq.h + Vector quantization + + 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 VQ_H +#define VQ_H + +int vq_index(float *in, float *codebook, int len, int entries); + +void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); + +void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); + +#endif |