summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2001-12-17 05:39:26 +0000
committerMonty <xiphmont@xiph.org>2001-12-17 05:39:26 +0000
commite47d07fd3d639b7f1f38b7354be524b706bad139 (patch)
tree0b7d4c871b8fb74979227fad01380957f2be804c
downloadlibvorbis-git-e47d07fd3d639b7f1f38b7354be524b706bad139.tar.gz
rearrangement of vorbisenc.c into the proto-form of the two-tier
detailed/high-level setup API Monty svn path=/branches/branch_monty_20011217/vorbis/; revision=2627
-rw-r--r--configure.in190
-rw-r--r--lib/Makefile510
-rw-r--r--lib/bitrate.c583
-rw-r--r--lib/codec_internal.h173
-rw-r--r--lib/info.c598
-rw-r--r--lib/mapping0.c706
-rw-r--r--lib/modes/psych_44.h641
-rw-r--r--lib/os.h163
-rw-r--r--lib/psy.h167
-rw-r--r--lib/vorbisenc.c877
10 files changed, 4608 insertions, 0 deletions
diff --git a/configure.in b/configure.in
new file mode 100644
index 00000000..7a9b8bfd
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,190 @@
+dnl Process this file with autoconf to produce a configure script
+
+dnl ------------------------------------------------
+dnl Initialization and Versioning
+dnl ------------------------------------------------
+
+AC_INIT(lib/mdct.c)
+AM_INIT_AUTOMAKE(libvorbis,1.0rc3)
+
+dnl Library versioning
+
+V_LIB_CURRENT=0
+V_LIB_REVISION=1
+V_LIB_AGE=0
+VF_LIB_CURRENT=1
+VF_LIB_REVISION=0
+VF_LIB_AGE=1
+VE_LIB_CURRENT=0
+VE_LIB_REVISION=1
+VE_LIB_AGE=0
+AC_SUBST(V_LIB_CURRENT)
+AC_SUBST(V_LIB_REVISION)
+AC_SUBST(V_LIB_AGE)
+AC_SUBST(VF_LIB_CURRENT)
+AC_SUBST(VF_LIB_REVISION)
+AC_SUBST(VF_LIB_AGE)
+AC_SUBST(VE_LIB_CURRENT)
+AC_SUBST(VE_LIB_REVISION)
+AC_SUBST(VE_LIB_AGE)
+
+dnl --------------------------------------------------
+dnl Check for programs
+dnl --------------------------------------------------
+
+dnl save $CFLAGS since AC_PROG_CC likes to insert "-g -O2"
+dnl if $CFLAGS is blank
+cflags_save="$CFLAGS"
+AC_PROG_CC
+AC_PROG_CPP
+CFLAGS="$cflags_save"
+
+AM_PROG_LIBTOOL
+
+dnl --------------------------------------------------
+dnl Set build flags based on environment
+dnl --------------------------------------------------
+
+AC_CANONICAL_HOST
+
+dnl Set some target options
+
+cflags_save="$CFLAGS"
+ldflags_save="$LDFLAGS"
+if test -z "$GCC"; then
+ case $host in
+ *-*-irix*)
+ dnl If we're on IRIX, we wanna use cc even if gcc
+ dnl is there (unless the user has overriden us)...
+ if test -z "$CC"; then
+ CC=cc
+ fi
+ DEBUG="-g -signed"
+ CFLAGS="-O2 -w -signed"
+ PROFILE="-p -g3 -O2 -signed" ;;
+ sparc-sun-solaris*)
+ DEBUG="-v -g"
+ CFLAGS="-xO4 -fast -w -fsimple -native -xcg92"
+ PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" ;;
+ *)
+ DEBUG="-g"
+ CFLAGS="-O"
+ PROFILE="-g -p" ;;
+ esac
+else
+
+ case $host in
+ *86-*-linux*)
+ DEBUG="-g -Wall -W -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char"
+# PROFILE="-Wall -W -pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char -fno-inline -static"
+ PROFILE="-Wall -W -pg -g -O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char -fno-inline -static"
+
+ # glibc < 2.1.3 has a serious FP bug in the math inline header
+ # that will cripple Vorbis. Look to see if the magic FP stack
+ # clobber is missing in the mathinline header, thus indicating
+ # the buggy version
+
+ AC_EGREP_CPP(log10.*fldlg2.*fxch,[
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+ ],bad=maybe,bad=no)
+ if test ${bad} = "maybe" ;then
+ AC_EGREP_CPP(log10.*fldlg2.*fxch.*st\([[0123456789]]*\),
+ [
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+ ],bad=no,bad=yes)
+ fi
+ if test ${bad} = "yes" ;then
+ AC_MSG_WARN([ ])
+ AC_MSG_WARN([********************************************************])
+ AC_MSG_WARN([* The glibc headers on this machine have a serious bug *])
+ AC_MSG_WARN([* in /usr/include/bits/mathinline.h This bug affects *])
+ AC_MSG_WARN([* all floating point code, not just Ogg, built on this *])
+ AC_MSG_WARN([* machine. Upgrading to glibc 2.1.3 is strongly urged *])
+ AC_MSG_WARN([* to correct the problem. Note that upgrading glibc *])
+ AC_MSG_WARN([* will not fix any previously built programs; this is *])
+ AC_MSG_WARN([* a compile-time time bug. *])
+ AC_MSG_WARN([* To work around the problem for this build of Ogg, *])
+ AC_MSG_WARN([* autoconf is disabling all math inlining. This will *])
+ AC_MSG_WARN([* hurt Ogg performace but is necessary for an Ogg that *])
+ AC_MSG_WARN([* will actually work. Once glibc is upgraded, rerun *])
+ AC_MSG_WARN([* configure and make to build with inlining. *])
+ AC_MSG_WARN([********************************************************])
+ AC_MSG_WARN([ ])
+
+ CFLAGS=${OPT}" -D__NO_MATH_INLINES"
+ PROFILE=${PROFILE}" -D__NO_MATH_INLINES"
+ fi;;
+ *-*-linux*)
+ DEBUG="-g -Wall -W -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char";;
+ sparc-sun-*)
+ DEBUG="-g -Wall -W -D__NO_MATH_INLINES -fsigned-char -mv8"
+ CFLAGS="-O20 -ffast-math -D__NO_MATH_INLINES -fsigned-char -mv8"
+ PROFILE="-pg -g -O20 -D__NO_MATH_INLINES -fsigned-char -mv8" ;;
+ *-*-darwin*)
+ DEBUG="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O0 -fsigned-char"
+ CFLAGS="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O4 -ffast-math -fsigned-char"
+ PROFILE="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -pg -O4 -ffast-math -fsigned-char";;
+ *)
+ DEBUG="-g -Wall -W -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -D__NO_MATH_INLINES -fsigned-char"
+ PROFILE="-O20 -g -pg -D__NO_MATH_INLINES -fsigned-char" ;;
+ esac
+fi
+CFLAGS="$CFLAGS $cflags_save"
+LDFLAGS="$LDFLAGS $ldflags_save"
+
+dnl --------------------------------------------------
+dnl Check for headers
+dnl --------------------------------------------------
+
+AC_CHECK_HEADER(memory.h,CFLAGS="$CFLAGS -DUSE_MEMORY_H",:)
+
+dnl --------------------------------------------------
+dnl Check for typedefs, structures, etc
+dnl --------------------------------------------------
+
+dnl none
+
+dnl --------------------------------------------------
+dnl Check for libraries
+dnl --------------------------------------------------
+
+AC_CHECK_LIB(m, cos, LIBS="-lm", LIBS="")
+AC_CHECK_LIB(pthread, pthread_create, pthread_lib="-lpthread", :)
+
+AM_PATH_OGG(, AC_MSG_ERROR(must have Ogg installed!))
+
+dnl --------------------------------------------------
+dnl Check for library functions
+dnl --------------------------------------------------
+
+AC_FUNC_ALLOCA
+AC_FUNC_MEMCMP
+
+AC_CHECK_FUNCS(sqrtf)
+AC_CHECK_FUNCS(logf)
+AC_CHECK_FUNCS(expf)
+AC_CHECK_FUNCS(acosf)
+AC_CHECK_FUNCS(atanf)
+AC_CHECK_FUNCS(frexpf)
+AC_CHECK_FUNCS(rintf)
+
+dnl --------------------------------------------------
+dnl Do substitutions
+dnl --------------------------------------------------
+
+LIBS="$LIBS $OGG_LIBS"
+
+AC_SUBST(LIBS)
+AC_SUBST(DEBUG)
+AC_SUBST(PROFILE)
+AC_SUBST(pthread_lib)
+
+AC_OUTPUT(Makefile lib/Makefile lib/modes/Makefile lib/books/Makefile doc/Makefile doc/vorbisfile/Makefile doc/vorbisenc/Makefile include/Makefile include/vorbis/Makefile examples/Makefile win32/Makefile debian/Makefile vq/Makefile)
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 00000000..80ee0579
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,510 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/libvorbis
+pkglibdir = $(libdir)/libvorbis
+pkgincludedir = $(includedir)/libvorbis
+
+top_builddir = ..
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = powerpc-unknown-linux-gnu
+host_triplet = powerpc-unknown-linux-gnu
+AS = @AS@
+CC = gcc
+CPP = gcc -E
+DEBUG = -g -Wall -W -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char
+DLLTOOL = @DLLTOOL@
+ECHO = echo
+EXEEXT =
+LIBS = -lm -logg
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+MAKEINFO = makeinfo
+OBJDUMP = @OBJDUMP@
+OBJEXT = o
+OGG_CFLAGS = -INONE/include
+OGG_LIBS = -logg
+PACKAGE = libvorbis
+PROFILE = -pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char
+RANLIB = ranlib
+STRIP = strip
+VERSION = 1.0rc3
+VE_LIB_AGE = 0
+VE_LIB_CURRENT = 0
+VE_LIB_REVISION = 1
+VF_LIB_AGE = 1
+VF_LIB_CURRENT = 1
+VF_LIB_REVISION = 0
+V_LIB_AGE = 0
+V_LIB_CURRENT = 0
+V_LIB_REVISION = 1
+pthread_lib = -lpthread
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = modes books
+
+INCLUDES = -I$(top_srcdir)/include -INONE/include
+
+lib_LTLIBRARIES = libvorbis.la libvorbisfile.la libvorbisenc.la
+
+libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c lpc.c analysis.c synthesis.c psy.c info.c time0.c floor1.c floor0.c res0.c mapping0.c registry.c codebook.c sharedbook.c lookup.c bitrate.c envelope.h lpc.h lsp.h codebook.h misc.h psy.h masking.h iir.h os.h mdct.h smallft.h registry.h scales.h window.h lookup.h lookup_data.h codec_internal.h backends.h bitrate.h
+
+libvorbis_la_LDFLAGS = -version-info 0:1:0
+
+libvorbisfile_la_SOURCES = vorbisfile.c
+libvorbisfile_la_LDFLAGS = -version-info 1:0:1
+
+libvorbisenc_la_SOURCES = vorbisenc.c registry-api.h
+libvorbisenc_la_LDFLAGS = -version-info 0:1:0
+
+EXTRA_PROGRAMS = barkmel tone psytune
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+barkmel_SOURCES = barkmel.c
+tone_SOURCES = tone.c
+psytune_SOURCES = psytune.c
+psytune_LDFLAGS = -static
+psytune_LDADD = libvorbis.la
+
+EXTRA_DIST = lookups.pl iir.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = -DPACKAGE=\"libvorbis\" -DVERSION=\"1.0rc3\" -DHAVE_DLFCN_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_SQRTF=1 -DHAVE_LOGF=1 -DHAVE_EXPF=1 -DHAVE_ACOSF=1 -DHAVE_ATANF=1 -DHAVE_FREXPF=1 -DHAVE_RINTF=1 -I. -I$(srcdir)
+CPPFLAGS =
+LDFLAGS =
+libvorbis_la_LIBADD =
+libvorbis_la_OBJECTS = mdct.lo smallft.lo block.lo envelope.lo \
+window.lo lsp.lo lpc.lo analysis.lo synthesis.lo psy.lo info.lo \
+time0.lo floor1.lo floor0.lo res0.lo mapping0.lo registry.lo \
+codebook.lo sharedbook.lo lookup.lo bitrate.lo
+libvorbisfile_la_LIBADD =
+libvorbisfile_la_OBJECTS = vorbisfile.lo
+libvorbisenc_la_LIBADD =
+libvorbisenc_la_OBJECTS = vorbisenc.lo
+barkmel_OBJECTS = barkmel.$(OBJEXT)
+barkmel_LDADD = $(LDADD)
+barkmel_DEPENDENCIES =
+barkmel_LDFLAGS =
+tone_OBJECTS = tone.$(OBJEXT)
+tone_LDADD = $(LDADD)
+tone_DEPENDENCIES =
+tone_LDFLAGS =
+psytune_OBJECTS = psytune.$(OBJEXT)
+psytune_DEPENDENCIES = libvorbis.la
+CFLAGS = -O20 -ffast-math -D_REENTRANT -fsigned-char -DUSE_MEMORY_H
+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 $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES = .deps/analysis.P .deps/barkmel.P .deps/bitrate.P \
+.deps/block.P .deps/codebook.P .deps/envelope.P .deps/floor0.P \
+.deps/floor1.P .deps/info.P .deps/lookup.P .deps/lpc.P .deps/lsp.P \
+.deps/mapping0.P .deps/mdct.P .deps/psy.P .deps/psytune.P \
+.deps/registry.P .deps/res0.P .deps/sharedbook.P .deps/smallft.P \
+.deps/synthesis.P .deps/time0.P .deps/tone.P .deps/vorbisenc.P \
+.deps/vorbisfile.P .deps/window.P
+SOURCES = $(libvorbis_la_SOURCES) $(libvorbisfile_la_SOURCES) $(libvorbisenc_la_SOURCES) $(barkmel_SOURCES) $(tone_SOURCES) $(psytune_SOURCES)
+OBJECTS = $(libvorbis_la_OBJECTS) $(libvorbisfile_la_OBJECTS) $(libvorbisenc_la_OBJECTS) $(barkmel_OBJECTS) $(tone_OBJECTS) $(psytune_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ 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
+
+# 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:
+
+.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:
+
+libvorbis.la: $(libvorbis_la_OBJECTS) $(libvorbis_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libvorbis_la_LDFLAGS) $(libvorbis_la_OBJECTS) $(libvorbis_la_LIBADD) $(LIBS)
+
+libvorbisfile.la: $(libvorbisfile_la_OBJECTS) $(libvorbisfile_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libvorbisfile_la_LDFLAGS) $(libvorbisfile_la_OBJECTS) $(libvorbisfile_la_LIBADD) $(LIBS)
+
+libvorbisenc.la: $(libvorbisenc_la_OBJECTS) $(libvorbisenc_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libvorbisenc_la_LDFLAGS) $(libvorbisenc_la_OBJECTS) $(libvorbisenc_la_LIBADD) $(LIBS)
+
+barkmel$(EXEEXT): $(barkmel_OBJECTS) $(barkmel_DEPENDENCIES)
+ @rm -f barkmel$(EXEEXT)
+ $(LINK) $(barkmel_LDFLAGS) $(barkmel_OBJECTS) $(barkmel_LDADD) $(LIBS)
+
+tone$(EXEEXT): $(tone_OBJECTS) $(tone_DEPENDENCIES)
+ @rm -f tone$(EXEEXT)
+ $(LINK) $(tone_LDFLAGS) $(tone_OBJECTS) $(tone_LDADD) $(LIBS)
+
+psytune$(EXEEXT): $(psytune_OBJECTS) $(psytune_DEPENDENCIES)
+ @rm -f psytune$(EXEEXT)
+ $(LINK) $(psytune_LDFLAGS) $(psytune_OBJECTS) $(psytune_LDADD) $(LIBS)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ 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 = lib
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign lib/Makefile
+ @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
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-recursive
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ 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-recursive
+
+.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 install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend 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-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+debug:
+ $(MAKE) all CFLAGS="-g -Wall -W -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+
+profile:
+ $(MAKE) all CFLAGS="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char"
+
+# 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/lib/bitrate.c b/lib/bitrate.c
new file mode 100644
index 00000000..0d5c8c67
--- /dev/null
+++ b/lib/bitrate.c
@@ -0,0 +1,583 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: bitrate tracking and management
+ last mod: $Id: bitrate.c,v 1.3.2.1 2001/12/17 05:39:23 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "os.h"
+#include "bitrate.h"
+
+#define BINBITS(pos,bin) ((bin)>0?bm->queue_binned[(pos)*bins+(bin)-1]:0)
+#define LIMITBITS(pos,bin) ((bin)>-bins?\
+ bm->minmax_binstack[(pos)*bins*2+((bin)+bins)-1]:0)
+
+static long LACING_ADJUST(long bits){
+ int addto=((bits+7)/8+1)/256+1;
+ return( ((bits+7)/8+addto)*8 );
+}
+
+static double floater_interpolate(bitrate_manager_state *bm,vorbis_info *vi,
+ double desired_rate){
+ int bin=bm->avgfloat*BITTRACK_DIVISOR-1.;
+ double lobitrate;
+ double hibitrate;
+
+ lobitrate=(double)(bin==0?0:bm->avg_binacc[bin-1])/bm->avg_sampleacc*vi->rate;
+ while(lobitrate>desired_rate && bin>0){
+ bin--;
+ lobitrate=(double)(bin==0?0:bm->avg_binacc[bin-1])/bm->avg_sampleacc*vi->rate;
+ }
+
+ hibitrate=(double)(bin>=bm->queue_bins?bm->avg_binacc[bm->queue_bins-1]:
+ bm->avg_binacc[bin])/bm->avg_sampleacc*vi->rate;
+ while(hibitrate<desired_rate && bin<bm->queue_bins){
+ bin++;
+ if(bin<bm->queue_bins)
+ hibitrate=(double)bm->avg_binacc[bin]/bm->avg_sampleacc*vi->rate;
+ }
+
+ /* interpolate */
+ if(bin==bm->queue_bins){
+ return bin/(double)BITTRACK_DIVISOR;
+ }else{
+ double delta=(desired_rate-lobitrate)/(hibitrate-lobitrate);
+ return (bin+delta)/(double)BITTRACK_DIVISOR;
+ }
+}
+
+/* try out a new limit */
+static long limit_sum(bitrate_manager_state *bm,int limit){
+ int i=bm->minmax_stackptr;
+ long acc=bm->minmax_acctotal;
+ long bins=bm->queue_bins;
+
+ acc-=LIMITBITS(i,0);
+ acc+=LIMITBITS(i,limit);
+
+ while(i-->0){
+ if(bm->minmax_limitstack[i]<=limit)break;
+ acc-=LIMITBITS(i,bm->minmax_limitstack[i]);
+ acc+=LIMITBITS(i,limit);
+ }
+ return(acc);
+}
+
+/* compute bitrate tracking setup, allocate circular packet size queue */
+void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
+ int i;
+ codec_setup_info *ci=vi->codec_setup;
+ bitrate_manager_info *bi=&ci->bi;
+ long maxlatency;
+
+ memset(bm,0,sizeof(*bm));
+
+ if(bi){
+
+ bm->avg_sampledesired=bi->queue_avg_time*vi->rate;
+ bm->avg_centerdesired=bi->queue_avg_time*vi->rate*bi->queue_avg_center;
+ bm->minmax_sampledesired=bi->queue_minmax_time*vi->rate;
+
+ /* first find the max possible needed queue size */
+ maxlatency=max(bm->avg_sampledesired-bm->avg_centerdesired,
+ bm->minmax_sampledesired)+bm->avg_centerdesired;
+
+ if(maxlatency>0 &&
+ (bi->queue_avgmin>0 || bi->queue_avgmax>0 || bi->queue_hardmax>0 ||
+ bi->queue_hardmin>0)){
+ long maxpackets=maxlatency/(ci->blocksizes[0]>>1)+3;
+ long bins=BITTRACK_DIVISOR*ci->passlimit[ci->coupling_passes-1];
+
+ bm->queue_size=maxpackets;
+ bm->queue_bins=bins;
+ bm->queue_binned=_ogg_malloc(maxpackets*bins*sizeof(*bm->queue_binned));
+ bm->queue_actual=_ogg_malloc(maxpackets*sizeof(*bm->queue_actual));
+
+ if((bi->queue_avgmin>0 || bi->queue_avgmax>0) &&
+ bi->queue_avg_time>0){
+
+ bm->avg_binacc=_ogg_malloc(bins*sizeof(*bm->avg_binacc));
+ bm->avgfloat=bi->avgfloat_initial;
+
+
+ }else{
+ bm->avg_tail= -1;
+ }
+
+ if((bi->queue_hardmin>0 || bi->queue_hardmax>0) &&
+ bi->queue_minmax_time>0){
+
+ bm->minmax_binstack=_ogg_malloc((bins+1)*bins*2*
+ sizeof(bm->minmax_binstack));
+ bm->minmax_posstack=_ogg_malloc((bins+1)*
+ sizeof(bm->minmax_posstack));
+ bm->minmax_limitstack=_ogg_malloc((bins+1)*
+ sizeof(bm->minmax_limitstack));
+ }else{
+ bm->minmax_tail= -1;
+ }
+
+ /* space for the packet queueing */
+ bm->queue_packet_buffers=calloc(maxpackets,sizeof(*bm->queue_packet_buffers));
+ bm->queue_packets=calloc(maxpackets,sizeof(*bm->queue_packets));
+ for(i=0;i<maxpackets;i++)
+ oggpack_writeinit(bm->queue_packet_buffers+i);
+
+ }else{
+ bm->queue_packet_buffers=calloc(1,sizeof(*bm->queue_packet_buffers));
+ bm->queue_packets=calloc(1,sizeof(*bm->queue_packets));
+ oggpack_writeinit(bm->queue_packet_buffers);
+ }
+ }
+}
+
+void vorbis_bitrate_clear(bitrate_manager_state *bm){
+ int i;
+ if(bm){
+ if(bm->queue_binned)_ogg_free(bm->queue_binned);
+ if(bm->queue_actual)_ogg_free(bm->queue_actual);
+ if(bm->avg_binacc)_ogg_free(bm->avg_binacc);
+ if(bm->minmax_binstack)_ogg_free(bm->minmax_binstack);
+ if(bm->minmax_posstack)_ogg_free(bm->minmax_posstack);
+ if(bm->minmax_limitstack)_ogg_free(bm->minmax_limitstack);
+ if(bm->queue_packet_buffers){
+ if(bm->queue_size==0){
+ oggpack_writeclear(bm->queue_packet_buffers);
+ _ogg_free(bm->queue_packet_buffers);
+ }else{
+ for(i=0;i<bm->queue_size;i++)
+ oggpack_writeclear(bm->queue_packet_buffers+i);
+ _ogg_free(bm->queue_packet_buffers);
+ }
+ }
+ if(bm->queue_packets)_ogg_free(bm->queue_packets);
+ memset(bm,0,sizeof(*bm));
+ }
+}
+
+int vorbis_bitrate_managed(vorbis_block *vb){
+ vorbis_dsp_state *vd=vb->vd;
+ backend_lookup_state *b=vd->backend_state;
+ bitrate_manager_state *bm=&b->bms;
+
+ if(bm->queue_binned)return(1);
+ return(0);
+}
+
+int vorbis_bitrate_maxmarkers(void){
+ return 8*BITTRACK_DIVISOR;
+}
+
+/* finish taking in the block we just processed */
+int vorbis_bitrate_addblock(vorbis_block *vb){
+ int i;
+ vorbis_block_internal *vbi=vb->internal;
+ vorbis_dsp_state *vd=vb->vd;
+ backend_lookup_state *b=vd->backend_state;
+ bitrate_manager_state *bm=&b->bms;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ bitrate_manager_info *bi=&ci->bi;
+ int eofflag=vb->eofflag;
+ int head=bm->queue_head;
+ int next_head=head+1;
+ int bins=bm->queue_bins;
+ int minmax_head,new_minmax_head;
+
+ ogg_uint32_t *head_ptr;
+ oggpack_buffer temp;
+
+ if(!bm->queue_binned){
+ oggpack_buffer temp;
+ /* not a bitrate managed stream, but for API simplicity, we'll
+ buffer one packet to keep the code path clean */
+
+ if(bm->queue_head)return(-1); /* one has been submitted without
+ being claimed */
+ bm->queue_head++;
+
+ bm->queue_packets[0].packet=oggpack_get_buffer(&vb->opb);
+ bm->queue_packets[0].bytes=oggpack_bytes(&vb->opb);
+ bm->queue_packets[0].b_o_s=0;
+ bm->queue_packets[0].e_o_s=vb->eofflag;
+ bm->queue_packets[0].granulepos=vb->granulepos;
+ bm->queue_packets[0].packetno=vb->sequence; /* for sake of completeness */
+
+ memcpy(&temp,bm->queue_packet_buffers,sizeof(vb->opb));
+ memcpy(bm->queue_packet_buffers,&vb->opb,sizeof(vb->opb));
+ memcpy(&vb->opb,&temp,sizeof(vb->opb));
+
+ return(0);
+ }
+
+ /* add encoded packet to head */
+ if(next_head>=bm->queue_size)next_head=0;
+ head_ptr=bm->queue_binned+bins*head;
+
+ /* is there room to add a block? In proper use of the API, this will
+ never come up... but guard it anyway */
+ if(next_head==bm->avg_tail || next_head==bm->minmax_tail)return(-1);
+
+ /* add the block to the toplevel queue */
+ bm->queue_head=next_head;
+ bm->queue_actual[head]=(vb->W?0x80000000UL:0);
+
+ /* buffer packet fields */
+ bm->queue_packets[head].packet=oggpack_get_buffer(&vb->opb);
+ bm->queue_packets[head].bytes=oggpack_bytes(&vb->opb);
+ bm->queue_packets[head].b_o_s=0;
+ bm->queue_packets[head].e_o_s=vb->eofflag;
+ bm->queue_packets[head].granulepos=vb->granulepos;
+ bm->queue_packets[head].packetno=vb->sequence; /* for sake of completeness */
+
+ /* swap packet buffers */
+ memcpy(&temp,bm->queue_packet_buffers+head,sizeof(vb->opb));
+ memcpy(bm->queue_packet_buffers+head,&vb->opb,sizeof(vb->opb));
+ memcpy(&vb->opb,&temp,sizeof(vb->opb));
+
+ /* save markers */
+ memcpy(head_ptr,vbi->packet_markers,sizeof(*head_ptr)*bins);
+
+ if(bm->avg_binacc)
+ new_minmax_head=minmax_head=bm->avg_center;
+ else
+ new_minmax_head=minmax_head=head;
+
+ /* the average tracking queue is updated first; its results (if it's
+ in use) are taken into account by the min/max limiter (if min/max
+ is in use) */
+ if(bm->avg_binacc){
+ long desired_center=bm->avg_centerdesired;
+ if(eofflag)desired_center=0;
+
+ /* update the avg head */
+ for(i=0;i<bins;i++)
+ bm->avg_binacc[i]+=LACING_ADJUST(head_ptr[i]);
+ bm->avg_sampleacc+=ci->blocksizes[vb->W]>>1;
+ bm->avg_centeracc+=ci->blocksizes[vb->W]>>1;
+
+ /* update the avg tail if needed */
+ while(bm->avg_sampleacc>bm->avg_sampledesired){
+ int samples=
+ ci->blocksizes[bm->queue_actual[bm->avg_tail]&0x80000000UL?1:0]>>1;
+ for(i=0;i<bm->queue_bins;i++)
+ bm->avg_binacc[i]-=LACING_ADJUST(bm->queue_binned[bins*bm->avg_tail+i]);
+ bm->avg_sampleacc-=samples;
+ bm->avg_tail++;
+ if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0;
+ }
+
+ /* update the avg center */
+ if(bm->avg_centeracc>desired_center){
+ /* choose the new average floater */
+ double upper=floater_interpolate(bm,vi,bi->queue_avgmax);
+ double lower=floater_interpolate(bm,vi,bi->queue_avgmin);
+ double new=bi->avgfloat_initial,slew;
+ int bin;
+
+ if(upper>0. && upper<new)new=upper;
+ if(lower<bi->avgfloat_minimum)
+ lower=bi->avgfloat_minimum;
+ if(lower>new)new=lower;
+
+ slew=new-bm->avgfloat;
+
+ if(slew<bi->avgfloat_downhyst || slew>bi->avgfloat_uphyst){
+ if(slew<bi->avgfloat_downslew_max)
+ new=bm->avgfloat+bi->avgfloat_downslew_max;
+ if(slew>bi->avgfloat_upslew_max)
+ new=bm->avgfloat+bi->avgfloat_upslew_max;
+
+ bm->avgfloat=new;
+ }
+
+ /* apply the average floater to new blocks */
+ bin=bm->avgfloat*BITTRACK_DIVISOR; /* truncate on purpose */
+ fprintf(stderr,"float:%d ",bin);
+ while(bm->avg_centeracc>desired_center){
+ int samples=
+ samples=ci->blocksizes[bm->queue_actual[bm->avg_center]&
+ 0x80000000UL?1:0]>>1;
+
+ bm->queue_actual[bm->avg_center]|=bin;
+
+ bm->avg_centeracc-=samples;
+ bm->avg_center++;
+ if(bm->noisetrigger_postpone)bm->noisetrigger_postpone-=samples;
+ if(bm->avg_center>=bm->queue_size)bm->avg_center=0;
+ }
+ new_minmax_head=bm->avg_center;
+
+ /* track noise bias triggers and noise bias */
+ if(bm->avgfloat<bi->avgfloat_noise_lowtrigger)
+ bm->noisetrigger_request+=1.f;
+
+ if(bm->avgfloat>bi->avgfloat_noise_hightrigger)
+ bm->noisetrigger_request-=1.f;
+
+ if(bm->noisetrigger_postpone<=0){
+ if(bm->noisetrigger_request<0.){
+ bm->avgnoise-=1.f;
+ if(bm->noisetrigger_request<bm->avg_sampleacc/2)
+ bm->avgnoise-=1.f;
+ bm->noisetrigger_postpone=bm->avg_sampleacc/2;
+ }
+ if(bm->noisetrigger_request>0.){
+ bm->avgnoise+=1.f;
+ if(bm->noisetrigger_request>bm->avg_sampleacc/2)
+ bm->avgnoise+=1.f;
+ bm->noisetrigger_postpone=bm->avg_sampleacc/2;
+ }
+
+ /* we generally want the noise bias to drift back to zero */
+ bm->noisetrigger_request=0.f;
+ if(bm->avgnoise>0)
+ bm->noisetrigger_request= -1.;
+ if(bm->avgnoise<0)
+ bm->noisetrigger_request= +1.;
+
+ if(bm->avgnoise<bi->avgfloat_noise_minval)
+ bm->avgnoise=bi->avgfloat_noise_minval;
+ if(bm->avgnoise>bi->avgfloat_noise_maxval)
+ bm->avgnoise=bi->avgfloat_noise_maxval;
+ }
+ fprintf(stderr,"noise:%f req:%ld trigger:%ld\n",bm->avgnoise,
+ bm->noisetrigger_request,bm->noisetrigger_postpone);
+
+ }
+ }else{
+ /* if we're not using an average tracker, the 'float' is nailed to
+ the avgfloat_initial value. It needs to be set for the min/max
+ to deal properly */
+ long bin=bi->avgfloat_initial*BITTRACK_DIVISOR; /* truncate on purpose */
+ bm->queue_actual[head]|=bin;
+ new_minmax_head=next_head;
+ }
+
+ /* update the min/max queues and enforce limits */
+ if(bm->minmax_binstack){
+ long sampledesired=eofflag?0:bm->minmax_sampledesired;
+
+ /* add to stack recent */
+ while(minmax_head!=new_minmax_head){
+ int samples=ci->blocksizes[bm->queue_actual[minmax_head]&
+ 0x80000000UL?1:0]>>1;
+
+ /* the construction here is not parallel to the floater's
+ stack.
+
+ floater[bin-1] <-> floater supported at bin
+ ...
+ floater[0] <-> floater supported at 1
+ supported at zero is implicit.
+ the BINBITS macro performs offsetting
+
+
+ bin minmax[bin*2-1] <-> floater supported at bin
+ ...
+ 1 minmax[bin] <-> floater supported at 1
+ 0 minmax[bin-1] <-> no limit/support (limited to/supported at bin 0,
+ ie, no effect)
+ -1 minmax[bin-2] <-> floater limited to bin-1
+ ...
+ -bin+1 minmax[0] <-> floater limited to 1
+ limited to zero (val= -bin) is implicit
+ */
+ for(i=0;i<bins;i++){
+ bm->minmax_binstack[bm->minmax_stackptr*bins*2+bins+i]+=
+ LACING_ADJUST(
+ BINBITS(minmax_head,
+ (bm->queue_actual[minmax_head]&0x7fffffffUL)>i+1?
+ (bm->queue_actual[minmax_head]&0x7fffffffUL):i+1));
+
+ bm->minmax_binstack[bm->minmax_stackptr*bins*2+i]+=
+ LACING_ADJUST(
+ BINBITS(minmax_head,
+ (bm->queue_actual[minmax_head]&0x7fffffffUL)<i+1?
+ (bm->queue_actual[minmax_head]&0x7fffffffUL):i+1));
+ }
+
+ bm->minmax_posstack[bm->minmax_stackptr]=minmax_head; /* not one
+ past
+ like
+ typical */
+ bm->minmax_limitstack[bm->minmax_stackptr]=0;
+ bm->minmax_sampleacc+=samples;
+ bm->minmax_acctotal+=
+ LACING_ADJUST(
+ BINBITS(minmax_head,(bm->queue_actual[minmax_head]&0x7fffffffUL)));
+
+ minmax_head++;
+ if(minmax_head>=bm->queue_size)minmax_head=0;
+ }
+
+ /* check limits, enforce changes */
+ if(bm->minmax_sampleacc>sampledesired){
+ double bitrate=(double)bm->minmax_acctotal/bm->minmax_sampleacc*vi->rate;
+ int limit=0;
+
+ fprintf(stderr,"prelimit:%dkbps ",(int)bitrate/1000);
+ if(bitrate>bi->queue_hardmax || bitrate<bi->queue_hardmin){
+ int newstack;
+ int stackctr;
+ long bitsum=limit_sum(bm,0);
+ bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
+
+ /* we're off rate. Iteratively try out new hard floater
+ limits until we find one that brings us inside. Here's
+ where we see the whole point of the limit stacks. */
+ if(bitrate>bi->queue_hardmax){
+ for(limit=-1;limit>-bins;limit--){
+ long bitsum=limit_sum(bm,limit);
+ bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
+ if(bitrate<=bi->queue_hardmax)break;
+ }
+ }else if(bitrate<bi->queue_hardmin){
+ for(limit=1;limit<bins;limit++){
+ long bitsum=limit_sum(bm,limit);
+ bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
+ if(bitrate>=bi->queue_hardmin)break;
+ }
+ if(bitrate>bi->queue_hardmax)limit--;
+ }
+
+ bitsum=limit_sum(bm,limit);
+ bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate;
+ fprintf(stderr,"postlimit:%dkbps ",(int)bitrate/1000);
+
+ /* trace the limit backward, stop when we see a lower limit */
+ newstack=bm->minmax_stackptr-1;
+ while(newstack>=0){
+ if(bm->minmax_limitstack[newstack]<limit)break;
+ newstack--;
+ }
+
+ /* update bit counter with new limit and replace any stack
+ limits that have been replaced by our new lower limit */
+ stackctr=bm->minmax_stackptr;
+ while(stackctr>newstack){
+ bm->minmax_acctotal-=
+ LIMITBITS(stackctr,bm->minmax_limitstack[stackctr]);
+ bm->minmax_acctotal+=LIMITBITS(stackctr,limit);
+
+ if(stackctr<bm->minmax_stackptr)
+ for(i=0;i<bins*2;i++)
+ bm->minmax_binstack[stackctr*bins*2+i]+=
+ bm->minmax_binstack[(stackctr+1)*bins*2+i];
+
+ stackctr--;
+ }
+ stackctr++;
+ bm->minmax_posstack[stackctr]=bm->minmax_posstack[bm->minmax_stackptr];
+ bm->minmax_limitstack[stackctr]=limit;
+ fprintf(stderr,"limit:%d\n",limit);
+
+ /* set up new blank stack entry */
+ stackctr++;
+ bm->minmax_stackptr=stackctr;
+ memset(&bm->minmax_binstack[stackctr*bins*2],
+ 0,
+ sizeof(*bm->minmax_binstack)*bins*2);
+ bm->minmax_limitstack[stackctr]=0;
+ bm->minmax_posstack[stackctr]=-1;
+
+ }
+ }
+
+ /* remove from tail */
+ while(bm->minmax_sampleacc>sampledesired){
+ int samples=
+ ci->blocksizes[bm->queue_actual[bm->minmax_tail]&0x80000000UL?1:0]>>1;
+ int actual=bm->queue_actual[bm->minmax_tail]&0x7fffffffUL;
+
+ for(i=0;i<bins;i++){
+ bm->minmax_binstack[bins+i]-= /* always comes off the stack bottom */
+ LACING_ADJUST(BINBITS(bm->minmax_tail,actual>i+1?actual:i+1));
+ bm->minmax_binstack[i]-=
+ LACING_ADJUST(BINBITS(bm->minmax_tail,actual<i+1?actual:i+1));
+ }
+
+ /* always perform in this order; max overrules min */
+ if(bm->minmax_limitstack[0]>actual)
+ actual=bm->minmax_limitstack[0];
+ if(bins+bm->minmax_limitstack[0]<actual)
+ actual=bins+bm->minmax_limitstack[0];
+
+ bm->minmax_acctotal-=LACING_ADJUST(BINBITS(bm->minmax_tail,actual));
+ bm->minmax_sampleacc-=samples;
+
+ /* revise queue_actual to reflect the limit */
+ bm->queue_actual[bm->minmax_tail]=actual;
+
+ if(bm->minmax_tail==bm->minmax_posstack[0]){
+ /* the stack becomes a FIFO; the first data has fallen off */
+ memmove(bm->minmax_binstack,bm->minmax_binstack+bins*2,
+ sizeof(*bm->minmax_binstack)*bins*2*bm->minmax_stackptr);
+ memmove(bm->minmax_posstack,bm->minmax_posstack+1,
+ sizeof(*bm->minmax_posstack)*bm->minmax_stackptr);
+ memmove(bm->minmax_limitstack,bm->minmax_limitstack+1,
+ sizeof(*bm->minmax_limitstack)*bm->minmax_stackptr);
+ bm->minmax_stackptr--;
+ }
+
+ bm->minmax_tail++;
+ if(bm->minmax_tail>=bm->queue_size)bm->minmax_tail=0;
+ }
+
+
+ bm->last_to_flush=bm->minmax_tail;
+ }else{
+ bm->last_to_flush=bm->avg_center;
+ }
+ if(eofflag)
+ bm->last_to_flush=bm->queue_head;
+ return(0);
+}
+
+int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
+ backend_lookup_state *b=vd->backend_state;
+ bitrate_manager_state *bm=&b->bms;
+
+ if(bm->queue_size==0){
+ if(bm->queue_head==0)return(0);
+
+ memcpy(op,bm->queue_packets,sizeof(*op));
+ bm->queue_head=0;
+
+ }else{
+ long bins=bm->queue_bins;
+ long bin;
+ long bytes;
+
+ if(bm->next_to_flush==bm->last_to_flush)return(0);
+
+ bin=bm->queue_actual[bm->next_to_flush]&0x7fffffffUL;
+ bytes=(BINBITS(bm->next_to_flush,bin)+7)/8;
+
+ memcpy(op,bm->queue_packets+bm->next_to_flush,sizeof(*op));
+ if(bytes<op->bytes)op->bytes=bytes;
+
+ bm->next_to_flush++;
+ if(bm->next_to_flush>=bm->queue_size)bm->next_to_flush=0;
+
+ }
+
+ return(1);
+}
diff --git a/lib/codec_internal.h b/lib/codec_internal.h
new file mode 100644
index 00000000..a5657958
--- /dev/null
+++ b/lib/codec_internal.h
@@ -0,0 +1,173 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec_internal.h,v 1.10.2.1 2001/12/17 05:39:23 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_CODECI_H_
+#define _V_CODECI_H_
+
+#include "envelope.h"
+#include "codebook.h"
+
+#define BLOCKTYPE_IMPULSE 0
+#define BLOCKTYPE_PADDING 1
+#define BLOCKTYPE_TRANSITION 0
+#define BLOCKTYPE_LONG 1
+
+typedef struct vorbis_block_internal{
+ float **pcmdelay; /* this is a pointer into local storage */
+ float ampmax;
+ int blocktype;
+
+ ogg_uint32_t *packet_markers;
+} vorbis_block_internal;
+
+typedef void vorbis_look_time;
+typedef void vorbis_look_mapping;
+typedef void vorbis_look_floor;
+typedef void vorbis_look_residue;
+typedef void vorbis_look_transform;
+
+/* mode ************************************************************/
+typedef struct {
+ int blockflag;
+ int windowtype;
+ int transformtype;
+ int mapping;
+} vorbis_info_mode;
+
+typedef void vorbis_info_time;
+typedef void vorbis_info_floor;
+typedef void vorbis_info_residue;
+typedef void vorbis_info_mapping;
+
+#include "psy.h"
+#include "bitrate.h"
+
+typedef struct backend_lookup_state {
+ /* local lookup storage */
+ envelope_lookup *ve; /* envelope lookup */
+ float **window[2][2][2]; /* block, leadin, leadout, type */
+ vorbis_look_transform **transform[2]; /* block, type */
+ codebook *fullbooks;
+ vorbis_look_psy_global *psy_g_look;
+
+ /* backend lookups are tied to the mode, not the backend or naked mapping */
+ int modebits;
+ vorbis_look_mapping **mode;
+
+ /* local storage, only used on the encoding side. This way the
+ application does not need to worry about freeing some packets'
+ memory and not others'; packet storage is always tracked.
+ Cleared next call to a _dsp_ function */
+ unsigned char *header;
+ unsigned char *header1;
+ unsigned char *header2;
+
+ bitrate_manager_state bms;
+
+} backend_lookup_state;
+
+/* high level configuration information for setting things up
+ step-by-step with the detaile vorbis_encode_ctl interface */
+
+typedef struct highlevel_block {
+ double tone_mask_quality;
+ double tone_peaklimit_quality;
+
+ double noise_bias_quality;
+ double noise_compand_quality;
+
+ double ath_quality;
+
+} highlevel_block;
+
+typedef struct highlevel_encode_setup {
+ double base_quality; /* these have to be tracked by the ctl */
+ double base_quality_short; /* interface so that the right books get */
+ double base_quality_long; /* chosen... */
+
+ int short_block_p;
+ int long_block_p;
+ int impulse_block_p;
+
+ int stereo_couple_p;
+ int stereo_backfill_p;
+ int residue_backfill_p;
+
+ int stereo_point_dB;
+ double stereo_point_kHz[2];
+ double lowpass_kHz[2];
+
+ double ath_floating_dB;
+ double ath_absolute_dB;
+
+ double amplitude_track_dBpersec;
+ double trigger_quality;
+
+ highlevel_block blocktype[4]; /* impulse, padding, trans, long */
+
+} highlevel_encode_setup;
+
+/* codec_setup_info contains all the setup information specific to the
+ specific compression/decompression mode in progress (eg,
+ psychoacoustic settings, channel setup, options, codebook
+ etc).
+*********************************************************************/
+
+typedef struct codec_setup_info {
+
+ /* Vorbis supports only short and long blocks, but allows the
+ encoder to choose the sizes */
+
+ long blocksizes[2];
+
+ /* modes are the primary means of supporting on-the-fly different
+ blocksizes, different channel mappings (LR or M/A),
+ different residue backends, etc. Each mode consists of a
+ blocksize flag and a mapping (along with the mapping setup */
+
+ int modes;
+ int maps;
+ int times;
+ int floors;
+ int residues;
+ int books;
+ int psys; /* encode only */
+
+ vorbis_info_mode *mode_param[64];
+ int map_type[64];
+ vorbis_info_mapping *map_param[64];
+ int time_type[64];
+ vorbis_info_time *time_param[64];
+ int floor_type[64];
+ vorbis_info_floor *floor_param[64];
+ int residue_type[64];
+ vorbis_info_residue *residue_param[64];
+ static_codebook *book_param[256];
+
+ vorbis_info_psy *psy_param[64]; /* encode only */
+ vorbis_info_psy_global psy_g_param;
+
+ bitrate_manager_info bi;
+ highlevel_encode_setup hi;
+
+ int passlimit[32]; /* iteration limit per couple/quant pass */
+ int coupling_passes;
+} codec_setup_info;
+
+extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);
+extern void _vp_global_free(vorbis_look_psy_global *look);
+
+#endif
diff --git a/lib/info.c b/lib/info.c
new file mode 100644
index 00000000..4d0d2189
--- /dev/null
+++ b/lib/info.c
@@ -0,0 +1,598 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+
+ ********************************************************************
+
+ function: maintain the info structure, info <-> header packets
+ last mod: $Id: info.c,v 1.49.2.1 2001/12/17 05:39:24 xiphmont Exp $
+
+ ********************************************************************/
+
+/* general handling of the header and the vorbis_info structure (and
+ substructures) */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "registry.h"
+#include "window.h"
+#include "psy.h"
+#include "misc.h"
+#include "os.h"
+
+/* helpers */
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static void _v_writestring(oggpack_buffer *o,char *s, int bytes){
+
+ while(bytes--){
+ oggpack_write(o,*s++,8);
+ }
+}
+
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+ while(bytes--){
+ *buf++=oggpack_read(o,8);
+ }
+}
+
+void vorbis_comment_init(vorbis_comment *vc){
+ memset(vc,0,sizeof(*vc));
+}
+
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+ vc->user_comments=_ogg_realloc(vc->user_comments,
+ (vc->comments+2)*sizeof(*vc->user_comments));
+ vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
+ (vc->comments+2)*sizeof(*vc->comment_lengths));
+ vc->comment_lengths[vc->comments]=strlen(comment);
+ vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
+ strcpy(vc->user_comments[vc->comments], comment);
+ vc->comments++;
+ vc->user_comments[vc->comments]=NULL;
+}
+
+void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
+ char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+ strcpy(comment, tag);
+ strcat(comment, "=");
+ strcat(comment, contents);
+ vorbis_comment_add(vc, comment);
+}
+
+/* This is more or less the same as strncasecmp - but that doesn't exist
+ * everywhere, and this is a fairly trivial function, so we include it */
+static int tagcompare(const char *s1, const char *s2, int n){
+ int c=0;
+ while(c < n){
+ if(toupper(s1[c]) != toupper(s2[c]))
+ return !0;
+ c++;
+ }
+ return 0;
+}
+
+char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
+ long i;
+ int found = 0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+ 1);
+
+ strcpy(fulltag, tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+ if(count == found)
+ /* We return a pointer to the data, not a copy */
+ return vc->user_comments[i] + taglen;
+ else
+ found++;
+ }
+ }
+ return NULL; /* didn't find anything */
+}
+
+int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
+ int i,count=0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+1);
+ strcpy(fulltag,tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+ count++;
+ }
+
+ return count;
+}
+
+void vorbis_comment_clear(vorbis_comment *vc){
+ if(vc){
+ long i;
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
+ if(vc->user_comments)_ogg_free(vc->user_comments);
+ if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
+ if(vc->vendor)_ogg_free(vc->vendor);
+ }
+ memset(vc,0,sizeof(*vc));
+}
+
+/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
+ They may be equal, but short will never ge greater than long */
+int vorbis_info_blocksize(vorbis_info *vi,int zo){
+ codec_setup_info *ci = vi->codec_setup;
+ return ci ? ci->blocksizes[zo] : -1;
+}
+
+/* used by synthesis, which has a full, alloced vi */
+void vorbis_info_init(vorbis_info *vi){
+ memset(vi,0,sizeof(*vi));
+ vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+}
+
+void vorbis_info_clear(vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+
+ if(ci){
+
+ for(i=0;i<ci->modes;i++)
+ if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+
+ for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+ _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+
+ for(i=0;i<ci->times;i++) /* unpack does the range checking */
+ _time_P[ci->time_type[i]]->free_info(ci->time_param[i]);
+
+ for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+ _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+
+ for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+ _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
+
+ for(i=0;i<ci->books;i++){
+ if(ci->book_param[i]){
+ /* knows if the book was not alloced */
+ vorbis_staticbook_destroy(ci->book_param[i]);
+ }
+ }
+
+ for(i=0;i<ci->psys;i++)
+ _vi_psy_free(ci->psy_param[i]);
+
+ _ogg_free(ci);
+ }
+
+ memset(vi,0,sizeof(*vi));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ vi->version=oggpack_read(opb,32);
+ if(vi->version!=0)return(OV_EVERSION);
+
+ vi->channels=oggpack_read(opb,8);
+ vi->rate=oggpack_read(opb,32);
+
+ vi->bitrate_upper=oggpack_read(opb,32);
+ vi->bitrate_nominal=oggpack_read(opb,32);
+ vi->bitrate_lower=oggpack_read(opb,32);
+
+ ci->blocksizes[0]=1<<oggpack_read(opb,4);
+ ci->blocksizes[1]=1<<oggpack_read(opb,4);
+
+ if(vi->rate<1)goto err_out;
+ if(vi->channels<1)goto err_out;
+ if(ci->blocksizes[0]<8)goto err_out;
+ if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
+ int i;
+ int vendorlen=oggpack_read(opb,32);
+ if(vendorlen<0)goto err_out;
+ vc->vendor=_ogg_calloc(vendorlen+1,1);
+ _v_readstring(opb,vc->vendor,vendorlen);
+ vc->comments=oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
+ vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
+
+ for(i=0;i<vc->comments;i++){
+ int len=oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=_ogg_calloc(len+1,1);
+ _v_readstring(opb,vc->user_comments[i],len);
+ }
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_comment_clear(vc);
+ return(OV_EBADHEADER);
+}
+
+/* all of the real encoding details are here. The modes, books,
+ everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ /* codebooks */
+ ci->books=oggpack_read(opb,8)+1;
+ /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
+ for(i=0;i<ci->books;i++){
+ ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i]));
+ if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
+ }
+
+ /* time backend settings */
+ ci->times=oggpack_read(opb,6)+1;
+ /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/
+ /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/
+ for(i=0;i<ci->times;i++){
+ ci->time_type[i]=oggpack_read(opb,16);
+ if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;
+ ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);
+ if(!ci->time_param[i])goto err_out;
+ }
+
+ /* floor backend settings */
+ ci->floors=oggpack_read(opb,6)+1;
+ /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
+ /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
+ for(i=0;i<ci->floors;i++){
+ ci->floor_type[i]=oggpack_read(opb,16);
+ if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
+ ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+ if(!ci->floor_param[i])goto err_out;
+ }
+
+ /* residue backend settings */
+ ci->residues=oggpack_read(opb,6)+1;
+ /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
+ /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
+ for(i=0;i<ci->residues;i++){
+ ci->residue_type[i]=oggpack_read(opb,16);
+ if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
+ ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
+ if(!ci->residue_param[i])goto err_out;
+ }
+
+ /* map backend settings */
+ ci->maps=oggpack_read(opb,6)+1;
+ /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
+ /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
+ for(i=0;i<ci->maps;i++){
+ ci->map_type[i]=oggpack_read(opb,16);
+ if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
+ ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
+ if(!ci->map_param[i])goto err_out;
+ }
+
+ /* mode settings */
+ ci->modes=oggpack_read(opb,6)+1;
+ /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
+ for(i=0;i<ci->modes;i++){
+ ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
+ ci->mode_param[i]->blockflag=oggpack_read(opb,1);
+ ci->mode_param[i]->windowtype=oggpack_read(opb,16);
+ ci->mode_param[i]->transformtype=oggpack_read(opb,16);
+ ci->mode_param[i]->mapping=oggpack_read(opb,8);
+
+ if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
+ }
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+ the first page that identifies basic parameters, a second packet
+ with bitstream comments and a third packet that holds the
+ codebook. */
+
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
+ oggpack_buffer opb;
+
+ if(op){
+ oggpack_readinit(&opb,op->packet,op->bytes);
+
+ /* Which of the three types of header is this? */
+ /* Also verify header-ness, vorbis */
+ {
+ char buffer[6];
+ int packtype=oggpack_read(&opb,8);
+ memset(buffer,0,6);
+ _v_readstring(&opb,buffer,6);
+ if(memcmp(buffer,"vorbis",6)){
+ /* not a vorbis header */
+ return(OV_ENOTVORBIS);
+ }
+ switch(packtype){
+ case 0x01: /* least significant *bit* is read first */
+ if(!op->b_o_s){
+ /* Not the initial packet */
+ return(OV_EBADHEADER);
+ }
+ if(vi->rate!=0){
+ /* previously initialized info header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_info(vi,&opb));
+
+ case 0x03: /* least significant *bit* is read first */
+ if(vi->rate==0){
+ /* um... we didn't get the initial header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_comment(vc,&opb));
+
+ case 0x05: /* least significant *bit* is read first */
+ if(vi->rate==0 || vc->vendor==NULL){
+ /* um... we didn;t get the initial header or comments yet */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_books(vi,&opb));
+
+ default:
+ /* Not a valid vorbis header type */
+ return(OV_EBADHEADER);
+ break;
+ }
+ }
+ }
+ return(OV_EBADHEADER);
+}
+
+/* pack side **********************************************************/
+
+static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ /* preamble */
+ oggpack_write(opb,0x01,8);
+ _v_writestring(opb,"vorbis", 6);
+
+ /* basic information about the stream */
+ oggpack_write(opb,0x00,32);
+ oggpack_write(opb,vi->channels,8);
+ oggpack_write(opb,vi->rate,32);
+
+ oggpack_write(opb,vi->bitrate_upper,32);
+ oggpack_write(opb,vi->bitrate_nominal,32);
+ oggpack_write(opb,vi->bitrate_lower,32);
+
+ oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
+ oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+ char temp[]="Xiphophorus libVorbis I 20011217";
+ int bytes = strlen(temp);
+
+ /* preamble */
+ oggpack_write(opb,0x03,8);
+ _v_writestring(opb,"vorbis", 6);
+
+ /* vendor */
+ oggpack_write(opb,bytes,32);
+ _v_writestring(opb,temp, bytes);
+
+ /* comments */
+
+ oggpack_write(opb,vc->comments,32);
+ if(vc->comments){
+ int i;
+ for(i=0;i<vc->comments;i++){
+ if(vc->user_comments[i]){
+ oggpack_write(opb,vc->comment_lengths[i],32);
+ _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
+ }else{
+ oggpack_write(opb,0,32);
+ }
+ }
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ oggpack_write(opb,0x05,8);
+ _v_writestring(opb,"vorbis", 6);
+
+ /* books */
+ oggpack_write(opb,ci->books-1,8);
+ for(i=0;i<ci->books;i++)
+ if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
+
+ /* times */
+ oggpack_write(opb,ci->times-1,6);
+ for(i=0;i<ci->times;i++){
+ oggpack_write(opb,ci->time_type[i],16);
+ _time_P[ci->time_type[i]]->pack(ci->time_param[i],opb);
+ }
+
+ /* floors */
+ oggpack_write(opb,ci->floors-1,6);
+ for(i=0;i<ci->floors;i++){
+ oggpack_write(opb,ci->floor_type[i],16);
+ _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
+ }
+
+ /* residues */
+ oggpack_write(opb,ci->residues-1,6);
+ for(i=0;i<ci->residues;i++){
+ oggpack_write(opb,ci->residue_type[i],16);
+ _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
+ }
+
+ /* maps */
+ oggpack_write(opb,ci->maps-1,6);
+ for(i=0;i<ci->maps;i++){
+ oggpack_write(opb,ci->map_type[i],16);
+ _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
+ }
+
+ /* modes */
+ oggpack_write(opb,ci->modes-1,6);
+ for(i=0;i<ci->modes;i++){
+ oggpack_write(opb,ci->mode_param[i]->blockflag,1);
+ oggpack_write(opb,ci->mode_param[i]->windowtype,16);
+ oggpack_write(opb,ci->mode_param[i]->transformtype,16);
+ oggpack_write(opb,ci->mode_param[i]->mapping,8);
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+err_out:
+ return(-1);
+}
+
+int vorbis_commentheader_out(vorbis_comment *vc,
+ ogg_packet *op){
+
+ oggpack_buffer opb;
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
+
+ op->packet = _ogg_malloc(oggpack_bytes(&opb));
+ memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
+
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=0;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ return 0;
+}
+
+int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code){
+ int ret=OV_EIMPL;
+ vorbis_info *vi=v->vi;
+ oggpack_buffer opb;
+ backend_lookup_state *b=v->backend_state;
+
+ if(!b){
+ ret=OV_EFAULT;
+ goto err_out;
+ }
+
+ /* first header packet **********************************************/
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_info(&opb,vi))goto err_out;
+
+ /* build the packet */
+ if(b->header)_ogg_free(b->header);
+ b->header=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
+ op->packet=b->header;
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=1;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ /* second header packet (comments) **********************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_comment(&opb,vc))goto err_out;
+
+ if(b->header1)_ogg_free(b->header1);
+ b->header1=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
+ op_comm->packet=b->header1;
+ op_comm->bytes=oggpack_bytes(&opb);
+ op_comm->b_o_s=0;
+ op_comm->e_o_s=0;
+ op_comm->granulepos=0;
+
+ /* third header packet (modes/codebooks) ****************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_books(&opb,vi))goto err_out;
+
+ if(b->header2)_ogg_free(b->header2);
+ b->header2=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
+ op_code->packet=b->header2;
+ op_code->bytes=oggpack_bytes(&opb);
+ op_code->b_o_s=0;
+ op_code->e_o_s=0;
+ op_code->granulepos=0;
+
+ oggpack_writeclear(&opb);
+ return(0);
+ err_out:
+ oggpack_writeclear(&opb);
+ memset(op,0,sizeof(*op));
+ memset(op_comm,0,sizeof(*op_comm));
+ memset(op_code,0,sizeof(*op_code));
+
+ if(b->header)_ogg_free(b->header);
+ if(b->header1)_ogg_free(b->header1);
+ if(b->header2)_ogg_free(b->header2);
+ b->header=NULL;
+ b->header1=NULL;
+ b->header2=NULL;
+ return(ret);
+}
+
diff --git a/lib/mapping0.c b/lib/mapping0.c
new file mode 100644
index 00000000..4052f5ef
--- /dev/null
+++ b/lib/mapping0.c
@@ -0,0 +1,706 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+ last mod: $Id: mapping0.c,v 1.39.2.1 2001/12/17 05:39:24 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "registry.h"
+#include "psy.h"
+#include "misc.h"
+
+/* simplistic, wasteful way of doing this (unique lookup for each
+ mode/submapping); there should be a central repository for
+ identical lookups. That will require minor work, so I'm putting it
+ off as low priority.
+
+ Why a lookup for each backend in a given mode? Because the
+ blocksize is set by the mode, and low backend lookups may require
+ parameters from other areas of the mode/mapping */
+
+extern int analysis_noisy;
+
+typedef struct {
+ drft_lookup fft_look;
+ vorbis_info_mode *mode;
+ vorbis_info_mapping0 *map;
+
+ vorbis_look_time **time_look;
+ vorbis_look_floor **floor_look;
+
+ vorbis_look_residue **residue_look;
+ vorbis_look_psy *psy_look[2];
+
+ vorbis_func_time **time_func;
+ vorbis_func_floor **floor_func;
+ vorbis_func_residue **residue_func;
+
+ int ch;
+ long lastframe; /* if a different mode is called, we need to
+ invalidate decay */
+} vorbis_look_mapping0;
+
+static vorbis_info_mapping *mapping0_copy_info(vorbis_info_mapping *vm){
+ vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
+ vorbis_info_mapping0 *ret=_ogg_malloc(sizeof(*ret));
+ memcpy(ret,info,sizeof(*ret));
+ return(ret);
+}
+
+static void mapping0_free_info(vorbis_info_mapping *i){
+ vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
+ if(info){
+ memset(info,0,sizeof(*info));
+ _ogg_free(info);
+ }
+}
+
+static void mapping0_free_look(vorbis_look_mapping *look){
+ int i;
+ vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
+ if(l){
+ drft_clear(&l->fft_look);
+
+ for(i=0;i<l->map->submaps;i++){
+ l->time_func[i]->free_look(l->time_look[i]);
+ l->floor_func[i]->free_look(l->floor_look[i]);
+ l->residue_func[i]->free_look(l->residue_look[i]);
+ }
+ if(l->psy_look[1] && l->psy_look[1]!=l->psy_look[0]){
+ _vp_psy_clear(l->psy_look[1]);
+ _ogg_free(l->psy_look[1]);
+ }
+ if(l->psy_look[0]){
+ _vp_psy_clear(l->psy_look[0]);
+ _ogg_free(l->psy_look[0]);
+ }
+ _ogg_free(l->time_func);
+ _ogg_free(l->floor_func);
+ _ogg_free(l->residue_func);
+ _ogg_free(l->time_look);
+ _ogg_free(l->floor_look);
+ _ogg_free(l->residue_look);
+ memset(l,0,sizeof(*l));
+ _ogg_free(l);
+ }
+}
+
+static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
+ vorbis_info_mapping *m){
+ int i;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_look_mapping0 *look=_ogg_calloc(1,sizeof(*look));
+ vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
+ look->mode=vm;
+
+ look->time_look=_ogg_calloc(info->submaps,sizeof(*look->time_look));
+ look->floor_look=_ogg_calloc(info->submaps,sizeof(*look->floor_look));
+
+ look->residue_look=_ogg_calloc(info->submaps,sizeof(*look->residue_look));
+
+ look->time_func=_ogg_calloc(info->submaps,sizeof(*look->time_func));
+ look->floor_func=_ogg_calloc(info->submaps,sizeof(*look->floor_func));
+ look->residue_func=_ogg_calloc(info->submaps,sizeof(*look->residue_func));
+
+ for(i=0;i<info->submaps;i++){
+ int timenum=info->timesubmap[i];
+ int floornum=info->floorsubmap[i];
+ int resnum=info->residuesubmap[i];
+
+ look->time_func[i]=_time_P[ci->time_type[timenum]];
+ look->time_look[i]=look->time_func[i]->
+ look(vd,vm,ci->time_param[timenum]);
+ look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
+ look->floor_look[i]=look->floor_func[i]->
+ look(vd,vm,ci->floor_param[floornum]);
+ look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
+ look->residue_look[i]=look->residue_func[i]->
+ look(vd,vm,ci->residue_param[resnum]);
+
+ }
+ if(ci->psys && vd->analysisp){
+ if(info->psy[0] != info->psy[1]){
+
+ int psynum=info->psy[0];
+ look->psy_look[0]=_ogg_calloc(1,sizeof(*look->psy_look[0]));
+ _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
+ &ci->psy_g_param,
+ ci->blocksizes[vm->blockflag]/2,vi->rate);
+
+ psynum=info->psy[1];
+ look->psy_look[1]=_ogg_calloc(1,sizeof(*look->psy_look[1]));
+ _vp_psy_init(look->psy_look[1],ci->psy_param[psynum],
+ &ci->psy_g_param,
+ ci->blocksizes[vm->blockflag]/2,vi->rate);
+ }else{
+
+ int psynum=info->psy[0];
+ look->psy_look[0]=_ogg_calloc(1,sizeof(*look->psy_look[0]));
+ look->psy_look[1]=look->psy_look[0];
+ _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
+ &ci->psy_g_param,
+ ci->blocksizes[vm->blockflag]/2,vi->rate);
+
+ }
+ }
+
+ look->ch=vi->channels;
+
+ if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]);
+ return(look);
+}
+
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
+ oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
+
+ /* another 'we meant to do it this way' hack... up to beta 4, we
+ packed 4 binary zeros here to signify one submapping in use. We
+ now redefine that to mean four bitflags that indicate use of
+ deeper features; bit0:submappings, bit1:coupling,
+ bit2,3:reserved. This is backward compatable with all actual uses
+ of the beta code. */
+
+ if(info->submaps>1){
+ oggpack_write(opb,1,1);
+ oggpack_write(opb,info->submaps-1,4);
+ }else
+ oggpack_write(opb,0,1);
+
+ if(info->coupling_steps>0){
+ oggpack_write(opb,1,1);
+ oggpack_write(opb,info->coupling_steps-1,8);
+
+ for(i=0;i<info->coupling_steps;i++){
+ oggpack_write(opb,info->coupling_mag[i],ilog2(vi->channels));
+ oggpack_write(opb,info->coupling_ang[i],ilog2(vi->channels));
+ }
+ }else
+ oggpack_write(opb,0,1);
+
+ oggpack_write(opb,0,2); /* 2,3:reserved */
+
+ /* we don't write the channel submappings if we only have one... */
+ if(info->submaps>1){
+ for(i=0;i<vi->channels;i++)
+ oggpack_write(opb,info->chmuxlist[i],4);
+ }
+ for(i=0;i<info->submaps;i++){
+ oggpack_write(opb,info->timesubmap[i],8);
+ oggpack_write(opb,info->floorsubmap[i],8);
+ oggpack_write(opb,info->residuesubmap[i],8);
+ }
+}
+
+/* also responsible for range checking */
+static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
+ codec_setup_info *ci=vi->codec_setup;
+ memset(info,0,sizeof(*info));
+
+ if(oggpack_read(opb,1))
+ info->submaps=oggpack_read(opb,4)+1;
+ else
+ info->submaps=1;
+
+ if(oggpack_read(opb,1)){
+ info->coupling_steps=oggpack_read(opb,8)+1;
+
+ for(i=0;i<info->coupling_steps;i++){
+ int testM=info->coupling_mag[i]=oggpack_read(opb,ilog2(vi->channels));
+ int testA=info->coupling_ang[i]=oggpack_read(opb,ilog2(vi->channels));
+
+ if(testM<0 ||
+ testA<0 ||
+ testM==testA ||
+ testM>=vi->channels ||
+ testA>=vi->channels) goto err_out;
+ }
+
+ }
+
+ if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
+
+ if(info->submaps>1){
+ for(i=0;i<vi->channels;i++){
+ info->chmuxlist[i]=oggpack_read(opb,4);
+ if(info->chmuxlist[i]>=info->submaps)goto err_out;
+ }
+ }
+ for(i=0;i<info->submaps;i++){
+ info->timesubmap[i]=oggpack_read(opb,8);
+ if(info->timesubmap[i]>=ci->times)goto err_out;
+ info->floorsubmap[i]=oggpack_read(opb,8);
+ if(info->floorsubmap[i]>=ci->floors)goto err_out;
+ info->residuesubmap[i]=oggpack_read(opb,8);
+ if(info->residuesubmap[i]>=ci->residues)goto err_out;
+ }
+
+ return info;
+
+ err_out:
+ mapping0_free_info(info);
+ return(NULL);
+}
+
+#include "os.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "psy.h"
+#include "scales.h"
+
+/* no time mapping implementation for now */
+static long seq=0;
+static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ backend_lookup_state *b=vb->vd->backend_state;
+ bitrate_manager_state *bm=&b->bms;
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *info=look->map;
+ vorbis_info_mode *mode=look->mode;
+ vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
+ int n=vb->pcmend;
+ int i,j;
+ float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+ int *nonzero=alloca(sizeof(*nonzero)*vi->channels);
+
+ float *work=_vorbis_block_alloc(vb,n*sizeof(*work));
+
+ float global_ampmax=vbi->ampmax;
+ float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
+ int blocktype=vbi->blocktype;
+
+ /* we differentiate between short and long block types to help the
+ masking engine; the window shapes also matter.
+ impulse block (a short block in which an impulse occurs)
+ padding block (a short block that pads between a transitional
+ long block and an impulse block, or vice versa)
+ transition block (the wqeird one; a long block with the transition
+ window; affects bass/midrange response and that must be
+ accounted for in masking)
+ long block (run of the mill long block)
+ */
+
+ for(i=0;i<vi->channels;i++){
+ float scale=4.f/n;
+
+ /* the following makes things clearer to *me* anyway */
+ float *pcm =vb->pcm[i];
+ float *fft =work;
+ float *logfft =pcm+n/2;
+
+ /*float *res =pcm;
+ float *mdct =pcm;
+ float *codedflr=pcm+n/2;
+ float *logmax =work;
+ float *logmask =work+n/2;*/
+
+ _analysis_output("pcm",seq+i,pcm,n,0,0);
+
+ /* window the PCM data */
+ for(j=0;j<n;j++)
+ fft[j]=pcm[j]*=window[j];
+
+ //_analysis_output("windowed",seq+i,pcm,n,0,0);
+
+ /* transform the PCM data */
+ /* only MDCT right now.... */
+ mdct_forward(b->transform[vb->W][0],pcm,pcm);
+
+ /* FFT yields more accurate tonal estimation (not phase sensitive) */
+ drft_forward(&look->fft_look,fft);
+ fft[0]*=scale;
+ logfft[0]=todB(fft);
+ local_ampmax[i]=logfft[0];
+ for(j=1;j<n-1;j+=2){
+ float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
+ temp=logfft[(j+1)>>1]=todB(&temp);
+ if(temp>local_ampmax[i])local_ampmax[i]=temp;
+ }
+
+ if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
+ if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
+
+ _analysis_output("fft",seq+i,logfft,n/2,1,0);
+ }
+
+ for(i=0;i<vi->channels;i++){
+ int submap=info->chmuxlist[i];
+
+ /* the following makes things clearer to *me* anyway */
+ float *mdct =vb->pcm[i];
+ float *res =mdct;
+ float *codedflr=mdct+n/2;
+ float *logfft =mdct+n/2;
+
+ float *logmdct =work;
+ float *logmax =mdct+n/2;
+ float *logmask =work+n/2;
+
+ for(j=0;j<n/2;j++)
+ logmdct[j]=todB(mdct+j);
+ _analysis_output("mdct",seq+i,logmdct,n/2,1,0);
+
+
+ /* perform psychoacoustics; do masking */
+ _vp_compute_mask(look->psy_look[blocktype],
+ b->psy_g_look,
+ i,
+ logfft, /* -> logmax */
+ logmdct,
+ logmask,
+ global_ampmax,
+ local_ampmax[i],
+ ci->blocksizes[vb->lW]/2,
+ bm->avgnoise);
+
+ _analysis_output("mask",seq+i,logmask,n/2,1,0);
+ /* perform floor encoding */
+ nonzero[i]=look->floor_func[submap]->
+ forward(vb,look->floor_look[submap],
+ mdct,
+ logmdct,
+ logmask,
+ logmax,
+
+ codedflr);
+
+
+ _vp_remove_floor(look->psy_look[blocktype],
+ b->psy_g_look,
+ logmdct,
+ mdct,
+ codedflr,
+ res,
+ local_ampmax[i]);
+
+ /*for(j=0;j<n/2;j++)
+ if(fabs(res[j])>1200){
+ analysis_noisy=1;
+ fprintf(stderr,"%ld ",seq+i);
+ }*/
+
+ //_analysis_output("res",seq+i,res,n/2,1,0);
+ _analysis_output("codedflr",seq+i,codedflr,n/2,1,1);
+
+ }
+
+ vbi->ampmax=global_ampmax;
+
+ /* partition based prequantization and channel coupling */
+ /* Steps in prequant and coupling:
+
+ classify by |mag| across all pcm vectors
+
+ down-couple/down-quantize from perfect residue -> quantized vector
+
+ do{
+ encode quantized vector; add encoded values to 'so-far' vector
+ more? [not yet at bitrate/not yet at target]
+ yes{
+ down-couple/down-quantize from perfect-'so-far' ->
+ quantized vector; when subtracting coupling,
+ account for +/- out-of-phase component
+ }no{
+ break
+ }
+ }
+ done.
+
+ quantization in each iteration is done (after circular normalization
+ in coupling) using a by-iteration quantization granule value.
+ */
+
+ {
+ float **pcm=vb->pcm;
+ float **quantized=alloca(sizeof(*quantized)*vi->channels);
+ float **sofar=alloca(sizeof(*sofar)*vi->channels);
+
+ long ***classifications=alloca(sizeof(*classifications)*info->submaps);
+ float ***qbundle=alloca(sizeof(*qbundle)*info->submaps);
+ float ***pcmbundle=alloca(sizeof(*pcmbundle)*info->submaps);
+ float ***sobundle=alloca(sizeof(*sobundle)*info->submaps);
+ int **zerobundle=alloca(sizeof(*zerobundle)*info->submaps);
+ int *chbundle=alloca(sizeof(*chbundle)*info->submaps);
+ int chcounter=0;
+
+ /* play a little loose with this abstraction */
+ int quant_passes=ci->coupling_passes;
+
+ for(i=0;i<vi->channels;i++){
+ quantized[i]=_vorbis_block_alloc(vb,n*sizeof(*sofar[i]));
+ sofar[i]=quantized[i]+n/2;
+ memset(sofar[i],0,sizeof(*sofar[i])*n/2);
+ }
+
+ qbundle[0]=alloca(sizeof(*qbundle[0])*vi->channels);
+ pcmbundle[0]=alloca(sizeof(*pcmbundle[0])*vi->channels);
+ sobundle[0]=alloca(sizeof(*sobundle[0])*vi->channels);
+ zerobundle[0]=alloca(sizeof(*zerobundle[0])*vi->channels);
+
+ /* initial down-quantized coupling */
+
+ if(info->coupling_steps==0){
+ /* this assumes all or nothing coupling right now. it should pass
+ through any channels left uncoupled, but it doesn't do that now */
+ for(i=0;i<vi->channels;i++){
+ float *lpcm=pcm[i];
+ float *lqua=quantized[i];
+ for(j=0;j<n/2;j++)
+ lqua[j]=lpcm[j];
+ }
+ }else{
+ _vp_quantize_couple(look->psy_look[blocktype],
+ info,
+ pcm,
+ sofar,
+ quantized,
+ nonzero,
+ 0);
+ }
+
+ //for(i=0;i<vi->channels;i++)
+ //_analysis_output("quant",seq+i,quantized[i],n/2,1,0);
+
+
+ /* classify, by submap */
+
+ for(i=0;i<info->submaps;i++){
+ int ch_in_bundle=0;
+ qbundle[i]=qbundle[0]+chcounter;
+ sobundle[i]=sobundle[0]+chcounter;
+ zerobundle[i]=zerobundle[0]+chcounter;
+
+ for(j=0;j<vi->channels;j++){
+ if(info->chmuxlist[j]==i){
+ if(nonzero[j])
+ zerobundle[i][ch_in_bundle]=1;
+ else
+ zerobundle[i][ch_in_bundle]=0;
+ qbundle[i][ch_in_bundle]=quantized[j];
+ pcmbundle[i][ch_in_bundle]=pcm[j];
+ sobundle[i][ch_in_bundle++]=sofar[j];
+ }
+ }
+ chbundle[i]=ch_in_bundle;
+ chcounter+=ch_in_bundle;
+
+ classifications[i]=look->residue_func[i]->
+ class(vb,look->residue_look[i],pcmbundle[i],zerobundle[i],chbundle[i]);
+ }
+
+ /* actual encoding loop; we pack all the iterations to collect
+ management data */
+
+ for(i=0;i<quant_passes;){
+
+ /* perform residue encoding of this pass's quantized residue
+ vector, according residue mapping */
+
+ for(j=0;j<info->submaps;j++){
+ look->residue_func[j]->
+ forward(vb,look->residue_look[j],
+ qbundle[j],sobundle[j],zerobundle[j],chbundle[j],
+ i,classifications[j],vbi->packet_markers);
+
+ }
+ i++;
+
+ if(i<quant_passes){
+ /* down-couple/down-quantize from perfect-'so-far' ->
+ new quantized vector */
+ if(info->coupling_steps==0){
+ /* this assumes all or nothing coupling right now. it should pass
+ through any channels left uncoupled, but it doesn't do that now */
+ int k;
+ for(k=0;k<vi->channels;k++){
+ float *lpcm=pcm[k];
+ float *lsof=sofar[k];
+ float *lqua=quantized[k];
+ for(j=0;j<n/2;j++)
+ lqua[j]=lpcm[j]-lsof[j];
+ }
+ }else{
+ _vp_quantize_couple(look->psy_look[blocktype],
+ info,
+ pcm,
+ sofar,
+ quantized,
+ nonzero,
+ i);
+
+ }
+ }
+ }
+ seq+=vi->channels;
+ }
+
+ look->lastframe=vb->sequence;
+ return(0);
+}
+
+static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ backend_lookup_state *b=vd->backend_state;
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *info=look->map;
+ vorbis_info_mode *mode=look->mode;
+ int i,j;
+ long n=vb->pcmend=ci->blocksizes[vb->W];
+
+ float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+ float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
+ int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
+
+ int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
+ void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
+
+ /* time domain information decode (note that applying the
+ information would have to happen later; we'll probably add a
+ function entry to the harness for that later */
+ /* NOT IMPLEMENTED */
+
+ /* recover the spectral envelope; store it in the PCM vector for now */
+ for(i=0;i<vi->channels;i++){
+ int submap=info->chmuxlist[i];
+ floormemo[i]=look->floor_func[submap]->
+ inverse1(vb,look->floor_look[submap]);
+ if(floormemo[i])
+ nonzero[i]=1;
+ else
+ nonzero[i]=0;
+ memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
+ }
+
+ /* channel coupling can 'dirty' the nonzero listing */
+ for(i=0;i<info->coupling_steps;i++){
+ if(nonzero[info->coupling_mag[i]] ||
+ nonzero[info->coupling_ang[i]]){
+ nonzero[info->coupling_mag[i]]=1;
+ nonzero[info->coupling_ang[i]]=1;
+ }
+ }
+
+ /* recover the residue into our working vectors */
+ for(i=0;i<info->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(info->chmuxlist[j]==i){
+ if(nonzero[j])
+ zerobundle[ch_in_bundle]=1;
+ else
+ zerobundle[ch_in_bundle]=0;
+ pcmbundle[ch_in_bundle++]=vb->pcm[j];
+ }
+ }
+
+ look->residue_func[i]->inverse(vb,look->residue_look[i],
+ pcmbundle,zerobundle,ch_in_bundle);
+ }
+
+ /* channel coupling */
+ for(i=info->coupling_steps-1;i>=0;i--){
+ float *pcmM=vb->pcm[info->coupling_mag[i]];
+ float *pcmA=vb->pcm[info->coupling_ang[i]];
+
+ for(j=0;j<n/2;j++){
+ float mag=pcmM[j];
+ float ang=pcmA[j];
+
+ if(mag>0)
+ if(ang>0){
+ pcmM[j]=mag;
+ pcmA[j]=mag-ang;
+ }else{
+ pcmA[j]=mag;
+ pcmM[j]=mag+ang;
+ }
+ else
+ if(ang>0){
+ pcmM[j]=mag;
+ pcmA[j]=mag+ang;
+ }else{
+ pcmA[j]=mag;
+ pcmM[j]=mag-ang;
+ }
+ }
+ }
+
+ /* compute and apply spectral envelope */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ int submap=info->chmuxlist[i];
+ look->floor_func[submap]->
+ inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
+ }
+
+ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+ /* only MDCT right now.... */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ mdct_backward(b->transform[vb->W][0],pcm,pcm);
+ }
+
+ /* window the data */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ if(nonzero[i])
+ for(j=0;j<n;j++)
+ pcm[j]*=window[j];
+ else
+ for(j=0;j<n;j++)
+ pcm[j]=0.f;
+
+ }
+
+ /* all done! */
+ return(0);
+}
+
+/* export hooks */
+vorbis_func_mapping mapping0_exportbundle={
+ &mapping0_pack,
+ &mapping0_unpack,
+ &mapping0_look,
+ &mapping0_copy_info,
+ &mapping0_free_info,
+ &mapping0_free_look,
+ &mapping0_forward,
+ &mapping0_inverse
+};
diff --git a/lib/modes/psych_44.h b/lib/modes/psych_44.h
new file mode 100644
index 00000000..95dc57ff
--- /dev/null
+++ b/lib/modes/psych_44.h
@@ -0,0 +1,641 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: key psychoacoustic settings for 44.1/48kHz
+ last mod: $Id: psych_44.h,v 1.3.2.1 2001/12/17 05:39:26 xiphmont Exp $
+
+ ********************************************************************/
+
+
+/* preecho trigger settings *****************************************/
+
+static vorbis_info_psy_global _psy_global_44[3]={
+
+ {8, /* lines per eighth octave */
+ //{990.f,990.f,990.f,990.f}, {-990.f,-990.f,-990.f,-990.f}, -90.f,
+ //{0.f,0.f,0.f,0.f}, {-0.f,-0.f,-0.f,-0.f}, -90.f,
+ {30.f,30.f,30.f,34.f}, {-990.f,-990.f,-990.f,-990.f}, -90.f,
+ -6.f, 0,
+ },
+ {8, /* lines per eighth octave */
+ // {990.f,990.f,990.f,990.f}, {-990.f,-990.f,-990.f,-990.f}, -90.f,
+ {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
+ -6.f, 0,
+ },
+ {8, /* lines per eighth octave */
+ {26.f,26.f,26.f,30.f}, {-26.f,-26.f,-26.f,-30.f}, -90.f,
+ -6.f, 0,
+ }
+};
+
+/* noise compander lookups * low, mid, high quality ****************/
+
+static float _psy_compand_44_short[3][NOISE_COMPAND_LEVELS]={
+ /* sub-mode Z */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, /* 7dB */
+ 8.f, 9.f,10.f,11.f,12.f,13.f,14.f, 15.f, /* 15dB */
+ 16.f,17.f,18.f,19.f,20.f,21.f,22.f, 23.f, /* 23dB */
+ 24.f,25.f,26.f,27.f,28.f,29.f,30.f, 31.f, /* 31dB */
+ 32.f,33.f,34.f,35.f,36.f,37.f,38.f, 39.f, /* 39dB */
+ },
+ /* mode_Z nominal */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f, /* 7dB */
+ 7.f, 7.f, 7.f, 7.f, 6.f, 6.f, 6.f, 7.f, /* 15dB */
+ 7.f, 8.f, 9.f,10.f,11.f,12.f,13.f, 14.f, /* 23dB */
+ 15.f,16.f,17.f,17.f,17.f,18.f,18.f, 19.f, /* 31dB */
+ 19.f,19.f,20.f,21.f,22.f,23.f,24.f, 25.f, /* 39dB */
+ },
+ /* mode A */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 5.f, 5.f, /* 7dB */
+ 6.f, 6.f, 6.f, 5.f, 4.f, 4.f, 4.f, 4.f, /* 15dB */
+ 4.f, 4.f, 5.f, 5.f, 5.f, 6.f, 6.f, 6.f, /* 23dB */
+ 7.f, 7.f, 7.f, 8.f, 8.f, 8.f, 9.f, 10.f, /* 31dB */
+ 11.f,12.f,13.f,14.f,15.f,16.f,17.f, 18.f, /* 39dB */
+ }
+};
+
+static float _psy_compand_44[3][NOISE_COMPAND_LEVELS]={
+ /* sub-mode Z */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, /* 7dB */
+ 8.f, 9.f,10.f,11.f,12.f,13.f,14.f, 15.f, /* 15dB */
+ 16.f,17.f,18.f,19.f,20.f,21.f,22.f, 23.f, /* 23dB */
+ 24.f,25.f,26.f,27.f,28.f,29.f,30.f, 31.f, /* 31dB */
+ 32.f,33.f,34.f,35.f,36.f,37.f,38.f, 39.f, /* 39dB */
+ },
+ /* mode_Z nominal */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, /* 7dB */
+ 8.f, 9.f,10.f,11.f,12.f,12.f,13.f, 13.f, /* 15dB */
+ 13.f,14.f,14.f,14.f,15.f,15.f,15.f, 15.f, /* 23dB */
+ 16.f,16.f,17.f,17.f,17.f,18.f,18.f, 19.f, /* 31dB */
+ 19.f,19.f,20.f,21.f,22.f,23.f,24.f, 25.f, /* 39dB */
+ },
+ /* mode A */
+ {
+ 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, /* 7dB */
+ 8.f, 8.f, 7.f, 6.f, 5.f, 4.f, 4.f, 4.f, /* 15dB */
+ 4.f, 4.f, 5.f, 5.f, 5.f, 6.f, 6.f, 6.f, /* 23dB */
+ 7.f, 7.f, 7.f, 8.f, 8.f, 8.f, 9.f, 10.f, /* 31dB */
+ 11.f,12.f,13.f,14.f,15.f,16.f,17.f, 18.f, /* 39dB */
+ }
+};
+
+/* tonal masking curve level adjustments *************************/
+static vp_adjblock _vp_tonemask_adj_longblock[6]={
+ /* adjust for mode zero */
+ {{
+ { 10, 10, 5, }, /*63*/
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 125 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 250 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 500 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 1000 */
+ { 10, 10, 5, },
+
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /* 2000 */
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /* 4000 */
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /* 8000 */
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 16, 16, 14, 12, 12, 15, 15, 15, 15, 15, 10}, /* 16000 */
+ }},
+
+ /* adjust for mode two */
+ {{
+ { 10, 10, 5, }, /*63*/
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 125 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 250 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 500 */
+ { 10, 10, 5, },
+ { 10, 10, 5, }, /* 1000 */
+ { 10, 10, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 10, 5, 5, }, /* 4000 */
+ { 10, 10, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 7, 5, 5, 10, 10, 10, 5, },
+ { 16, 16, 14, 8, 8, 8, 10, 10, 10, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode four */
+ {{
+ { 10, 5, 5, }, /*63*/
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 125 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 250 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 500 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 1000 */
+ { 10, 5, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 10, 5, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 5, 5, 5, 10, 10, 10, 5, },
+ { 16, 16, 14, 8, 8, 8, 10, 10, 10, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode six */
+ {{
+ { 10, 5, 5, }, /*63*/
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 125 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 250 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 500 */
+ { 10, 5, 5, },
+ { 10, 5, 5, }, /* 1000 */
+ { 10, 5, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 10, 5, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 5, 5, 5, 5, 5, 5, },
+ { 12, 10, 10, 5, 5, 5, 5, 5, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode eight */
+ {{
+ { 0, }, /*63*/
+ { 0, },
+ { 0, }, /* 125 */
+ { 0, },
+ { 0, }, /* 250 */
+ { 0, },
+ { 0, }, /* 500 */
+ { 0, },
+ { 0, }, /* 1000 */
+ { 0, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 0, },
+ { 0, }, /* 8000 */
+ { 0, },
+ { 5, 5, 5, 5, 5, 5, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode ten */
+ {{
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*63*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*125*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*250*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*500*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*1000*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*2000*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*4000*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*8000*/
+ { 0, 0, 0, -5,-10,-10,-10,-15,-15,-15,-15},
+ { 0, 0, 0, 0, 0, -5, -5,-10,-15,-15,-15}, /*16000*/
+ }},
+};
+
+static vp_adjblock _vp_tonemask_adj_otherblock[6]={
+ /* adjust for mode zero */
+ {{
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*63*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*125*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*250*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 5, 5, 5, 0, -5, -5, -5, -5, -5, -5, -5}, /*500*/
+ { 5, 5, 5, 0, -5, -5, -5, -5, -5, -5, -5},
+
+ { 5, 5, 5, }, /*1000*/
+ { 5, 5, 5, },
+
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /*2000*/
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /*4000*/
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, /*8000*/
+ { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
+ { 16, 16, 14, 12, 12, 15, 15, 15, 15, 15, 10}, /*16000*/
+ }},
+
+ /* adjust for mode two */
+ {{
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*63*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*125*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10}, /*250*/
+ { 0, 0, 0, 0,-10,-10,-10,-10,-10,-10,-10},
+ { 5, 5, 5, 0, -5, -5, -5, -5, -5, -5, -5}, /*500*/
+ { 5, 5, 5, 0, -5, -5, -5, -5, -5, -5, -5},
+
+ { 10, 10, 5, }, /* 1000 */
+ { 10, 10, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 10, 5, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 7, 5, 5, 10, 10, 10, 5, },
+ { 16, 16, 14, 8, 8, 8, 10, 10, 10, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode four */
+ {{
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*63*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*125*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*250*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*500*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+
+ { 5, 5, 5, }, /* 1000 */
+ { 5, 5, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 10, 5, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 5, 5, 5, 10, 10, 10, 5, },
+ { 16, 16, 14, 8, 8, 8, 10, 10, 10, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode six */
+ {{
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*63*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*125*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*250*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*500*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+
+ { 5, 5, 5, }, /* 1000 */
+ { 5, 5, 5, },
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 10, 5, 5, },
+ { 10, 10, 7, 5, }, /* 8000 */
+ { 10, 10, 7, 5, 5, 5, 5, 5, 5, },
+ { 12, 10, 10, 5, 5, 5, 5, 5, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode eight */
+ {{
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20}, /*63*/
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20},
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20}, /*125*/
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20},
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20}, /*250*/
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20},
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20}, /*500*/
+ {-10,-10,-10,-15,-15,-15,-15,-20,-20,-20,-20},
+
+ { 0,-10,-10,-15,-15,-15,-15,-15,-15,-15,-15},
+ { 0,-10,-10,-15,-15,-15,-15,-15,-15,-15,-15},
+
+ { 0, }, /* 2000 */
+ { 0, },
+ { 0, }, /* 4000 */
+ { 0, },
+ { 0, }, /* 8000 */
+ { 0, },
+ { 5, 5, 5, 5, 5, 5, 5, }, /* 16000 */
+ }},
+
+ /* adjust for mode ten */
+ {{
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20}, /*63*/
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20},
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20}, /*125*/
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20},
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20}, /*250*/
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20},
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20}, /*500*/
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20},
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20}, /*1000*/
+ { 0, 0, 0, -5,-15,-20,-20,-20,-20,-20,-20},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*2000*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*4000*/
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15},
+ { 0, 0, 0, -5,-15,-15,-15,-15,-15,-15,-15}, /*8000*/
+ { 0, 0, 0, -5,-10,-10,-10,-15,-15,-15,-15},
+ { 0, 0, 0, 0, 0, -5, -5,-10,-15,-15,-15}, /*16000*/
+ }},
+};
+
+static vp_adjblock _vp_peakguard[6]={
+ /* zero */
+ {{
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},/*63*/
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},/*125*/
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},/*250*/
+ {-14,-16,-18,-19,-24,-24,-24,-24,-24,-24,-24},
+ {-10,-10,-10,-10,-16,-16,-18,-20,-22,-24,-24},/*500*/
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-24,-24},
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-24,-24},/*1000*/
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-24,-24},
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-24,-24},/*2000*/
+ {-10,-10,-10,-12,-16,-16,-16,-20,-22,-24,-24},
+ {-10,-10,-10,-12,-16,-16,-16,-20,-22,-24,-24},/*4000*/
+ {-10,-10,-10,-12,-12,-14,-16,-18,-22,-24,-24},
+ {-10,-10,-10,-10,-10,-14,-16,-18,-22,-24,-24},/*8000*/
+ {-10,-10,-10,-10,-10,-14,-16,-18,-22,-24,-24},
+ {-10,-10,-10,-10,-10,-12,-16,-18,-22,-24,-24},/*16000*/
+ }},
+ /* two */
+ {{
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},/*63*/
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},/*125*/
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},/*250*/
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},
+ {-14,-20,-20,-20,-26,-30,-30,-30,-30,-30,-30},/*500*/
+ {-10,-10,-10,-10,-14,-14,-14,-20,-26,-30,-30},
+ {-10,-10,-10,-10,-14,-14,-14,-20,-22,-30,-30},/*1000*/
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-30,-30},
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-30,-30},/*2000*/
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-30,-30},
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-30,-30},/*4000*/
+ {-10,-10,-10,-10,-10,-11,-12,-13,-22,-30,-30},
+ {-10,-10,-10,-10,-10,-11,-12,-13,-22,-30,-30},/*8000*/
+ {-10,-10,-10,-10,-10,-10,-10,-11,-22,-30,-30},
+ {-10,-10,-10,-10,-10,-10,-10,-10,-20,-30,-30},/*16000*/
+ }},
+ /* four */
+ {{
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*63*/
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*125*/
+ {-14,-20,-20,-20,-20,-20,-20,-30,-32,-32,-40},
+ {-14,-20,-20,-20,-20,-20,-20,-30,-32,-32,-40},/*250*/
+ {-14,-20,-20,-20,-20,-20,-20,-24,-32,-32,-40},
+ {-14,-20,-20,-20,-20,-20,-20,-24,-32,-32,-40},/*500*/
+ {-10,-10,-10,-10,-14,-16,-20,-24,-26,-32,-40},
+ {-10,-10,-10,-10,-14,-16,-20,-24,-22,-32,-40},/*1000*/
+ {-10,-10,-10,-10,-14,-16,-20,-24,-22,-32,-40},
+ {-10,-10,-10,-10,-14,-16,-20,-24,-22,-32,-40},/*2000*/
+ {-10,-10,-10,-10,-14,-16,-20,-24,-22,-32,-40},
+ {-10,-10,-10,-10,-14,-14,-16,-20,-22,-32,-40},/*4000*/
+ {-10,-10,-10,-10,-10,-11,-12,-13,-22,-32,-40},
+ {-10,-10,-10,-10,-10,-11,-12,-13,-22,-32,-40},/*8000*/
+ {-10,-10,-10,-10,-10,-10,-10,-11,-22,-32,-40},
+ {-10,-10,-10,-10,-10,-10,-10,-10,-20,-32,-40},/*16000*/
+ }},
+ /* six */
+ {{
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*63*/
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*125*/
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*250*/
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},
+ {-14,-20,-20,-20,-26,-32,-32,-32,-32,-32,-40},/*500*/
+ {-14,-14,-14,-16,-20,-22,-24,-24,-28,-32,-40},
+ {-14,-14,-14,-16,-20,-22,-24,-24,-28,-32,-40},/*1000*/
+ {-14,-14,-14,-16,-20,-22,-24,-24,-28,-32,-40},
+ {-14,-14,-16,-20,-24,-26,-26,-28,-30,-32,-40},/*2000*/
+ {-14,-14,-16,-20,-24,-26,-26,-28,-30,-32,-40},
+ {-14,-14,-16,-20,-24,-26,-26,-28,-30,-32,-40},/*4000*/
+ {-14,-14,-14,-20,-22,-22,-24,-24,-26,-32,-40},
+ {-14,-14,-14,-18,-20,-20,-24,-24,-24,-32,-40},/*8000*/
+ {-14,-14,-14,-18,-20,-20,-24,-24,-24,-32,-40},
+ {-14,-14,-14,-18,-20,-20,-22,-24,-24,-32,-40},/*16000*/
+ }},
+ /* eight */
+ {{
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*63*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*88*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*125*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*170*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*250*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*350*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*500*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*700*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*1000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*1400*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*2000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*2800*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*4000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*5600*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*8000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*11500*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-40,-40},/*16600*/
+ }},
+ /* ten */
+ {{
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*63*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*88*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*125*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*170*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*250*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*350*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*500*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*700*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*1000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*1400*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*2000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*2800*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*4000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*5600*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*8000*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*11500*/
+ {-14,-20,-24,-26,-32,-34,-36,-38,-40,-44,-46},/*16600*/
+ }}
+};
+
+static int _psy_noisebias_long[11][17]={
+ /*63 125 250 500 1k 2k 4k 8k 16k*/
+ {-20,-20,-18,-18,-18,-16,-14, -8, -6, -2, 0, 2, 3, 3, 4, 4, 10},
+ {-20,-20,-20,-20,-20,-20,-20,-10, -6, -2, -2, -2, 1, 1, 2, 2, 4},
+ {-20,-20,-20,-20,-20,-20,-20,-10, -6, -2, -3, -3, -1, -1, 0, 1, 2},
+ {-20,-20,-20,-20,-20,-20,-20,-10, -6, -2, -3, -3, -1, -1, 0, 1, 2},
+ {-20,-20,-20,-20,-20,-20,-20,-10, -6, -3, -4, -4, -2, -1, 0, 0, 2},
+
+ {-20,-20,-20,-20,-20,-20,-20,-18,-10, -4, -6, -6, -3, -2, -2, -2, 0},
+ {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -8, -8, -7, -7, -6, -6, -4},
+ {-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-16,-16,-14,-12,-10,-10, -8},
+
+ {-24,-24,-24,-24,-24,-24,-24,-20,-20,-20,-20,-20,-16,-16,-14,-14,-10},
+ {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-24,-24,-24},
+ {-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-46},
+};
+
+static int _psy_noisebias_impulse[11][17]={
+ /*63 125 250 500 1k 2k 4k 8k 16k*/
+ {-20,-20,-20,-20,-20,-18,-14,-10,-10, -2, 2, 2, 2, 2, 2, 3, 6},
+ {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -2, -2, -2, -2, 2},
+ {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0},
+ {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, -2},
+ {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2},
+
+ {-30,-30,-30,-30,-30,-30,-24,-20,-10,-12,-14,-14,-10, -9, -8, -6, -4},
+ {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10, -8},
+ {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14},
+
+ {-34,-34,-34,-34,-30,-30,-30,-30,-30,-26,-26,-26,-26,-22,-20,-20,-16},
+ {-40,-40,-40,-40,-40,-40,-40,-40,-40,-36,-36,-36,-36,-36,-36,-30,-30},
+ {-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50},
+};
+
+static int _psy_noisebias_other[11][17]={
+ /*63 125 250 500 1k 2k 4k 8k 16k*/
+ {-20,-20,-20,-20,-20,-18,-14,-10, -6, -2, 2, 2, 3, 3, 4, 4, 10},
+ {-26,-26,-26,-26,-26,-22,-20,-14,-10, -2, -2, -2, 1, 1, 2, 2, 4},
+ {-30,-30,-30,-30,-26,-22,-20,-14,-10, -2, -3, -3, -1, -1, 0, 1, 2},
+ {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -1, -1, 0, 1, 2},
+ {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -2, -1, 0, 0, 2},
+
+ {-30,-30,-30,-30,-30,-30,-24,-20,-10, -4, -6, -6, -3, -2, -2, -2, 0},
+ {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -8, -8, -7, -7, -6, -6, -4},
+ {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10, -8},
+
+ {-34,-34,-34,-34,-30,-30,-30,-20,-20,-20,-20,-20,-16,-16,-14,-14,-10},
+ {-40,-40,-40,-40,-40,-40,-40,-30,-30,-30,-30,-30,-30,-24,-24,-24,-24},
+ {-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-46},
+};
+
+static int _psy_noiseguards_short[33]={
+ 2,2,-1,
+ 4,4,-1,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+ 4,4,15,
+};
+static int _psy_noiseguards_long[33]={
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+ 10,10,100,
+};
+
+static double _psy_tone_masteratt[11]={
+ 3.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
+};
+
+static double _psy_tone_masterguard[11]={
+ -18.,-24.,-24.,-24.,-26.,-40.,-40.,-40.,-40.,-45.,-45.,-45.,
+};
+
+static double _psy_tone_suppress[11]={
+ -10.,-20.,-20.,-20.,-30.,-30.,-40.,-40.,-40.,-45.,-45.,-45.,
+};
+
+static double _psy_tone_0dB[11]={
+ 95.,95.,95.,95.,95.,105.,105.,105.,105.,105.,105.,
+};
+
+static double _psy_noise_suppress[11]={
+ -0.,-24.,-24.,-24.,-24.,-30.,-40.,-40.,-40.,-45.,-45.,-45.,
+};
+
+static int _psy_ehmer_bandlimit[11]={
+ 0,0,0,0,4,4,30,30,30,30,30,
+};
+
+static vorbis_info_psy _psy_info_template={
+ {-1},-110.,-140.,
+ /* tonemask att,guard,suppr,curves peakattp,curvelimitp,peaksettings*/
+ 0.f, -40.f,-40.f, {{{0.}}}, 1, 0, {{{0.}}},
+
+ /*noisemaskp,supp, low/high window, low/hi guard, minimum */
+ 1, -0.f, .5f, .5f, 0,0,0,
+ {-1},{-1},105.f,{{-1,-1,{{-1,-1,-1,-1}}}}
+};
+
+/* ath ****************/
+
+static double _psy_ath_floater[11]={
+ -100.,-100.,-100.,-100.,-100.,-100.,-105.,-105.,-105.,-110.,-120.,
+};
+
+static double _psy_ath_abs[11]={
+ -110.,-110.,-120.,-140.,-140.,-140.,-140.,-140.,-140.,-140.,-150.,
+};
+
+static float ATH_Bark_dB[][27]={
+ {
+ 0.f, 15.f, 15.f, 15.f, 11.f, 10.f, 8.f, 7.f, 7.f, 7.f,
+ 6.f, 2.f, 0.f, 0.f, -2.f, -5.f, -6.f, -6.f, -4.f, 4.f,
+ 14.f, 20.f, 19.f, 17.f, 30.f, 60.f, 60.f,
+ },
+ {
+ 0.f, 15.f, 15.f, 15.f, 11.f, 10.f, 8.f, 7.f, 7.f, 7.f,
+ 6.f, 2.f, 0.f, 0.f, -2.f, -5.f, -6.f, -6.f, -4.f, 0.f,
+ 2.f, 6.f, 5.f, 5.f, 15.f, 25.f, 35.f,
+ },
+ {
+ 0.f, 15.f, 15.f, 15.f, 11.f, 10.f, 8.f, 7.f, 7.f, 7.f,
+ 6.f, 2.f, 0.f, 0.f, -3.f, -5.f, -6.f, -6.f,-4.5f, 0.f,
+ 2.f, 6.f, 5.f, 5.f, 15.f, 15.f, 15.f,
+ }
+};
+
+/* stereo ****************/
+static int _psy_stereo_point_dB_44[11]={4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0};
+static double _psy_stereo_point_kHz_44[2][11]={
+ {4., 6., 6., 6., 10., 6., 6., 4., 4., 4., 4.},
+ {6., 6., 6., 10., 10., 6., 6., 4., 4., 4., 4.}
+};
+
+/* lowpass **************/
+static double _psy_lowpass_44[11]={
+ 15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999.
+};
diff --git a/lib/os.h b/lib/os.h
new file mode 100644
index 00000000..40b1fe6e
--- /dev/null
+++ b/lib/os.h
@@ -0,0 +1,163 @@
+#ifndef _OS_H
+#define _OS_H
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: os.h,v 1.27.6.1 2001/12/17 05:39:24 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <math.h>
+#include <ogg/os_types.h>
+
+#ifndef _V_IFDEFJAIL_H_
+# define _V_IFDEFJAIL_H_
+
+# ifdef __GNUC__
+# define STIN static __inline__
+# elif _WIN32
+# define STIN static __inline
+#else
+# define STIN static
+#endif
+
+#ifndef M_PI
+# define M_PI (3.1415926536f)
+#endif
+
+#ifdef _WIN32
+# include <malloc.h>
+# define rint(x) (floor((x)+0.5f))
+# define NO_FLOAT_MATH_LIB
+# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
+#endif
+
+#ifdef HAVE_SQRTF
+# define sqrt sqrtf
+#endif
+#ifdef HAVE_LOGF
+# define log logf
+#endif
+#ifdef HAVE_EXPF
+# define exp expf
+#endif
+#ifdef HAVE_ACOSF
+# define acos acosf
+#endif
+#ifdef HAVE_ATANF
+# define atan atanf
+#endif
+#ifdef HAVE_FREXPF
+# define frexp frexpf
+#endif
+#ifdef HAVE_RINTF
+# define rint rintf
+#endif
+
+#ifndef FAST_HYPOT
+# define FAST_HYPOT hypot
+#endif
+
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#ifdef USE_MEMORY_H
+# include <memory.h>
+#endif
+
+#ifndef min
+# define min(x,y) ((x)>(y)?(y):(x))
+#endif
+
+#ifndef max
+# define max(x,y) ((x)<(y)?(y):(x))
+#endif
+
+#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
+# define VORBIS_FPU_CONTROL
+/* both GCC and MSVC are kinda stupid about rounding/casting to int.
+ Because of encapsulation constraints (GCC can't see inside the asm
+ block and so we end up doing stupid things like a store/load that
+ is collectively a noop), we do it this way */
+
+/* we must set up the fpu before this works!! */
+
+typedef ogg_int16_t vorbis_fpu_control;
+
+static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
+ ogg_int16_t ret;
+ ogg_int16_t temp;
+ __asm__ __volatile__("fnstcw %0\n\t"
+ "movw %0,%%dx\n\t"
+ "orw $62463,%%dx\n\t"
+ "movw %%dx,%1\n\t"
+ "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
+ *fpu=ret;
+}
+
+static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
+ __asm__ __volatile__("fldcw %0":: "m"(fpu));
+}
+
+/* assumes the FPU is in round mode! */
+static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
+ we get extra fst/fld to
+ truncate precision */
+ int i;
+ __asm__("fistl %0": "=m"(i) : "t"(f));
+ return(i);
+}
+#endif
+
+
+#if defined(_WIN32) && !defined(__GNUC__)
+# define VORBIS_FPU_CONTROL
+
+typedef ogg_int16_t vorbis_fpu_control;
+
+static __inline int vorbis_ftoi(double f){
+ int i;
+ __asm{
+ fld f
+ fistp i
+ }
+ return i;
+}
+
+static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
+}
+
+static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
+}
+
+#endif
+
+
+#ifndef VORBIS_FPU_CONTROL
+
+typedef int vorbis_fpu_control;
+
+static int vorbis_ftoi(double f){
+ return (int)(f+.5);
+}
+
+/* We don't have special code for this compiler/arch, so do it the slow way */
+# define vorbis_fpu_setround(vorbis_fpu_control) {}
+# define vorbis_fpu_restore(vorbis_fpu_control) {}
+
+#endif
+
+#endif /* _OS_H */
diff --git a/lib/psy.h b/lib/psy.h
new file mode 100644
index 00000000..000a7fdf
--- /dev/null
+++ b/lib/psy.h
@@ -0,0 +1,167 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+
+ ********************************************************************
+
+ function: random psychoacoustics (not including preecho)
+ last mod: $Id: psy.h,v 1.25.2.1 2001/12/17 05:39:24 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_PSY_H_
+#define _V_PSY_H_
+#include "smallft.h"
+
+#include "backends.h"
+
+#ifndef EHMER_MAX
+#define EHMER_MAX 56
+#endif
+
+/* psychoacoustic setup ********************************************/
+#define MAX_BARK 27
+#define P_BANDS 17
+#define P_LEVELS 11
+
+typedef struct vp_couple{
+ int limit; /* sample post */
+
+ int outofphase_redundant_flip_p;
+ float outofphase_requant_limit;
+
+ float amppost_point;
+
+} vp_couple;
+
+typedef struct vp_couple_pass{
+ float granulem;
+ float igranulem;
+
+ vp_couple couple_pass[8];
+} vp_couple_pass;
+
+typedef struct vp_attenblock{
+ float block[P_BANDS][P_LEVELS];
+} vp_attenblock;
+
+#define NOISE_COMPAND_LEVELS 40
+typedef struct vorbis_info_psy{
+ float ath[27];
+
+ float ath_adjatt;
+ float ath_maxatt;
+
+ float tone_masteratt;
+ float tone_guard;
+ float tone_abs_limit;
+ vp_attenblock toneatt;
+
+ int peakattp;
+ int curvelimitp;
+ vp_attenblock peakatt;
+
+ int noisemaskp;
+ float noisemaxsupp;
+ float noisewindowlo;
+ float noisewindowhi;
+ int noisewindowlomin;
+ int noisewindowhimin;
+ int noisewindowfixed;
+ float noiseoff[P_BANDS];
+ float noisecompand[NOISE_COMPAND_LEVELS];
+
+ float max_curve_dB;
+
+ vp_couple_pass couple_pass[8];
+
+} vorbis_info_psy;
+
+typedef struct{
+ int eighth_octave_lines;
+
+ /* for block long/short tuning; encode only */
+ float preecho_thresh[4];
+ float postecho_thresh[4];
+ float preecho_minenergy;
+
+ float ampmax_att_per_sec;
+
+ /* delay caching... how many samples to keep around prior to our
+ current block to aid in analysis? */
+ int delaycache;
+} vorbis_info_psy_global;
+
+typedef struct {
+ float ampmax;
+ int channels;
+
+ vorbis_info_psy_global *gi;
+} vorbis_look_psy_global;
+
+
+typedef struct {
+ int n;
+ struct vorbis_info_psy *vi;
+
+ float ***tonecurves;
+ float *noisethresh;
+ float *noiseoffset;
+
+ float *ath;
+ long *octave; /* in n.ocshift format */
+ long *bark;
+
+ long firstoc;
+ long shiftoc;
+ int eighth_octave_lines; /* power of two, please */
+ int total_octave_lines;
+ long rate; /* cache it */
+} vorbis_look_psy;
+
+extern void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
+ vorbis_info_psy_global *gi,int n,long rate);
+extern void _vp_psy_clear(vorbis_look_psy *p);
+extern void *_vi_psy_dup(void *source);
+
+extern void _vi_psy_free(vorbis_info_psy *i);
+extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
+
+extern void _vp_remove_floor(vorbis_look_psy *p,
+ vorbis_look_psy_global *g,
+ float *logmdct,
+ float *mdct,
+ float *codedflr,
+ float *residue,
+ float local_specmax);
+
+extern void _vp_compute_mask(vorbis_look_psy *p,
+ vorbis_look_psy_global *g,
+ int channel,
+ float *fft,
+ float *mdct,
+ float *mask,
+ float global_specmax,
+ float local_specmax,
+ int lastsize,
+ float bitrate_noise_offset);
+
+extern void _vp_quantize_couple(vorbis_look_psy *p,
+ vorbis_info_mapping0 *vi,
+ float **pcm,
+ float **sofar,
+ float **quantized,
+ int *nonzero,
+ int passno);
+
+extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
+
+#endif
+
+
diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c
new file mode 100644
index 00000000..44e1dc18
--- /dev/null
+++ b/lib/vorbisenc.c
@@ -0,0 +1,877 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple programmatic interface for encoder mode setup
+ last mod: $Id: vorbisenc.c,v 1.23.2.1 2001/12/17 05:39:24 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdarg.h>
+
+#include "vorbis/codec.h"
+#include "vorbis/vorbisenc.h"
+
+#include "codec_internal.h"
+#include "registry-api.h"
+
+#include "os.h"
+#include "misc.h"
+
+/* careful with this; it's using static array sizing to make managing
+ all the modes a little less annoying. If we use a residue backend
+ with > 10 partition types, or a different division of iteration,
+ this needs to be updated. */
+typedef struct {
+ vorbis_info_residue0 *res[2];
+ static_codebook *book_aux[2];
+ static_codebook *books_base[5][10][3];
+ static_codebook *books_stereo_backfill[5][10];
+ static_codebook *books_residue_backfill[5][10][2];
+} vorbis_residue_template;
+
+static double stereo_threshholds[]={0.0, 2.5, 4.5, 8.5, 16.5};
+
+typedef struct vp_adjblock{
+ int block[P_BANDS][P_LEVELS];
+} vp_adjblock;
+
+#include "modes/residue_44.h"
+#include "modes/psych_44.h"
+#include "modes/floor_44.h"
+
+/* a few static coder conventions */
+static vorbis_info_time0 _time_dummy={0};
+static vorbis_info_mode _mode_set_short={0,0,0,0};
+static vorbis_info_mode _mode_set_long={1,0,0,1};
+
+/* mapping conventions:
+ only one submap (this would change for efficient 5.1 support for example)*/
+/* Four psychoacoustic profiles are used, one for each blocktype */
+static vorbis_info_mapping0 _mapping_set_short={
+ 1, {0,0}, {0}, {0}, {0}, {0,1}, 0,{0},{0}};
+static vorbis_info_mapping0 _mapping_set_long={
+ 1, {0,0}, {0}, {1}, {1}, {2,3}, 0,{0},{0}};
+
+static int vorbis_encode_toplevel_setup(vorbis_info *vi,int small,int large,int ch,long rate){
+ if(vi && vi->codec_setup){
+ codec_setup_info *ci=vi->codec_setup;
+
+ vi->version=0;
+ vi->channels=ch;
+ vi->rate=rate;
+
+ ci->blocksizes[0]=small;
+ ci->blocksizes[1]=large;
+
+ /* time mapping hooks are unused in vorbis I */
+ ci->times=1;
+ ci->time_type[0]=0;
+ ci->time_param[0]=calloc(1,sizeof(_time_dummy));
+ memcpy(ci->time_param[0],&_time_dummy,sizeof(_time_dummy));
+
+ /* by convention, two modes: one for short, one for long blocks.
+ short block mode uses mapping sero, long block uses mapping 1 */
+ ci->modes=2;
+ ci->mode_param[0]=calloc(1,sizeof(_mode_set_short));
+ memcpy(ci->mode_param[0],&_mode_set_short,sizeof(_mode_set_short));
+ ci->mode_param[1]=calloc(1,sizeof(_mode_set_long));
+ memcpy(ci->mode_param[1],&_mode_set_long,sizeof(_mode_set_long));
+
+ /* by convention two mappings, both mapping type zero (polyphonic
+ PCM), first for short, second for long blocks */
+ ci->maps=2;
+ ci->map_type[0]=0;
+ ci->map_param[0]=calloc(1,sizeof(_mapping_set_short));
+ memcpy(ci->map_param[0],&_mapping_set_short,sizeof(_mapping_set_short));
+ ci->map_type[1]=0;
+ ci->map_param[1]=calloc(1,sizeof(_mapping_set_long));
+ memcpy(ci->map_param[1],&_mapping_set_long,sizeof(_mapping_set_long));
+
+ return(0);
+ }
+ return(OV_EINVAL);
+}
+
+static int vorbis_encode_floor_setup(vorbis_info *vi,double q,int block,
+ static_codebook ***books,
+ vorbis_info_floor1 *in,
+ ...){
+ int x[11],i,k,iq=rint(q*10);
+ vorbis_info_floor1 *f=calloc(1,sizeof(*f));
+ codec_setup_info *ci=vi->codec_setup;
+ va_list ap;
+
+ va_start(ap,in);
+ for(i=0;i<11;i++)
+ x[i]=va_arg(ap,int);
+ va_end(ap);
+
+ memcpy(f,in+x[iq],sizeof(*f));
+ /* fill in the lowpass field, even if it's temporary */
+ f->n=ci->blocksizes[block]>>1;
+
+ /* books */
+ {
+ int partitions=f->partitions;
+ int maxclass=-1;
+ int maxbook=-1;
+ for(i=0;i<partitions;i++)
+ if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
+ for(i=0;i<=maxclass;i++){
+ if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
+ f->class_book[i]+=ci->books;
+ for(k=0;k<(1<<f->class_subs[i]);k++){
+ if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
+ if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
+ }
+ }
+
+ for(i=0;i<=maxbook;i++)
+ ci->book_param[ci->books++]=books[x[iq]][i];
+ }
+
+ /* for now, we're only using floor 1 */
+ ci->floor_type[ci->floors]=1;
+ ci->floor_param[ci->floors]=f;
+ ci->floors++;
+
+ return(0);
+}
+
+static int vorbis_encode_global_psych_setup(vorbis_info *vi,double q,
+ vorbis_info_psy_global *in, ...){
+ int i,iq=q*10;
+ double x[11],dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy_global *g=&ci->psy_g_param;
+ va_list ap;
+
+ va_start(ap,in);
+ for(i=0;i<11;i++)
+ x[i]=va_arg(ap,double);
+ va_end(ap);
+
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ memcpy(g,in+(int)x[iq],sizeof(*g));
+
+ dq=x[iq]*(1.-dq)+x[iq+1]*dq;
+ iq=(int)dq;
+ dq-=iq;
+ if(dq==0 && iq>0){
+ iq--;
+ dq=1.;
+ }
+
+ /* interpolate the trigger threshholds */
+ for(i=0;i<4;i++){
+ g->preecho_thresh[i]=in[iq].preecho_thresh[i]*(1.-dq)+in[iq+1].preecho_thresh[i]*dq;
+ g->postecho_thresh[i]=in[iq].postecho_thresh[i]*(1.-dq)+in[iq+1].postecho_thresh[i]*dq;
+ }
+ g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
+ return(0);
+}
+
+static int vorbis_encode_psyset_setup(vorbis_info *vi,int block){
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+
+ if(block>=ci->psys)
+ ci->psys=block+1;
+ if(!p){
+ p=calloc(1,sizeof(*p));
+ ci->psy_param[block]=p;
+ }
+
+ memcpy(p,&_psy_info_template,sizeof(*p));
+
+ return 0;
+}
+
+static int vorbis_encode_tonemask_setup(vorbis_info *vi,double q,int block,
+ double *att,
+ double *max,
+ int *peaklimit_bands,
+ vp_adjblock *in){
+ int i,j,iq;
+ double dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+
+ iq=q*10;
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ p->tone_masteratt=att[iq]*(1.-dq)+att[iq+1]*dq;
+ p->max_curve_dB=max[iq];
+ p->curvelimitp=peaklimit_bands[iq];
+
+ iq=q*5.;
+ if(iq==5){
+ iq=5;
+ dq=1.;
+ }else{
+ dq=q*5.-iq;
+ }
+
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++)
+ p->toneatt.block[i][j]=(j<4?4:j)*-10.+
+ in[iq].block[i][j]*(1.-dq)+in[iq+1].block[i][j]*dq;
+ return(0);
+}
+
+
+static int vorbis_encode_compand_setup(vorbis_info *vi,double q,int block,
+ float in[][NOISE_COMPAND_LEVELS], ...){
+ int i,iq=q*10;
+ double x[11],dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+ va_list ap;
+
+ va_start(ap,in);
+ for(i=0;i<11;i++)
+ x[i]=va_arg(ap,double);
+ va_end(ap);
+
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ dq=x[iq]*(1.-dq)+x[iq+1]*dq;
+ iq=(int)dq;
+ dq-=iq;
+ if(dq==0 && iq>0){
+ iq--;
+ dq=1.;
+ }
+
+ /* interpolate the compander settings */
+ for(i=0;i<NOISE_COMPAND_LEVELS;i++)
+ p->noisecompand[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq;
+ return(0);
+}
+
+static int vorbis_encode_peak_setup(vorbis_info *vi,double q,int block,
+ double *guard,
+ double *suppress,
+ vp_adjblock *in){
+ int i,j,iq;
+ double dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+
+ iq=q*10;
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ p->peakattp=1;
+ p->tone_guard=guard[iq]*(1.-dq)+guard[iq+1]*dq;
+ p->tone_abs_limit=suppress[iq]*(1.-dq)+suppress[iq+1]*dq;
+
+ iq=q*5.;
+ if(iq==5){
+ iq=5;
+ dq=1.;
+ }else{
+ dq=q*5.-iq;
+ }
+
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++)
+ p->peakatt.block[i][j]=(j<4?4:j)*-10.+
+ in[iq].block[i][j]*(1.-dq)+in[iq+1].block[i][j]*dq;
+ return(0);
+}
+
+static int vorbis_encode_noisebias_setup(vorbis_info *vi,double q,int block,
+ double *suppress,
+ int in[][17],int guard[33]){
+ int i,iq=q*10;
+ double dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ p->noisemaxsupp=suppress[iq]*(1.-dq)+suppress[iq+1]*dq;
+ p->noisewindowlomin=guard[iq*3];
+ p->noisewindowhimin=guard[iq*3+1];
+ p->noisewindowfixed=guard[iq*3+2];
+
+ for(i=0;i<P_BANDS;i++)
+ p->noiseoff[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq;
+ return(0);
+}
+
+static int vorbis_encode_ath_setup(vorbis_info *vi,double q,int block,
+ float in[][27], ...){
+ int i,iq=q*10;
+ double x[11],dq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy *p=ci->psy_param[block];
+ va_list ap;
+
+ va_start(ap,in);
+ for(i=0;i<11;i++)
+ x[i]=va_arg(ap,double);
+ va_end(ap);
+
+ p->ath_adjatt=ci->hi.ath_floating_dB;
+ p->ath_maxatt=ci->hi.ath_absolute_dB;
+
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ dq=x[iq]*(1.-dq)+x[iq+1]*dq;
+ iq=(int)dq;
+ dq-=iq;
+ if(dq==0 && iq>0){
+ iq--;
+ dq=1.;
+ }
+
+ for(i=0;i<27;i++)
+ p->ath[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq;
+ return(0);
+}
+
+
+static int book_dup_or_new(codec_setup_info *ci,static_codebook *book){
+ int i;
+ for(i=0;i<ci->books;i++)
+ if(ci->book_param[i]==book)return(i);
+
+ return(ci->books++);
+}
+
+static int vorbis_encode_residue_setup(vorbis_info *vi,double q,int block,
+ int coupled_p,
+ int stereo_backfill_p,
+ int residue_backfill_p,
+ vorbis_residue_template *in,
+ int point_dB,
+ double point_kHz){
+
+ int i,iq=q*10;
+ int n,k;
+ int partition_position;
+ int res_position;
+ int iterations=1;
+ int amplitude_select=0;
+
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_residue0 *r;
+ vorbis_info_psy *psy=ci->psy_param[block*2];
+
+ /* may be re-called due to ctl */
+ if(ci->residue_param[block])
+ /* free preexisting instance */
+ residue_free_info(ci->residue_param[block],ci->residue_type[block]);
+
+ r=ci->residue_param[block]=malloc(sizeof(*r));
+ memcpy(r,in[iq].res[block],sizeof(*r));
+ if(ci->residues<=block)ci->residues=block+1;
+
+ if(block){
+ r->grouping=32;
+ }else{
+ r->grouping=16;
+ }
+
+ /* for uncoupled, we use type 1, else type 2 */
+ if(coupled_p){
+ ci->residue_type[block]=2;
+ }else{
+ ci->residue_type[block]=1;
+ }
+
+ switch(ci->residue_type[block]){
+ case 1:
+ n=r->end=ci->blocksizes[block?1:0]>>1; /* to be adjusted by lowpass later */
+ partition_position=rint(point_kHz*1000./(vi->rate/2)*n/r->grouping);
+ res_position=partition_position*r->grouping;
+ break;
+ case 2:
+ n=r->end=(ci->blocksizes[block?1:0]>>1)*vi->channels; /* to be adjusted by lowpass later */
+ partition_position=rint(point_kHz*1000./(vi->rate/2)*n/r->grouping);
+ res_position=partition_position*r->grouping/vi->channels;
+ break;
+ }
+
+ for(i=0;i<r->partitions;i++)
+ if(r->blimit[i]<0)r->blimit[i]=partition_position;
+
+ for(i=0;i<r->partitions;i++)
+ for(k=0;k<3;k++)
+ if(in[iq].books_base[point_dB][i][k])
+ r->secondstages[i]|=(1<<k);
+
+ ci->passlimit[0]=3;
+
+ if(coupled_p){
+ vorbis_info_mapping0 *map=ci->map_param[block];
+
+ map->coupling_steps=1;
+ map->coupling_mag[0]=0;
+ map->coupling_ang[0]=1;
+
+ psy->couple_pass[0].granulem=1.;
+ psy->couple_pass[0].igranulem=1.;
+
+ psy->couple_pass[0].couple_pass[0].limit=res_position;
+ psy->couple_pass[0].couple_pass[0].outofphase_redundant_flip_p=1;
+ psy->couple_pass[0].couple_pass[0].outofphase_requant_limit=9e10;
+ psy->couple_pass[0].couple_pass[0].amppost_point=0;
+ psy->couple_pass[0].couple_pass[1].limit=9999;
+ psy->couple_pass[0].couple_pass[1].outofphase_redundant_flip_p=1;
+ psy->couple_pass[0].couple_pass[1].outofphase_requant_limit=9e10;
+ psy->couple_pass[0].couple_pass[1].amppost_point=
+ stereo_threshholds[point_dB];
+ amplitude_select=point_dB;
+
+ if(stereo_backfill_p && amplitude_select){
+ memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1,
+ sizeof(*psy->couple_pass));
+ amplitude_select=amplitude_select-1;
+ psy->couple_pass[1].couple_pass[1].amppost_point=stereo_threshholds[amplitude_select-1];
+ ci->passlimit[1]=4;
+ for(i=0;i<r->partitions;i++)
+ if(in[iq].books_stereo_backfill[amplitude_select-1][i])
+ r->secondstages[i]|=8;
+ iterations++;
+ }
+
+ if(residue_backfill_p){
+ memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1,
+ sizeof(*psy->couple_pass));
+ psy->couple_pass[iterations].granulem=.333333333;
+ psy->couple_pass[iterations].igranulem=3.;
+ for(i=0;i<r->partitions;i++)
+ if(in[iq].books_residue_backfill[amplitude_select][i][0])
+ r->secondstages[i]|=(1<<(iterations+2));
+ ci->passlimit[iterations]=ci->passlimit[iterations-1]+1;
+ iterations++;
+
+ memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1,
+ sizeof(*psy->couple_pass));
+ psy->couple_pass[iterations].granulem=.1111111111;
+ psy->couple_pass[iterations].igranulem=9.;
+ for(i=0;i<r->partitions;i++)
+ if(in[iq].books_residue_backfill[amplitude_select][i][1])
+ r->secondstages[i]|=(1<<(iterations+2));
+ ci->passlimit[iterations]=ci->passlimit[iterations-1]+1;
+ iterations++;
+ }
+ ci->coupling_passes=iterations;
+
+ }else{
+
+ if(residue_backfill_p){
+ for(i=0;i<r->partitions;i++){
+ if(in[iq].books_residue_backfill[0][i][0])
+ r->secondstages[i]|=8;
+ if(in[iq].books_residue_backfill[0][i][1])
+ r->secondstages[i]|=16;
+ }
+ ci->passlimit[1]=4;
+ ci->passlimit[2]=5;
+ ci->coupling_passes=3;
+ }else
+ ci->coupling_passes=1;
+ }
+
+ memcpy(&ci->psy_param[block*2+1]->couple_pass,
+ &ci->psy_param[block*2]->couple_pass,
+ sizeof(psy->couple_pass[0]));
+
+ /* fill in all the books */
+ {
+ int booklist=0,k;
+ r->groupbook=ci->books;
+ ci->book_param[ci->books++]=in[iq].book_aux[block];
+ for(i=0;i<r->partitions;i++){
+ for(k=0;k<3;k++){
+ if(in[iq].books_base[point_dB][i][k]){
+ int bookid=book_dup_or_new(ci,in[iq].books_base[point_dB][i][k]);
+ r->booklist[booklist++]=bookid;
+ ci->book_param[bookid]=in[iq].books_base[point_dB][i][k];
+ }
+ }
+ if(coupled_p && stereo_backfill_p && point_dB &&
+ in[iq].books_stereo_backfill[point_dB][i]){
+ int bookid=book_dup_or_new(ci,in[iq].books_stereo_backfill[point_dB][i]);
+ r->booklist[booklist++]=bookid;
+ ci->book_param[bookid]=in[iq].books_stereo_backfill[point_dB][i];
+ }
+ if(residue_backfill_p){
+ for(k=0;k<2;k++){
+ if(in[iq].books_residue_backfill[amplitude_select][i][k]){
+ int bookid=book_dup_or_new(ci,in[iq].books_residue_backfill[amplitude_select][i][k]);
+ r->booklist[booklist++]=bookid;
+ ci->book_param[bookid]=in[iq].books_residue_backfill[amplitude_select][i][k];
+ }
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+static int vorbis_encode_lowpass_setup(vorbis_info *vi,double q,int block){
+ int iq=q*10;
+ double dq;
+ double freq;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_floor1 *f=ci->floor_param[block];
+ vorbis_info_residue0 *r=ci->residue_param[block];
+ int blocksize=ci->blocksizes[block]>>1;
+ double nyq=vi->rate/2.;
+
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=q*10.-iq;
+ }
+
+ freq=ci->hi.lowpass_kHz[block]*1000.;
+ if(freq>vi->rate/2)freq=vi->rate/2;
+ /* lowpass needs to be set in the floor and the residue. */
+
+ /* in the floor, the granularity can be very fine; it doesn't alter
+ the encoding structure, only the samples used to fit the floor
+ approximation */
+ f->n=freq/nyq*blocksize;
+
+ /* in the residue, we're constrained, physically, by partition
+ boundaries. We still lowpass 'wherever', but we have to round up
+ here to next boundary, or the vorbis spec will round it *down* to
+ previous boundary in encode/decode */
+ if(ci->residue_type[block]==2)
+ r->end=((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */
+ r->grouping;
+ else
+ r->end=((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
+ r->grouping;
+ return(0);
+}
+
+/* encoders will need to use vorbis_info_init beforehand and call
+ vorbis_info clear when all done */
+
+/* two interfaces; this, more detailed one, and later a convenience
+ layer on top */
+
+/* the final setup call */
+int vorbis_encode_setup_init(vorbis_info *vi){
+ int ret=0;
+ long rate=vi->rate;
+ long channels=vi->channels;
+ codec_setup_info *ci=vi->codec_setup;
+ highlevel_encode_setup *hi=&ci->hi;
+
+ ret|=vorbis_encode_floor_setup(vi,hi->base_quality_short,0,
+ _floor_44_128_books,_floor_44_128,
+ 0,1,1,2,2,2,2,2,2,2,2);
+ ret|=vorbis_encode_floor_setup(vi,hi->base_quality_long,1,
+ _floor_44_1024_books,_floor_44_1024,
+ 0,0,0,0,0,0,0,0,0,0,0);
+
+ ret|=vorbis_encode_global_psych_setup(vi,hi->trigger_quality,_psy_global_44,
+ 0., 1., 1.5, 2., 2., 2., 2., 2., 2., 2., 2.);
+
+ ret|=vorbis_encode_psyset_setup(vi,0);
+ ret|=vorbis_encode_psyset_setup(vi,1);
+ ret|=vorbis_encode_psyset_setup(vi,2);
+ ret|=vorbis_encode_psyset_setup(vi,3);
+
+ ret|=vorbis_encode_tonemask_setup(vi,hi->blocktype[0].tone_mask_quality,0,
+ _psy_tone_masteratt,_psy_tone_0dB,_psy_ehmer_bandlimit,
+ _vp_tonemask_adj_otherblock);
+ ret|=vorbis_encode_tonemask_setup(vi,hi->blocktype[1].tone_mask_quality,1,
+ _psy_tone_masteratt,_psy_tone_0dB,_psy_ehmer_bandlimit,
+ _vp_tonemask_adj_otherblock);
+ ret|=vorbis_encode_tonemask_setup(vi,hi->blocktype[2].tone_mask_quality,2,
+ _psy_tone_masteratt,_psy_tone_0dB,_psy_ehmer_bandlimit,
+ _vp_tonemask_adj_otherblock);
+ ret|=vorbis_encode_tonemask_setup(vi,hi->blocktype[3].tone_mask_quality,3,
+ _psy_tone_masteratt,_psy_tone_0dB,_psy_ehmer_bandlimit,
+ _vp_tonemask_adj_longblock);
+
+ ret|=vorbis_encode_compand_setup(vi,hi->blocktype[0].noise_compand_quality,
+ 0,_psy_compand_44_short,
+ 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.);
+ ret|=vorbis_encode_compand_setup(vi,hi->blocktype[1].noise_compand_quality,
+ 1,_psy_compand_44_short,
+ 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.);
+ ret|=vorbis_encode_compand_setup(vi,hi->blocktype[2].noise_compand_quality,
+ 2,_psy_compand_44,
+ 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.);
+ ret|=vorbis_encode_compand_setup(vi,hi->blocktype[3].noise_compand_quality,
+ 3,_psy_compand_44,
+ 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.);
+
+ ret|=vorbis_encode_peak_setup(vi,hi->blocktype[0].tone_peaklimit_quality,
+ 0,_psy_tone_masterguard,_psy_tone_suppress,
+ _vp_peakguard);
+ ret|=vorbis_encode_peak_setup(vi,hi->blocktype[1].tone_peaklimit_quality,
+ 1,_psy_tone_masterguard,_psy_tone_suppress,
+ _vp_peakguard);
+ ret|=vorbis_encode_peak_setup(vi,hi->blocktype[2].tone_peaklimit_quality,
+ 2,_psy_tone_masterguard,_psy_tone_suppress,
+ _vp_peakguard);
+ ret|=vorbis_encode_peak_setup(vi,hi->blocktype[3].tone_peaklimit_quality,
+ 3,_psy_tone_masterguard,_psy_tone_suppress,
+ _vp_peakguard);
+
+ ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[0].noise_bias_quality,
+ 0,_psy_noise_suppress,_psy_noisebias_impulse,
+ _psy_noiseguards_short);
+ ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[1].noise_bias_quality,
+ 1,_psy_noise_suppress,_psy_noisebias_other,
+ _psy_noiseguards_short);
+ ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[2].noise_bias_quality,
+ 2,_psy_noise_suppress,_psy_noisebias_other,
+ _psy_noiseguards_long);
+ ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[3].noise_bias_quality,
+ 3,_psy_noise_suppress,_psy_noisebias_long,
+ _psy_noiseguards_long);
+
+ ret|=vorbis_encode_ath_setup(vi,hi->blocktype[0].ath_quality,0,ATH_Bark_dB,
+ 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.);
+ ret|=vorbis_encode_ath_setup(vi,hi->blocktype[1].ath_quality,1,ATH_Bark_dB,
+ 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.);
+ ret|=vorbis_encode_ath_setup(vi,hi->blocktype[2].ath_quality,2,ATH_Bark_dB,
+ 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.);
+ ret|=vorbis_encode_ath_setup(vi,hi->blocktype[3].ath_quality,3,ATH_Bark_dB,
+ 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.);
+
+ if(ret){
+ vorbis_info_clear(vi);
+ return ret;
+ }
+
+ if(channels==2 && hi->stereo_couple_p){
+ /* setup specific to stereo coupling */
+
+ ret|=vorbis_encode_residue_setup(vi,hi->base_quality_short,0,
+ 1, /* coupled */
+ hi->stereo_backfill_p,
+ hi->residue_backfill_p,
+ _residue_template_44_stereo,
+ hi->stereo_point_dB,
+ hi->stereo_point_kHz[0]);
+
+ ret|=vorbis_encode_residue_setup(vi,hi->base_quality_long,1,
+ 1, /* coupled */
+ hi->stereo_backfill_p,
+ hi->residue_backfill_p,
+ _residue_template_44_stereo,
+ hi->stereo_point_dB,
+ hi->stereo_point_kHz[1]);
+
+ }else{
+ /* setup specific to non-stereo (mono or uncoupled polyphonic)
+ coupling */
+ ret|=vorbis_encode_residue_setup(vi,hi->base_quality_short,0,
+ 0, /* uncoupled */
+ 0,
+ hi->residue_backfill_p,
+ _residue_template_44_uncoupled,
+ 0,
+ hi->stereo_point_kHz[0]); /* just
+ used as an encoding partitioning
+ point */
+
+ ret|=vorbis_encode_residue_setup(vi,hi->base_quality_long,1,
+ 0, /* uncoupled */
+ 0,
+ hi->residue_backfill_p,
+ _residue_template_44_uncoupled,
+ 0,
+ hi->stereo_point_kHz[1]); /* just
+ used as an encoding partitioning
+ point */
+ }
+ ret|=vorbis_encode_lowpass_setup(vi,hi->lowpass_kHz[0],0);
+ ret|=vorbis_encode_lowpass_setup(vi,hi->lowpass_kHz[1],1);
+
+ if(ret)
+ vorbis_info_clear(vi);
+ return(ret);
+
+}
+
+/* only populates the high-level settings so that we can tweak with ctl before final setup */
+int vorbis_encode_setup_vbr(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ float base_quality){
+ int ret=0,i,iq;
+ double dq;
+ codec_setup_info *ci=vi->codec_setup;
+ highlevel_encode_setup *hi=&ci->hi;
+
+ base_quality+=.0001;
+ if(base_quality<0.)base_quality=0.;
+ if(base_quality>.999)base_quality=.999;
+
+ iq=base_quality*10;
+ if(iq==10){
+ iq=9;
+ dq=1.;
+ }else{
+ dq=base_quality*10.-iq;
+ }
+
+ ret|=vorbis_encode_toplevel_setup(vi,256,2048,channels,rate);
+ hi->base_quality=base_quality;
+ hi->base_quality_short=base_quality;
+ hi->base_quality_long=base_quality;
+ hi->trigger_quality=base_quality;
+
+ for(i=0;i<4;i++){
+ hi->blocktype[i].tone_mask_quality=base_quality;
+ hi->blocktype[i].tone_peaklimit_quality=base_quality;
+ hi->blocktype[i].noise_bias_quality=base_quality;
+ hi->blocktype[i].noise_compand_quality=base_quality;
+ hi->blocktype[i].ath_quality=base_quality;
+ }
+
+ hi->short_block_p=1;
+ hi->long_block_p=1;
+ hi->impulse_block_p=1;
+ hi->amplitude_track_dBpersec=-6.;
+
+ hi->stereo_couple_p=1; /* only relevant if a two channel input */
+ hi->stereo_backfill_p=0;
+ hi->residue_backfill_p=0;
+
+ /* set the ATH floaters */
+ hi->ath_floating_dB=_psy_ath_floater[iq]*(1.-dq)+_psy_ath_floater[iq+1]*dq;
+ hi->ath_absolute_dB=_psy_ath_abs[iq]*(1.-dq)+_psy_ath_abs[iq+1]*dq;
+
+ /* set stereo dB and Hz */
+ hi->stereo_point_dB=_psy_stereo_point_dB_44[iq];
+ hi->stereo_point_kHz[0]=_psy_stereo_point_kHz_44[0][iq]*(1.-dq)+
+ _psy_stereo_point_kHz_44[0][iq+1]*dq;
+ hi->stereo_point_kHz[1]=_psy_stereo_point_kHz_44[1][iq]*(1.-dq)+
+ _psy_stereo_point_kHz_44[1][iq+1]*dq;
+
+ /* set lowpass */
+ hi->lowpass_kHz[0]=
+ hi->lowpass_kHz[1]=
+ _psy_lowpass_44[iq]*(1.-dq)+_psy_lowpass_44[iq+1]*dq;
+
+ return(ret);
+}
+
+int vorbis_encode_init_vbr(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ float base_quality /* 0. to 1. */
+ ){
+ int ret=0;
+
+ ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
+ if(ret){
+ vorbis_info_clear(vi);
+ return ret;
+ }
+ ret=vorbis_encode_setup_init(vi);
+ if(ret)
+ vorbis_info_clear(vi);
+ return(ret);
+}
+
+int vorbis_encode_init(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ long max_bitrate,
+ long nominal_bitrate,
+ long min_bitrate){
+
+ /* it's temporary while I do the merge; relax */
+ if(rate>40000){
+ if(nominal_bitrate>360000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, 1.));
+ }else if(nominal_bitrate>270000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .9));
+ }else if(nominal_bitrate>230000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .8));
+ }else if(nominal_bitrate>200000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .7));
+ }else if(nominal_bitrate>180000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .6));
+ }else if(nominal_bitrate>140000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .5));
+ }else if(nominal_bitrate>120000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .4));
+ }else if(nominal_bitrate>100000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .3));
+ }else if(nominal_bitrate>90000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .2));
+ }else if(nominal_bitrate>75000){
+ return(vorbis_encode_init_vbr(vi,channels,rate, .1));
+ }else{
+ return(vorbis_encode_init_vbr(vi,channels,rate, .0));
+ }
+ }
+
+ return(OV_EIMPL);
+}
+
+int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
+ return(OV_EIMPL);
+}
+
+
+
+
+
+
+
+