summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2000-08-31 08:05:48 +0000
committerMonty <xiphmont@xiph.org>2000-08-31 08:05:48 +0000
commit039bc284b20be003d7a46abc9040e16ebcd739b1 (patch)
tree7a3558f1e02ac15686f2b3b70abf90c795da367b
parent40da4a2fb5096c1bbb0cb229ba291066b8244b05 (diff)
downloadlibvorbis-git-039bc284b20be003d7a46abc9040e16ebcd739b1.tar.gz
merge recent mainline fixes into branch_postbeta2
svn path=/branches/branch_postbeta2/vorbis/; revision=611
-rwxr-xr-xconfigure2540
-rw-r--r--configure.in358
-rw-r--r--examples/decoder_example.c299
-rw-r--r--include/vorbis/codec.h431
-rw-r--r--include/vorbis/os_types.h.in2
-rw-r--r--include/vorbis/vorbisfile.h118
-rw-r--r--lib/Makefile.in100
-rw-r--r--lib/envelope.c215
-rw-r--r--lib/floor0.c419
-rw-r--r--lib/framing.c1623
-rw-r--r--lib/psy.c702
-rw-r--r--lib/sharedbook.c627
-rw-r--r--lib/vorbisfile.c1156
13 files changed, 8589 insertions, 1 deletions
diff --git a/configure b/configure
new file mode 100755
index 00000000..d6aedd33
--- /dev/null
+++ b/configure
@@ -0,0 +1,2540 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+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'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=lib/mdct.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+#AC_CONFIG_HEADER(config.h)
+
+cp configure.guess config.guess
+cp configure.sub config.sub
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:556: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+case $host in
+ *-*-irix*)
+ if test -z "$CC"; then
+ CC=cc
+ fi
+ echo $ac_n "checking for ALwritesamps in -laudio""... $ac_c" 1>&6
+echo "configure:583: checking for ALwritesamps in -laudio" >&5
+ac_lib_var=`echo audio'_'ALwritesamps | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-laudio $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 591 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ALwritesamps();
+
+int main() {
+ALwritesamps()
+; return 0; }
+EOF
+if { (eval echo configure:602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo audio | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-laudio $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ ;;
+# BeOS does not use -lm
+# *-*-beos)
+# LIBS=""
+# ;;
+# added better check below
+
+esac
+
+cflags_save="$CFLAGS"
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:642: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:672: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:723: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:755: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 766 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:797: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:802: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:811: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:830: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# because AC_PROG_CC likes to set -g
+CFLAGS="$cflags_save"
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:865: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 880 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 897 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 914 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:920: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:947: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:977: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "install", so it can be a program name with args.
+set dummy install; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1006: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_INSTALL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$INSTALL"; then
+ ac_cv_prog_INSTALL="$INSTALL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_INSTALL="install"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+INSTALL="$ac_cv_prog_INSTALL"
+if test -n "$INSTALL"; then
+ echo "$ac_t""$INSTALL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#not everyone uses libm (eg, BeOS)
+#AC_CHECK_LIB(m, cos, LIBS="-lm"; AC_DEFINE(HAVE_LIBM), LIBS="")
+# We no longer use config.h
+echo $ac_n "checking for cos in -lm""... $ac_c" 1>&6
+echo "configure:1037: checking for cos in -lm" >&5
+ac_lib_var=`echo m'_'cos | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1045 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cos();
+
+int main() {
+cos()
+; return 0; }
+EOF
+if { (eval echo configure:1056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="-lm"
+else
+ echo "$ac_t""no" 1>&6
+LIBS=""
+fi
+
+
+if test -z "$GCC"; then
+ case $host in
+ *-*-irix*)
+ DEBUG="-g -signed"
+ OPT="-O2 -w -signed"
+ PROFILE="-p -g3 -O2 -signed" ;;
+ sparc-sun-solaris*)
+ DEBUG="-v -g"
+ OPT="-xO4 -fast -w -fsimple -native -xcg92"
+ PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" ;;
+ *)
+ DEBUG="-g"
+ OPT="-O"
+ PROFILE="-g -p" ;;
+ esac
+else
+
+ case $host in
+ *86-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char"
+
+ # 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
+
+ cat > conftest.$ac_ext <<EOF
+#line 1107 "configure"
+#include "confdefs.h"
+
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "log10.*fldlg2.*fxch" >/dev/null 2>&1; then
+ rm -rf conftest*
+ bad=maybe
+else
+ rm -rf conftest*
+ bad=no
+fi
+rm -f conftest*
+
+ if test ${bad} = "maybe" ;then
+ cat > conftest.$ac_ext <<EOF
+#line 1127 "configure"
+#include "confdefs.h"
+
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "log10.*fldlg2.*fxch.*st\([0123456789]*\)" >/dev/null 2>&1; then
+ rm -rf conftest*
+ bad=no
+else
+ rm -rf conftest*
+ bad=yes
+fi
+rm -f conftest*
+
+ fi
+ if test ${bad} = "yes" ;then
+ echo "configure: warning: " 1>&2
+ echo "configure: warning: ********************************************************" 1>&2
+ echo "configure: warning: * The glibc headers on this machine have a serious bug *" 1>&2
+ echo "configure: warning: * in /usr/include/bits/mathinline.h This bug affects *" 1>&2
+ echo "configure: warning: * all floating point code, not just Ogg, built on this *" 1>&2
+ echo "configure: warning: * machine. Upgrading to glibc 2.1.3 is strongly urged *" 1>&2
+ echo "configure: warning: * to correct the problem. Note that upgrading glibc *" 1>&2
+ echo "configure: warning: * will not fix any previously built programs; this is *" 1>&2
+ echo "configure: warning: * a compile-time time bug. *" 1>&2
+ echo "configure: warning: * To work around the problem for this build of Ogg, *" 1>&2
+ echo "configure: warning: * autoconf is disabling all math inlining. This will *" 1>&2
+ echo "configure: warning: * hurt Ogg performace but is necessary for an Ogg that *" 1>&2
+ echo "configure: warning: * will actually work. Once glibc is upgraded, rerun *" 1>&2
+ echo "configure: warning: * configure and make to build with inlining. *" 1>&2
+ echo "configure: warning: ********************************************************" 1>&2
+ echo "configure: warning: " 1>&2
+
+ OPT=${OPT}" -D__NO_MATH_INLINES"
+ PROFILE=${PROFILE}" -D__NO_MATH_INLINES"
+ fi;;
+ *-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char";;
+ sparc-sun-*)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char -mv8"
+ OPT="-O20 -ffast-math -D__NO_MATH_INLINES -fsigned-char -mv8"
+ PROFILE="-pg -g -O20 -D__NO_MATH_INLINES -fsigned-char -mv8" ;;
+ *)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -D__NO_MATH_INLINES -fsigned-char"
+ PROFILE="-O20 -g -pg -D__NO_MATH_INLINES -fsigned-char" ;;
+ esac
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1183: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1188 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1196: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1213 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1231 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1252 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1263: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+
+#AC_CHECK_LIB(pthread, pthread_create,
+# pthread_lib="-lpthread"; AC_DEFINE(HAVE_LIBPTHREAD), :)
+# We no longer use config.h
+echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:1292: checking for pthread_create in -lpthread" >&5
+ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lpthread $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1300 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pthread_create();
+
+int main() {
+pthread_create()
+; return 0; }
+EOF
+if { (eval echo configure:1311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ pthread_lib="-lpthread"
+else
+ echo "$ac_t""no" 1>&6
+:
+fi
+
+
+#dnl Linuxthreads require you to define _REENTRANT in all threaded
+#dnl code. Bogus, bogus...
+#
+#if test -n "$pthread_lib"; then
+# case $host in
+# i?86-*-linux*)
+# AC_DEFINE(_REENTRANT)
+# ;;
+# esac
+#fi
+# We no longer use config.h
+
+#if test -n "$x_libraries"; then
+# XOGG="yes"
+#
+# dnl If we find libgtk installed, great; otherwise assume we have
+# dnl to build it ourselves.
+#
+# AC_CHECK_LIB(gtk, gtk_main, :, LIBGTKDIR="libgtk", $X_LIBS -lglib -lgdk -lX11 -lXext -lm)
+#
+# dnl libpthread is required for xogg.
+#
+# if test -z "$pthread_lib"; then XOGG=""; fi
+#
+# dnl If we don't have libgtk installed, and we don't have a libgtk
+# dnl subdirectory to build the library ourself, we can't build xogg.
+#
+# if test -n "$LIBGTKDIR" -a ! -d "$LIBGTKDIR"; then
+# XOGG=""
+# LIBGTKDIR=""
+# fi
+#fi
+
+
+dummy="__noconf"
+
+#if test -d "$LIBGTKDIR"; then
+# enable_shared="no"; export enable_shared
+# dummy="libgtk"
+# AC_CONFIG_SUBDIRS("$dummy")
+# X_LIBS="-L${srcdir}/libgtk/gtk/.libs -L${srcdir}/libgtk/gdk/.libs -L${srcdir}/libgtk/glib/.libs $X_LIBS"
+#fi
+
+# check macro modified from Jon Shiring's to compensate for autoconf's lagging
+# behind the times on type madness
+
+echo $ac_n "checking for int16_t""... $ac_c" 1>&6
+echo "configure:1380: checking for int16_t" >&5
+if eval "test \"`echo '$''{'has_int16_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ has_int16_t=no
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1389 "configure"
+#include "confdefs.h"
+
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int16_t foo;
+int main() {return 0;}
+
+EOF
+if { (eval echo configure:1400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ has_int16_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ has_int16_t=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$has_int16_t" 1>&6
+
+echo $ac_n "checking for int32_t""... $ac_c" 1>&6
+echo "configure:1417: checking for int32_t" >&5
+if eval "test \"`echo '$''{'has_int32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ has_int32_t=no
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1426 "configure"
+#include "confdefs.h"
+
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int32_t foo;
+int main() {return 0;}
+
+EOF
+if { (eval echo configure:1437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ has_int32_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ has_int32_t=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$has_int32_t" 1>&6
+
+echo $ac_n "checking for uint32_t""... $ac_c" 1>&6
+echo "configure:1454: checking for uint32_t" >&5
+if eval "test \"`echo '$''{'has_uint32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ has_uint32_t=no
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1463 "configure"
+#include "confdefs.h"
+
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+uint32_t foo;
+int main() {return 0;}
+
+EOF
+if { (eval echo configure:1474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ has_uint32_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ has_uint32_t=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$has_uint32_t" 1>&6
+
+echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
+echo "configure:1491: checking for u_int32_t" >&5
+if eval "test \"`echo '$''{'has_u_int32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ has_u_int32_t=no
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1500 "configure"
+#include "confdefs.h"
+
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+u_int32_t foo;
+int main() {return 0;}
+
+EOF
+if { (eval echo configure:1511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ has_u_int32_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ has_u_int32_t=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$has_u_int32_t" 1>&6
+
+echo $ac_n "checking for int64_t""... $ac_c" 1>&6
+echo "configure:1528: checking for int64_t" >&5
+if eval "test \"`echo '$''{'has_int64_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ has_int64_t=no
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1537 "configure"
+#include "confdefs.h"
+
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int64_t foo;
+int main() {return 0;}
+
+EOF
+if { (eval echo configure:1548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ has_int64_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ has_int64_t=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$has_int64_t" 1>&6
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1565: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1573 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(short));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_short=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1604: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1612 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(int));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_int=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1643: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1651 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:1682: checking size of long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1690 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
+
+
+if test x$has_int16_t = "xyes" ; then
+ SIZE16="int16_t"
+else
+ case 2 in
+ $ac_cv_sizeof_short) SIZE16="short";;
+ $ac_cv_sizeof_int) SIZE16="int";;
+ esac
+fi
+
+if test x$has_int32_t = "xyes" ; then
+ SIZE32="int32_t"
+else
+ case 4 in
+ $ac_cv_sizeof_short) SIZE32="short";;
+ $ac_cv_sizeof_int) SIZE32="int";;
+ $ac_cv_sizeof_long) SIZE32="long";;
+ esac
+fi
+
+if test x$has_uint32_t = "xyes" ; then
+ USIZE32="uint32_t"
+else
+ if test x$has_u_int32_t = "xyes" ; then
+ USIZE32="u_int32_t"
+ else
+ case 4 in
+ $ac_cv_sizeof_short) USIZE32="unsigned short";;
+ $ac_cv_sizeof_int) USIZE32="unsigned int";;
+ $ac_cv_sizeof_long) USIZE32="unsigned long";;
+ esac
+ fi
+fi
+
+if test x$has_int64_t = "xyes" ; then
+ SIZE64="int64_t"
+else
+case 8 in
+ $ac_cv_sizeof_int) SIZE64="int";;
+ $ac_cv_sizeof_long) SIZE64="long";;
+ $ac_cv_sizeof_long_long) SIZE64="long long";;
+esac
+fi
+
+if test -z "$SIZE16"; then
+ { echo "configure: error: No 16 bit type found on this platform!" 1>&2; exit 1; }
+fi
+if test -z "$SIZE32"; then
+ { echo "configure: error: No 32 bit type found on this platform!" 1>&2; exit 1; }
+fi
+if test -z "$USIZE32"; then
+ { echo "configure: error: No unsigned 32 bit type found on this platform!" 1>&2; exit 1; }
+fi
+if test -z "$SIZE64"; then
+ echo "configure: warning: No 64 bit type found on this platform!" 1>&2
+fi
+
+#AC_CHECK_HEADER(alloca.h,AC_DEFINE(USE_ALLOCA_H),:)
+#AC_CHECK_HEADER(memory.h,AC_DEFINE(USE_MEMORY_H),:)
+# We no longer use config.h
+ac_safe=`echo "alloca.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for alloca.h""... $ac_c" 1>&6
+echo "configure:1783: checking for alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1788 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1793: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ CFLAGS="$CFLAGS -DUSE_ALLOCA_H"
+else
+ echo "$ac_t""no" 1>&6
+:
+fi
+
+ac_safe=`echo "memory.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for memory.h""... $ac_c" 1>&6
+echo "configure:1817: checking for memory.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1822 "configure"
+#include "confdefs.h"
+#include <memory.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ CFLAGS="$CFLAGS -DUSE_MEMORY_H"
+else
+ echo "$ac_t""no" 1>&6
+:
+fi
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1851: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1856 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1926: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1931 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1940: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:1961: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1966 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:1974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1996: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
+echo "configure:2023: checking for 8-bit clean memcmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_memcmp_clean=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2031 "configure"
+#include "confdefs.h"
+
+main()
+{
+ char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+ exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
+}
+
+EOF
+if { (eval echo configure:2041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_memcmp_clean=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_memcmp_clean=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2059: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2064 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:2081: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+for ac_func in gettimeofday select strcspn strerror strspn sigaction
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2102: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2107 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+#AC_SUBST(XOGG)
+#AC_SUBST(LIBGTKDIR)
+
+
+subdirs="vorbis-tools/libao"
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile lib/Makefile examples/Makefile include/vorbis/os_types.h\
+ vorbis-tools/Makefile\
+ vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile kmpg/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@RANLIB@%$RANLIB%g
+s%@AR@%$AR%g
+s%@INSTALL@%$INSTALL%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@SIZE16@%$SIZE16%g
+s%@SIZE32@%$SIZE32%g
+s%@USIZE32@%$USIZE32%g
+s%@SIZE64@%$SIZE64%g
+s%@OPT@%$OPT%g
+s%@DEBUG@%$DEBUG%g
+s%@PROFILE@%$PROFILE%g
+s%@pthread_lib@%$pthread_lib%g
+s%@subdirs@%$subdirs%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile examples/Makefile include/vorbis/os_types.h\
+ vorbis-tools/Makefile\
+ vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile kmpg/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in vorbis-tools/libao; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 00000000..22b5fedc
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,358 @@
+# $Id: configure.in,v 1.20.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+AC_INIT(lib/mdct.c)
+#AC_CONFIG_HEADER(config.h)
+
+cp configure.guess config.guess
+cp configure.sub config.sub
+
+AC_CANONICAL_HOST
+
+dnl If we're on IRIX, we wanna use cc even if gcc is there (unless the user
+dnl has overriden us)...
+case $host in
+ *-*-irix*)
+ if test -z "$CC"; then
+ CC=cc
+ fi
+ AC_CHECK_LIB(audio, ALwritesamps)
+ ;;
+# BeOS does not use -lm
+# *-*-beos)
+# LIBS=""
+# ;;
+# added better check below
+
+esac
+
+cflags_save="$CFLAGS"
+AC_PROG_CC
+# because AC_PROG_CC likes to set -g
+CFLAGS="$cflags_save"
+
+AC_PROG_CPP
+AC_PROG_RANLIB
+AC_CHECK_PROG(AR,ar,ar)
+AC_CHECK_PROG(INSTALL,install,install)
+
+#not everyone uses libm (eg, BeOS)
+#AC_CHECK_LIB(m, cos, LIBS="-lm"; AC_DEFINE(HAVE_LIBM), LIBS="")
+# We no longer use config.h
+AC_CHECK_LIB(m, cos, LIBS="-lm", LIBS="")
+
+dnl Set some target options
+if test -z "$GCC"; then
+ case $host in
+ *-*-irix*)
+ DEBUG="-g -signed"
+ OPT="-O2 -w -signed"
+ PROFILE="-p -g3 -O2 -signed" ;;
+ sparc-sun-solaris*)
+ DEBUG="-v -g"
+ OPT="-xO4 -fast -w -fsimple -native -xcg92"
+ PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" ;;
+ *)
+ DEBUG="-g"
+ OPT="-O"
+ PROFILE="-g -p" ;;
+ esac
+else
+
+ case $host in
+ *86-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char"
+
+ # 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([ ])
+
+ OPT=${OPT}" -D__NO_MATH_INLINES"
+ PROFILE=${PROFILE}" -D__NO_MATH_INLINES"
+ fi;;
+ *-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char";;
+ sparc-sun-*)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char -mv8"
+ OPT="-O20 -ffast-math -D__NO_MATH_INLINES -fsigned-char -mv8"
+ PROFILE="-pg -g -O20 -D__NO_MATH_INLINES -fsigned-char -mv8" ;;
+ *)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char"
+ OPT="-O20 -D__NO_MATH_INLINES -fsigned-char"
+ PROFILE="-O20 -g -pg -D__NO_MATH_INLINES -fsigned-char" ;;
+ esac
+fi
+
+AC_HEADER_STDC
+
+dnl AC_PATH_X
+dnl AC_PATH_XTRA
+
+#AC_CHECK_LIB(pthread, pthread_create,
+# pthread_lib="-lpthread"; AC_DEFINE(HAVE_LIBPTHREAD), :)
+# We no longer use config.h
+AC_CHECK_LIB(pthread, pthread_create, pthread_lib="-lpthread", :)
+
+#dnl Linuxthreads require you to define _REENTRANT in all threaded
+#dnl code. Bogus, bogus...
+#
+#if test -n "$pthread_lib"; then
+# case $host in
+# i?86-*-linux*)
+# AC_DEFINE(_REENTRANT)
+# ;;
+# esac
+#fi
+# We no longer use config.h
+
+#if test -n "$x_libraries"; then
+# XOGG="yes"
+#
+# dnl If we find libgtk installed, great; otherwise assume we have
+# dnl to build it ourselves.
+#
+# AC_CHECK_LIB(gtk, gtk_main, :, LIBGTKDIR="libgtk", $X_LIBS -lglib -lgdk -lX11 -lXext -lm)
+#
+# dnl libpthread is required for xogg.
+#
+# if test -z "$pthread_lib"; then XOGG=""; fi
+#
+# dnl If we don't have libgtk installed, and we don't have a libgtk
+# dnl subdirectory to build the library ourself, we can't build xogg.
+#
+# if test -n "$LIBGTKDIR" -a ! -d "$LIBGTKDIR"; then
+# XOGG=""
+# LIBGTKDIR=""
+# fi
+#fi
+
+dnl This seems to be the only way to make autoconf only *sometimes* configure
+dnl a subdirectory with AC_CONFIG_SUBDIRS. "__noconf" is assumed to not
+dnl exist as a directory, so configure won't try to recursively enter it, unless
+dnl the shell variable $dummy is reset to an existing directory inside the
+dnl if clause.
+
+dummy="__noconf"
+
+#if test -d "$LIBGTKDIR"; then
+# enable_shared="no"; export enable_shared
+# dummy="libgtk"
+# AC_CONFIG_SUBDIRS("$dummy")
+# X_LIBS="-L${srcdir}/libgtk/gtk/.libs -L${srcdir}/libgtk/gdk/.libs -L${srcdir}/libgtk/glib/.libs $X_LIBS"
+#fi
+
+# check macro modified from Jon Shiring's to compensate for autoconf's lagging
+# behind the times on type madness
+
+AC_MSG_CHECKING(for int16_t)
+AC_CACHE_VAL(has_int16_t,
+[AC_TRY_RUN([
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int16_t foo;
+int main() {return 0;}
+],
+has_int16_t=yes,
+has_int16_t=no,
+has_int16_t=no
+)])
+AC_MSG_RESULT($has_int16_t)
+
+AC_MSG_CHECKING(for int32_t)
+AC_CACHE_VAL(has_int32_t,
+[AC_TRY_RUN([
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int32_t foo;
+int main() {return 0;}
+],
+has_int32_t=yes,
+has_int32_t=no,
+has_int32_t=no
+)])
+AC_MSG_RESULT($has_int32_t)
+
+AC_MSG_CHECKING(for uint32_t)
+AC_CACHE_VAL(has_uint32_t,
+[AC_TRY_RUN([
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+uint32_t foo;
+int main() {return 0;}
+],
+has_uint32_t=yes,
+has_uint32_t=no,
+has_uint32_t=no
+)])
+AC_MSG_RESULT($has_uint32_t)
+
+AC_MSG_CHECKING(for u_int32_t)
+AC_CACHE_VAL(has_u_int32_t,
+[AC_TRY_RUN([
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+u_int32_t foo;
+int main() {return 0;}
+],
+has_u_int32_t=yes,
+has_u_int32_t=no,
+has_u_int32_t=no
+)])
+AC_MSG_RESULT($has_u_int32_t)
+
+AC_MSG_CHECKING(for int64_t)
+AC_CACHE_VAL(has_int64_t,
+[AC_TRY_RUN([
+#ifdef __BEOS__
+#include <inttypes.h>
+#endif
+#include <sys/types.h>
+int64_t foo;
+int main() {return 0;}
+],
+has_int64_t=yes,
+has_int64_t=no,
+has_int64_t=no
+)])
+AC_MSG_RESULT($has_int64_t)
+
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+
+
+if test x$has_int16_t = "xyes" ; then
+ SIZE16="int16_t"
+else
+ case 2 in
+ $ac_cv_sizeof_short) SIZE16="short";;
+ $ac_cv_sizeof_int) SIZE16="int";;
+ esac
+fi
+
+if test x$has_int32_t = "xyes" ; then
+ SIZE32="int32_t"
+else
+ case 4 in
+ $ac_cv_sizeof_short) SIZE32="short";;
+ $ac_cv_sizeof_int) SIZE32="int";;
+ $ac_cv_sizeof_long) SIZE32="long";;
+ esac
+fi
+
+if test x$has_uint32_t = "xyes" ; then
+ USIZE32="uint32_t"
+else
+ if test x$has_u_int32_t = "xyes" ; then
+ USIZE32="u_int32_t"
+ else
+ case 4 in
+ $ac_cv_sizeof_short) USIZE32="unsigned short";;
+ $ac_cv_sizeof_int) USIZE32="unsigned int";;
+ $ac_cv_sizeof_long) USIZE32="unsigned long";;
+ esac
+ fi
+fi
+
+if test x$has_int64_t = "xyes" ; then
+ SIZE64="int64_t"
+else
+case 8 in
+ $ac_cv_sizeof_int) SIZE64="int";;
+ $ac_cv_sizeof_long) SIZE64="long";;
+ $ac_cv_sizeof_long_long) SIZE64="long long";;
+esac
+fi
+
+if test -z "$SIZE16"; then
+ AC_MSG_ERROR(No 16 bit type found on this platform!)
+fi
+if test -z "$SIZE32"; then
+ AC_MSG_ERROR(No 32 bit type found on this platform!)
+fi
+if test -z "$USIZE32"; then
+ AC_MSG_ERROR(No unsigned 32 bit type found on this platform!)
+fi
+if test -z "$SIZE64"; then
+ AC_MSG_WARN(No 64 bit type found on this platform!)
+fi
+
+#AC_CHECK_HEADER(alloca.h,AC_DEFINE(USE_ALLOCA_H),:)
+#AC_CHECK_HEADER(memory.h,AC_DEFINE(USE_MEMORY_H),:)
+# We no longer use config.h
+AC_CHECK_HEADER(alloca.h,CFLAGS="$CFLAGS -DUSE_ALLOCA_H",:)
+AC_CHECK_HEADER(memory.h,CFLAGS="$CFLAGS -DUSE_MEMORY_H",:)
+
+AC_C_CONST
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+AC_PROG_MAKE_SET
+AC_FUNC_MEMCMP
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS(gettimeofday select strcspn strerror strspn sigaction)
+
+AC_SUBST(SIZE16)
+AC_SUBST(SIZE32)
+AC_SUBST(USIZE32)
+AC_SUBST(SIZE64)
+AC_SUBST(OPT)
+AC_SUBST(LIBS)
+AC_SUBST(DEBUG)
+AC_SUBST(PROFILE)
+AC_SUBST(CC)
+AC_SUBST(RANLIB)
+#AC_SUBST(XOGG)
+#AC_SUBST(LIBGTKDIR)
+AC_SUBST(pthread_lib)
+
+AC_CONFIG_SUBDIRS(vorbis-tools/libao)
+
+AC_OUTPUT(Makefile lib/Makefile examples/Makefile include/vorbis/os_types.h\
+ vorbis-tools/Makefile\
+ vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile kmpg/Makefile)
+
diff --git a/examples/decoder_example.c b/examples/decoder_example.c
new file mode 100644
index 00000000..9d81fc7f
--- /dev/null
+++ b/examples/decoder_example.c
@@ -0,0 +1,299 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple example decoder
+ last mod: $Id: decoder_example.c,v 1.11.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ ********************************************************************/
+
+/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to
+ stdout. Decodes simple and chained OggVorbis files from beginning
+ to end. Vorbisfile.a is somewhat more complex than the code below. */
+
+/* Note that this is POSIX, not ANSI code */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "vorbis/codec.h"
+
+#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(macintosh) && defined(__MWERKS__)
+#include <console.h> /* CodeWarrior's Mac "command-line" support */
+#endif
+
+ogg_int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
+int convsize=4096;
+
+int main(int argc, char **argv){
+ ogg_sync_state oy; /* sync and verify incoming physical bitstream */
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream
+ settings */
+ vorbis_comment vc; /* struct that stores all the bitstream user comments */
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ char *buffer;
+ int bytes;
+
+#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
+ /* Beware the evil ifdef. We avoid these where we can, but this one we
+ cannot. Don't add any more, you'll probably go to hell if you do. */
+ _setmode( _fileno( stdin ), _O_BINARY );
+ _setmode( _fileno( stdout ), _O_BINARY );
+#endif
+
+#if defined(macintosh) && defined(__MWERKS__)
+
+ argc = ccommand(&argv); /* get a "command line" from the Mac user */
+ /* this also lets the user set stdin and stdout */
+#endif
+
+ /********** Decode setup ************/
+
+ ogg_sync_init(&oy); /* Now we can read pages */
+
+ while(1){ /* we repeat if the bitstream is chained */
+ int eos=0;
+ int i;
+
+ /* grab some data at the head of the stream. We want the first page
+ (which is guaranteed to be small and only contain the Vorbis
+ stream initial header) We need the first page to get the stream
+ serialno. */
+
+ /* submit a 4k block to libvorbis' Ogg layer */
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ ogg_sync_wrote(&oy,bytes);
+
+ /* Get the first page. */
+ if(ogg_sync_pageout(&oy,&og)!=1){
+ /* have we simply run out of data? If so, we're done. */
+ if(bytes<4096)break;
+
+ /* error case. Must not be Vorbis data */
+ fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
+ exit(1);
+ }
+
+ /* Get the serial number and set up the rest of decode. */
+ /* serialno first; use it to set up a logical stream */
+ ogg_stream_init(&os,ogg_page_serialno(&og));
+
+ /* extract the initial header from the first page and verify that the
+ Ogg bitstream is in fact Vorbis data */
+
+ /* I handle the initial header first instead of just having the code
+ read all three Vorbis headers at once because reading the initial
+ header is an easy way to identify a Vorbis bitstream and it's
+ useful to see that functionality seperated out. */
+
+ vorbis_info_init(&vi);
+ vorbis_comment_init(&vc);
+ if(ogg_stream_pagein(&os,&og)<0){
+ /* error; stream version mismatch perhaps */
+ fprintf(stderr,"Error reading first page of Ogg bitstream data.\n");
+ exit(1);
+ }
+
+ if(ogg_stream_packetout(&os,&op)!=1){
+ /* no page? must not be vorbis */
+ fprintf(stderr,"Error reading initial header packet.\n");
+ exit(1);
+ }
+
+ if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){
+ /* error case; not a vorbis header */
+ fprintf(stderr,"This Ogg bitstream does not contain Vorbis "
+ "audio data.\n");
+ exit(1);
+ }
+
+ /* At this point, we're sure we're Vorbis. We've set up the logical
+ (Ogg) bitstream decoder. Get the comment and codebook headers and
+ set up the Vorbis decoder */
+
+ /* The next two packets in order are the comment and codebook headers.
+ They're likely large and may span multiple pages. Thus we reead
+ and submit data until we get our two pacakets, watching that no
+ pages are missing. If a page is missing, error out; losing a
+ header page is the only place where missing data is fatal. */
+
+ i=0;
+ while(i<2){
+ while(i<2){
+ int result=ogg_sync_pageout(&oy,&og);
+ if(result==0)break; /* Need more data */
+ /* Don't complain about missing or corrupt data yet. We'll
+ catch it at the packet output phase */
+ if(result==1){
+ ogg_stream_pagein(&os,&og); /* we can ignore any errors here
+ as they'll also become apparent
+ at packetout */
+ while(i<2){
+ result=ogg_stream_packetout(&os,&op);
+ if(result==0)break;
+ if(result==-1){
+ /* Uh oh; data at some point was corrupted or missing!
+ We can't tolerate that in a header. Die. */
+ fprintf(stderr,"Corrupt secondary header. Exiting.\n");
+ exit(1);
+ }
+ vorbis_synthesis_headerin(&vi,&vc,&op);
+ i++;
+ }
+ }
+ }
+ /* no harm in not checking before adding more */
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ if(bytes==0 && i<2){
+ fprintf(stderr,"End of file before finding all Vorbis headers!\n");
+ exit(1);
+ }
+ ogg_sync_wrote(&oy,bytes);
+ }
+
+ /* Throw the comments plus a few lines about the bitstream we're
+ decoding */
+ {
+ char **ptr=vc.user_comments;
+ while(*ptr){
+ fprintf(stderr,"%s\n",*ptr);
+ ++ptr;
+ }
+ fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi.channels,vi.rate);
+ fprintf(stderr,"Encoded by: %s\n\n",vc.vendor);
+ }
+
+ convsize=4096/vi.channels;
+
+ /* OK, got and parsed all three headers. Initialize the Vorbis
+ packet->PCM decoder. */
+ vorbis_synthesis_init(&vd,&vi); /* central decode state */
+ vorbis_block_init(&vd,&vb); /* local state for most of the decode
+ so multiple block decodes can
+ proceed in parallel. We could init
+ multiple vorbis_block structures
+ for vd here */
+
+ /* The rest is just a straight decode loop until end of stream */
+ while(!eos){
+ while(!eos){
+ int result=ogg_sync_pageout(&oy,&og);
+ if(result==0)break; /* need more data */
+ if(result==-1){ /* missing or corrupt data at this page position */
+ fprintf(stderr,"Corrupt or missing data in bitstream; "
+ "continuing...\n");
+ }else{
+ ogg_stream_pagein(&os,&og); /* can safely ignore errors at
+ this point */
+ while(1){
+ result=ogg_stream_packetout(&os,&op);
+
+ if(result==0)break; /* need more data */
+ if(result==-1){ /* missing or corrupt data at this page position */
+ /* no reason to complain; already complained above */
+ }else{
+ /* we have a packet. Decode it */
+ double **pcm;
+ int samples;
+
+ if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
+ vorbis_synthesis_blockin(&vd,&vb);
+ /*
+
+ **pcm is a multichannel double vector. In stereo, for
+ example, pcm[0] is left, and pcm[1] is right. samples is
+ the size of each channel. Convert the float values
+ (-1.<=range<=1.) to whatever PCM format and write it out */
+
+ while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
+ int j;
+ int clipflag=0;
+ int bout=(samples<convsize?samples:convsize);
+
+ /* convert doubles to 16 bit signed ints (host order) and
+ interleave */
+ for(i=0;i<vi.channels;i++){
+ ogg_int16_t *ptr=convbuffer+i;
+ double *mono=pcm[i];
+ for(j=0;j<bout;j++){
+ int val=mono[j]*32767.;
+ /* might as well guard against clipping */
+ if(val>32767){
+ val=32767;
+ clipflag=1;
+ }
+ if(val<-32768){
+ val=-32768;
+ clipflag=1;
+ }
+ *ptr=val;
+ ptr+=2;
+ }
+ }
+
+ if(clipflag)
+ fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence));
+
+
+ fwrite(convbuffer,2*vi.channels,bout,stdout);
+
+ vorbis_synthesis_read(&vd,bout); /* tell libvorbis how
+ many samples we
+ actually consumed */
+ }
+ }
+ }
+ if(ogg_page_eos(&og))eos=1;
+ }
+ }
+ if(!eos){
+ buffer=ogg_sync_buffer(&oy,4096);
+ bytes=fread(buffer,1,4096,stdin);
+ ogg_sync_wrote(&oy,bytes);
+ if(bytes==0)eos=1;
+ }
+ }
+
+ /* clean up this logical bitstream; before exit we see if we're
+ followed by another [chained] */
+
+ ogg_stream_clear(&os);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_info_clear(&vi); /* must be called last */
+ }
+
+ /* OK, clean up the framer */
+ ogg_sync_clear(&oy);
+
+ fprintf(stderr,"Done.\n");
+ return(0);
+}
+
diff --git a/include/vorbis/codec.h b/include/vorbis/codec.h
new file mode 100644
index 00000000..581a23cb
--- /dev/null
+++ b/include/vorbis/codec.h
@@ -0,0 +1,431 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec.h,v 1.27.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _vorbis_codec_h_
+#define _vorbis_codec_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define MAX_BARK 27
+
+#include "os_types.h"
+#include "vorbis/codebook.h"
+#include "vorbis/internal.h"
+
+typedef void vorbis_look_transform;
+typedef void vorbis_info_time;
+typedef void vorbis_look_time;
+typedef void vorbis_info_floor;
+typedef void vorbis_look_floor;
+typedef void vorbis_echstate_floor;
+typedef void vorbis_info_residue;
+typedef void vorbis_look_residue;
+typedef void vorbis_info_mapping;
+typedef void vorbis_look_mapping;
+
+/* mode ************************************************************/
+typedef struct {
+ int blockflag;
+ int windowtype;
+ int transformtype;
+ int mapping;
+} vorbis_info_mode;
+
+/* psychoacoustic setup ********************************************/
+#define P_BANDS 17
+#define P_LEVELS 11
+typedef struct vorbis_info_psy{
+ int athp;
+ int decayp;
+ int smoothp;
+
+ int noisecullp;
+ double noisecull_barkwidth;
+
+ double ath_adjatt;
+ double ath_maxatt;
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ int tonemaskp;
+ double toneatt[P_BANDS][P_LEVELS];
+
+ int peakattp;
+ double peakatt[P_BANDS][P_LEVELS];
+
+ int noisemaskp;
+ double noiseatt[P_BANDS][P_LEVELS];
+
+ double max_curve_dB;
+
+ /* decay setup */
+ double attack_coeff;
+ double decay_coeff;
+} vorbis_info_psy;
+
+/* vorbis_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 vorbis_info{
+ int version;
+ int channels;
+ long rate;
+
+ /* The below bitrate declarations are *hints*.
+ Combinations of the three values carry the following implications:
+
+ all three set to the same value:
+ implies a fixed rate bitstream
+ only nominal set:
+ implies a VBR stream that averages the nominal bitrate. No hard
+ upper/lower limit
+ upper and or lower set:
+ implies a VBR bitstream that obeys the bitrate limits. nominal
+ may also be set to give a nominal rate.
+ none set:
+ the coder does not care to speculate.
+ */
+
+ long bitrate_upper;
+ long bitrate_nominal;
+ long bitrate_lower;
+
+ /* 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 mid-side),
+ 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 */
+
+ /* for block long/sort tuning; encode only */
+ int envelopesa;
+ double preecho_thresh;
+ double preecho_clamp;
+ double preecho_minenergy;
+} vorbis_info;
+
+/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
+
+typedef struct {
+ unsigned char *header;
+ long header_len;
+ unsigned char *body;
+ long body_len;
+} ogg_page;
+
+/* ogg_stream_state contains the current encode/decode state of a logical
+ Ogg bitstream **********************************************************/
+
+typedef struct {
+ unsigned char *body_data; /* bytes from packet bodies */
+ long body_storage; /* storage elements allocated */
+ long body_fill; /* elements stored; fill mark */
+ long body_returned; /* elements of fill returned */
+
+
+ int *lacing_vals; /* The values that will go to the segment table */
+ ogg_int64_t *pcm_vals; /* pcm_pos values for headers. Not compact
+ this way, but it is simple coupled to the
+ lacing fifo */
+ long lacing_storage;
+ long lacing_fill;
+ long lacing_packet;
+ long lacing_returned;
+
+ unsigned char header[282]; /* working space for header encode */
+ int header_fill;
+
+ int e_o_s; /* set when we have buffered the last packet in the
+ logical bitstream */
+ int b_o_s; /* set after we've written the initial page
+ of a logical bitstream */
+ long serialno;
+ int pageno;
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a seperate abstraction
+ layer) also knows about the gap */
+ ogg_int64_t pcmpos;
+
+} ogg_stream_state;
+
+/* ogg_packet is used to encapsulate the data and metadata belonging
+ to a single raw Ogg/Vorbis packet *************************************/
+
+typedef struct {
+ unsigned char *packet;
+ long bytes;
+ long b_o_s;
+ long e_o_s;
+
+ ogg_int64_t frameno;
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a seperate abstraction
+ layer) also knows about the gap */
+
+} ogg_packet;
+
+typedef struct {
+ unsigned char *data;
+ int storage;
+ int fill;
+ int returned;
+
+ int unsynced;
+ int headerbytes;
+ int bodybytes;
+} ogg_sync_state;
+
+/* vorbis_dsp_state buffers the current vorbis audio
+ analysis/synthesis state. The DSP state belongs to a specific
+ logical bitstream ****************************************************/
+typedef struct vorbis_dsp_state{
+ int analysisp;
+ vorbis_info *vi;
+ int modebits;
+
+ double **pcm;
+ double **pcmret;
+ int pcm_storage;
+ int pcm_current;
+ int pcm_returned;
+
+ int preextrapolate;
+ int eofflag;
+
+ long lW;
+ long W;
+ long nW;
+ long centerW;
+
+ ogg_int64_t frameno;
+ ogg_int64_t sequence;
+
+ ogg_int64_t glue_bits;
+ ogg_int64_t time_bits;
+ ogg_int64_t floor_bits;
+ ogg_int64_t res_bits;
+
+ /* local lookup storage */
+ void *ve; /* envelope lookup */
+ double **window[2][2][2]; /* block, leadin, leadout, type */
+ vorbis_look_transform **transform[2]; /* block, type */
+ codebook *fullbooks;
+ /* backend lookups are tied to the mode, not the backend or naked mapping */
+ 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;
+
+} vorbis_dsp_state;
+
+/* vorbis_block is a single block of data to be processed as part of
+the analysis/synthesis stream; it belongs to a specific logical
+bitstream, but is independant from other vorbis_blocks belonging to
+that logical bitstream. *************************************************/
+
+struct alloc_chain{
+ void *ptr;
+ struct alloc_chain *next;
+};
+
+typedef struct vorbis_block{
+ /* necessary stream state for linking to the framing abstraction */
+ double **pcm; /* this is a pointer into local storage */
+ oggpack_buffer opb;
+
+ long lW;
+ long W;
+ long nW;
+ int pcmend;
+ int mode;
+
+ int eofflag;
+ ogg_int64_t frameno;
+ ogg_int64_t sequence;
+ vorbis_dsp_state *vd; /* For read-only access of configuration */
+
+ /* local storage to avoid remallocing; it's up to the mapping to
+ structure it */
+ void *localstore;
+ long localtop;
+ long localalloc;
+ long totaluse;
+ struct alloc_chain *reap;
+
+ /* bitmetrics for the frame */
+ long glue_bits;
+ long time_bits;
+ long floor_bits;
+ long res_bits;
+
+} vorbis_block;
+
+#include "vorbis/backends.h"
+
+/* vorbis_info contains all the setup information specific to the
+ specific compression/decompression mode in progress (eg,
+ psychoacoustic settings, channel setup, options, codebook
+ etc). vorbis_info and substructures are in backends.h.
+*********************************************************************/
+
+/* the comments are not part of vorbis_info so that vorbis_info can be
+ static storage */
+typedef struct vorbis_comment{
+ /* unlimited user comment fields. libvorbis writes 'libvorbis'
+ whatever vendor is set to in encode */
+ char **user_comments;
+ int *comment_lengths;
+ int comments;
+ char *vendor;
+
+} vorbis_comment;
+
+
+/* libvorbis encodes in two abstraction layers; first we perform DSP
+ and produce a packet (see docs/analysis.txt). The packet is then
+ coded into a framed OggSquish bitstream by the second layer (see
+ docs/framing.txt). Decode is the reverse process; we sync/frame
+ the bitstream and extract individual packets, then decode the
+ packet back into PCM audio.
+
+ The extra framing/packetizing is used in streaming formats, such as
+ files. Over the net (such as with UDP), the framing and
+ packetization aren't necessary as they're provided by the transport
+ and the streaming layer is not used */
+
+/* OggSquish BITSREAM PRIMITIVES: encoding **************************/
+
+extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
+
+/* OggSquish BITSREAM PRIMITIVES: decoding **************************/
+
+extern int ogg_sync_init(ogg_sync_state *oy);
+extern int ogg_sync_clear(ogg_sync_state *oy);
+extern int ogg_sync_destroy(ogg_sync_state *oy);
+extern int ogg_sync_reset(ogg_sync_state *oy);
+
+extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
+extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
+extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
+extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
+extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
+
+/* OggSquish BITSREAM PRIMITIVES: general ***************************/
+
+extern int ogg_stream_init(ogg_stream_state *os,int serialno);
+extern int ogg_stream_clear(ogg_stream_state *os);
+extern int ogg_stream_reset(ogg_stream_state *os);
+extern int ogg_stream_destroy(ogg_stream_state *os);
+extern int ogg_stream_eof(ogg_stream_state *os);
+
+extern int ogg_page_version(ogg_page *og);
+extern int ogg_page_continued(ogg_page *og);
+extern int ogg_page_bos(ogg_page *og);
+extern int ogg_page_eos(ogg_page *og);
+extern ogg_int64_t ogg_page_frameno(ogg_page *og);
+extern int ogg_page_serialno(ogg_page *og);
+extern int ogg_page_pageno(ogg_page *og);
+
+/* Vorbis PRIMITIVES: general ***************************************/
+
+extern void vorbis_info_init(vorbis_info *vi);
+extern void vorbis_info_clear(vorbis_info *vi);
+extern void vorbis_comment_init(vorbis_comment *vc);
+extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
+extern void vorbis_comment_add_tag(vorbis_comment *vc,
+ char *tag, char *contents);
+extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
+extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
+extern void vorbis_comment_clear(vorbis_comment *vc);
+
+extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
+extern int vorbis_block_clear(vorbis_block *vb);
+extern void vorbis_dsp_clear(vorbis_dsp_state *v);
+
+/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+
+extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code);
+extern double **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
+
+/* Vorbis PRIMITIVES: synthesis layer *******************************/
+extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
+ ogg_packet *op);
+
+extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
+extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm);
+extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/include/vorbis/os_types.h.in b/include/vorbis/os_types.h.in
index f4638a66..936ff5d6 100644
--- a/include/vorbis/os_types.h.in
+++ b/include/vorbis/os_types.h.in
@@ -14,7 +14,7 @@
********************************************************************
function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id: os_types.h.in,v 1.3 2000/08/30 07:09:46 xiphmont Exp $
+ last mod: $Id: os_types.h.in,v 1.3.2.1 2000/08/31 08:05:47 xiphmont Exp $
********************************************************************/
diff --git a/include/vorbis/vorbisfile.h b/include/vorbis/vorbisfile.h
new file mode 100644
index 00000000..a7a8433e
--- /dev/null
+++ b/include/vorbis/vorbisfile.h
@@ -0,0 +1,118 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: stdio-based convenience library for opening/seeking/decoding
+ last mod: $Id: vorbisfile.h,v 1.6.6.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _OV_FILE_H_
+#define _OV_FILE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include "codec.h"
+
+/* The function prototypes for the callbacks are basically the same as for
+ * the stdio functions fread, fseek, fclose, ftell.
+ * The one difference is that the FILE * arguments have been replaced with
+ * a void * - this is to be used as a pointer to whatever internal data these
+ * functions might need. In the stdio case, it's just a FILE * cast to a void *
+ *
+ * If you use other functions, check the docs for these functions and return
+ * the right values. For seek_func(), you *MUST* return -1 if the stream is
+ * unseekable
+ */
+typedef struct {
+ size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
+ int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
+ int (*close_func) (void *datasource);
+ long (*tell_func) (void *datasource);
+} ov_callbacks;
+
+
+typedef struct {
+ void *datasource; /* Pointer to a FILE *, etc. */
+ int seekable;
+ ogg_int64_t offset;
+ ogg_int64_t end;
+ ogg_sync_state oy;
+
+ /* If the FILE handle isn't seekable (eg, a pipe), only the current
+ stream appears */
+ int links;
+ ogg_int64_t *offsets;
+ ogg_int64_t *dataoffsets;
+ long *serialnos;
+ ogg_int64_t *pcmlengths;
+ vorbis_info *vi;
+ vorbis_comment *vc;
+
+ /* Decoding working state local storage */
+ ogg_int64_t pcm_offset;
+ int decode_ready;
+ long current_serialno;
+ int current_link;
+
+ double bittrack;
+ double samptrack;
+
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ ov_callbacks callbacks;
+
+} OggVorbis_File;
+
+extern int ov_clear(OggVorbis_File *vf);
+extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
+ char *initial, long ibytes, ov_callbacks callbacks);
+
+extern long ov_bitrate(OggVorbis_File *vf,int i);
+extern long ov_bitrate_instant(OggVorbis_File *vf);
+extern long ov_streams(OggVorbis_File *vf);
+extern long ov_seekable(OggVorbis_File *vf);
+extern long ov_serialnumber(OggVorbis_File *vf,int i);
+
+extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
+extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
+extern double ov_time_total(OggVorbis_File *vf,int i);
+
+extern int ov_raw_seek(OggVorbis_File *vf,long pos);
+extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_time_seek(OggVorbis_File *vf,double pos);
+
+extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
+extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
+extern double ov_time_tell(OggVorbis_File *vf);
+
+extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
+
+extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
+
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644
index 00000000..c82532d3
--- /dev/null
+++ b/lib/Makefile.in
@@ -0,0 +1,100 @@
+# vorbis makefile configured for use with gcc on any platform
+# $Id: Makefile.in,v 1.33.4.1 2000/08/31 08:05:47 xiphmont Exp $
+
+###############################################################################
+# #
+# To build a production vorbis (preferrably using gmake), just type 'make'. #
+# To build with debugging or profiling information, use 'make debug' or #
+# 'make profile' respectively. 'make clean' is a good idea between builds #
+# with different target names, or before a final build. #
+# #
+###############################################################################
+
+
+# DO NOT EDIT BELOW! ##########################################################
+# (unless, of course, you know what you are doing :) ##########################
+
+@SET_MAKE@
+FLAGS=-I. -I../include @CFLAGS@
+OPT=@OPT@ $(FLAGS)
+DEBUG=@DEBUG@ $(FLAGS)
+PROFILE=@PROFILE@ $(FLAGS)
+CC=@CC@
+LD=@CC@
+LDFLAGS=@LDFLAGS@ $(FLAGS)
+AR=@AR@
+RANLIB=@RANLIB@
+LIBS=@LIBS@
+
+HFILES = ../include/vorbis/codec.h \
+ ../include/vorbis/internal.h ../include/vorbis/backends.h \
+ ../include/vorbis/codebook.h \
+ bitwise.h envelope.h lpc.h lsp.h bookinternal.h misc.h\
+ psy.h smallft.h window.h scales.h os.h mdct.h registry.h\
+ masking.h sharedbook.h iir.h
+LFILES = framing.o mdct.o smallft.o block.o envelope.o window.o\
+ lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o\
+ time0.o floor0.o res0.o mapping0.o registry.o\
+ codebook.o sharedbook.o iir.o
+VF_HFILES = ../include/vorbis/vorbisfile.h ../include/vorbis/codec.h \
+ ../include/vorbis/internal.h ../include/vorbis/codebook.h \
+ os.h misc.h
+VF_LFILES = vorbisfile.o
+
+PSY_FILES = mdct.o psy.o lpc.o smallft.o window.o psytune.o floor0.o \
+ bitwise.o lsp.o codebook.o sharedbook.o
+
+all:
+ $(MAKE) target CFLAGS="$(OPT)"
+
+debug:
+ $(MAKE) target CFLAGS="$(DEBUG)"
+
+analysis:
+ $(MAKE) target CFLAGS="$(DEBUG) -DANALYSIS"
+
+profile:
+ $(MAKE) target CFLAGS="$(PROFILE)"
+
+target: libvorbis.a vorbisfile.a psytune
+
+selftest:
+ $(MAKE) clean
+ $(CC) $(DEBUG) $(LDFLAGS) -D_V_SELFTEST framing.c -o test_framing
+ $(CC) $(DEBUG) $(LDFLAGS) -D_V_SELFTEST bitwise.c\
+ -o test_bitwise $(LIBS)
+ $(CC) $(DEBUG) $(LDFLAGS) -c bitwise.c
+ $(CC) $(DEBUG) $(LDFLAGS) -D_V_SELFTEST sharedbook.c\
+ -o test_sharedbook $(LIBS)
+ $(CC) $(DEBUG) $(LDFLAGS) -c sharedbook.c
+ $(CC) $(DEBUG) $(LDFLAGS) -D_V_SELFTEST codebook.c \
+ sharedbook.o bitwise.o -o test_codebook $(LIBS)
+ @echo
+ @./test_framing
+ @./test_bitwise
+ @./test_sharedbook
+ @./test_codebook
+
+libvorbis.a: $(LFILES)
+ $(AR) -r libvorbis.a $(LFILES)
+ $(RANLIB) libvorbis.a
+
+vorbisfile.a: $(VF_LFILES)
+ $(AR) -r vorbisfile.a $(VF_LFILES)
+ $(RANLIB) vorbisfile.a
+
+psytune: $(PSY_FILES)
+ $(CC) $(CFLAGS) $(LDFLAGS) $(PSY_FILES) -o $@ $(LIBS)
+
+$(LFILES): $(HFILES)
+$(VF_LFILES): $(VF_HFILES)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ -rm -f *.o *.a test* *~ *.out ogg config.* tone psytune
+
+distclean: clean
+ -rm -f Makefile
+
diff --git a/lib/envelope.c b/lib/envelope.c
new file mode 100644
index 00000000..5f1fdf0c
--- /dev/null
+++ b/lib/envelope.c
@@ -0,0 +1,215 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: PCM data envelope analysis and manipulation
+ last mod: $Id: envelope.c,v 1.21.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ Preecho calculation.
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "vorbis/codec.h"
+
+#include "os.h"
+#include "scales.h"
+#include "envelope.h"
+#include "bitwise.h"
+#include "misc.h"
+
+/* We use a Chebyshev bandbass for the preecho trigger bandpass; it's
+ close enough for sample rates 32000-48000 Hz (corner frequencies at
+ 6k/14k assuming sample rate of 44.1kHz) */
+
+/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
+ Command line: /www/usr/fisher/helpers/mkfilter -Ch \
+ -6.0000000000e+00 -Bp -o 5 -a 1.3605442177e-01 3.1746031746e-01 -l */
+
+#if 0
+static int cheb_bandpass_stages=10;
+static double cheb_bandpass_gain=5.589612458e+01;
+static double cheb_bandpass_B[]={-1.,0.,5.,0.,-10.,0.,10.,0.,-5.,0.,1};
+static double cheb_bandpass_A[]={
+ -0.1917409386,
+ 0.0078657069,
+ -0.7126903444,
+ 0.0266343467,
+ -1.4047174730,
+ 0.0466964232,
+ -1.9032773429,
+ 0.0451493360,
+ -1.4471447397,
+ 0.0303413711};
+#endif
+
+static int cheb_highpass_stages=10;
+static double cheb_highpass_gain= 5.291963434e+01;
+/* z^-stage, z^-stage+1... */
+static double cheb_highpass_B[]={1,-10,45,-120,210,-252,210,-120,45,-10,1};
+static double cheb_highpass_A[]={
+ -0.1247628029,
+ 0.1334086523,
+ -0.3997715614,
+ 0.3213011089,
+ -1.1131924119,
+ 1.7692446626,
+ -3.6241199038,
+ 4.1950871291,
+ -4.2771757867,
+ 2.3920318913};
+
+void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
+ int ch=vi->channels;
+ int window=vi->envelopesa;
+ int i;
+ e->winlength=window;
+ e->minenergy=fromdB(vi->preecho_minenergy);
+ e->iir=calloc(ch,sizeof(IIR_state));
+ e->filtered=calloc(ch,sizeof(double *));
+ e->ch=ch;
+ e->storage=128;
+ for(i=0;i<ch;i++){
+ IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass_gain,
+ cheb_highpass_A,cheb_highpass_B);
+ e->filtered[i]=calloc(e->storage,sizeof(double));
+ }
+
+ drft_init(&e->drft,window);
+ e->window=malloc(e->winlength*sizeof(double));
+ /* We just use a straight sin(x) window for this */
+ for(i=0;i<e->winlength;i++)
+ e->window[i]=sin((i+.5)/e->winlength*M_PI);
+}
+
+void _ve_envelope_clear(envelope_lookup *e){
+ int i;
+ for(i=0;i<e->ch;i++){
+ IIR_clear((e->iir+i));
+ free(e->filtered[i]);
+ }
+ drft_clear(&e->drft);
+ free(e->window);
+ free(e->filtered);
+ memset(e,0,sizeof(envelope_lookup));
+}
+
+static double _ve_deltai(envelope_lookup *ve,IIR_state *iir,
+ double *pre,double *post){
+ long n2=ve->winlength*2;
+ long n=ve->winlength;
+
+ double *workA=alloca(sizeof(double)*n2),A=0.;
+ double *workB=alloca(sizeof(double)*n2),B=0.;
+ long i;
+
+ /*_analysis_output("A",frameno,pre,n,0,0);
+ _analysis_output("B",frameno,post,n,0,0);*/
+
+ for(i=0;i<n;i++){
+ workA[i]=pre[i]*ve->window[i];
+ workB[i]=post[i]*ve->window[i];
+ }
+
+ /*_analysis_output("Awin",frameno,workA,n,0,0);
+ _analysis_output("Bwin",frameno,workB,n,0,0);*/
+
+ drft_forward(&ve->drft,workA);
+ drft_forward(&ve->drft,workB);
+
+ /* we want to have a 'minimum bar' for energy, else we're just
+ basing blocks on quantization noise that outweighs the signal
+ itself (for low power signals) */
+ {
+ double min=ve->minenergy;
+ for(i=0;i<n;i++){
+ if(fabs(workA[i])<min)workA[i]=min;
+ if(fabs(workB[i])<min)workB[i]=min;
+ }
+ }
+
+ /*_analysis_output("Afft",frameno,workA,n,0,0);
+ _analysis_output("Bfft",frameno,workB,n,0,0);*/
+
+ for(i=0;i<n;i++){
+ A+=workA[i]*workA[i];
+ B+=workB[i]*workB[i];
+ }
+
+ A=todB(A);
+ B=todB(B);
+
+ return(B-A);
+}
+
+long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
+ vorbis_info *vi=v->vi;
+ envelope_lookup *ve=v->ve;
+ long i,j;
+
+ /* make sure we have enough storage to match the PCM */
+ if(v->pcm_storage>ve->storage){
+ ve->storage=v->pcm_storage;
+ for(i=0;i<ve->ch;i++)
+ ve->filtered[i]=realloc(ve->filtered[i],ve->storage*sizeof(double));
+ }
+
+ /* catch up the highpass to match the pcm */
+ for(i=0;i<ve->ch;i++){
+ double *filtered=ve->filtered[i];
+ double *pcm=v->pcm[i];
+ IIR_state *iir=ve->iir+i;
+
+ for(j=ve->current;j<v->pcm_current;j++)
+ filtered[j]=IIR_filter(iir,pcm[j]);
+ }
+ ve->current=v->pcm_current;
+
+ /* Now search through our cached highpass data for breaking points */
+ /* starting point */
+ if(v->W)
+ j=v->centerW+vi->blocksizes[1]/4-vi->blocksizes[0]/4;
+ else
+ j=v->centerW;
+
+ while(j+ve->winlength<=v->pcm_current){
+ for(i=0;i<ve->ch;i++){
+ double *filtered=ve->filtered[i]+j;
+ IIR_state *iir=ve->iir+i;
+ double m=_ve_deltai(ve,iir,filtered-ve->winlength,filtered);
+
+ if(m>vi->preecho_thresh){
+ /*frameno++;*/
+ return(0);
+ }
+ /*frameno++;*/
+ }
+
+ j+=vi->blocksizes[0]/2;
+ if(j>=searchpoint)return(1);
+ }
+
+ return(-1);
+}
+
+void _ve_envelope_shift(envelope_lookup *e,long shift){
+ int i;
+ for(i=0;i<e->ch;i++)
+ memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)*
+ sizeof(double));
+ e->current-=shift;
+}
+
+
diff --git a/lib/floor0.c b/lib/floor0.c
new file mode 100644
index 00000000..b2f1c6af
--- /dev/null
+++ b/lib/floor0.c
@@ -0,0 +1,419 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: floor backend 0 implementation
+ last mod: $Id: floor0.c,v 1.23.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "registry.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "bookinternal.h"
+#include "sharedbook.h"
+#include "scales.h"
+#include "misc.h"
+#include "os.h"
+
+#include "misc.h"
+#include <stdio.h>
+
+typedef struct {
+ long n;
+ int ln;
+ int m;
+ int *linearmap;
+
+ vorbis_info_floor0 *vi;
+ lpc_lookup lpclook;
+ double *lsp_look;
+
+} vorbis_look_floor0;
+
+/* infrastructure for finding fit */
+static long _f0_fit(codebook *book,
+ double *orig,
+ double *workfit,
+ int cursor){
+ int dim=book->dim;
+ double norm,base=0.;
+ int i,best=0;
+ double *lsp=workfit+cursor;
+
+ if(cursor)base=workfit[cursor-1];
+ norm=orig[cursor+dim-1]-base;
+
+ for(i=0;i<dim;i++)
+ lsp[i]=(orig[i+cursor]-base);
+ best=_best(book,lsp,1);
+
+ memcpy(lsp,book->valuelist+best*dim,dim*sizeof(double));
+ for(i=0;i<dim;i++)
+ lsp[i]+=base;
+ return(best);
+}
+
+/***********************************************/
+
+static void free_info(vorbis_info_floor *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_floor0));
+ free(i);
+ }
+}
+
+static void free_look(vorbis_look_floor *i){
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ if(i){
+ if(look->linearmap)free(look->linearmap);
+ if(look->lsp_look)free(look->lsp_look);
+ lpc_clear(&look->lpclook);
+ memset(look,0,sizeof(vorbis_look_floor0));
+ free(look);
+ }
+}
+
+static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ int j;
+ _oggpack_write(opb,info->order,8);
+ _oggpack_write(opb,info->rate,16);
+ _oggpack_write(opb,info->barkmap,16);
+ _oggpack_write(opb,info->ampbits,6);
+ _oggpack_write(opb,info->ampdB,8);
+ _oggpack_write(opb,info->numbooks-1,4);
+ for(j=0;j<info->numbooks;j++)
+ _oggpack_write(opb,info->books[j],8);
+}
+
+static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
+ int j;
+ vorbis_info_floor0 *info=malloc(sizeof(vorbis_info_floor0));
+ info->order=_oggpack_read(opb,8);
+ info->rate=_oggpack_read(opb,16);
+ info->barkmap=_oggpack_read(opb,16);
+ info->ampbits=_oggpack_read(opb,6);
+ info->ampdB=_oggpack_read(opb,8);
+ info->numbooks=_oggpack_read(opb,4)+1;
+
+ if(info->order<1)goto err_out;
+ if(info->rate<1)goto err_out;
+ if(info->barkmap<1)goto err_out;
+ if(info->numbooks<1)goto err_out;
+
+ for(j=0;j<info->numbooks;j++){
+ info->books[j]=_oggpack_read(opb,8);
+ if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
+ }
+ return(info);
+ err_out:
+ free_info(info);
+ return(NULL);
+}
+
+/* initialize Bark scale and normalization lookups. We could do this
+ with static tables, but Vorbis allows a number of possible
+ combinations, so it's best to do it computationally.
+
+ The below is authoritative in terms of defining scale mapping.
+ Note that the scale depends on the sampling rate as well as the
+ linear block and mapping sizes */
+
+static vorbis_look_floor *look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
+ vorbis_info_floor *i){
+ int j;
+ double scale;
+ vorbis_info *vi=vd->vi;
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ vorbis_look_floor0 *look=calloc(1,sizeof(vorbis_look_floor0));
+ look->m=info->order;
+ look->n=vi->blocksizes[mi->blockflag]/2;
+ look->ln=info->barkmap;
+ look->vi=info;
+
+ if(vd->analysisp)
+ lpc_init(&look->lpclook,look->ln,look->m);
+
+ /* we choose a scaling constant so that:
+ floor(bark(rate/2-1)*C)=mapped-1
+ floor(bark(rate/2)*C)=mapped */
+ scale=look->ln/toBARK(info->rate/2.);
+
+ /* the mapping from a linear scale to a smaller bark scale is
+ straightforward. We do *not* make sure that the linear mapping
+ does not skip bark-scale bins; the decoder simply skips them and
+ the encoder may do what it wishes in filling them. They're
+ necessary in some mapping combinations to keep the scale spacing
+ accurate */
+ look->linearmap=malloc(look->n*sizeof(int));
+ for(j=0;j<look->n;j++){
+ int val=floor( toBARK((info->rate/2.)/look->n*j)
+ *scale); /* bark numbers represent band edges */
+ if(val>look->ln)val=look->ln; /* guard against the approximation */
+ look->linearmap[j]=val;
+ }
+
+ look->lsp_look=malloc(look->ln*sizeof(double));
+ for(j=0;j<look->ln;j++)
+ look->lsp_look[j]=2*cos(M_PI/look->ln*j);
+
+ return look;
+}
+
+/* less efficient than the decode side (written for clarity). We're
+ not bottlenecked here anyway */
+
+double _curve_to_lpc(double *curve,double *lpc,
+ vorbis_look_floor0 *l,long frameno){
+ /* map the input curve to a bark-scale curve for encoding */
+
+ int mapped=l->ln;
+ double *work=alloca(sizeof(double)*mapped);
+ int i,j,last=0;
+ int bark=0;
+
+ memset(work,0,sizeof(double)*mapped);
+
+ /* Only the decode side is behavior-specced; for now in the encoder,
+ we select the maximum value of each band as representative (this
+ helps make sure peaks don't go out of range. In error terms,
+ selecting min would make more sense, but the codebook is trained
+ numerically, so we don't actually lose. We'd still want to
+ use the original curve for error and noise estimation */
+
+ for(i=0;i<l->n;i++){
+ bark=l->linearmap[i];
+ if(work[bark]<curve[i])work[bark]=curve[i];
+ if(bark>last+1){
+ /* If the bark scale is climbing rapidly, some bins may end up
+ going unused. This isn't a waste actually; it keeps the
+ scale resolution even so that the LPC generator has an easy
+ time. However, if we leave the bins empty we lose energy.
+ So, fill 'em in. The decoder does not do anything with he
+ unused bins, so we can fill them anyway we like to end up
+ with a better spectral curve */
+
+ /* we'll always have a bin zero, so we don't need to guard init */
+ long span=bark-last;
+ for(j=1;j<span;j++){
+ double del=(double)j/span;
+ work[j+last]=work[bark]*del+work[last]*(1.-del);
+ }
+ }
+ last=bark;
+ }
+
+ /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
+ for(i=bark+1;i<mapped;i++)
+ work[i]=work[i-1];
+
+#if 0
+ { /******************/
+ FILE *of;
+ char buffer[80];
+ int i;
+
+ sprintf(buffer,"Fmask_%d.m",frameno);
+ of=fopen(buffer,"w");
+ for(i=0;i<mapped;i++)
+ fprintf(of,"%g\n",work[i]);
+ fclose(of);
+ }
+#endif
+
+ return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
+}
+
+/* generate the whole freq response curve of an LSP IIR filter */
+
+void _lsp_to_curve(double *curve,double *lsp,double amp,
+ vorbis_look_floor0 *l,char *name,long frameno){
+ /* l->m+1 must be less than l->ln, but guard in case we get a bad stream */
+ double *lcurve=alloca(sizeof(double)*l->ln);
+ int i;
+
+ if(amp==0){
+ memset(curve,0,sizeof(double)*l->n);
+ return;
+ }
+ vorbis_lsp_to_curve(lcurve,l->ln,lsp,l->m,amp,l->lsp_look);
+
+ for(i=0;i<l->n;i++)curve[i]=lcurve[l->linearmap[i]];
+
+}
+
+static long seq=0;
+static int forward(vorbis_block *vb,vorbis_look_floor *i,
+ double *in,double *out){
+ long j;
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ vorbis_info_floor0 *info=look->vi;
+ double *work=alloca((look->ln+look->n)*sizeof(double));
+ double amp;
+ long bits=0;
+
+#ifdef TRAIN_LSP
+ FILE *of;
+ FILE *ef;
+ char buffer[80];
+
+#if 1
+ sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
+ of=fopen(buffer,"a");
+#endif
+
+ sprintf(buffer,"lsp0ent_%d.vqd",vb->mode);
+ ef=fopen(buffer,"a");
+#endif
+
+ /* our floor comes in on a linear scale; go to a [-Inf...0] dB
+ scale. The curve has to be positive, so we offset it. */
+
+ for(j=0;j<look->n;j++)
+ work[j]=todB(in[j])+info->ampdB;
+
+ /* use 'out' as temp storage */
+ /* Convert our floor to a set of lpc coefficients */
+ amp=sqrt(_curve_to_lpc(work,out,look,seq));
+
+ /* amp is in the range (0. to ampdB]. Encode that range using
+ ampbits bits */
+
+ {
+ long maxval=(1L<<info->ampbits)-1;
+
+ long val=rint(amp/info->ampdB*maxval);
+
+ if(val<0)val=0; /* likely */
+ if(val>maxval)val=maxval; /* not bloody likely */
+
+ _oggpack_write(&vb->opb,val,info->ampbits);
+ if(val>0)
+ amp=(float)val/maxval*info->ampdB;
+ else
+ amp=0;
+ }
+
+ if(amp>0){
+
+ /* the spec supports using one of a number of codebooks. Right
+ now, encode using this lib supports only one */
+ codebook *b=vb->vd->fullbooks+info->books[0];
+ _oggpack_write(&vb->opb,0,_ilog(info->numbooks));
+
+ /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
+ vorbis_lpc_to_lsp(out,out,look->m);
+
+#if 1
+#ifdef TRAIN_LSP
+ {
+ double last=0.;
+ for(j=0;j<look->m;j++){
+ fprintf(of,"%.12g, ",out[j]-last);
+ last=out[j];
+ }
+ }
+ fprintf(of,"\n");
+ fclose(of);
+#endif
+#endif
+
+ /* code the spectral envelope, and keep track of the actual
+ quantized values; we don't want creeping error as each block is
+ nailed to the last quantized value of the previous block. */
+
+ for(j=0;j<look->m;j+=b->dim){
+ int entry=_f0_fit(b,out,work,j);
+ bits+=vorbis_book_encode(b,entry,&vb->opb);
+
+#ifdef TRAIN_LSP
+ fprintf(ef,"%d,\n",entry);
+#endif
+
+ }
+
+#ifdef ANALYSIS
+ {
+ double last=0;
+ for(j=0;j<look->m;j++){
+ out[j]=work[j]-last;
+ last=work[j];
+ }
+ }
+ _analysis_output("lsp",seq,out,look->m,0,0);
+
+#endif
+
+#ifdef TRAIN_LSP
+ fclose(ef);
+#endif
+
+ /* take the coefficients back to a spectral envelope curve */
+ _lsp_to_curve(out,work,amp,look,"Ffloor",seq++);
+ for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
+ return(1);
+ }
+
+ memset(out,0,sizeof(double)*look->n);
+ seq++;
+ return(0);
+}
+
+static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ vorbis_info_floor0 *info=look->vi;
+ int j,k;
+
+ int ampraw=_oggpack_read(&vb->opb,info->ampbits);
+ if(ampraw>0){ /* also handles the -1 out of data case */
+ long maxval=(1<<info->ampbits)-1;
+ double amp=(float)ampraw/maxval*info->ampdB;
+ int booknum=_oggpack_read(&vb->opb,_ilog(info->numbooks));
+
+ if(booknum!=-1){
+ codebook *b=vb->vd->fullbooks+info->books[booknum];
+ double last=0.;
+
+ memset(out,0,sizeof(double)*look->m);
+
+ for(j=0;j<look->m;j+=b->dim)
+ if(vorbis_book_decodevs(b,out+j,&vb->opb,1,-1)==-1)goto eop;
+ for(j=0;j<look->m;){
+ for(k=0;k<b->dim;k++,j++)out[j]+=last;
+ last=out[j-1];
+ }
+
+ /* take the coefficients back to a spectral envelope curve */
+ _lsp_to_curve(out,out,amp,look,"",0);
+
+ for(j=0;j<look->n;j++)out[j]=fromdB(out[j]-info->ampdB);
+ return(1);
+ }
+ }
+
+ eop:
+ memset(out,0,sizeof(double)*look->n);
+ return(0);
+}
+
+/* export hooks */
+vorbis_func_floor floor0_exportbundle={
+ &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse
+};
+
+
diff --git a/lib/framing.c b/lib/framing.c
new file mode 100644
index 00000000..39c4841b
--- /dev/null
+++ b/lib/framing.c
@@ -0,0 +1,1623 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: code raw [Vorbis] packets into framed OggSquish stream and
+ decode Ogg streams back into raw packets
+ last mod: $Id: framing.c,v 1.24.2.1 2000/08/31 08:05:47 xiphmont Exp $
+
+ note: The CRC code is directly derived from public domain code by
+ Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
+ for details.
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "misc.h"
+
+/* A complete description of Ogg framing exists in docs/framing.html */
+
+int ogg_page_version(ogg_page *og){
+ return((int)(og->header[4]));
+}
+
+int ogg_page_continued(ogg_page *og){
+ return((int)(og->header[5]&0x01));
+}
+
+int ogg_page_bos(ogg_page *og){
+ return((int)(og->header[5]&0x02));
+}
+
+int ogg_page_eos(ogg_page *og){
+ return((int)(og->header[5]&0x04));
+}
+
+ogg_int64_t ogg_page_frameno(ogg_page *og){
+ unsigned char *page=og->header;
+ ogg_int64_t pcmpos=page[13]&(0xff);
+ pcmpos= (pcmpos<<8)|(page[12]&0xff);
+ pcmpos= (pcmpos<<8)|(page[11]&0xff);
+ pcmpos= (pcmpos<<8)|(page[10]&0xff);
+ pcmpos= (pcmpos<<8)|(page[9]&0xff);
+ pcmpos= (pcmpos<<8)|(page[8]&0xff);
+ pcmpos= (pcmpos<<8)|(page[7]&0xff);
+ pcmpos= (pcmpos<<8)|(page[6]&0xff);
+ return(pcmpos);
+}
+
+int ogg_page_serialno(ogg_page *og){
+ return(og->header[14] |
+ (og->header[15]<<8) |
+ (og->header[16]<<16) |
+ (og->header[17]<<24));
+}
+
+int ogg_page_pageno(ogg_page *og){
+ return(og->header[18] |
+ (og->header[19]<<8) |
+ (og->header[20]<<16) |
+ (og->header[21]<<24));
+}
+
+/* helper to initialize lookup for direct-table CRC */
+
+static ogg_uint32_t crc_lookup[256];
+static int crc_ready=0;
+
+static ogg_uint32_t _ogg_crc_entry(unsigned long index){
+ int i;
+ unsigned long r;
+
+ r = index << 24;
+ for (i=0; i<8; i++)
+ if (r & 0x80000000UL)
+ r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
+ polynomial, although we use an
+ unreflected alg and an init/final
+ of 0, not 0xffffffff */
+ else
+ r<<=1;
+ return (r & 0xffffffffUL);
+}
+
+/* mind this in threaded code; sync_init and stream_init call it.
+ It's thread safe only after the first time it returns */
+
+static void _ogg_crc_init(void){
+ if(!crc_ready){
+ /* initialize the crc_lookup table */
+ int i;
+ for (i=0;i<256;i++)
+ crc_lookup[i]=_ogg_crc_entry((unsigned long)i);
+ crc_ready=0;
+ }
+}
+
+/* init the encode/decode logical stream state */
+
+int ogg_stream_init(ogg_stream_state *os,int serialno){
+ if(os){
+ memset(os,0,sizeof(ogg_stream_state));
+ os->body_storage=16*1024;
+ os->body_data=malloc(os->body_storage*sizeof(char));
+
+ os->lacing_storage=1024;
+ os->lacing_vals=malloc(os->lacing_storage*sizeof(int));
+ os->pcm_vals=malloc(os->lacing_storage*sizeof(ogg_int64_t));
+
+ /* initialize the crc_lookup table if not done */
+ _ogg_crc_init();
+
+ os->serialno=serialno;
+
+ return(0);
+ }
+ return(-1);
+}
+
+/* _clear does not free os, only the non-flat storage within */
+int ogg_stream_clear(ogg_stream_state *os){
+ if(os){
+ if(os->body_data)free(os->body_data);
+ if(os->lacing_vals)free(os->lacing_vals);
+ if(os->pcm_vals)free(os->pcm_vals);
+
+ memset(os,0,sizeof(ogg_stream_state));
+ }
+ return(0);
+}
+
+int ogg_stream_destroy(ogg_stream_state *os){
+ if(os){
+ ogg_stream_clear(os);
+ free(os);
+ }
+ return(0);
+}
+
+/* Helpers for ogg_stream_encode; this keeps the structure and
+ what's happening fairly clear */
+
+static void _os_body_expand(ogg_stream_state *os,int needed){
+ if(os->body_storage<=os->body_fill+needed){
+ os->body_storage+=(needed+1024);
+ os->body_data=realloc(os->body_data,os->body_storage);
+ }
+}
+
+static void _os_lacing_expand(ogg_stream_state *os,int needed){
+ if(os->lacing_storage<=os->lacing_fill+needed){
+ os->lacing_storage+=(needed+32);
+ os->lacing_vals=realloc(os->lacing_vals,os->lacing_storage*sizeof(int));
+ os->pcm_vals=realloc(os->pcm_vals,os->lacing_storage*sizeof(ogg_int64_t));
+ }
+}
+
+/* checksum the page */
+/* Direct table CRC; note that this will be faster in the future if we
+ perform the checksum silmultaneously with other copies */
+
+static void _os_checksum(ogg_page *og){
+ ogg_uint32_t crc_reg=0;
+ int i;
+
+ for(i=0;i<og->header_len;i++)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
+ for(i=0;i<og->body_len;i++)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
+
+ og->header[22]=crc_reg&0xff;
+ og->header[23]=(crc_reg>>8)&0xff;
+ og->header[24]=(crc_reg>>16)&0xff;
+ og->header[25]=(crc_reg>>24)&0xff;
+}
+
+/* submit data to the internal buffer of the framing engine */
+int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
+ int lacing_vals=op->bytes/255+1,i;
+
+ if(os->body_returned){
+ /* advance packet data according to the body_returned pointer. We
+ had to keep it around to return a pointer into the buffer last
+ call */
+
+ os->body_fill-=os->body_returned;
+ if(os->body_fill)
+ memmove(os->body_data,os->body_data+os->body_returned,
+ os->body_fill*sizeof(char));
+ os->body_returned=0;
+ }
+
+ /* make sure we have the buffer storage */
+ _os_body_expand(os,op->bytes);
+ _os_lacing_expand(os,lacing_vals);
+
+ /* Copy in the submitted packet. Yes, the copy is a waste; this is
+ the liability of overly clean abstraction for the time being. It
+ will actually be fairly easy to eliminate the extra copy in the
+ future */
+
+ memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
+ os->body_fill+=op->bytes;
+
+ /* Store lacing vals for this packet */
+ for(i=0;i<lacing_vals-1;i++){
+ os->lacing_vals[os->lacing_fill+i]=255;
+ os->pcm_vals[os->lacing_fill+i]=os->pcmpos;
+ }
+ os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
+ os->pcmpos=os->pcm_vals[os->lacing_fill+i]=op->frameno;
+
+ /* flag the first segment as the beginning of the packet */
+ os->lacing_vals[os->lacing_fill]|= 0x100;
+
+ os->lacing_fill+=lacing_vals;
+
+ /* for the sake of completeness */
+ os->packetno++;
+
+ if(op->e_o_s)os->e_o_s=1;
+
+ return(0);
+}
+
+/* This will flush remaining packets into a page (returning nonzero),
+ even if there is not enough data to trigger a flush normally
+ (undersized page). If there are no packets or partial packets to
+ flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
+ try to flush a normal sized page like ogg_stream_pageout; a call to
+ ogg_stream_flush does not gurantee that all packets have flushed.
+ Only a return value of 0 from ogg_stream_flush indicates all packet
+ data is flushed into pages.
+
+ ogg_stream_page will flush the last page in a stream even if it's
+ undersized; you almost certainly want to use ogg_stream_pageout
+ (and *not* ogg_stream_flush) unless you need to flush an undersized
+ page in the middle of a stream for some reason. */
+
+int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
+ int i;
+ int vals=0;
+ int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
+ int bytes=0;
+ long acc=0;
+ ogg_int64_t pcm_pos=os->pcm_vals[0];
+
+ if(maxvals==0)return(0);
+
+ /* construct a page */
+ /* decide how many segments to include */
+
+ /* If this is the initial header case, the first page must only include
+ the initial header packet */
+ if(os->b_o_s==0){ /* 'initial header page' case */
+ pcm_pos=0;
+ for(vals=0;vals<maxvals;vals++){
+ if((os->lacing_vals[vals]&0x0ff)<255){
+ vals++;
+ break;
+ }
+ }
+ }else{
+ for(vals=0;vals<maxvals;vals++){
+ if(acc>4096)break;
+ acc+=os->lacing_vals[vals]&0x0ff;
+ pcm_pos=os->pcm_vals[vals];
+ }
+ }
+
+ /* construct the header in temp storage */
+ memcpy(os->header,"OggS",4);
+
+ /* stream structure version */
+ os->header[4]=0x00;
+
+ /* continued packet flag? */
+ os->header[5]=0x00;
+ if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
+ /* first page flag? */
+ if(os->b_o_s==0)os->header[5]|=0x02;
+ /* last page flag? */
+ if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
+ os->b_o_s=1;
+
+ /* 64 bits of PCM position */
+ for(i=6;i<14;i++){
+ os->header[i]=(pcm_pos&0xff);
+ pcm_pos>>=8;
+ }
+
+ /* 32 bits of stream serial number */
+ {
+ long serialno=os->serialno;
+ for(i=14;i<18;i++){
+ os->header[i]=(serialno&0xff);
+ serialno>>=8;
+ }
+ }
+
+ /* 32 bits of page counter (we have both counter and page header
+ because this val can roll over) */
+ if(os->pageno==-1)os->pageno=0; /* because someone called
+ stream_reset; this would be a
+ strange thing to do in an
+ encode stream, but it has
+ plausible uses */
+ {
+ long pageno=os->pageno++;
+ for(i=18;i<22;i++){
+ os->header[i]=(pageno&0xff);
+ pageno>>=8;
+ }
+ }
+
+ /* zero for computation; filled in later */
+ os->header[22]=0;
+ os->header[23]=0;
+ os->header[24]=0;
+ os->header[25]=0;
+
+ /* segment table */
+ os->header[26]=vals&0xff;
+ for(i=0;i<vals;i++)
+ bytes+=os->header[i+27]=(os->lacing_vals[i]&0xff);
+
+ /* set pointers in the ogg_page struct */
+ og->header=os->header;
+ og->header_len=os->header_fill=vals+27;
+ og->body=os->body_data+os->body_returned;
+ og->body_len=bytes;
+
+ /* advance the lacing data and set the body_returned pointer */
+
+ os->lacing_fill-=vals;
+ memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(int));
+ memmove(os->pcm_vals,os->pcm_vals+vals,os->lacing_fill*sizeof(ogg_int64_t));
+ os->body_returned+=bytes;
+
+ /* calculate the checksum */
+
+ _os_checksum(og);
+
+ /* done */
+ return(1);
+}
+
+
+/* This constructs pages from buffered packet segments. The pointers
+returned are to static buffers; do not free. The returned buffers are
+good only until the next call (using the same ogg_stream_state) */
+
+int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
+
+ if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
+ os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */
+ os->lacing_fill>=255 || /* 'segment table full' case */
+ (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */
+
+ return(ogg_stream_flush(os,og));
+ }
+
+ /* not enough data to construct a page and not end of stream */
+ return(0);
+}
+
+int ogg_stream_eof(ogg_stream_state *os){
+ return os->e_o_s;
+}
+
+/* DECODING PRIMITIVES: packet streaming layer **********************/
+
+/* This has two layers to place more of the multi-serialno and paging
+ control in the application's hands. First, we expose a data buffer
+ using ogg_sync_buffer(). The app either copies into the
+ buffer, or passes it directly to read(), etc. We then call
+ ogg_sync_wrote() to tell how many bytes we just added.
+
+ Pages are returned (pointers into the buffer in ogg_sync_state)
+ by ogg_sync_pageout(). The page is then submitted to
+ ogg_stream_pagein() along with the appropriate
+ ogg_stream_state* (ie, matching serialno). We then get raw
+ packets out calling ogg_stream_packetout() with a
+ ogg_stream_state. See the 'frame-prog.txt' docs for details and
+ example code. */
+
+/* initialize the struct to a known state */
+int ogg_sync_init(ogg_sync_state *oy){
+ if(oy){
+ memset(oy,0,sizeof(ogg_sync_state));
+ _ogg_crc_init();
+ }
+ return(0);
+}
+
+/* clear non-flat storage within */
+int ogg_sync_clear(ogg_sync_state *oy){
+ if(oy){
+ if(oy->data)free(oy->data);
+ ogg_sync_init(oy);
+ }
+ return(0);
+}
+
+char *ogg_sync_buffer(ogg_sync_state *oy, long size){
+
+ /* first, clear out any space that has been previously returned */
+ if(oy->returned){
+ oy->fill-=oy->returned;
+ if(oy->fill>0)
+ memmove(oy->data,oy->data+oy->returned,
+ (oy->fill)*sizeof(char));
+ oy->returned=0;
+ }
+
+ if(size>oy->storage-oy->fill){
+ /* We need to extend the internal buffer */
+ long newsize=size+oy->fill+4096; /* an extra page to be nice */
+
+ if(oy->data)
+ oy->data=realloc(oy->data,newsize);
+ else
+ oy->data=malloc(newsize);
+ oy->storage=newsize;
+ }
+
+ /* expose a segment at least as large as requested at the fill mark */
+ return((char *)oy->data+oy->fill);
+}
+
+int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
+ if(oy->fill+bytes>oy->storage)return(-1);
+ oy->fill+=bytes;
+ return(0);
+}
+
+/* sync the stream. This is meant to be useful for finding page
+ boundaries.
+
+ return values for this:
+ -n) skipped n bytes
+ 0) page not ready; more data (no bytes skipped)
+ n) page synced at current location; page length n bytes
+
+*/
+
+long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
+ unsigned char *page=oy->data+oy->returned;
+ unsigned char *next;
+ long bytes=oy->fill-oy->returned;
+
+ if(oy->headerbytes==0){
+ int headerbytes,i;
+ if(bytes<27)return(0); /* not enough for a header */
+
+ /* verify capture pattern */
+ if(memcmp(page,"OggS",4))goto sync_fail;
+
+ headerbytes=page[26]+27;
+ if(bytes<headerbytes)return(0); /* not enough for header + seg table */
+
+ /* count up body length in the segment table */
+
+ for(i=0;i<page[26];i++)
+ oy->bodybytes+=page[27+i];
+ oy->headerbytes=headerbytes;
+ }
+
+ if(oy->bodybytes+oy->headerbytes>bytes)return(0);
+
+ /* The whole test page is buffered. Verify the checksum */
+ {
+ /* Grab the checksum bytes, set the header field to zero */
+ char chksum[4];
+ ogg_page log;
+
+ memcpy(chksum,page+22,4);
+ memset(page+22,0,4);
+
+ /* set up a temp page struct and recompute the checksum */
+ log.header=page;
+ log.header_len=oy->headerbytes;
+ log.body=page+oy->headerbytes;
+ log.body_len=oy->bodybytes;
+ _os_checksum(&log);
+
+ /* Compare */
+ if(memcmp(chksum,page+22,4)){
+ /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
+ at all) */
+ /* replace the computed checksum with the one actually read in */
+ memcpy(page+22,chksum,4);
+
+ /* Bad checksum. Lose sync */
+ goto sync_fail;
+ }
+ }
+
+ /* yes, have a whole page all ready to go */
+ {
+ unsigned char *page=oy->data+oy->returned;
+ long bytes;
+
+ if(og){
+ og->header=page;
+ og->header_len=oy->headerbytes;
+ og->body=page+oy->headerbytes;
+ og->body_len=oy->bodybytes;
+ }
+
+ oy->unsynced=0;
+ oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ return(bytes);
+ }
+
+ sync_fail:
+
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+
+ /* search for possible capture */
+ next=memchr(page+1,'O',bytes-1);
+ if(!next)
+ next=oy->data+oy->fill;
+
+ oy->returned=next-oy->data;
+ return(-(next-page));
+}
+
+/* sync the stream and get a page. Keep trying until we find a page.
+ Supress 'sync errors' after reporting the first.
+
+ return values:
+ -1) recapture (hole in data)
+ 0) need more data
+ 1) page returned
+
+ Returns pointers into buffered data; invalidated by next call to
+ _stream, _clear, _init, or _buffer */
+
+int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
+
+ /* all we need to do is verify a page at the head of the stream
+ buffer. If it doesn't verify, we look for the next potential
+ frame */
+
+ while(1){
+ long ret=ogg_sync_pageseek(oy,og);
+ if(ret>0){
+ /* have a page */
+ return(1);
+ }
+ if(ret==0){
+ /* need more data */
+ return(0);
+ }
+
+ /* head did not start a synced page... skipped some bytes */
+ if(!oy->unsynced){
+ oy->unsynced=1;
+ return(-1);
+ }
+
+ /* loop. keep looking */
+
+ }
+}
+
+/* add the incoming page to the stream state; we decompose the page
+ into packet segments here as well. */
+
+int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
+ unsigned char *header=og->header;
+ unsigned char *body=og->body;
+ long bodysize=og->body_len;
+ int segptr=0;
+
+ int version=ogg_page_version(og);
+ int continued=ogg_page_continued(og);
+ int bos=ogg_page_bos(og);
+ int eos=ogg_page_eos(og);
+ ogg_int64_t pcmpos=ogg_page_frameno(og);
+ int serialno=ogg_page_serialno(og);
+ int pageno=ogg_page_pageno(og);
+ int segments=header[26];
+
+ /* clean up 'returned data' */
+ {
+ long lr=os->lacing_returned;
+ long br=os->body_returned;
+
+ /* body data */
+ if(br){
+ os->body_fill-=br;
+ if(os->body_fill)
+ memmove(os->body_data,os->body_data+br,os->body_fill);
+ os->body_returned=0;
+ }
+
+ if(lr){
+ /* segment table */
+ if(os->lacing_fill-lr){
+ memmove(os->lacing_vals,os->lacing_vals+lr,
+ (os->lacing_fill-lr)*sizeof(int));
+ memmove(os->pcm_vals,os->pcm_vals+lr,
+ (os->lacing_fill-lr)*sizeof(ogg_int64_t));
+ }
+ os->lacing_fill-=lr;
+ os->lacing_packet-=lr;
+ os->lacing_returned=0;
+ }
+ }
+
+ /* check the serial number */
+ if(serialno!=os->serialno)return(-1);
+ if(version>0)return(-1);
+
+ _os_lacing_expand(os,segments+1);
+
+ /* are we in sequence? */
+ if(pageno!=os->pageno){
+ int i;
+
+ /* unroll previous partial packet (if any) */
+ for(i=os->lacing_packet;i<os->lacing_fill;i++)
+ os->body_fill-=os->lacing_vals[i]&0xff;
+ os->lacing_fill=os->lacing_packet;
+
+ /* make a note of dropped data in segment table */
+ if(os->pageno!=-1){
+ os->lacing_vals[os->lacing_fill++]=0x400;
+ os->lacing_packet++;
+ }
+
+ /* are we a 'continued packet' page? If so, we'll need to skip
+ some segments */
+ if(continued){
+ bos=0;
+ for(;segptr<segments;segptr++){
+ int val=header[27+segptr];
+ body+=val;
+ bodysize-=val;
+ if(val<255){
+ segptr++;
+ break;
+ }
+ }
+ }
+ }
+
+ if(bodysize){
+ _os_body_expand(os,bodysize);
+ memcpy(os->body_data+os->body_fill,body,bodysize);
+ os->body_fill+=bodysize;
+ }
+
+ {
+ int saved=-1;
+ while(segptr<segments){
+ int val=header[27+segptr];
+ os->lacing_vals[os->lacing_fill]=val;
+ os->pcm_vals[os->lacing_fill]=-1;
+
+ if(bos){
+ os->lacing_vals[os->lacing_fill]|=0x100;
+ bos=0;
+ }
+
+ if(val<255)saved=os->lacing_fill;
+
+ os->lacing_fill++;
+ segptr++;
+
+ if(val<255)os->lacing_packet=os->lacing_fill;
+ }
+
+ /* set the pcmpos on the last pcmval of the last full packet */
+ if(saved!=-1){
+ os->pcm_vals[saved]=pcmpos;
+ }
+
+ }
+
+ if(eos){
+ os->e_o_s=1;
+ if(os->lacing_fill>0)
+ os->lacing_vals[os->lacing_fill-1]|=0x200;
+ }
+
+ os->pageno=pageno+1;
+
+ return(0);
+}
+
+/* clear things to an initial state. Good to call, eg, before seeking */
+int ogg_sync_reset(ogg_sync_state *oy){
+ oy->fill=0;
+ oy->returned=0;
+ oy->unsynced=0;
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ return(0);
+}
+
+int ogg_stream_reset(ogg_stream_state *os){
+ os->body_fill=0;
+ os->body_returned=0;
+
+ os->lacing_fill=0;
+ os->lacing_packet=0;
+ os->lacing_returned=0;
+
+ os->header_fill=0;
+
+ os->e_o_s=0;
+ os->b_o_s=0;
+ os->pageno=-1;
+ os->packetno=0;
+ os->pcmpos=0;
+
+ return(0);
+}
+
+int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
+
+ /* The last part of decode. We have the stream broken into packet
+ segments. Now we need to group them into packets (or return the
+ out of sync markers) */
+
+ int ptr=os->lacing_returned;
+
+ if(os->lacing_packet<=ptr)return(0);
+
+ if(os->lacing_vals[ptr]&0x400){
+ /* We lost sync here; let the app know */
+ os->lacing_returned++;
+
+ /* we need to tell the codec there's a gap; it might need to
+ handle previous packet dependencies. */
+ os->packetno++;
+ return(-1);
+ }
+
+ /* Gather the whole packet. We'll have no holes or a partial packet */
+ {
+ int size=os->lacing_vals[ptr]&0xff;
+ int bytes=0;
+
+ op->packet=os->body_data+os->body_returned;
+ op->e_o_s=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
+ op->b_o_s=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
+ bytes+=size;
+
+ while(size==255){
+ int val=os->lacing_vals[++ptr];
+ size=val&0xff;
+ if(val&0x200)op->e_o_s=0x200;
+ bytes+=size;
+ }
+
+ op->packetno=os->packetno;
+ op->frameno=os->pcm_vals[ptr];
+ op->bytes=bytes;
+
+ os->body_returned+=bytes;
+ os->lacing_returned=ptr+1;
+ }
+ os->packetno++;
+ return(1);
+}
+
+#ifdef _V_SELFTEST
+#include <stdio.h>
+
+ogg_stream_state os_en, os_de;
+ogg_sync_state oy;
+
+void checkpacket(ogg_packet *op,int len, int no, int pos){
+ long j;
+ static int sequence=0;
+ static int lastno=0;
+
+ if(op->bytes!=len){
+ fprintf(stderr,"incorrect packet length!\n");
+ exit(1);
+ }
+ if(op->frameno!=pos){
+ fprintf(stderr,"incorrect packet position!\n");
+ exit(1);
+ }
+
+ /* packet number just follows sequence/gap; adjust the input number
+ for that */
+ if(no==0){
+ sequence=0;
+ }else{
+ sequence++;
+ if(no>lastno+1)
+ sequence++;
+ }
+ lastno=no;
+ if(op->packetno!=sequence){
+ fprintf(stderr,"incorrect packet sequence %ld != %d\n",
+ (long)(op->packetno),sequence);
+ exit(1);
+ }
+
+ /* Test data */
+ for(j=0;j<op->bytes;j++)
+ if(op->packet[j]!=((j+no)&0xff)){
+ fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
+ j,op->packet[j],(j+no)&0xff);
+ exit(1);
+ }
+}
+
+void check_page(unsigned char *data,const int *header,ogg_page *og){
+ long j;
+ /* Test data */
+ for(j=0;j<og->body_len;j++)
+ if(og->body[j]!=data[j]){
+ fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
+ j,data[j],og->body[j]);
+ exit(1);
+ }
+
+ /* Test header */
+ for(j=0;j<og->header_len;j++){
+ if(og->header[j]!=header[j]){
+ fprintf(stderr,"header content mismatch at pos %ld:\n",j);
+ for(j=0;j<header[26]+27;j++)
+ fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
+ fprintf(stderr,"\n");
+ exit(1);
+ }
+ }
+ if(og->header_len!=header[26]+27){
+ fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
+ og->header_len,header[26]+27);
+ exit(1);
+ }
+}
+
+void print_header(ogg_page *og){
+ int j;
+ fprintf(stderr,"\nHEADER:\n");
+ fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
+ og->header[0],og->header[1],og->header[2],og->header[3],
+ (int)og->header[4],(int)og->header[5]);
+
+ fprintf(stderr," pcmpos: %d serialno: %d pageno: %d\n",
+ (og->header[9]<<24)|(og->header[8]<<16)|
+ (og->header[7]<<8)|og->header[6],
+ (og->header[17]<<24)|(og->header[16]<<16)|
+ (og->header[15]<<8)|og->header[14],
+ (og->header[21]<<24)|(og->header[20]<<16)|
+ (og->header[19]<<8)|og->header[18]);
+
+ fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
+ (int)og->header[22],(int)og->header[23],
+ (int)og->header[24],(int)og->header[25],
+ (int)og->header[26]);
+
+ for(j=27;j<og->header_len;j++)
+ fprintf(stderr,"%d ",(int)og->header[j]);
+ fprintf(stderr,")\n\n");
+}
+
+void copy_page(ogg_page *og){
+ unsigned char *temp=malloc(og->header_len);
+ memcpy(temp,og->header,og->header_len);
+ og->header=temp;
+
+ temp=malloc(og->body_len);
+ memcpy(temp,og->body,og->body_len);
+ og->body=temp;
+}
+
+void error(void){
+ fprintf(stderr,"error!\n");
+ exit(1);
+}
+
+/* 17 only */
+const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x15,0xed,0xec,0x91,
+ 1,
+ 17};
+
+/* 17, 254, 255, 256, 500, 510, 600 byte, pad */
+const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x59,0x10,0x6c,0x2c,
+ 1,
+ 17};
+const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
+ 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x89,0x33,0x85,0xce,
+ 13,
+ 254,255,0,255,1,255,245,255,255,0,
+ 255,255,90};
+
+/* nil packets; beginning,middle,end */
+const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
+ 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x5c,0x3f,0x66,0xcb,
+ 17,
+ 17,254,255,0,0,255,1,0,255,245,255,255,0,
+ 255,255,90,0};
+
+/* large initial packet */
+const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x01,0x27,0x31,0xaa,
+ 18,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,10};
+
+const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
+ 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x7f,0x4e,0x8a,0xd2,
+ 4,
+ 255,4,255,0};
+
+
+/* continuing packet test */
+const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+
+const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
+ 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x34,0x24,0xd5,0x29,
+ 17,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255};
+
+const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
+ 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0xc8,0xc3,0xcb,0xed,
+ 5,
+ 10,255,4,255,0};
+
+
+/* page with the 255 segment limit */
+const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+
+const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
+ 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0xed,0x2a,0x2e,0xa7,
+ 255,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10};
+
+const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
+ 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0x6c,0x3b,0x82,0x3d,
+ 1,
+ 50};
+
+
+/* packet that overspans over an entire page */
+const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+
+const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
+ 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x3c,0xd9,0x4d,0x3f,
+ 17,
+ 100,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255};
+
+const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
+ 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0xbd,0xd5,0xb5,0x8b,
+ 17,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255};
+
+const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
+ 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,3,0,0,0,
+ 0xef,0xdd,0x88,0xde,
+ 7,
+ 255,255,75,255,4,255,0};
+
+/* packet that overspans over an entire page */
+const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+
+const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
+ 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x3c,0xd9,0x4d,0x3f,
+ 17,
+ 100,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255};
+
+const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
+ 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0xd4,0xe0,0x60,0xe5,
+ 1,0};
+
+void test_pack(const int *pl, const int **headers){
+ unsigned char *data=malloc(1024*1024); /* for scripted test cases only */
+ long inptr=0;
+ long outptr=0;
+ long deptr=0;
+ long depacket=0;
+ long pcm_pos=7;
+ int i,j,packets,pageno=0,pageout=0;
+ int eosflag=0;
+ int bosflag=0;
+
+ ogg_stream_reset(&os_en);
+ ogg_stream_reset(&os_de);
+ ogg_sync_reset(&oy);
+
+ for(packets=0;;packets++)if(pl[packets]==-1)break;
+
+ for(i=0;i<packets;i++){
+ /* construct a test packet */
+ ogg_packet op;
+ int len=pl[i];
+
+ op.packet=data+inptr;
+ op.bytes=len;
+ op.e_o_s=(pl[i+1]<0?1:0);
+ op.frameno=pcm_pos;
+
+ pcm_pos+=1024;
+
+ for(j=0;j<len;j++)data[inptr++]=i+j;
+
+ /* submit the test packet */
+ ogg_stream_packetin(&os_en,&op);
+
+ /* retrieve any finished pages */
+ {
+ ogg_page og;
+
+ while(ogg_stream_pageout(&os_en,&og)){
+ /* We have a page. Check it carefully */
+
+ fprintf(stderr,"%d, ",pageno);
+
+ if(headers[pageno]==NULL){
+ fprintf(stderr,"coded too many pages!\n");
+ exit(1);
+ }
+
+ check_page(data+outptr,headers[pageno],&og);
+
+ outptr+=og.body_len;
+ pageno++;
+
+ /* have a complete page; submit it to sync/decode */
+
+ {
+ ogg_page og_de;
+ ogg_packet op_de;
+ char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
+ memcpy(buf,og.header,og.header_len);
+ memcpy(buf+og.header_len,og.body,og.body_len);
+ ogg_sync_wrote(&oy,og.header_len+og.body_len);
+
+ while(ogg_sync_pageout(&oy,&og_de)>0){
+ /* got a page. Happy happy. Verify that it's good. */
+
+ check_page(data+deptr,headers[pageout],&og_de);
+ deptr+=og_de.body_len;
+ pageout++;
+
+ /* submit it to deconstitution */
+ ogg_stream_pagein(&os_de,&og_de);
+
+ /* packets out? */
+ while(ogg_stream_packetout(&os_de,&op_de)>0){
+
+ /* verify the packet! */
+ /* check data */
+ if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
+ fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
+ depacket);
+ exit(1);
+ }
+ /* check bos flag */
+ if(bosflag==0 && op_de.b_o_s==0){
+ fprintf(stderr,"b_o_s flag not set on packet!\n");
+ exit(1);
+ }
+ if(bosflag && op_de.b_o_s){
+ fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
+ exit(1);
+ }
+ bosflag=1;
+ depacket+=op_de.bytes;
+
+ /* check eos flag */
+ if(eosflag){
+ fprintf(stderr,"Multiple decoded packets with eos flag!\n");
+ exit(1);
+ }
+
+ if(op_de.e_o_s)eosflag=1;
+
+ /* check pcmpos flag */
+ if(op_de.frameno!=-1){
+ fprintf(stderr," pcm:%ld ",(long)op_de.frameno);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ free(data);
+ if(headers[pageno]!=NULL){
+ fprintf(stderr,"did not write last page!\n");
+ exit(1);
+ }
+ if(headers[pageout]!=NULL){
+ fprintf(stderr,"did not decode last page!\n");
+ exit(1);
+ }
+ if(inptr!=outptr){
+ fprintf(stderr,"encoded page data incomplete!\n");
+ exit(1);
+ }
+ if(inptr!=deptr){
+ fprintf(stderr,"decoded page data incomplete!\n");
+ exit(1);
+ }
+ if(inptr!=depacket){
+ fprintf(stderr,"decoded packet data incomplete!\n");
+ exit(1);
+ }
+ if(!eosflag){
+ fprintf(stderr,"Never got a packet with EOS set!\n");
+ exit(1);
+ }
+ fprintf(stderr,"ok.\n");
+}
+
+int main(void){
+
+ ogg_stream_init(&os_en,0x04030201);
+ ogg_stream_init(&os_de,0x04030201);
+ ogg_sync_init(&oy);
+
+ /* Exercise each code path in the framing code. Also verify that
+ the checksums are working. */
+
+ {
+ /* 17 only */
+ const int packets[]={17, -1};
+ const int *headret[]={head1_0,NULL};
+
+ fprintf(stderr,"testing single page encoding... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
+ const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
+ const int *headret[]={head1_1,head2_1,NULL};
+
+ fprintf(stderr,"testing basic page encoding... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* nil packets; beginning,middle,end */
+ const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
+ const int *headret[]={head1_2,head2_2,NULL};
+
+ fprintf(stderr,"testing basic nil packets... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* large initial packet */
+ const int packets[]={4345,259,255,-1};
+ const int *headret[]={head1_3,head2_3,NULL};
+
+ fprintf(stderr,"testing initial-packet lacing > 4k... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* continuing packet test */
+ const int packets[]={0,4345,259,255,-1};
+ const int *headret[]={head1_4,head2_4,head3_4,NULL};
+
+ fprintf(stderr,"testing single packet page span... ");
+ test_pack(packets,headret);
+ }
+
+ /* page with the 255 segment limit */
+ {
+
+ const int packets[]={0,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,50,-1};
+ const int *headret[]={head1_5,head2_5,head3_5,NULL};
+
+ fprintf(stderr,"testing max packet segments... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* packet that overspans over an entire page */
+ const int packets[]={0,100,9000,259,255,-1};
+ const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
+
+ fprintf(stderr,"testing very large packets... ");
+ test_pack(packets,headret);
+ }
+
+ {
+ /* term only page. why not? */
+ const int packets[]={0,100,4080,-1};
+ const int *headret[]={head1_7,head2_7,head3_7,NULL};
+
+ fprintf(stderr,"testing zero data page (1 nil packet)... ");
+ test_pack(packets,headret);
+ }
+
+
+
+ {
+ /* build a bunch of pages for testing */
+ unsigned char *data=malloc(1024*1024);
+ int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
+ int inptr=0,i,j;
+ ogg_page og[5];
+
+ ogg_stream_reset(&os_en);
+
+ for(i=0;pl[i]!=-1;i++){
+ ogg_packet op;
+ int len=pl[i];
+
+ op.packet=data+inptr;
+ op.bytes=len;
+ op.e_o_s=(pl[i+1]<0?1:0);
+ op.frameno=(i+1)*1000;
+
+ for(j=0;j<len;j++)data[inptr++]=i+j;
+ ogg_stream_packetin(&os_en,&op);
+ }
+
+ free(data);
+
+ /* retrieve finished pages */
+ for(i=0;i<5;i++){
+ if(ogg_stream_pageout(&os_en,&og[i])==0){
+ fprintf(stderr,"Too few pages output building sync tests!\n");
+ exit(1);
+ }
+ copy_page(&og[i]);
+ }
+
+ /* Test lost pages on pagein/packetout: no rollback */
+ {
+ ogg_page temp;
+ ogg_packet test;
+
+ fprintf(stderr,"Testing loss of pages... ");
+
+ ogg_sync_reset(&oy);
+ ogg_stream_reset(&os_de);
+ for(i=0;i<5;i++){
+ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
+ og[i].header_len);
+ ogg_sync_wrote(&oy,og[i].header_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
+ ogg_sync_wrote(&oy,og[i].body_len);
+ }
+
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+ ogg_sync_pageout(&oy,&temp);
+ /* skip */
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+
+ /* do we get the expected results/packets? */
+
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,0,0,0);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,100,1,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,4079,2,3000);
+ if(ogg_stream_packetout(&os_de,&test)!=-1){
+ fprintf(stderr,"Error: loss of page did not return error\n");
+ exit(1);
+ }
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,76,5,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,34,6,-1);
+ fprintf(stderr,"ok.\n");
+ }
+
+ /* Test lost pages on pagein/packetout: rollback with continuation */
+ {
+ ogg_page temp;
+ ogg_packet test;
+
+ fprintf(stderr,"Testing loss of pages (rollback required)... ");
+
+ ogg_sync_reset(&oy);
+ ogg_stream_reset(&os_de);
+ for(i=0;i<5;i++){
+ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
+ og[i].header_len);
+ ogg_sync_wrote(&oy,og[i].header_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
+ ogg_sync_wrote(&oy,og[i].body_len);
+ }
+
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+ ogg_sync_pageout(&oy,&temp);
+ /* skip */
+ ogg_sync_pageout(&oy,&temp);
+ ogg_stream_pagein(&os_de,&temp);
+
+ /* do we get the expected results/packets? */
+
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,0,0,0);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,100,1,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,4079,2,3000);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,2956,3,4000);
+ if(ogg_stream_packetout(&os_de,&test)!=-1){
+ fprintf(stderr,"Error: loss of page did not return error\n");
+ exit(1);
+ }
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,300,13,14000);
+ fprintf(stderr,"ok.\n");
+ }
+
+ /* the rest only test sync */
+ {
+ ogg_page og_de;
+ /* Test fractional page inputs: incomplete capture */
+ fprintf(stderr,"Testing sync on partial inputs... ");
+ ogg_sync_reset(&oy);
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+ 3);
+ ogg_sync_wrote(&oy,3);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ /* Test fractional page inputs: incomplete fixed header */
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
+ 20);
+ ogg_sync_wrote(&oy,20);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ /* Test fractional page inputs: incomplete header */
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
+ 5);
+ ogg_sync_wrote(&oy,5);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ /* Test fractional page inputs: incomplete body */
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
+ og[1].header_len-28);
+ ogg_sync_wrote(&oy,og[1].header_len-28);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
+ ogg_sync_wrote(&oy,1000);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
+ og[1].body_len-1000);
+ ogg_sync_wrote(&oy,og[1].body_len-1000);
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
+ fprintf(stderr,"ok.\n");
+ }
+
+ /* Test fractional page inputs: page + incomplete capture */
+ {
+ ogg_page og_de;
+ fprintf(stderr,"Testing sync on 1+partial inputs... ");
+ ogg_sync_reset(&oy);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+ og[1].header_len);
+ ogg_sync_wrote(&oy,og[1].header_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+ og[1].body_len);
+ ogg_sync_wrote(&oy,og[1].body_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+ 20);
+ ogg_sync_wrote(&oy,20);
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
+ og[1].header_len-20);
+ ogg_sync_wrote(&oy,og[1].header_len-20);
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+ og[1].body_len);
+ ogg_sync_wrote(&oy,og[1].body_len);
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
+ fprintf(stderr,"ok.\n");
+ }
+
+ /* Test recapture: garbage + page */
+ {
+ ogg_page og_de;
+ fprintf(stderr,"Testing search for capture... ");
+ ogg_sync_reset(&oy);
+
+ /* 'garbage' */
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+ og[1].body_len);
+ ogg_sync_wrote(&oy,og[1].body_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+ og[1].header_len);
+ ogg_sync_wrote(&oy,og[1].header_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+ og[1].body_len);
+ ogg_sync_wrote(&oy,og[1].body_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
+ 20);
+ ogg_sync_wrote(&oy,20);
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+
+ memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
+ og[2].header_len-20);
+ ogg_sync_wrote(&oy,og[2].header_len-20);
+ memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
+ og[2].body_len);
+ ogg_sync_wrote(&oy,og[2].body_len);
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
+ fprintf(stderr,"ok.\n");
+ }
+
+ /* Test recapture: page + garbage + page */
+ {
+ ogg_page og_de;
+ fprintf(stderr,"Testing recapture... ");
+ ogg_sync_reset(&oy);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+ og[1].header_len);
+ ogg_sync_wrote(&oy,og[1].header_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+ og[1].body_len);
+ ogg_sync_wrote(&oy,og[1].body_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
+ og[2].header_len);
+ ogg_sync_wrote(&oy,og[2].header_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
+ og[2].header_len);
+ ogg_sync_wrote(&oy,og[2].header_len);
+
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
+ memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
+ og[2].body_len-5);
+ ogg_sync_wrote(&oy,og[2].body_len-5);
+
+ memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
+ og[3].header_len);
+ ogg_sync_wrote(&oy,og[3].header_len);
+
+ memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
+ og[3].body_len);
+ ogg_sync_wrote(&oy,og[3].body_len);
+
+ if(ogg_sync_pageout(&oy,&og_de)>0)error();
+ if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
+ fprintf(stderr,"ok.\n");
+ }
+ }
+
+ return(0);
+}
+
+#endif
+
+
+
+
diff --git a/lib/psy.c b/lib/psy.c
new file mode 100644
index 00000000..ce2e2555
--- /dev/null
+++ b/lib/psy.c
@@ -0,0 +1,702 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: psychoacoustics not including preecho
+ last mod: $Id: psy.c,v 1.26.2.1 2000/08/31 08:05:48 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "vorbis/codec.h"
+
+#include "masking.h"
+#include "psy.h"
+#include "os.h"
+#include "lpc.h"
+#include "smallft.h"
+#include "scales.h"
+#include "misc.h"
+
+/* Why Bark scale for encoding but not masking computation? Because
+ masking has a strong harmonic dependancy */
+
+/* the beginnings of real psychoacoustic infrastructure. This is
+ still not tightly tuned */
+void _vi_psy_free(vorbis_info_psy *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_psy));
+ free(i);
+ }
+}
+
+/* Set up decibel threshhold slopes on a Bark frequency scale */
+/* ATH is the only bit left on a Bark scale. No reason to change it
+ right now */
+static void set_curve(double *ref,double *c,int n, double crate){
+ int i,j=0;
+
+ for(i=0;i<MAX_BARK-1;i++){
+ int endpos=rint(fromBARK(i+1)*2*n/crate);
+ double base=ref[i];
+ if(j<endpos){
+ double delta=(ref[i+1]-base)/(endpos-j);
+ for(;j<endpos && j<n;j++){
+ c[j]=base;
+ base+=delta;
+ }
+ }
+ }
+}
+
+static void min_curve(double *c,
+ double *c2){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
+}
+static void max_curve(double *c,
+ double *c2){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
+}
+
+static void attenuate_curve(double *c,double att){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)
+ c[i]+=att;
+}
+
+static void linear_curve(double *c){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)
+ if(c[i]<=-200.)
+ c[i]=0.;
+ else
+ c[i]=fromdB(c[i]);
+}
+
+static void interp_curve(double *c,double *c1,double *c2,double del){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)
+ c[i]=c2[i]*del+c1[i]*(1.-del);
+}
+
+static void setup_curve(double **c,
+ int band,
+ double *curveatt_dB){
+ int i,j;
+ double ath[EHMER_MAX];
+ double tempc[P_LEVELS][EHMER_MAX];
+
+ memcpy(c[0],c[4],sizeof(double)*EHMER_MAX);
+ memcpy(c[2],c[4],sizeof(double)*EHMER_MAX);
+
+ /* we add back in the ATH to avoid low level curves falling off to
+ -infinity and unneccessarily cutting off high level curves in the
+ curve limiting (last step). But again, remember... a half-band's
+ settings must be valid over the whole band, and it's better to
+ mask too little than too much, so be pessimal. */
+
+ for(i=0;i<EHMER_MAX;i++){
+ double oc_min=band*.5-1+(i-EHMER_OFFSET)*.125;
+ double oc_max=band*.5-1+(i-EHMER_OFFSET+1)*.125;
+ double bark=toBARK(fromOC(oc_min));
+ int ibark=floor(bark);
+ double del=bark-ibark;
+ double ath_min,ath_max;
+
+ if(ibark<26)
+ ath_min=ATH_Bark_dB[ibark]*(1.-del)+ATH_Bark_dB[ibark+1]*del;
+ else
+ ath_min=200.;
+
+ bark=toBARK(fromOC(oc_max));
+ ibark=floor(bark);
+ del=bark-ibark;
+
+ if(ibark<26)
+ ath_max=ATH_Bark_dB[ibark]*(1.-del)+ATH_Bark_dB[ibark+1]*del;
+ else
+ ath_max=200.;
+
+ ath[i]=min(ath_min,ath_max);
+ }
+
+ /* The c array is comes in as dB curves at 20 40 60 80 100 dB.
+ interpolate intermediate dB curves */
+ for(i=1;i<P_LEVELS;i+=2){
+ interp_curve(c[i],c[i-1],c[i+1],.5);
+ }
+
+ /* normalize curves so the driving amplitude is 0dB */
+ /* make temp curves with the ATH overlayed */
+ for(i=0;i<P_LEVELS;i++){
+ attenuate_curve(c[i],curveatt_dB[i]);
+ memcpy(tempc[i],ath,EHMER_MAX*sizeof(double));
+ attenuate_curve(tempc[i],-i*10.);
+ max_curve(tempc[i],c[i]);
+ }
+
+ /* Now limit the louder curves.
+
+ the idea is this: We don't know what the playback attenuation
+ will be; 0dB SL moves every time the user twiddles the volume
+ knob. So that means we have to use a single 'most pessimal' curve
+ for all masking amplitudes, right? Wrong. The *loudest* sound
+ can be in (we assume) a range of ...+100dB] SL. However, sounds
+ 20dB down will be in a range ...+80], 40dB down is from ...+60],
+ etc... */
+
+ for(i=P_LEVELS-1;i>0;i--){
+ for(j=0;j<i;j++)
+ min_curve(c[i],tempc[j]);
+ }
+
+ /* take things out of dB domain into linear amplitude */
+ for(i=0;i<P_LEVELS;i++)
+ linear_curve(c[i]);
+
+}
+
+void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
+ long i,j;
+ memset(p,0,sizeof(vorbis_look_psy));
+ p->ath=malloc(n*sizeof(double));
+ p->octave=malloc(n*sizeof(int));
+ p->bark=malloc(n*sizeof(double));
+ p->vi=vi;
+ p->n=n;
+
+ /* set up the lookups for a given blocksize and sample rate */
+ /* Vorbis max sample rate is limited by 26 Bark (54kHz) */
+ set_curve(ATH_Bark_dB, p->ath,n,rate);
+ for(i=0;i<n;i++)
+ p->ath[i]=fromdB(p->ath[i]);
+ for(i=0;i<n;i++)
+ p->bark[i]=toBARK(rate/(2*n)*i);
+
+ for(i=0;i<n;i++){
+ int oc=toOC((i+.5)*rate/(2*n))*2.+2; /* half octaves, actually */
+ if(oc<0)oc=0;
+ if(oc>=P_BANDS)oc=P_BANDS-1;
+ p->octave[i]=oc;
+ }
+
+ p->tonecurves=malloc(P_BANDS*sizeof(double **));
+ p->noiseatt=malloc(P_BANDS*sizeof(double **));
+ p->peakatt=malloc(P_BANDS*sizeof(double *));
+ for(i=0;i<P_BANDS;i++){
+ p->tonecurves[i]=malloc(P_LEVELS*sizeof(double *));
+ p->noiseatt[i]=malloc(P_LEVELS*sizeof(double));
+ p->peakatt[i]=malloc(P_LEVELS*sizeof(double));
+ }
+
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++){
+ p->tonecurves[i][j]=malloc(EHMER_MAX*sizeof(double));
+ }
+
+ /* OK, yeah, this was a silly way to do it */
+ memcpy(p->tonecurves[0][4],tone_125_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[0][6],tone_125_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[0][8],tone_125_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[0][10],tone_125_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[2][4],tone_125_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[2][6],tone_125_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[2][8],tone_125_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[2][10],tone_125_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[4][4],tone_250_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[4][6],tone_250_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[4][8],tone_250_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[4][10],tone_250_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[6][4],tone_500_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[6][6],tone_500_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[6][8],tone_500_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[6][10],tone_500_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[8][4],tone_1000_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[8][6],tone_1000_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[8][8],tone_1000_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[8][10],tone_1000_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[10][4],tone_2000_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[10][6],tone_2000_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[10][8],tone_2000_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[10][10],tone_2000_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[12][4],tone_4000_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[12][6],tone_4000_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[12][8],tone_4000_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[12][10],tone_4000_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[14][4],tone_8000_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[14][6],tone_8000_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[14][8],tone_8000_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[14][10],tone_8000_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ memcpy(p->tonecurves[16][4],tone_8000_40dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[16][6],tone_8000_60dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[16][8],tone_8000_80dB_SL,sizeof(double)*EHMER_MAX);
+ memcpy(p->tonecurves[16][10],tone_8000_100dB_SL,sizeof(double)*EHMER_MAX);
+
+ /* interpolate curves between */
+ for(i=1;i<P_BANDS;i+=2)
+ for(j=4;j<P_LEVELS;j+=2){
+ memcpy(p->tonecurves[i][j],p->tonecurves[i-1][j],EHMER_MAX*sizeof(double));
+ /*interp_curve(p->tonecurves[i][j],
+ p->tonecurves[i-1][j],
+ p->tonecurves[i+1][j],.5);*/
+ min_curve(p->tonecurves[i][j],p->tonecurves[i+1][j]);
+ /*min_curve(p->tonecurves[i][j],p->tonecurves[i-1][j]);*/
+ }
+
+ /*for(i=0;i<P_BANDS-1;i++)
+ for(j=4;j<P_LEVELS;j+=2)
+ min_curve(p->tonecurves[i][j],p->tonecurves[i+1][j]);*/
+
+ /* set up the final curves */
+ for(i=0;i<P_BANDS;i++)
+ setup_curve(p->tonecurves[i],i,vi->toneatt[i]);
+
+ /* set up attenuation levels */
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++){
+ p->peakatt[i][j]=fromdB(p->vi->peakatt[i][j]);
+ p->noiseatt[i][j]=fromdB(p->vi->noiseatt[i][j]);
+ }
+
+}
+
+void _vp_psy_clear(vorbis_look_psy *p){
+ int i,j;
+ if(p){
+ if(p->ath)free(p->ath);
+ if(p->octave)free(p->octave);
+ if(p->tonecurves){
+ for(i=0;i<P_BANDS;i++){
+ for(j=0;j<P_LEVELS;j++){
+ free(p->tonecurves[i][j]);
+ }
+ free(p->noiseatt[i]);
+ free(p->tonecurves[i]);
+ free(p->peakatt[i]);
+ }
+ free(p->tonecurves);
+ free(p->noiseatt);
+ free(p->peakatt);
+ }
+ memset(p,0,sizeof(vorbis_look_psy));
+ }
+}
+
+static void compute_decay_fixed(vorbis_look_psy *p,double *f, double *decay, int n){
+ /* handle decay */
+ int i;
+ double decscale=fromdB(p->vi->decay_coeff*n);
+ double attscale=1./fromdB(p->vi->attack_coeff);
+
+ for(i=10;i<n;i++){
+ double pre=decay[i];
+ if(decay[i]){
+ double val=decay[i]*decscale;
+ double att=fabs(f[i]/val);
+
+ if(att>attscale)
+ decay[i]=fabs(f[i]/attscale);
+ else
+ decay[i]=val;
+ }else{
+ decay[i]=fabs(f[i]/attscale);
+ }
+ if(pre>f[i])f[i]=pre;
+ }
+}
+
+static long _eights[EHMER_MAX+1]={
+ 981,1069,1166,1272,
+ 1387,1512,1649,1798,
+ 1961,2139,2332,2543,
+ 2774,3025,3298,3597,
+ 3922,4277,4664,5087,
+ 5547,6049,6597,7194,
+ 7845,8555,9329,10173,
+ 11094,12098,13193,14387,
+ 15689,17109,18658,20347,
+ 22188,24196,26386,28774,
+ 31379,34219,37316,40693,
+ 44376,48393,52772,57549,
+ 62757,68437,74631,81386,
+ 88752,96785,105545,115097,
+ 125515};
+
+static int seed_curve(double *flr,
+ double **curves,
+ double amp,double specmax,
+ int x,int n,double specatt,
+ int maxEH){
+ int i;
+ double *curve;
+
+ /* make this attenuation adjustable */
+ int choice=(int)((todB(amp)-specmax+specatt)/10.+.5);
+ choice=max(choice,0);
+ choice=min(choice,P_LEVELS-1);
+
+ for(i=maxEH;i>=0;i--)
+ if(((x*_eights[i])>>12)<n)break;
+ maxEH=i;
+ curve=curves[choice];
+
+ for(;i>=0;i--)
+ if(curve[i]>0.)break;
+
+ for(;i>=0;i--){
+ double lin=curve[i];
+ if(lin>0.){
+ double *fp=flr+((x*_eights[i])>>12);
+ lin*=amp;
+ if(*fp<lin)*fp=lin;
+ }else break;
+ }
+ return(maxEH);
+}
+
+static void seed_peak(double *flr,
+ double *att,
+ double amp,double specmax,
+ int x,int n,double specatt){
+ int prevx=(x*_eights[16])>>12;
+
+ /* make this attenuation adjustable */
+ int choice=rint((todB(amp)-specmax+specatt)/10.+.5);
+ if(choice<0)choice=0;
+ if(choice>=P_LEVELS)choice=P_LEVELS-1;
+
+ if(prevx<n){
+ double lin=att[choice];
+ if(lin){
+ lin*=amp;
+ if(flr[prevx]<lin)flr[prevx]=lin;
+ }
+ }
+}
+
+static void seed_generic(vorbis_look_psy *p,
+ double ***curves,
+ double *f,
+ double *flr,
+ double *seeds,
+ double specmax){
+ vorbis_info_psy *vi=p->vi;
+ long n=p->n,i;
+ int maxEH=EHMER_MAX-1;
+
+ /* prime the working vector with peak values */
+ /* Use the 125 Hz curve up to 125 Hz and 8kHz curve after 8kHz. */
+ for(i=0;i<n;i++)
+ if(f[i]>flr[i])
+ maxEH=seed_curve(seeds,curves[p->octave[i]],
+ f[i],specmax,i,n,vi->max_curve_dB,maxEH);
+}
+
+static void seed_att(vorbis_look_psy *p,
+ double **att,
+ double *f,
+ double *flr,
+ double specmax){
+ vorbis_info_psy *vi=p->vi;
+ long n=p->n,i;
+
+ for(i=0;i<n;i++)
+ if(f[i]>flr[i])
+ seed_peak(flr,att[p->octave[i]],f[i],
+ specmax,i,n,vi->max_curve_dB);
+}
+
+static void seed_point(vorbis_look_psy *p,
+ double **att,
+ double *f,
+ double *flr,
+ double specmax){
+ vorbis_info_psy *vi=p->vi;
+ long n=p->n,i;
+
+ for(i=0;i<n;i++){
+ /* make this attenuation adjustable */
+ int choice=rint((todB(f[i])-specmax+vi->max_curve_dB)/10.+.5);
+ double lin;
+ if(choice<0)choice=0;
+ if(choice>=P_LEVELS)choice=P_LEVELS-1;
+ lin=att[p->octave[i]][choice]*f[i];
+ if(flr[i]<lin)flr[i]=lin;
+ }
+}
+
+/* bleaugh, this is more complicated than it needs to be */
+static void max_seeds(vorbis_look_psy *p,double *seeds,double *flr){
+ long n=p->n,i,j;
+ long *posstack=alloca(n*sizeof(long));
+ double *ampstack=alloca(n*sizeof(double));
+ long stack=0;
+
+ for(i=0;i<n;i++){
+ if(stack<2){
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ }else{
+ while(1){
+ if(seeds[i]<ampstack[stack-1]){
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ break;
+ }else{
+ if(i<posstack[stack-1]*1.0905077080){
+ if(stack>1 && ampstack[stack-1]<ampstack[stack-2] &&
+ i<posstack[stack-2]*1.0905077080){
+ /* we completely overlap, making stack-1 irrelevant. pop it */
+ stack--;
+ continue;
+ }
+ }
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ break;
+
+ }
+ }
+ }
+ }
+
+ /* the stack now contains only the positions that are relevant. Scan
+ 'em straight through */
+ {
+ long pos=0;
+ for(i=0;i<stack;i++){
+ long endpos;
+ if(i<stack-1 && ampstack[i+1]>ampstack[i]){
+ endpos=posstack[i+1];
+ }else{
+ endpos=posstack[i]*1.0905077080+1; /* +1 is important, else bin 0 is
+ discarded in short frames */
+ }
+ if(endpos>n)endpos=n;
+ for(j=pos;j<endpos;j++)
+ if(flr[j]<ampstack[i])
+ flr[j]=ampstack[i];
+ pos=endpos;
+ }
+ }
+
+ /* there. Linear time. I now remember this was on a problem set I
+ had in Grad Skool... I didn't solve it at the time ;-) */
+}
+
+static void bark_noise(long n,double *b,double *f,double *noise){
+ long i=1,lo=0,hi=2;
+ double acc=0.,val,del=0.;
+
+ double *norm=alloca(n*sizeof(double));
+
+ memset(noise,0,n*sizeof(double));
+ memset(norm,0,n*sizeof(double));
+
+ while(hi<n){
+ val=todB(f[i]*f[i])+400.;
+ del=1./(i-lo);
+ noise[lo]+=val*del;
+ noise[i]-=val*del;
+ norm[lo]+=del;
+ norm[i]-=del;
+
+ del=1./(hi-i);
+ noise[i]-=val*del;
+ noise[hi]+=val*del;
+ norm[hi]+=del;
+ norm[i]-=del;
+
+
+ i++;
+ for(;hi<n && b[hi]-.3<b[i];hi++);
+ for(;lo<i-1 && b[lo]+.3<b[i];lo++);
+ if(i==hi)hi++;
+ }
+
+ {
+ long ilo=i-lo;
+ long hii=hi-i;
+
+ for(;i<n;i++){
+ val=todB(f[i]*f[i])+400.;
+ del=1./(hii);
+ noise[i]-=val*del;
+ norm[i]-=del;
+
+ del=1./(ilo);
+ noise[i-ilo]+=val*del;
+ noise[i]-=val*del;
+ norm[i-ilo]+=del;
+ norm[i]-=del;
+ }
+ for(i=1,lo=n-ilo;lo<n;lo++,i++){
+ val=todB(f[n-i]*f[n-i])+400.;
+ del=1./ilo;
+ noise[lo]+=val*del;
+ norm[lo]+=del;
+ }
+ }
+
+
+ acc=0;
+ val=0;
+
+ for(i=0;i<n;i++){
+ val+=norm[i];
+ norm[i]=val;
+ acc+=noise[i];
+ noise[i]=acc;
+ }
+
+ val=0;
+ acc=0;
+ for(i=0;i<n;i++){
+ val+=norm[i];
+ acc+=noise[i];
+ if(val==0){
+ noise[i]=0.;
+ norm[i]=0;
+ }else{
+ double v=acc/val-400;
+ noise[i]=sqrt(fromdB(v));
+ }
+ }
+}
+
+void _vp_compute_mask(vorbis_look_psy *p,double *f,
+ double *flr,
+ double *decay){
+ double *smooth=alloca(sizeof(double)*p->n);
+ int i,n=p->n;
+ double specmax=0.;
+
+ double *seed=alloca(sizeof(double)*p->n);
+ double *seed2=alloca(sizeof(double)*p->n);
+
+ memset(flr,0,n*sizeof(double));
+
+ /* noise masking */
+ if(p->vi->noisemaskp){
+ memset(seed,0,n*sizeof(double));
+ bark_noise(n,p->bark,f,seed);
+ seed_point(p,p->noiseatt,seed,flr,specmax);
+
+ }
+
+ /* smooth the data is that's called for ********************************/
+ for(i=0;i<n;i++)smooth[i]=fabs(f[i]);
+ if(p->vi->smoothp){
+ /* compute power^.5 of three neighboring bins to smooth for peaks
+ that get split twixt bins/peaks that nail the bin. This evens
+ out treatment as we're not doing additive masking any longer. */
+ double acc=smooth[0]*smooth[0]+smooth[1]*smooth[1];
+ double prev=smooth[0];
+
+ smooth[0]=sqrt(acc);
+ for(i=1;i<n-1;i++){
+ double this=smooth[i];
+ acc+=smooth[i+1]*smooth[i+1];
+ if(acc<0)acc=0; /* it can happen due to finite precision */
+ smooth[i]=sqrt(acc);
+ acc-=prev*prev;
+ prev=this;
+ }
+ smooth[n-1]=sqrt(acc);
+ }
+
+ /* find the highest peak so we know the limits *************************/
+ for(i=0;i<n;i++){
+ if(smooth[i]>specmax)specmax=smooth[i];
+ }
+ specmax=todB(specmax);
+
+ /* set the ATH (floating below specmax by a specified att) */
+ if(p->vi->athp){
+ double att=specmax+p->vi->ath_adjatt;
+ if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
+ att=fromdB(att);
+
+ for(i=0;i<n;i++){
+ double av=p->ath[i]*att;
+ if(av>flr[i])flr[i]=av;
+ }
+ }
+
+ /* peak attenuation ******/
+ if(p->vi->peakattp){
+ memset(seed,0,n*sizeof(double));
+ seed_att(p,p->peakatt,smooth,seed,specmax);
+ max_seeds(p,seed,flr);
+ }
+
+ /* tone masking */
+ if(p->vi->tonemaskp){
+ memset(seed,0,n*sizeof(double));
+ memset(seed2,0,n*sizeof(double));
+
+ seed_generic(p,p->tonecurves,smooth,flr,seed2,specmax);
+ max_seeds(p,seed2,seed2);
+
+ for(i=0;i<n;i++)if(seed2[i]<flr[i])seed2[i]=flr[i];
+ for(i=0;i<n;i++)if(seed2[i]<decay[i])seed2[i]=decay[i];
+
+ seed_generic(p,p->tonecurves,smooth,seed2,seed,specmax);
+ max_seeds(p,seed,seed);
+
+ if(p->vi->decayp)
+ compute_decay_fixed(p,seed,decay,n);
+
+ for(i=0;i<n;i++)if(flr[i]<seed[i])flr[i]=seed[i];
+
+ }
+
+ /* doing this here is clean, but we need to find a faster way to do
+ it than to just tack it on */
+
+ for(i=0;i<n;i++)if(2.*f[i]>flr[i] || -2.*f[i]>flr[i])break;
+ if(i==n)memset(flr,0,sizeof(double)*n);
+
+}
+
+
+/* this applies the floor and (optionally) tries to preserve noise
+ energy in low resolution portions of the spectrum */
+/* f and flr are *linear* scale, not dB */
+void _vp_apply_floor(vorbis_look_psy *p,double *f, double *flr){
+ double *work=alloca(p->n*sizeof(double));
+ int j;
+
+ /* subtract the floor */
+ for(j=0;j<p->n;j++){
+ if(flr[j]<=0)
+ work[j]=0.;
+ else
+ work[j]=f[j]/flr[j];
+ }
+
+ memcpy(f,work,p->n*sizeof(double));
+}
+
+
diff --git a/lib/sharedbook.c b/lib/sharedbook.c
new file mode 100644
index 00000000..320f3d3a
--- /dev/null
+++ b/lib/sharedbook.c
@@ -0,0 +1,627 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: basic shared codebook operations
+ last mod: $Id: sharedbook.c,v 1.7.4.1 2000/08/31 08:05:48 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "os.h"
+#include "vorbis/codec.h"
+#include "vorbis/codebook.h"
+#include "bitwise.h"
+#include "scales.h"
+#include "sharedbook.h"
+
+/**** pack/unpack helpers ******************************************/
+int _ilog(unsigned int v){
+ int ret=0;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+/* 32 bit float (not IEEE; nonnormalized mantissa +
+ biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
+ Why not IEEE? It's just not that important here. */
+
+#define VQ_FEXP 10
+#define VQ_FMAN 21
+#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
+
+/* doesn't currently guard under/overflow */
+long _float32_pack(double val){
+ int sign=0;
+ long exp;
+ long mant;
+ if(val<0){
+ sign=0x80000000;
+ val= -val;
+ }
+ exp= floor(log(val)/log(2));
+ mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
+ exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
+
+ return(sign|exp|mant);
+}
+
+double _float32_unpack(long val){
+ double mant=val&0x1fffff;
+ double sign=val&0x80000000;
+ double exp =(val&0x7fe00000)>>VQ_FMAN;
+ if(sign)mant= -mant;
+ return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
+}
+
+/* given a list of word lengths, generate a list of codewords. Works
+ for length ordered or unordered, always assigns the lowest valued
+ codewords first. Extended to handle unused entries (length 0) */
+long *_make_words(long *l,long n){
+ long i,j;
+ long marker[33];
+ long *r=malloc(n*sizeof(long));
+ memset(marker,0,sizeof(marker));
+
+ for(i=0;i<n;i++){
+ long length=l[i];
+ if(length>0){
+ long entry=marker[length];
+
+ /* when we claim a node for an entry, we also claim the nodes
+ below it (pruning off the imagined tree that may have dangled
+ from it) as well as blocking the use of any nodes directly
+ above for leaves */
+
+ /* update ourself */
+ if(length<32 && (entry>>length)){
+ /* error condition; the lengths must specify an overpopulated tree */
+ free(r);
+ return(NULL);
+ }
+ r[i]=entry;
+
+ /* Look to see if the next shorter marker points to the node
+ above. if so, update it and repeat. */
+ {
+ for(j=length;j>0;j--){
+
+ if(marker[j]&1){
+ /* have to jump branches */
+ if(j==1)
+ marker[1]++;
+ else
+ marker[j]=marker[j-1]<<1;
+ break; /* invariant says next upper marker would already
+ have been moved if it was on the same path */
+ }
+ marker[j]++;
+ }
+ }
+
+ /* prune the tree; the implicit invariant says all the longer
+ markers were dangling from our just-taken node. Dangle them
+ from our *new* node. */
+ for(j=length+1;j<33;j++)
+ if((marker[j]>>1) == entry){
+ entry=marker[j];
+ marker[j]=marker[j-1]<<1;
+ }else
+ break;
+ }
+ }
+
+ /* bitreverse the words because our bitwise packer/unpacker is LSb
+ endian */
+ for(i=0;i<n;i++){
+ long temp=0;
+ for(j=0;j<l[i];j++){
+ temp<<=1;
+ temp|=(r[i]>>j)&1;
+ }
+ r[i]=temp;
+ }
+
+ return(r);
+}
+
+/* build the decode helper tree from the codewords */
+decode_aux *_make_decode_tree(codebook *c){
+ const static_codebook *s=c->c;
+ long top=0,i,j;
+ decode_aux *t=malloc(sizeof(decode_aux));
+ long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
+ long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
+ long *codelist=_make_words(s->lengthlist,s->entries);
+
+ if(codelist==NULL)return(NULL);
+ t->aux=c->entries*2;
+
+ for(i=0;i<c->entries;i++){
+ if(s->lengthlist[i]>0){
+ long ptr=0;
+ for(j=0;j<s->lengthlist[i]-1;j++){
+ int bit=(codelist[i]>>j)&1;
+ if(!bit){
+ if(!ptr0[ptr])
+ ptr0[ptr]= ++top;
+ ptr=ptr0[ptr];
+ }else{
+ if(!ptr1[ptr])
+ ptr1[ptr]= ++top;
+ ptr=ptr1[ptr];
+ }
+ }
+ if(!((codelist[i]>>j)&1))
+ ptr0[ptr]=-i;
+ else
+ ptr1[ptr]=-i;
+ }
+ }
+ free(codelist);
+ return(t);
+}
+
+/* there might be a straightforward one-line way to do the below
+ that's portable and totally safe against roundoff, but I haven't
+ thought of it. Therefore, we opt on the side of caution */
+long _book_maptype1_quantvals(const static_codebook *b){
+ long vals=floor(pow(b->entries,1./b->dim));
+
+ /* the above *should* be reliable, but we'll not assume that FP is
+ ever reliable when bitstream sync is at stake; verify via integer
+ means that vals really is the greatest value of dim for which
+ vals^b->bim <= b->entries */
+ /* treat the above as an initial guess */
+ while(1){
+ long acc=1;
+ long acc1=1;
+ int i;
+ for(i=0;i<b->dim;i++){
+ acc*=vals;
+ acc1*=vals+1;
+ }
+ if(acc<=b->entries && acc1>b->entries){
+ return(vals);
+ }else{
+ if(acc>b->entries){
+ vals--;
+ }else{
+ vals++;
+ }
+ }
+ }
+}
+
+/* unpack the quantized list of values for encode/decode ***********/
+/* we need to deal with two map types: in map type 1, the values are
+ generated algorithmically (each column of the vector counts through
+ the values in the quant vector). in map type 2, all the values came
+ in in an explicit list. Both value lists must be unpacked */
+double *_book_unquantize(const static_codebook *b){
+ long j,k;
+ if(b->maptype==1 || b->maptype==2){
+ int quantvals;
+ double mindel=_float32_unpack(b->q_min);
+ double delta=_float32_unpack(b->q_delta);
+ double *r=calloc(b->entries*b->dim,sizeof(double));
+
+ /* maptype 1 and 2 both use a quantized value vector, but
+ different sizes */
+ switch(b->maptype){
+ case 1:
+ /* most of the time, entries%dimensions == 0, but we need to be
+ well defined. We define that the possible vales at each
+ scalar is values == entries/dim. If entries%dim != 0, we'll
+ have 'too few' values (values*dim<entries), which means that
+ we'll have 'left over' entries; left over entries use zeroed
+ values (and are wasted). So don't generate codebooks like
+ that */
+ quantvals=_book_maptype1_quantvals(b);
+ for(j=0;j<b->entries;j++){
+ double last=0.;
+ int indexdiv=1;
+ for(k=0;k<b->dim;k++){
+ int index= (j/indexdiv)%quantvals;
+ double val=b->quantlist[index];
+ val=fabs(val)*delta+mindel+last;
+ if(b->q_sequencep)last=val;
+ r[j*b->dim+k]=val;
+ indexdiv*=quantvals;
+ }
+ }
+ break;
+ case 2:
+ for(j=0;j<b->entries;j++){
+ double last=0.;
+ for(k=0;k<b->dim;k++){
+ double val=b->quantlist[j*b->dim+k];
+ val=fabs(val)*delta+mindel+last;
+ if(b->q_sequencep)last=val;
+ r[j*b->dim+k]=val;
+ }
+ }
+ }
+ return(r);
+ }
+ return(NULL);
+}
+
+void vorbis_staticbook_clear(static_codebook *b){
+ if(b->quantlist)free(b->quantlist);
+ if(b->lengthlist)free(b->lengthlist);
+ if(b->nearest_tree){
+ free(b->nearest_tree->ptr0);
+ free(b->nearest_tree->ptr1);
+ free(b->nearest_tree->p);
+ free(b->nearest_tree->q);
+ memset(b->nearest_tree,0,sizeof(encode_aux_nearestmatch));
+ free(b->nearest_tree);
+ }
+ if(b->thresh_tree){
+ free(b->thresh_tree->quantthresh);
+ free(b->thresh_tree->quantmap);
+ memset(b->thresh_tree,0,sizeof(encode_aux_threshmatch));
+ free(b->thresh_tree);
+ }
+ memset(b,0,sizeof(static_codebook));
+}
+
+void vorbis_book_clear(codebook *b){
+ /* static book is not cleared; we're likely called on the lookup and
+ the static codebook belongs to the info struct */
+ if(b->decode_tree){
+ free(b->decode_tree->ptr0);
+ free(b->decode_tree->ptr1);
+ memset(b->decode_tree,0,sizeof(decode_aux));
+ free(b->decode_tree);
+ }
+ if(b->valuelist)free(b->valuelist);
+ if(b->codelist)free(b->codelist);
+ memset(b,0,sizeof(codebook));
+}
+
+int vorbis_book_init_encode(codebook *c,const static_codebook *s){
+ memset(c,0,sizeof(codebook));
+ c->c=s;
+ c->entries=s->entries;
+ c->dim=s->dim;
+ c->codelist=_make_words(s->lengthlist,s->entries);
+ c->valuelist=_book_unquantize(s);
+ return(0);
+}
+
+int vorbis_book_init_decode(codebook *c,const static_codebook *s){
+ memset(c,0,sizeof(codebook));
+ c->c=s;
+ c->entries=s->entries;
+ c->dim=s->dim;
+ c->valuelist=_book_unquantize(s);
+ c->decode_tree=_make_decode_tree(c);
+ if(c->decode_tree==NULL)goto err_out;
+ return(0);
+ err_out:
+ vorbis_book_clear(c);
+ return(-1);
+}
+
+static double _dist(int el,double *ref, double *b,int step){
+ int i;
+ double acc=0.;
+ for(i=0;i<el;i++){
+ double val=(ref[i]-b[i*step]);
+ acc+=val*val;
+ }
+ return(acc);
+}
+
+#include <stdio.h>
+int _best(codebook *book, double *a, int step){
+ encode_aux_nearestmatch *nt=book->c->nearest_tree;
+ encode_aux_threshmatch *tt=book->c->thresh_tree;
+ encode_aux_pigeonhole *pt=book->c->pigeon_tree;
+ int dim=book->dim;
+ int ptr=0,k,o;
+ /*int savebest=-1;
+ double saverr;*/
+
+ /* do we have a threshhold encode hint? */
+ if(tt){
+ int index=0;
+ /* find the quant val of each scalar */
+ for(k=0,o=step*(dim-1);k<dim;k++,o-=step){
+ int i;
+ /* linear search the quant list for now; it's small and although
+ with > 8 entries, it would be faster to bisect, this would be
+ a misplaced optimization for now */
+ for(i=0;i<tt->threshvals-1;i++)
+ if(a[o]<tt->quantthresh[i])break;
+
+ index=(index*tt->quantvals)+tt->quantmap[i];
+ }
+ /* regular lattices are easy :-) */
+ if(book->c->lengthlist[index]>0) /* is this unused? If so, we'll
+ use a decision tree after all
+ and fall through*/
+ return(index);
+ }
+
+ /* do we have a pigeonhole encode hint? */
+ if(pt){
+ const static_codebook *c=book->c;
+ int i,besti=-1;
+ double best;
+ int entry=0;
+
+ /* dealing with sequentialness is a pain in the ass */
+ if(c->q_sequencep){
+ int pv;
+ long mul=1;
+ double qlast=0;
+ for(k=0,o=0;k<dim;k++,o+=step){
+ pv=(int)((a[o]-qlast-pt->min)/pt->del);
+ if(pv<0 || pv>=pt->mapentries)break;
+ entry+=pt->pigeonmap[pv]*mul;
+ mul*=pt->quantvals;
+ qlast+=pv*pt->del+pt->min;
+ }
+ }else{
+ for(k=0,o=step*(dim-1);k<dim;k++,o-=step){
+ int pv=(int)((a[o]-pt->min)/pt->del);
+ if(pv<0 || pv>=pt->mapentries)break;
+ entry=entry*pt->quantvals+pt->pigeonmap[pv];
+ }
+ }
+
+ /* must be within the pigeonholable range; if we quant outside (or
+ in an entry that we define no list for), brute force it */
+ if(k==dim && pt->fitlength[entry]){
+ /* search the abbreviated list */
+ long *list=pt->fitlist+pt->fitmap[entry];
+ for(i=0;i<pt->fitlength[entry];i++){
+ double this=_dist(dim,book->valuelist+list[i]*dim,a,step);
+ if(besti==-1 || this<best){
+ best=this;
+ besti=list[i];
+ }
+ }
+
+ return(besti);
+ }
+ }
+
+ if(nt){
+ /* optimized using the decision tree */
+ while(1){
+ double c=0.;
+ double *p=book->valuelist+nt->p[ptr];
+ double *q=book->valuelist+nt->q[ptr];
+
+ for(k=0,o=0;k<dim;k++,o+=step)
+ c+=(p[k]-q[k])*(a[o]-(p[k]+q[k])*.5);
+
+ if(c>0.) /* in A */
+ ptr= -nt->ptr0[ptr];
+ else /* in B */
+ ptr= -nt->ptr1[ptr];
+ if(ptr<=0)break;
+ }
+ return(-ptr);
+ }
+
+ /* brute force it! */
+ {
+ const static_codebook *c=book->c;
+ int i,besti=-1;
+ double best;
+ double *e=book->valuelist;
+ for(i=0;i<book->entries;i++){
+ if(c->lengthlist[i]>0){
+ double this=_dist(dim,e,a,step);
+ if(besti==-1 || this<best){
+ best=this;
+ besti=i;
+ }
+ }
+ e+=dim;
+ }
+
+ /*if(savebest!=-1 && savebest!=besti){
+ fprintf(stderr,"brute force/pigeonhole disagreement:\n"
+ "original:");
+ for(i=0;i<dim*step;i+=step)fprintf(stderr,"%g,",a[i]);
+ fprintf(stderr,"\n"
+ "pigeonhole (entry %d, err %g):",savebest,saverr);
+ for(i=0;i<dim;i++)fprintf(stderr,"%g,",
+ (book->valuelist+savebest*dim)[i]);
+ fprintf(stderr,"\n"
+ "bruteforce (entry %d, err %g):",besti,best);
+ for(i=0;i<dim;i++)fprintf(stderr,"%g,",
+ (book->valuelist+besti*dim)[i]);
+ fprintf(stderr,"\n");
+ }*/
+ return(besti);
+ }
+}
+
+/* returns the entry number and *modifies a* to the remainder value ********/
+int vorbis_book_besterror(codebook *book,double *a,int step,int addmul){
+ int dim=book->dim,i,o;
+ int best=_best(book,a,step);
+ switch(addmul){
+ case 0:
+ for(i=0,o=0;i<dim;i++,o+=step)
+ a[o]-=(book->valuelist+best*dim)[i];
+ break;
+ case 1:
+ for(i=0,o=0;i<dim;i++,o+=step){
+ double val=(book->valuelist+best*dim)[i];
+ if(val==0){
+ a[o]=0;
+ }else{
+ a[o]/=val;
+ }
+ }
+ break;
+ }
+ return(best);
+}
+
+long vorbis_book_codeword(codebook *book,int entry){
+ return book->codelist[entry];
+}
+
+long vorbis_book_codelen(codebook *book,int entry){
+ return book->c->lengthlist[entry];
+}
+
+#ifdef _V_SELFTEST
+
+/* Unit tests of the dequantizer; this stuff will be OK
+ cross-platform, I simply want to be sure that special mapping cases
+ actually work properly; a bug could go unnoticed for a while */
+
+#include <stdio.h>
+
+/* cases:
+
+ no mapping
+ full, explicit mapping
+ algorithmic mapping
+
+ nonsequential
+ sequential
+*/
+
+static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1};
+static long partial_quantlist1[]={0,7,2};
+
+/* no mapping */
+static_codebook test1={
+ 4,16,
+ NULL,
+ 0,
+ 0,0,0,0,
+ NULL,
+ NULL,NULL
+};
+static double *test1_result=NULL;
+
+/* linear, full mapping, nonsequential */
+static_codebook test2={
+ 4,3,
+ NULL,
+ 2,
+ -533200896,1611661312,4,0,
+ full_quantlist1,
+ NULL,NULL
+};
+static double test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2};
+
+/* linear, full mapping, sequential */
+static_codebook test3={
+ 4,3,
+ NULL,
+ 2,
+ -533200896,1611661312,4,1,
+ full_quantlist1,
+ NULL,NULL
+};
+static double test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6};
+
+/* linear, algorithmic mapping, nonsequential */
+static_codebook test4={
+ 3,27,
+ NULL,
+ 1,
+ -533200896,1611661312,4,0,
+ partial_quantlist1,
+ NULL,NULL
+};
+static double test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3,
+ -3, 4,-3, 4, 4,-3, -1, 4,-3,
+ -3,-1,-3, 4,-1,-3, -1,-1,-3,
+ -3,-3, 4, 4,-3, 4, -1,-3, 4,
+ -3, 4, 4, 4, 4, 4, -1, 4, 4,
+ -3,-1, 4, 4,-1, 4, -1,-1, 4,
+ -3,-3,-1, 4,-3,-1, -1,-3,-1,
+ -3, 4,-1, 4, 4,-1, -1, 4,-1,
+ -3,-1,-1, 4,-1,-1, -1,-1,-1};
+
+/* linear, algorithmic mapping, sequential */
+static_codebook test5={
+ 3,27,
+ NULL,
+ 1,
+ -533200896,1611661312,4,1,
+ partial_quantlist1,
+ NULL,NULL
+};
+static double test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7,
+ -3, 1,-2, 4, 8, 5, -1, 3, 0,
+ -3,-4,-7, 4, 3, 0, -1,-2,-5,
+ -3,-6,-2, 4, 1, 5, -1,-4, 0,
+ -3, 1, 5, 4, 8,12, -1, 3, 7,
+ -3,-4, 0, 4, 3, 7, -1,-2, 2,
+ -3,-6,-7, 4, 1, 0, -1,-4,-5,
+ -3, 1, 0, 4, 8, 7, -1, 3, 2,
+ -3,-4,-5, 4, 3, 2, -1,-2,-3};
+
+void run_test(static_codebook *b,double *comp){
+ double *out=_book_unquantize(b);
+ int i;
+
+ if(comp){
+ if(!out){
+ fprintf(stderr,"_book_unquantize incorrectly returned NULL\n");
+ exit(1);
+ }
+
+ for(i=0;i<b->entries*b->dim;i++)
+ if(fabs(out[i]-comp[i])>.0001){
+ fprintf(stderr,"disagreement in unquantized and reference data:\n"
+ "position %d, %g != %g\n",i,out[i],comp[i]);
+ exit(1);
+ }
+
+ }else{
+ if(out){
+ fprintf(stderr,"_book_unquantize returned a value array: \n"
+ " correct result should have been NULL\n");
+ exit(1);
+ }
+ }
+}
+
+int main(){
+ /* run the nine dequant tests, and compare to the hand-rolled results */
+ fprintf(stderr,"Dequant test 1... ");
+ run_test(&test1,test1_result);
+ fprintf(stderr,"OK\nDequant test 2... ");
+ run_test(&test2,test2_result);
+ fprintf(stderr,"OK\nDequant test 3... ");
+ run_test(&test3,test3_result);
+ fprintf(stderr,"OK\nDequant test 4... ");
+ run_test(&test4,test4_result);
+ fprintf(stderr,"OK\nDequant test 5... ");
+ run_test(&test5,test5_result);
+ fprintf(stderr,"OK\n\n");
+
+ return(0);
+}
+
+#endif
diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
new file mode 100644
index 00000000..10a33dab
--- /dev/null
+++ b/lib/vorbisfile.c
@@ -0,0 +1,1156 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: stdio-based convenience library for opening/seeking/decoding
+ last mod: $Id: vorbisfile.c,v 1.27.2.1 2000/08/31 08:05:48 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+#include "vorbis/codec.h"
+#include "vorbis/vorbisfile.h"
+
+#include "os.h"
+#include "misc.h"
+
+/* A 'chained bitstream' is a Vorbis bitstream that contains more than
+ one logical bitstream arranged end to end (the only form of Ogg
+ multiplexing allowed in a Vorbis bitstream; grouping [parallel
+ multiplexing] is not allowed in Vorbis) */
+
+/* A Vorbis file can be played beginning to end (streamed) without
+ worrying ahead of time about chaining (see decoder_example.c). If
+ we have the whole file, however, and want random access
+ (seeking/scrubbing) or desire to know the total length/time of a
+ file, we need to account for the possibility of chaining. */
+
+/* We can handle things a number of ways; we can determine the entire
+ bitstream structure right off the bat, or find pieces on demand.
+ This example determines and caches structure for the entire
+ bitstream, but builds a virtual decoder on the fly when moving
+ between links in the chain. */
+
+/* There are also different ways to implement seeking. Enough
+ information exists in an Ogg bitstream to seek to
+ sample-granularity positions in the output. Or, one can seek by
+ picking some portion of the stream roughly in the desired area if
+ we only want course navigation through the stream. */
+
+/*************************************************************************
+ * Many, many internal helpers. The intention is not to be confusing;
+ * rampant duplication and monolithic function implementation would be
+ * harder to understand anyway. The high level functions are last. Begin
+ * grokking near the end of the file */
+
+/* read a little more data from the file/pipe into the ogg_sync framer */
+#define CHUNKSIZE 4096
+static long _get_data(OggVorbis_File *vf){
+ char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
+ long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
+ ogg_sync_wrote(&vf->oy,bytes);
+ return(bytes);
+}
+
+/* save a tiny smidge of verbosity to make the code more readable */
+static void _seek_helper(OggVorbis_File *vf,long offset){
+ (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
+ vf->offset=offset;
+ ogg_sync_reset(&vf->oy);
+}
+
+/* The read/seek functions track absolute position within the stream */
+
+/* from the head of the stream, get the next page. boundary specifies
+ if the function is allowed to fetch more data from the stream (and
+ how much) or only use internally buffered data.
+
+ boundary: -1) unbounded search
+ 0) read no additional data; use cached only
+ n) search for a new page beginning for n bytes
+
+ return: -1) did not find a page
+ n) found a page at absolute offset n */
+
+static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
+ if(boundary>0)boundary+=vf->offset;
+ while(1){
+ long more;
+
+ if(boundary>0 && vf->offset>=boundary)return(-1);
+ more=ogg_sync_pageseek(&vf->oy,og);
+
+ if(more<0){
+ /* skipped n bytes */
+ vf->offset-=more;
+ }else{
+ if(more==0){
+ /* send more paramedics */
+ if(!boundary)return(-1);
+ if(_get_data(vf)<=0)return(-1);
+ }else{
+ /* got a page. Return the offset at the page beginning,
+ advance the internal offset past the page end */
+ long ret=vf->offset;
+ vf->offset+=more;
+ return(ret);
+
+ }
+ }
+ }
+}
+
+/* find the latest page beginning before the current stream cursor
+ position. Much dirtier than the above as Ogg doesn't have any
+ backward search linkage. no 'readp' as it will certainly have to
+ read. */
+static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
+ long begin=vf->offset;
+ long ret;
+ int offset=-1;
+
+ while(offset==-1){
+ begin-=CHUNKSIZE;
+ _seek_helper(vf,begin);
+ while(vf->offset<begin+CHUNKSIZE){
+ ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
+ if(ret==-1){
+ break;
+ }else{
+ offset=ret;
+ }
+ }
+ }
+
+ /* we have the offset. Actually snork and hold the page now */
+ _seek_helper(vf,offset);
+ ret=_get_next_page(vf,og,CHUNKSIZE);
+ if(ret==-1){
+ /* this shouldn't be possible */
+ fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
+ "Exiting.\n");
+ exit(1);
+ }
+ return(offset);
+}
+
+/* finds each bitstream link one at a time using a bisection search
+ (has to begin by knowing the offset of the lb's initial page).
+ Recurses for each link so it can alloc the link storage after
+ finding them all, then unroll and fill the cache at the same time */
+static void _bisect_forward_serialno(OggVorbis_File *vf,
+ long begin,
+ long searched,
+ long end,
+ long currentno,
+ long m){
+ long endsearched=end;
+ long next=end;
+ ogg_page og;
+ long ret;
+
+ /* the below guards against garbage seperating the last and
+ first pages of two links. */
+ while(searched<endsearched){
+ long bisect;
+
+ if(endsearched-searched<CHUNKSIZE){
+ bisect=searched;
+ }else{
+ bisect=(searched+endsearched)/2;
+ }
+
+ _seek_helper(vf,bisect);
+ ret=_get_next_page(vf,&og,-1);
+ if(ret<0 || ogg_page_serialno(&og)!=currentno){
+ endsearched=bisect;
+ if(ret>=0)next=ret;
+ }else{
+ searched=ret+og.header_len+og.body_len;
+ }
+ }
+
+ _seek_helper(vf,next);
+ ret=_get_next_page(vf,&og,-1);
+
+ if(searched>=end || ret==-1){
+ vf->links=m+1;
+ vf->offsets=malloc((m+2)*sizeof(ogg_int64_t));
+ vf->offsets[m+1]=searched;
+ }else{
+ _bisect_forward_serialno(vf,next,vf->offset,
+ end,ogg_page_serialno(&og),m+1);
+ }
+
+ vf->offsets[m]=begin;
+}
+
+/* uses the local ogg_stream storage in vf; this is important for
+ non-streaming input sources */
+static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
+ long *serialno){
+ ogg_page og;
+ ogg_packet op;
+ int i,ret;
+
+ ret=_get_next_page(vf,&og,CHUNKSIZE);
+ if(ret==-1){
+ fprintf(stderr,"Did not find initial header for bitstream.\n");
+ return -1;
+ }
+
+ if(serialno)*serialno=ogg_page_serialno(&og);
+ ogg_stream_init(&vf->os,ogg_page_serialno(&og));
+
+ /* extract the initial header from the first page and verify that the
+ Ogg bitstream is in fact Vorbis data */
+
+ vorbis_info_init(vi);
+ vorbis_comment_init(vc);
+
+ i=0;
+ while(i<3){
+ ogg_stream_pagein(&vf->os,&og);
+ while(i<3){
+ int result=ogg_stream_packetout(&vf->os,&op);
+ if(result==0)break;
+ if(result==-1){
+ fprintf(stderr,"Corrupt header in logical bitstream.\n");
+ goto bail_header;
+ }
+ if(vorbis_synthesis_headerin(vi,vc,&op)){
+ fprintf(stderr,"Illegal header in logical bitstream.\n");
+ goto bail_header;
+ }
+ i++;
+ }
+ if(i<3)
+ if(_get_next_page(vf,&og,1)<0){
+ fprintf(stderr,"Missing header in logical bitstream.\n");
+ goto bail_header;
+ }
+ }
+ return 0;
+
+ bail_header:
+ vorbis_info_clear(vi);
+ vorbis_comment_clear(vc);
+ ogg_stream_clear(&vf->os);
+ return -1;
+}
+
+/* last step of the OggVorbis_File initialization; get all the
+ vorbis_info structs and PCM positions. Only called by the seekable
+ initialization (local stream storage is hacked slightly; pay
+ attention to how that's done) */
+static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
+ vorbis_comment *first_c,
+ long dataoffset){
+ ogg_page og;
+ int i,ret;
+
+ vf->vi=calloc(vf->links,sizeof(vorbis_info));
+ vf->vc=calloc(vf->links,sizeof(vorbis_info));
+ vf->dataoffsets=malloc(vf->links*sizeof(ogg_int64_t));
+ vf->pcmlengths=malloc(vf->links*sizeof(ogg_int64_t));
+ vf->serialnos=malloc(vf->links*sizeof(long));
+
+ for(i=0;i<vf->links;i++){
+ if(first_i && first_c && i==0){
+ /* we already grabbed the initial header earlier. This just
+ saves the waste of grabbing it again */
+ memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
+ memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
+ vf->dataoffsets[i]=dataoffset;
+ }else{
+
+ /* seek to the location of the initial header */
+
+ _seek_helper(vf,vf->offsets[i]);
+ if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
+ fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
+ vf->dataoffsets[i]=-1;
+ }else{
+ vf->dataoffsets[i]=vf->offset;
+ ogg_stream_clear(&vf->os);
+ }
+ }
+
+ /* get the serial number and PCM length of this link. To do this,
+ get the last page of the stream */
+ {
+ long end=vf->offsets[i+1];
+ _seek_helper(vf,end);
+
+ while(1){
+ ret=_get_prev_page(vf,&og);
+ if(ret==-1){
+ /* this should not be possible */
+ fprintf(stderr,"Could not find last page of logical "
+ "bitstream #%d\n\n",i);
+ vorbis_info_clear(vf->vi+i);
+ vorbis_comment_clear(vf->vc+i);
+ break;
+ }
+ if(ogg_page_frameno(&og)!=-1){
+ vf->serialnos[i]=ogg_page_serialno(&og);
+ vf->pcmlengths[i]=ogg_page_frameno(&og);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static int _make_decode_ready(OggVorbis_File *vf){
+ if(vf->decode_ready)exit(1);
+ vorbis_synthesis_init(&vf->vd,vf->vi);
+ vorbis_block_init(&vf->vd,&vf->vb);
+ vf->decode_ready=1;
+ return(0);
+}
+
+static int _open_seekable(OggVorbis_File *vf){
+ vorbis_info initial_i;
+ vorbis_comment initial_c;
+ long serialno,end;
+ int ret;
+ long dataoffset;
+ ogg_page og;
+
+ /* is this even vorbis...? */
+ ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
+ dataoffset=vf->offset;
+ ogg_stream_clear(&vf->os);
+ if(ret==-1)return(-1);
+
+ /* we can seek, so set out learning all about this file */
+ vf->seekable=1;
+ (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
+ vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
+
+ /* We get the offset for the last page of the physical bitstream.
+ Most OggVorbis files will contain a single logical bitstream */
+ end=_get_prev_page(vf,&og);
+
+ /* moer than one logical bitstream? */
+ if(ogg_page_serialno(&og)!=serialno){
+
+ /* Chained bitstream. Bisect-search each logical bitstream
+ section. Do so based on serial number only */
+ _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
+
+ }else{
+
+ /* Only one logical bitstream */
+ _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
+
+ }
+
+ _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
+ return(ov_raw_seek(vf,0));
+
+}
+
+static int _open_nonseekable(OggVorbis_File *vf){
+ /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
+ vf->links=1;
+ vf->vi=calloc(vf->links,sizeof(vorbis_info));
+ vf->vc=calloc(vf->links,sizeof(vorbis_info));
+
+ /* Try to fetch the headers, maintaining all the storage */
+ if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
+ _make_decode_ready(vf);
+
+ return 0;
+}
+
+/* clear out the current logical bitstream decoder */
+static void _decode_clear(OggVorbis_File *vf){
+ ogg_stream_clear(&vf->os);
+ vorbis_dsp_clear(&vf->vd);
+ vorbis_block_clear(&vf->vb);
+ vf->decode_ready=0;
+
+ vf->bittrack=0.;
+ vf->samptrack=0.;
+}
+
+/* fetch and process a packet. Handles the case where we're at a
+ bitstream boundary and dumps the decoding machine. If the decoding
+ machine is unloaded, it loads it. It also keeps pcm_offset up to
+ date (seek and read both use this. seek uses a special hack with
+ readp).
+
+ return: -1) hole in the data (lost packet)
+ 0) need more date (only if readp==0)/eof
+ 1) got a packet
+*/
+
+static int _process_packet(OggVorbis_File *vf,int readp){
+ ogg_page og;
+
+ /* handle one packet. Try to fetch it from current stream state */
+ /* extract packets from page */
+ while(1){
+
+ /* process a packet if we can. If the machine isn't loaded,
+ neither is a page */
+ if(vf->decode_ready){
+ ogg_packet op;
+ int result=ogg_stream_packetout(&vf->os,&op);
+ ogg_int64_t frameno;
+
+ /* if(result==-1)return(-1); hole in the data. For now, swallow
+ and go. We'll need to add a real
+ error code in a bit. */
+ if(result>0){
+ /* got a packet. process it */
+ frameno=op.frameno;
+ if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
+ header handling. The
+ header packets aren't
+ audio, so if/when we
+ submit them,
+ vorbis_synthesis will
+ reject them */
+
+ /* suck in the synthesis data and track bitrate */
+ {
+ int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
+ vorbis_synthesis_blockin(&vf->vd,&vf->vb);
+ vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
+ vf->bittrack+=op.bytes*8;
+ }
+
+ /* update the pcm offset. */
+ if(frameno!=-1 && !op.e_o_s){
+ int link=(vf->seekable?vf->current_link:0);
+ int i,samples;
+
+ /* this packet has a pcm_offset on it (the last packet
+ completed on a page carries the offset) After processing
+ (above), we know the pcm position of the *last* sample
+ ready to be returned. Find the offset of the *first*
+
+ As an aside, this trick is inaccurate if we begin
+ reading anew right at the last page; the end-of-stream
+ frameno declares the last frame in the stream, and the
+ last packet of the last page may be a partial frame.
+ So, we need a previous frameno from an in-sequence page
+ to have a reference point. Thus the !op.e_o_s clause
+ above */
+
+ samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
+
+ frameno-=samples;
+ for(i=0;i<link;i++)
+ frameno+=vf->pcmlengths[i];
+ vf->pcm_offset=frameno;
+ }
+ return(1);
+ }
+ }
+ }
+
+ if(!readp)return(0);
+ if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
+
+ /* bitrate tracking; add the header's bytes here, the body bytes
+ are done by packet above */
+ vf->bittrack+=og.header_len*8;
+
+ /* has our decoding just traversed a bitstream boundary? */
+ if(vf->decode_ready){
+ if(vf->current_serialno!=ogg_page_serialno(&og)){
+ _decode_clear(vf);
+ }
+ }
+
+ /* Do we need to load a new machine before submitting the page? */
+ /* This is different in the seekable and non-seekable cases.
+
+ In the seekable case, we already have all the header
+ information loaded and cached; we just initialize the machine
+ with it and continue on our merry way.
+
+ In the non-seekable (streaming) case, we'll only be at a
+ boundary if we just left the previous logical bitstream and
+ we're now nominally at the header of the next bitstream
+ */
+
+ if(!vf->decode_ready){
+ int link;
+ if(vf->seekable){
+ vf->current_serialno=ogg_page_serialno(&og);
+
+ /* match the serialno to bitstream section. We use this rather than
+ offset positions to avoid problems near logical bitstream
+ boundaries */
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
+ leave machine uninitialized */
+
+ vf->current_link=link;
+
+ ogg_stream_init(&vf->os,vf->current_serialno);
+ ogg_stream_reset(&vf->os);
+
+ }else{
+ /* we're streaming */
+ /* fetch the three header packets, build the info struct */
+
+ _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
+ vf->current_link++;
+ link=0;
+ }
+
+ _make_decode_ready(vf);
+ }
+ ogg_stream_pagein(&vf->os,&og);
+ }
+}
+
+/**********************************************************************
+ * The helpers are over; it's all toplevel interface from here on out */
+
+/* clear out the OggVorbis_File struct */
+int ov_clear(OggVorbis_File *vf){
+ if(vf){
+ vorbis_block_clear(&vf->vb);
+ vorbis_dsp_clear(&vf->vd);
+ ogg_stream_clear(&vf->os);
+
+ if(vf->vi && vf->links){
+ int i;
+ for(i=0;i<vf->links;i++){
+ vorbis_info_clear(vf->vi+i);
+ vorbis_comment_clear(vf->vc+i);
+ }
+ free(vf->vi);
+ free(vf->vc);
+ }
+ if(vf->dataoffsets)free(vf->dataoffsets);
+ if(vf->pcmlengths)free(vf->pcmlengths);
+ if(vf->serialnos)free(vf->serialnos);
+ if(vf->offsets)free(vf->offsets);
+ ogg_sync_clear(&vf->oy);
+ if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
+ memset(vf,0,sizeof(OggVorbis_File));
+ }
+#ifdef DEBUG_LEAKS
+ _VDBG_dump();
+#endif
+ return(0);
+}
+
+static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
+ return fseek(f,(int)off,whence);
+}
+
+/* inspects the OggVorbis file and finds/documents all the logical
+ bitstreams contained in it. Tries to be tolerant of logical
+ bitstream sections that are truncated/woogie.
+
+ return: -1) error
+ 0) OK
+*/
+
+int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
+ ov_callbacks callbacks = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) ftell
+ };
+
+ return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
+}
+
+
+int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
+ ov_callbacks callbacks)
+{
+ long offset=callbacks.seek_func(f,0,SEEK_CUR);
+ int ret;
+
+ memset(vf,0,sizeof(OggVorbis_File));
+ vf->datasource=f;
+ vf->callbacks = callbacks;
+
+ /* init the framing state */
+ ogg_sync_init(&vf->oy);
+
+ /* perhaps some data was previously read into a buffer for testing
+ against other stream types. Allow initialization from this
+ previously read data (as we may be reading from a non-seekable
+ stream) */
+ if(initial){
+ char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
+ memcpy(buffer,initial,ibytes);
+ ogg_sync_wrote(&vf->oy,ibytes);
+ }
+
+ /* can we seek? Stevens suggests the seek test was portable */
+ if(offset!=-1){
+ ret=_open_seekable(vf);
+ }else{
+ ret=_open_nonseekable(vf);
+ }
+ if(ret){
+ vf->datasource=NULL;
+ ov_clear(vf);
+ }
+ return(ret);
+}
+
+/* How many logical bitstreams in this physical bitstream? */
+long ov_streams(OggVorbis_File *vf){
+ return vf->links;
+}
+
+/* Is the FILE * associated with vf seekable? */
+long ov_seekable(OggVorbis_File *vf){
+ return vf->seekable;
+}
+
+/* returns the bitrate for a given logical bitstream or the entire
+ physical bitstream. If the file is open for random access, it will
+ find the *actual* average bitrate. If the file is streaming, it
+ returns the nominal bitrate (if set) else the average of the
+ upper/lower bounds (if set) else -1 (unset).
+
+ If you want the actual bitrate field settings, get them from the
+ vorbis_info structs */
+
+long ov_bitrate(OggVorbis_File *vf,int i){
+ if(i>=vf->links)return(-1);
+ if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
+ if(i<0){
+ ogg_int64_t bits=0;
+ int i;
+ for(i=0;i<vf->links;i++)
+ bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
+ return(rint(bits/ov_time_total(vf,-1)));
+ }else{
+ if(vf->seekable){
+ /* return the actual bitrate */
+ return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
+ }else{
+ /* return nominal if set */
+ if(vf->vi[i].bitrate_nominal>0){
+ return vf->vi[i].bitrate_nominal;
+ }else{
+ if(vf->vi[i].bitrate_upper>0){
+ if(vf->vi[i].bitrate_lower>0){
+ return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
+ }else{
+ return vf->vi[i].bitrate_upper;
+ }
+ }
+ return(-1);
+ }
+ }
+ }
+}
+
+/* returns the actual bitrate since last call. returns -1 if no
+ additional data to offer since last call (or at beginning of stream) */
+long ov_bitrate_instant(OggVorbis_File *vf){
+ int link=(vf->seekable?vf->current_link:0);
+ long ret;
+ if(vf->samptrack==0)return(-1);
+ ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
+ vf->bittrack=0.;
+ vf->samptrack=0.;
+ return(ret);
+}
+
+/* Guess */
+long ov_serialnumber(OggVorbis_File *vf,int i){
+ if(i>=vf->links)return(-1);
+ if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
+ if(i<0){
+ return(vf->current_serialno);
+ }else{
+ return(vf->serialnos[i]);
+ }
+}
+
+/* returns: total raw (compressed) length of content if i==-1
+ raw (compressed) length of that logical bitstream for i==0 to n
+ -1 if the stream is not seekable (we can't know the length)
+*/
+ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
+ if(!vf->seekable || i>=vf->links)return(-1);
+ if(i<0){
+ long acc=0;
+ int i;
+ for(i=0;i<vf->links;i++)
+ acc+=ov_raw_total(vf,i);
+ return(acc);
+ }else{
+ return(vf->offsets[i+1]-vf->offsets[i]);
+ }
+}
+
+/* returns: total PCM length (samples) of content if i==-1
+ PCM length (samples) of that logical bitstream for i==0 to n
+ -1 if the stream is not seekable (we can't know the length)
+*/
+ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
+ if(!vf->seekable || i>=vf->links)return(-1);
+ if(i<0){
+ ogg_int64_t acc=0;
+ int i;
+ for(i=0;i<vf->links;i++)
+ acc+=ov_pcm_total(vf,i);
+ return(acc);
+ }else{
+ return(vf->pcmlengths[i]);
+ }
+}
+
+/* returns: total seconds of content if i==-1
+ seconds in that logical bitstream for i==0 to n
+ -1 if the stream is not seekable (we can't know the length)
+*/
+double ov_time_total(OggVorbis_File *vf,int i){
+ if(!vf->seekable || i>=vf->links)return(-1);
+ if(i<0){
+ double acc=0;
+ int i;
+ for(i=0;i<vf->links;i++)
+ acc+=ov_time_total(vf,i);
+ return(acc);
+ }else{
+ return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
+ }
+}
+
+/* seek to an offset relative to the *compressed* data. This also
+ immediately sucks in and decodes pages to update the PCM cursor. It
+ will cross a logical bitstream boundary, but only if it can't get
+ any packets out of the tail of the bitstream we seek to (so no
+ surprises).
+
+ returns zero on success, nonzero on failure */
+
+int ov_raw_seek(OggVorbis_File *vf,long pos){
+
+ if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
+ if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
+
+ /* clear out decoding machine state */
+ vf->pcm_offset=-1;
+ _decode_clear(vf);
+
+ /* seek */
+ _seek_helper(vf,pos);
+
+ /* we need to make sure the pcm_offset is set. We use the
+ _fetch_packet helper to process one packet with readp set, then
+ call it until it returns '0' with readp not set (the last packet
+ from a page has the 'frameno' field set, and that's how the
+ helper updates the offset */
+
+ switch(_process_packet(vf,1)){
+ case 0:
+ /* oh, eof. There are no packets remaining. Set the pcm offset to
+ the end of file */
+ vf->pcm_offset=ov_pcm_total(vf,-1);
+ return(0);
+ case -1:
+ /* error! missing data or invalid bitstream structure */
+ goto seek_error;
+ default:
+ /* all OK */
+ break;
+ }
+
+ while(1){
+ switch(_process_packet(vf,0)){
+ case 0:
+ /* the offset is set. If it's a bogus bitstream with no offset
+ information, it's not but that's not our fault. We still run
+ gracefully, we're just missing the offset */
+ return(0);
+ case -1:
+ /* error! missing data or invalid bitstream structure */
+ goto seek_error;
+ default:
+ /* continue processing packets */
+ break;
+ }
+ }
+
+ seek_error:
+ /* dump the machine so we're in a known state */
+ vf->pcm_offset=-1;
+ _decode_clear(vf);
+ return -1;
+}
+
+/* seek to a sample offset relative to the decompressed pcm stream
+
+ returns zero on success, nonzero on failure */
+
+int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+ int link=-1;
+ ogg_int64_t total=ov_pcm_total(vf,-1);
+
+ if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
+ if(pos<0 || pos>total)goto seek_error;
+
+ /* which bitstream section does this pcm offset occur in? */
+ for(link=vf->links-1;link>=0;link--){
+ total-=vf->pcmlengths[link];
+ if(pos>=total)break;
+ }
+
+ /* search within the logical bitstream for the page with the highest
+ pcm_pos preceeding (or equal to) pos. There is a danger here;
+ missing pages or incorrect frame number information in the
+ bitstream could make our task impossible. Account for that (it
+ would be an error condition) */
+ {
+ ogg_int64_t target=pos-total;
+ long end=vf->offsets[link+1];
+ long begin=vf->offsets[link];
+ long best=begin;
+
+ ogg_page og;
+ while(begin<end){
+ long bisect;
+ long ret;
+
+ if(end-begin<CHUNKSIZE){
+ bisect=begin;
+ }else{
+ bisect=(end+begin)/2;
+ }
+
+ _seek_helper(vf,bisect);
+ ret=_get_next_page(vf,&og,end-bisect);
+
+ if(ret==-1){
+ end=bisect;
+ }else{
+ ogg_int64_t frameno=ogg_page_frameno(&og);
+ if(frameno<target){
+ best=ret; /* raw offset of packet with frameno */
+ begin=vf->offset; /* raw offset of next packet */
+ }else{
+ end=bisect;
+ }
+ }
+ }
+
+ /* found our page. seek to it (call raw_seek). */
+
+ if(ov_raw_seek(vf,best))goto seek_error;
+ }
+
+ /* verify result */
+ if(vf->pcm_offset>=pos)goto seek_error;
+ if(pos>ov_pcm_total(vf,-1))goto seek_error;
+
+ /* discard samples until we reach the desired position. Crossing a
+ logical bitstream boundary with abandon is OK. */
+ while(vf->pcm_offset<pos){
+ double **pcm;
+ long target=pos-vf->pcm_offset;
+ long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
+
+ if(samples>target)samples=target;
+ vorbis_synthesis_read(&vf->vd,samples);
+ vf->pcm_offset+=samples;
+
+ if(samples<target)
+ if(_process_packet(vf,1)==0)
+ vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
+ }
+ return 0;
+
+ seek_error:
+ /* dump machine so we're in a known state */
+ vf->pcm_offset=-1;
+ _decode_clear(vf);
+ return -1;
+}
+
+/* seek to a playback time relative to the decompressed pcm stream
+ returns zero on success, nonzero on failure */
+int ov_time_seek(OggVorbis_File *vf,double seconds){
+ /* translate time to PCM position and call ov_pcm_seek */
+
+ int link=-1;
+ ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
+ double time_total=ov_time_total(vf,-1);
+
+ if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
+ if(seconds<0 || seconds>time_total)goto seek_error;
+
+ /* which bitstream section does this time offset occur in? */
+ for(link=vf->links-1;link>=0;link--){
+ pcm_total-=vf->pcmlengths[link];
+ time_total-=ov_time_total(vf,link);
+ if(seconds>=time_total)break;
+ }
+
+ /* enough information to convert time offset to pcm offset */
+ {
+ ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
+ return(ov_pcm_seek(vf,target));
+ }
+
+ seek_error:
+ /* dump machine so we're in a known state */
+ vf->pcm_offset=-1;
+ _decode_clear(vf);
+ return -1;
+}
+
+/* tell the current stream offset cursor. Note that seek followed by
+ tell will likely not give the set offset due to caching */
+ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
+ return(vf->offset);
+}
+
+/* return PCM offset (sample) of next PCM sample to be read */
+ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
+ return(vf->pcm_offset);
+}
+
+/* return time offset (seconds) of next PCM sample to be read */
+double ov_time_tell(OggVorbis_File *vf){
+ /* translate time to PCM position and call ov_pcm_seek */
+
+ int link=-1;
+ ogg_int64_t pcm_total=0;
+ double time_total=0.;
+
+ if(vf->seekable){
+ pcm_total=ov_pcm_total(vf,-1);
+ time_total=ov_time_total(vf,-1);
+
+ /* which bitstream section does this time offset occur in? */
+ for(link=vf->links-1;link>=0;link--){
+ pcm_total-=vf->pcmlengths[link];
+ time_total-=ov_time_total(vf,link);
+ if(vf->pcm_offset>=pcm_total)break;
+ }
+ }
+
+ return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
+}
+
+/* link: -1) return the vorbis_info struct for the bitstream section
+ currently being decoded
+ 0-n) to request information for a specific bitstream section
+
+ In the case of a non-seekable bitstream, any call returns the
+ current bitstream. NULL in the case that the machine is not
+ initialized */
+
+vorbis_info *ov_info(OggVorbis_File *vf,int link){
+ if(vf->seekable){
+ if(link<0)
+ if(vf->decode_ready)
+ return vf->vi+vf->current_link;
+ else
+ return NULL;
+ else
+ if(link>=vf->links)
+ return NULL;
+ else
+ return vf->vi+link;
+ }else{
+ if(vf->decode_ready)
+ return vf->vi;
+ else
+ return NULL;
+ }
+}
+
+/* grr, strong typing, grr, no templates/inheritence, grr */
+vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
+ if(vf->seekable){
+ if(link<0)
+ if(vf->decode_ready)
+ return vf->vc+vf->current_link;
+ else
+ return NULL;
+ else
+ if(link>=vf->links)
+ return NULL;
+ else
+ return vf->vc+link;
+ }else{
+ if(vf->decode_ready)
+ return vf->vc;
+ else
+ return NULL;
+ }
+}
+
+int host_is_big_endian() {
+ short pattern = 0xbabe;
+ unsigned char *bytewise = (unsigned char *)&pattern;
+ if (bytewise[0] == 0xba) return 1;
+
+ assert(bytewise[0] == 0xbe);
+ return 0;
+}
+
+/* up to this point, everything could more or less hide the multiple
+ logical bitstream nature of chaining from the toplevel application
+ if the toplevel application didn't particularly care. However, at
+ the point that we actually read audio back, the multiple-section
+ nature must surface: Multiple bitstream sections do not necessarily
+ have to have the same number of channels or sampling rate.
+
+ ov_read returns the sequential logical bitstream number currently
+ being decoded along with the PCM data in order that the toplevel
+ application can take action on channel/sample rate changes. This
+ number will be incremented even for streamed (non-seekable) streams
+ (for seekable streams, it represents the actual logical bitstream
+ index within the physical bitstream. Note that the accessor
+ functions above are aware of this dichotomy).
+
+ input values: buffer) a buffer to hold packed PCM data for return
+ length) the byte length requested to be placed into buffer
+ bigendianp) should the data be packed LSB first (0) or
+ MSB first (1)
+ word) word size for output. currently 1 (byte) or
+ 2 (16 bit short)
+
+ return values: -1) error/hole in data
+ 0) EOF
+ n) number of bytes of PCM actually returned. The
+ below works on a packet-by-packet basis, so the
+ return length is not related to the 'length' passed
+ in, just guaranteed to fit.
+
+ *section) set to the logical bitstream number */
+
+long ov_read(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream){
+ int i,j;
+ int host_endian = host_is_big_endian();
+
+ while(1){
+ if(vf->decode_ready){
+ double **pcm;
+ long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
+ if(samples){
+ /* yay! proceed to pack data into the byte buffer */
+
+ long channels=ov_info(vf,-1)->channels;
+ long bytespersample=word * channels;
+ if(samples>length/bytespersample)samples=length/bytespersample;
+
+ /* a tight loop to pack each size */
+ {
+ int val;
+ if(word==1){
+ int off=(sgned?0:128);
+ for(j=0;j<samples;j++)
+ for(i=0;i<channels;i++){
+ val=(int)(pcm[i][j]*128. + 0.5);
+ if(val>127)val=127;
+ else if(val<-128)val=-128;
+ *buffer++=val+off;
+ }
+ }else{
+ int off=(sgned?0:32768);
+
+ if(host_endian==bigendianp){
+ if(sgned){
+ for(i=0;i<channels;i++) { /* It's faster in this order */
+ double *src=pcm[i];
+ short *dest=((short *)buffer)+i;
+ for(j=0;j<samples;j++) {
+ val=(int)(src[j]*32768. + 0.5);
+ if(val>32767)val=32767;
+ else if(val<-32768)val=-32768;
+ *dest=val;
+ dest+=channels;
+ }
+ }
+ }else{
+ for(i=0;i<channels;i++) {
+ double *src=pcm[i];
+ short *dest=((short *)buffer)+i;
+ for(j=0;j<samples;j++) {
+ val=(int)(src[j]*32768. + 0.5);
+ if(val>32767)val=32767;
+ else if(val<-32768)val=-32768;
+ *dest=val+off;
+ dest+=channels;
+ }
+ }
+ }
+ }else if(bigendianp){
+ for(j=0;j<samples;j++)
+ for(i=0;i<channels;i++){
+ val=(int)(pcm[i][j]*32768. + 0.5);
+ if(val>32767)val=32767;
+ else if(val<-32768)val=-32768;
+ val+=off;
+ *buffer++=(val>>8);
+ *buffer++=(val&0xff);
+ }
+ }else{
+ int val;
+ for(j=0;j<samples;j++)
+ for(i=0;i<channels;i++){
+ val=(int)(pcm[i][j]*32768. + 0.5);
+ if(val>32767)val=32767;
+ else if(val<-32768)val=-32768;
+ val+=off;
+ *buffer++=(val&0xff);
+ *buffer++=(val>>8);
+ }
+
+ }
+ }
+ }
+
+ vorbis_synthesis_read(&vf->vd,samples);
+ vf->pcm_offset+=samples;
+ if(bitstream)*bitstream=vf->current_link;
+ return(samples*bytespersample);
+ }
+ }
+
+ /* suck in another packet */
+ switch(_process_packet(vf,1)){
+ case 0:
+ return(0);
+ case -1:
+ return -1;
+ default:
+ break;
+ }
+ }
+}
+
+
+
+