summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Moffitt <jack@xiph.org>2000-09-27 06:21:04 +0000
committerJack Moffitt <jack@xiph.org>2000-09-27 06:21:04 +0000
commit0049026d58a1ba119069cb1c6da6382c59af1d80 (patch)
tree662d359853d16f025a6f2705beb5c3cbfcdbf15b
parentc293f43e78b2b4c9084613c6a9ef9e2ebe1849dc (diff)
downloadlibvorbis-git-0049026d58a1ba119069cb1c6da6382c59af1d80.tar.gz
merged branch_jackoggsvorbis into branch_postbeta2
svn path=/branches/branch_postbeta2/vorbis/; revision=699
-rw-r--r--.cvsignore10
-rw-r--r--Makefile.am13
-rw-r--r--Makefile.in33
-rwxr-xr-xautogen.sh47
-rw-r--r--configure.in330
-rw-r--r--doc/framing.html384
-rw-r--r--doc/oggstream.html192
-rw-r--r--doc/programming.html507
-rw-r--r--doc/stream.pngbin0 -> 2327 bytes
-rw-r--r--doc/v-comment.html194
-rw-r--r--doc/vorbis.html196
-rw-r--r--doc/vorbisword2.pngbin0 -> 1394 bytes
-rw-r--r--doc/wait.pngbin0 -> 455 bytes
-rw-r--r--doc/white-ogg.pngbin0 -> 1181 bytes
-rw-r--r--doc/white-xifish.pngbin0 -> 965 bytes
-rw-r--r--examples/.cvsignore4
-rw-r--r--examples/Makefile.in87
-rw-r--r--examples/chaining_example.c69
-rw-r--r--examples/decoder_example.c4
-rw-r--r--examples/encoder_example.c4
-rw-r--r--examples/seeking_example.c66
-rw-r--r--examples/vorbisfile_example.c91
-rw-r--r--include/.cvsignore2
-rw-r--r--include/Makefile.am5
-rw-r--r--include/vorbis/.cvsignore2
-rw-r--r--include/vorbis/Makefile.am11
-rw-r--r--include/vorbis/book/.cvsignore2
-rw-r--r--include/vorbis/book/Makefile.am30
-rw-r--r--include/vorbis/codec.h120
-rw-r--r--lib/.cvsignore6
-rw-r--r--lib/Makefile.am21
-rw-r--r--lib/analysis.c20
-rw-r--r--lib/block.c36
-rw-r--r--lib/bookinternal.h4
-rw-r--r--lib/codebook.c92
-rw-r--r--lib/envelope.c20
-rw-r--r--lib/floor0.c38
-rw-r--r--lib/framing.c1623
-rw-r--r--lib/info.c558
-rw-r--r--lib/mapping0.c25
-rw-r--r--lib/os.h (renamed from include/vorbis/os_types.h.in)59
-rw-r--r--lib/psytune.c15
-rw-r--r--lib/res0.c32
-rw-r--r--lib/scales.h6
-rw-r--r--lib/sharedbook.c4
-rw-r--r--lib/synthesis.c16
-rw-r--r--lib/vorbisfile.c30
-rw-r--r--libvorbis.spec73
48 files changed, 2847 insertions, 2234 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 00000000..0110e302
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,10 @@
+aclocal.m4
+config.h.in
+Makefile.in
+Makefile
+config.status
+libtool
+config.cache
+config.log
+configure
+*.gz
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 00000000..55efd1de
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign dist-zip
+
+SUBDIRS = lib include doc
+
+EXTRA_DIST = README COPYING todo.txt libvorbis.spec
+
+debug:
+ $(MAKE) all CFLAGS="@DEBUG@"
+
+profile:
+ $(MAKE) all CFLAGS="@PROFILE@"
diff --git a/Makefile.in b/Makefile.in
deleted file mode 100644
index 5db761bc..00000000
--- a/Makefile.in
+++ /dev/null
@@ -1,33 +0,0 @@
-# vorbis makefile configured for use with gcc on any platform
-
-# $Id: Makefile.in,v 1.11.2.1 2000/08/31 08:59:58 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@
-
-SUBDIRS = lib examples # vorbis-tools xmms vq huff kmpg
-
-# configure changes items in these, so get distclean to remove them.
-DCLEAN_DIRS = vorbis-tools xmms vq huff kmpg
-
-all debug profile selftest target clean:
- echo $(MAKECMDGOALS)
- @for dir in $(SUBDIRS); do (cd $$dir && $(MAKE) $(MFLAGS) $(MAKECMDGOALS)) || exit 1; done
- -rm -f *~
-
-distclean:
- @for dir in $(SUBDIRS) $(DCLEAN_DIRS); do (cd $$dir && $(MAKE) $(MFLAGS) $(MAKECMDGOALS)) || exit 1; done
- -rm -f Makefile config.*
-
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 00000000..1e6fa11a
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+# (basically ripped directly from enlightenment's autogen.sh)
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+cd "$srcdir"
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile libvorbis."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have automake installed to compile libvorbis."
+ echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+echo "Generating configuration files for libvorbis, please wait...."
+
+echo " aclocal $ACLOCAL_FLAGS"
+aclocal $ACLOCAL_FLAGS
+echo " autoheader"
+autoheader
+echo " automake --add-missing"
+automake --add-missing
+echo " autoconf"
+autoconf
+
+$srcdir/configure "$@" && echo
diff --git a/configure.in b/configure.in
index 67fa0821..db4c1aa5 100644
--- a/configure.in
+++ b/configure.in
@@ -1,59 +1,64 @@
-# $Id: configure.in,v 1.20.2.3 2000/09/02 05:19:24 xiphmont Exp $
+dnl Process this file with autoconf to produce a configure script
-AC_INIT(lib/mdct.c)
-#AC_CONFIG_HEADER(config.h)
+dnl ------------------------------------------------
+dnl Initialization and Versioning
+dnl ------------------------------------------------
-cp configure.guess config.guess
-cp configure.sub config.sub
+AC_INIT(lib/mdct.c)
+AM_INIT_AUTOMAKE(libvorbis,1.0.0)
-AC_CANONICAL_HOST
+dnl Library versioning
-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
+LIB_CURRENT=0
+LIB_REVISION=0
+LIB_AGE=0
+AC_SUBST(LIB_CURRENT)
+AC_SUBST(LIB_REVISION)
+AC_SUBST(LIB_AGE)
-esac
+dnl --------------------------------------------------
+dnl Check for programs
+dnl --------------------------------------------------
+dnl save $CFLAGS since AC_PROG_CC likes to insert "-g -O2"
+dnl if $CFLAGS is blank
cflags_save="$CFLAGS"
AC_PROG_CC
-# 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)
+AM_PROG_LIBTOOL
-#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 --------------------------------------------------
+dnl Additional arguments
+dnl --------------------------------------------------
+
+AC_ARG_WITH(ogg, [ --with-ogg=DIR Set where the Ogg library is located])
+
+dnl --------------------------------------------------
+dnl Set build flags based on environment
+dnl --------------------------------------------------
+
+AC_CANONICAL_HOST
dnl Set some target options
if test -z "$GCC"; then
case $host in
*-*-irix*)
+ dnl If we're on IRIX, we wanna use cc even if gcc
+ dnl is there (unless the user has overriden us)...
+ if test -z "$CC"; then
+ CC=cc
+ fi
DEBUG="-g -signed"
- OPT="-O2 -w -signed"
+ CFLAGS="-O2 -w -signed"
PROFILE="-p -g3 -O2 -signed" ;;
sparc-sun-solaris*)
DEBUG="-v -g"
- OPT="-xO4 -fast -w -fsimple -native -xcg92"
+ CFLAGS="-xO4 -fast -w -fsimple -native -xcg92"
PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" ;;
*)
DEBUG="-g"
- OPT="-O"
+ CFLAGS="-O"
PROFILE="-g -p" ;;
esac
else
@@ -61,7 +66,7 @@ else
case $host in
*86-*-linux*)
DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
- OPT="-O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char"
+ CFLAGS="-O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char"
# PROFILE="-Wall -W -pg -O20 -ffast-math -D_REENTRANT -fsigned-char -fno-inline -static"
PROFILE="-Wall -W -pg -O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char -fno-inline -static"
@@ -101,259 +106,64 @@ else
AC_MSG_WARN([********************************************************])
AC_MSG_WARN([ ])
- OPT=${OPT}" -D__NO_MATH_INLINES"
+ CFLAGS=${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"
+ CFLAGS="-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"
+ CFLAGS="-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"
+ CFLAGS="-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)
+dnl --------------------------------------------------
+dnl Check for headers
+dnl --------------------------------------------------
+AC_CHECK_HEADER(memory.h,CFLAGS="$CFLAGS -DUSE_MEMORY_H",:)
-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
+dnl --------------------------------------------------
+dnl Check for typedefs, structures, etc
+dnl --------------------------------------------------
-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
+dnl none
-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
+dnl --------------------------------------------------
+dnl Check for libraries
+dnl --------------------------------------------------
-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
+AC_CHECK_LIB(m, cos, LIBS="-lm", LIBS="")
+AC_CHECK_LIB(pthread, pthread_create, pthread_lib="-lpthread", :)
-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",:)
+dnl Check for libogg
+if test -n $with_ogg; then
+ CFLAGS="$CFLAGS -I$with_ogg/include -L$with_ogg/lib"
+fi
+AC_CHECK_LIB(ogg, oggpack_read, LIBS="$LIBS -logg", AC_MSG_ERROR([You must have libogg to compile vorbis!!!]))
-AC_C_CONST
-AC_HEADER_TIME
-AC_STRUCT_TM
+dnl --------------------------------------------------
+dnl Check for library functions
+dnl --------------------------------------------------
-AC_PROG_MAKE_SET
+AC_FUNC_ALLOCA
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)
+dnl --------------------------------------------------
+dnl Do substitutions
+dnl --------------------------------------------------
+
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 xmms/Makefile kmpg/Makefile)
-
+AC_OUTPUT(Makefile lib/Makefile doc/Makefile include/Makefile include/vorbis/Makefile include/vorbis/book/Makefile)
diff --git a/doc/framing.html b/doc/framing.html
new file mode 100644
index 00000000..51054c7d
--- /dev/null
+++ b/doc/framing.html
@@ -0,0 +1,384 @@
+<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
+<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
+<nobr><a href="vorbis.html"><img src="white-ogg.png" border=0><img
+src="vorbisword2.png" border=0></a></nobr><p>
+
+<h1><font color=#000070>
+Ogg logical bitstream framing
+</font></h1>
+
+<em>Last update to this document: July 15, 1999</em><br>
+
+<h2>Ogg bitstreams</h2>
+
+Vorbis encodes short-time blocks of PCM data into raw packets of
+bit-packed data. These raw packets may be used directly by transport
+mechanisms that provide their own framing and packet-seperation
+mechanisms (such as UDP datagrams). For stream based storage (such as
+files) and transport (such as TCP streams or pipes), Vorbis uses the
+Ogg bitstream format to provide framing/sync, sync recapture
+after error, landmarks during seeking, and enough information to
+properly seperate data back into packets at the original packet
+boundaries without relying on decoding to find packet boundaries.<p>
+
+<h2>Design constraints for Ogg bitstreams</h2>
+
+<ol><li>True streaming; we must not need to seek to build a 100%
+ complete bitstream.
+
+<li> Use no more than approximately 1-2% of bitstream bandwidth for
+ packet boundary marking, high-level framing, sync and seeking.
+
+<li> Specification of absolute position within the original sample
+ stream.
+
+<li> Simple mechanism to ease limited editing, such as a simplified
+ concatenation mechanism.
+
+<li> Detection of corruption, recapture after error and direct, random
+ access to data at arbitrary positions in the bitstream.
+</ol>
+
+<h2>Logical and Physical Bitstreams</h2>
+
+A <em>logical</em> Ogg bitstream is a contiguous stream of
+sequential pages belonging only to the logical bitstream. A
+<em>physical</em> Ogg bitstream is constructed from one or more
+than one logical Ogg bitstream (the simplest physical bitstream
+is simply a single logical bitstream). We describe below the exact
+formatting of an Ogg logical bitstream. Combining logical
+bitstreams into more complex physical bitstreams is described in the
+<a href="oggstream.html">Ogg bitstream overview</a>. The exact
+mapping of raw Vorbis packets into a valid Ogg Vorbis physical
+bitstream is described in <a href="vorbis-stream.html">Vorbis
+bitstream mapping</a>.
+
+<h2>Bitstream structure</h2>
+
+An Ogg stream is structured by dividing incoming packets into
+segments of up to 255 bytes and then wrapping a group of contiguous
+packet segments into a variable length page preceeded by a page
+header. Both the header size and page size are variable; the page
+header contains sizing information and checksum data to determine
+header/page size and data integrity.<p>
+
+The bitstream is captured (or recaptured) by looking for the beginning
+of a page, specifically the capture pattern. Once the capture pattern
+is found, the decoder verifies page sync and integrity by computing
+and comparing the checksum. At that point, the decoder can extract the
+packets themselves.<p>
+
+<h3>Packet segmentation</h3>
+
+Packets are logically divided into multiple segments before encoding
+into a page. Note that the segmentation and fragmentation process is a
+logical one; it's used to compute page header values and the original
+page data need not be disturbed, even when a packet spans page
+boundaries.<p>
+
+The raw packet is logically divided into [n] 255 byte segments and a
+last fractional segment of < 255 bytes. A packet size may well
+consist only of the trailing fractional segment, and a fractional
+segment may be zero length. These values, called "lacing values" are
+then saved and placed into the header segment table.<p>
+
+An example should make the basic concept clear:<p>
+
+<pre>
+<tt>
+raw packet:
+ ___________________________________________
+ |______________packet data__________________| 753 bytes
+
+lacing values for page header segment table: 255,255,243
+</tt>
+</pre>
+
+We simply add the lacing values for the total size; the last lacing
+value for a packet is always the value that is less than 255. Note
+that this encoding both avoids imposing a maximum packet size as well
+as imposing minimum overhead on small packets (as opposed to, eg,
+simply using two bytes at the head of every packet and having a max
+packet size of 32k. Small packets (<255, the typical case) are
+penalized with twice the segmentation overhead). Using the lacing
+values as suggested, small packets see the minimum possible
+byte-aligned overheade (1 byte) and large packets, over 512 bytes or
+so, see a fairly constant ~.5% overhead on encoding space.<p>
+
+Note that a lacing value of 255 implies that a second lacing value
+follows in the packet, and a value of < 255 marks the end of the
+packet after that many additional bytes. A packet of 255 bytes (or a
+multiple of 255 bytes) is terminated by a lacing value of 0:<p>
+
+<pre><tt>
+raw packet:
+ _______________________________
+ |________packet data____________| 255 bytes
+
+lacing values: 255, 0
+</tt></pre>
+
+Note also that a 'nil' (zero length) packet is not an error; it
+consists of nothing more than a lacing value of zero in the header.<p>
+
+<h3>Packets spanning pages</h3>
+
+Packets are not resticted to beginning and ending within a page,
+although individual segments are, by definition, required to do so.
+Packets are not restricted to a maximum size, although excessively
+large packets in the data stream are discouraged; the Ogg
+bitstream specification strongly recommends nominal page size of
+approximately 4-8kB (large packets are forseen as being useful for
+initialization data at the beginning of a logical bitstream).<p>
+
+After segmenting a packet, the encoder may decide not to place all the
+resulting segments into the current page; to do so, the encoder places
+the lacing values of the segments it wishes to belong to the current
+page into the current segment table, then finishes the page. The next
+page is begun with the first value in the segment table belonging to
+the next packet segment, thus continuing the packet (data in the
+packet body must also correspond properly to the lacing values in the
+spanned pages. The segment data in the first packet corresponding to
+the lacing values of the first page belong in that page; packet
+segments listed in the segment table of the following page must begin
+the page body of the subsequent page).<p>
+
+The last mechanic to spanning a page boundary is to set the header
+flag in the new page to indicate that the first lacing value in the
+segment table continues rather than begins a packet; a header flag of
+0x01 is set to indicate a continued packet. Although mandatory, it
+is not actually algorithmically necessary; one could inspect the
+preceeding segment table to determine if the packet is new or
+continued. Adding the information to the packet_header flag allows a
+simpler design (with no overhead) that needs only inspect the current
+page header after frame capture. This also allows faster error
+recovery in the event that the packet originates in a corrupt
+preceeding page, implying that the previous page's segment table
+cannot be trusted.<p>
+
+Note that a packet can span an arbitrary number of pages; the above
+spanning process is repeated for each spanned page boundary. Also a
+'zero termination' on a packet size that is an even multiple of 255
+must appear even if the lacing value appears in the next page as a
+zero-length continuation of the current packet. The header flag
+should be set to 0x01 to indicate that the packet spanned, even though
+the span is a nil case as far as data is concerned.<p>
+
+The encoding looks odd, but is properly optimized for speed and the
+expected case of the majority of packets being between 50 and 200
+bytes (note that it is designed such that packets of wildly different
+sizes can be handled within the model; placing packet size
+restrictions on the encoder would have only slightly simplified design
+in page generation and increased overall encoder complexity).<p>
+
+The main point behind tracking individual packets (and packet
+segments) is to allow more flexible encoding tricks that requiring
+explicit knowledge of packet size. An example is simple bandwidth
+limiting, implemented by simply truncating packets in the nominal case
+if the packet is arranged so that the least sensitive portion of the
+data comes last.<p>
+
+<h3>Page header</h3>
+
+The headering mechanism is designed to avoid copying and re-assembly
+of the packet data (ie, making the packet segmentation process a
+logical one); the header can be generated directly from incoming
+packet data. The encoder buffers packet data until it finishes a
+complete page at which point it writes the header followed by the
+buffered packet segments.<p>
+
+<h4>capture_pattern</h4>
+
+ A header begins with a capture pattern that simplifies identifying
+ pages; once the decoder has found the capture pattern it can do a more
+ intensive job of verifying that it has in fact found a page boundary
+ (as opposed to an inadvertant coincidence in the byte stream).<p>
+
+<pre><tt>
+ byte value
+
+ 0 0x4f 'O'
+ 1 0x67 'g'
+ 2 0x67 'g'
+ 3 0x53 'S'
+</tt></pre>
+
+<h4>stream_structure_version</h4>
+
+ The capture pattern is followed by the stream structure revision:
+
+<pre><tt>
+ byte value
+
+ 4 0x00
+</tt></pre>
+
+<h4>header_type_flag</h4>
+
+ The header type flag identifies this page's context in the bitstream:
+
+<pre><tt>
+ byte value
+
+ 5 bitflags: 0x01: unset = fresh packet
+ set = continued packet
+ 0x02: unset = not first page of logical bitstream
+ set = first page of logical bitstream (bos)
+ 0x04: unset = not last page of logical bitstream
+ set = last page of logical bitstream (eos)
+</tt></pre>
+
+<h4>PCM absolute position</h4>
+
+ (This is packed in the same way the rest of Ogg data is packed;
+ LSb of LSB first. Note that the 'position' data specifies a 'sample'
+ number (eg, in a CD quality sample is four octets, 16 bits for left
+ and 16 bits for right; in video it would be the frame number). The
+ position specified is the total samples encoded after including all
+ packets finished on this page (packets begun on this page but
+ continuing on to thenext page do not count). The rationale here is
+ that the position specified in the frame header of the last page
+ tells how long the PCM data coded by the bitstream is. A truncated
+ stream will still return the proper number of samples that can be
+ decoded fully.
+
+<pre><tt>
+ byte value
+
+ 6 0xXX LSB
+ 7 0xXX
+ 8 0xXX
+ 9 0xXX
+ 10 0xXX
+ 11 0xXX
+ 12 0xXX
+ 13 0xXX MSB
+</tt></pre>
+
+<h4>stream serial number</h4>
+
+ Ogg allows for seperate logical bitstreams to be mixed at page
+ granularity in a physical bitstream. The most common case would be
+ sequential arrangement, but it is possible to interleave pages for
+ two seperate bitstreams to be decoded concurrently. The serial
+ number is the means by which pages physical pages are associated with
+ a particular logical stream. Each logical stream must have a unique
+ serial number within a physical stream:
+
+<pre><tt>
+ byte value
+
+ 14 0xXX LSB
+ 15 0xXX
+ 16 0xXX
+ 17 0xXX MSB
+</tt></pre>
+
+<h4>page sequence no</h4>
+
+ Page counter; lets us know if a page is lost (useful where packets
+ span page boundaries).
+
+<pre><tt>
+ byte value
+
+ 18 0xXX LSB
+ 19 0xXX
+ 20 0xXX
+ 21 0xXX MSB
+</tt></pre>
+
+<h4>page checksum</h4>
+
+ 32 bit CRC value (direct algorithm, initial val and final XOR = 0,
+ generator polynomial=0x04c11db7). The value is computed over the
+ entire header (with the CRC field in the header set to zero) and then
+ continued over the page. The CRC field is then filled with the
+ computed value.<p>
+
+ (A thorough discussion of CRC algorithms can be found in <a
+ href="ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt">"A
+ Painless Guide to CRC Error Detection Algorithms"</a> by Ross
+ Williams <a
+ href="mailto:ross@guest.adelaide.edu.au">ross@guest.adelaide.edu.au</a>.)
+
+<pre><tt>
+ byte value
+
+ 22 0xXX LSB
+ 23 0xXX
+ 24 0xXX
+ 25 0xXX MSB
+</tt></pre>
+
+<h4>page_segments</h4>
+
+ The number of segment entries to appear in the segment table. The
+ maximum number of 255 segments (255 bytes each) sets the maximum
+ possible physical page size at 65307 bytes or just under 64kB (thus
+ we know that a header corrupted so as destroy sizing/alignment
+ information will not cause a runaway bitstream. We'll read in the
+ page according to the corrupted size information that's guaranteed to
+ be a reasonable size regardless, notice the checksum mismatch, drop
+ sync and then look for recapture).<p>
+
+<pre><tt>
+ byte value
+
+ 26 0x00-0xff (0-255)
+</tt></pre>
+
+<h4>segment_table (containing packet lacing values)</h4>
+
+ The lacing values for each packet segment physically appearing in
+ this page are listed in contiguous order.
+
+<pre><tt>
+ byte value
+
+ 27 0x00-0xff (0-255)
+ [...]
+ n 0x00-0xff (0-255, n=page_segments+26)
+</tt></pre>
+
+Total page size is calculated directly from the known header size and
+lacing values in the segment table. Packet data segments follow
+immediately after the header.<p>
+
+Page headers typically impose a flat .25-.5% space overhead assuming
+nominal ~8k page sizes. The segmentation table needed for exact
+packet recovery in the streaming layer adds approximately .5-1%
+nominal assuming expected encoder behavior in the 44.1kHz, 128kbps
+stereo encodings.<p>
+
+<hr>
+<a href="http://www.xiph.org/">
+<img src="white-xifish.png" align=left border=0>
+</a>
+<font size=-2 color=#505050>
+
+Ogg is a <a href="http://www.xiph.org">Xiphophorus</a> effort to
+protect essential tenets of Internet multimedia from corporate
+hostage-taking; Open Source is the net's greatest tool to keep
+everyone honest. See <a href="http://www.xiph.org/about.html">About
+Xiphophorus</a> for details.
+<p>
+
+Ogg Vorbis is the first Ogg audio CODEC. Anyone may
+freely use and distribute the Ogg and Vorbis specification,
+whether in a private, public or corporate capacity. However,
+Xiphophorus and the Ogg project (xiph.org) reserve the right to set
+the Ogg/Vorbis specification and certify specification compliance.<p>
+
+Xiphophorus's Vorbis software CODEC implementation is distributed
+under the Lessr/Library GNU Public License. This does not restrict
+third parties from distributing independent implementations of Vorbis
+software under other licenses.<p>
+
+OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of
+<a href="http://www.xiph.org/">Xiphophorus</a>. These pages are
+copyright (C) 1994-2000 Xiphophorus. All rights reserved.<p>
+
+</body>
+
+
diff --git a/doc/oggstream.html b/doc/oggstream.html
new file mode 100644
index 00000000..46a221c8
--- /dev/null
+++ b/doc/oggstream.html
@@ -0,0 +1,192 @@
+<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
+<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
+<nobr><a href="vorbis.html"><img src="white-ogg.png" border=0><img
+src="vorbisword2.png" border=0></a></nobr><p>
+
+
+<h1><font color=#000070>
+Ogg logical and physical bitstream overview
+</font></h1>
+
+<em>Last update to this document: July 18, 1999</em><br>
+
+<h2>Ogg bitstreams</h2>
+
+Ogg codecs use octet vectors of raw, compressed data
+(<em>packets</em>). These compressed packets do not have any
+high-level structure or boundary information; strung together, they
+appear to be streams of random bytes with no landmarks.<p>
+
+Raw packets may be used directly by transport mechanisms that provide
+their own framing and packet-seperation mechanisms (such as UDP
+datagrams). For stream based storage (such as files) and transport
+(such as TCP streams or pipes), Vorbis and other future Ogg codecs use
+the Ogg bitstream format to provide framing/sync, sync recapture
+after error, landmarks during seeking, and enough information to
+properly seperate data back into packets at the original packet
+boundaries without relying on decoding to find packet boundaries.<p>
+
+<h2>Logical and physical bitstreams</h2>
+
+Raw packets are grouped and encoded into contiguous pages of
+structured bitstream data called <em>logical bitstreams</em>. A
+logical bitstream consists of pages, in order, belonging to a single
+codec instance. Each page is a self contained entity (although it is
+possible that a packet may be split and encoded across one or more
+pages); that is, the page decode mechanism is designed to recognize,
+verify and handle single pages at a time from the overall bitstream.<p>
+
+Multiple logical bitstreams can be combined (with restricctions) into
+a single <em>physical bitstream</em>. A physical bitstream consists
+of multiple logical bitstreams multiplexed at the page level. Whole
+pages are taken in order from multiple logical bitstreams and combined
+into a single physical stream of pages. The decoder reconstructs the
+original logical bitstreams from the physical bitstream by taking the
+pages in order fromt he physical bitstream and redirecting them into
+the appropriate logical decoding entitiy. The simplest physical
+bitstream is a single, unmultiplexed logical bitstream. <p>
+
+<a href=framing.html>Ogg Logical Bitstream Framing</a> discusses
+the page format of an Ogg bitstream, the packet coding process
+and logical bitstreams in detail. The remainder of this document
+specifies requirements for constructing finished, physical Ogg
+bitstreams.<p>
+
+<h2>Mapping Restrictions</h2>
+
+Logical bitstreams may not be mapped/multiplexed into physical
+bitstreams without restriction. Here we discuss design restrictions
+on Ogg physical bitstreams in general, mostly to introduce
+design rationale. Each 'media' format defines its own (generally more
+restrictive) mapping. An '<a href="vorbis-stream.html">Ogg Vorbis
+Audio Bitstream</a>', for example, has a <a
+href="vorbis-stream.html">specific physical bitstream structure</a>.
+An 'Ogg A/V' bitstream (not currently specified) will also mandate a
+specific, restricted physical bitstream format.<p>
+
+<h3>additional end-to-end structure</h3>
+
+The <a href="framing.html">framing specification</a> defines
+'beginning of stream' and 'end of stream' page markers via a header
+flag (it is possible for a stream to consist of a single page). A
+stream always consists of an integer number of pages, an easy
+requirement given the variable size nature of pages.<p>
+
+In addition to the header flag marking the first and last pages of a
+logical bitstream, the first page of an Ogg bitstream obeys
+additional restrictions. Each individual media mapping specifies its
+own implementation details regarding these restrictions.<p>
+
+The first page of a logical Ogg bitstream consists of a single,
+small 'initial header' packet that includes sufficient information to
+identify the exact CODEC type and media requirements of the logical
+bitstream. The intent of this restriction is to simplify identifying
+the bitstream type and content; for a given media type (or across all
+Ogg media types) we can know that we only need a small, fixed
+amount of data to uniquely identify the bitstream type.<p>
+
+As an example, Ogg Vorbis places the name and revision of the Vorbis
+CODEC, the audio rate and the audio quality into this initial header,
+thus simplifying vastly the certain identification of an Ogg Vorbis
+audio bitstream.<p>
+
+<h3>sequential multiplexing (chaining)</h3>
+
+The simplest form of logical bitstream multiplexing is concatenation
+(<em>chaining</em>). Complete logical bitstreams are strung
+one-after-another in order. The bitstreams do not overlap; the final
+page of a given logical bitstream is immediately followed by the
+initial page of the next. Chaining is the only logical->physical
+mapping allowed by Ogg Vorbis.<p>
+
+Each chained logical bitstream must have a unique serial number within
+the scope of the physical bitstream.<p>
+
+<h3>concurrent multiplexing (grouping)</h3>
+
+Logical bitstreams may also be multiplexed 'in parallel'
+(<em>grouped</em>). An example of grouping would be to allow
+streaming of seperate audio and video streams, using differnt codecs
+and different logical bitstreams, in the same physical bitstream.
+Whole pages from multiple logical bitstreams are mixed together.<p>
+
+The initial pages of each logical bitstream must appear first; the
+media mapping specifies the order of the initial pages. For example,
+Ogg A/V will eventually specify an Ogg video bitstream with
+audio. The mapping may specify that the physical bitstream must begin
+with the initial page of a logical video bitstream, followed by the
+initial page of an audio stream. Unlike initial pages, terminal pages
+for the logical bitstreams need not all occur contiguously (although a
+specific media mapping may require this; it is not mandated by the
+generic Ogg stream spec). Terminal pages may be 'nil' pages,
+that is, pages containing no content but simply a page header with
+position information and the 'last page of bitstream' flag set in the
+page header.<p>
+
+Each grouped bitstream must have a unique serial number within the
+scope of the physical bitstream.<p>
+
+<h3>sequential and concurrent multiplexing</h3>
+
+Groups of concurrently multiplexed bitstreams may be chained
+consecutively. Such a physical bitstream obeys all the rules of both
+grouped and chained multiplexed streams; the groups, when unchained ,
+must stand on their own as a valid concurrently multiplexed
+bitstream.<p>
+
+<h3>multiplexing example</h3>
+
+Below, we present an example of a grouped and chained bitstream:<p>
+
+<img src=stream.png><p>
+
+In this example, we see pages from five total logical bitstreams
+multiplexed into a physical bitstream. Note the following
+characteristics:
+
+<ol><li>Grouped bitstreams begin together; all of the initial pages
+must appear before any data pages. When concurrently multiplexed
+groups are chained, the new group does not begin until all the
+bitstreams in the previous group have terminated.<p>
+
+<li>The pages of concurrently multiplexed bitstreams need not conform
+to a regular order; the only requirement is that page <tt>n</tt> of a
+logical bitstream follow page <tt>n-1</tt> in the physical bitstream.
+There are no restrictions on intervening pages belonging to other
+logical bitstreams. (Tying page appearence to bitrate demands is one
+logical strategy, ie, the page appears at the chronological point
+where decode requires more information).
+
+</ol>
+
+<hr>
+<a href="http://www.xiph.org/">
+<img src="white-xifish.png" align=left border=0>
+</a>
+<font size=-2 color=#505050>
+
+Ogg is a <a href="http://www.xiph.org">Xiphophorus</a> effort to
+protect essential tenets of Internet multimedia from corporate
+hostage-taking; Open Source is the net's greatest tool to keep
+everyone honest. See <a href="http://www.xiph.org/about.html">About
+Xiphophorus</a> for details.
+<p>
+
+Ogg Vorbis is the first Ogg audio CODEC. Anyone may
+freely use and distribute the Ogg and Vorbis specification,
+whether in a private, public or corporate capacity. However,
+Xiphophorus and the Ogg project (xiph.org) reserve the right to set
+the Ogg/Vorbis specification and certify specification compliance.<p>
+
+Xiphophorus's Vorbis software CODEC implementation is distributed
+under the Lesser/Library GNU Public License. This does not restrict
+third parties from distributing independent implementations of Vorbis
+software under other licenses.<p>
+
+OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of
+<a href="http://www.xiph.org/">Xiphophorus</a>. These pages are
+copyright (C) 1994-2000 Xiphophorus. All rights reserved.<p>
+
+</body>
+
+
diff --git a/doc/programming.html b/doc/programming.html
new file mode 100644
index 00000000..7f6e62fe
--- /dev/null
+++ b/doc/programming.html
@@ -0,0 +1,507 @@
+<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
+<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
+<nobr><img src="white-ogg.png"><img src="vorbisword2.png"></nobr><p>
+
+
+<h1><font color=#000070>
+Programming with Xiphophorus <tt>libvorbis</tt>
+</font></h1>
+
+<em>Last update to this document: July 22, 1999</em><br>
+
+<h2>Description</h2>
+
+Libvorbis is Xiphophorus's portable Ogg Vorbis CODEC implemented as a
+programmatic library. Libvorbis provides primitives to handle framing
+and manipulation of Ogg bitstreams (used by the Vorbis for
+streaming), a full analysis (encoding) interface as well as packet
+decoding and synthesis for playback. <p>
+
+The libvorbis library does not provide any system interface; a
+full-featured demonstration player included with the library
+distribtion provides example code for a variety of system interfaces
+as well as a working example of using libvorbis in production code.
+
+<h2>Encoding Overview</h2>
+
+
+
+<h2>Decoding Overview</h2>
+
+Decoding a bitstream with libvorbis follows roughly the following
+steps:
+
+<ol>
+<li>Frame the incoming bitstream into pages
+<li>Sort the pages by logical bitstream and buffer then into logical streams
+<li>Decompose the logical streams into raw packets
+<li>Reconstruct segments of the original data from each packet
+<li>Glue the reconstructed segments back into a decoded stream
+</ol>
+
+<h3>Framing</h3>
+
+An Ogg bitstream is logically arranged into pages, but to decode
+the pages, we have to find them first. The raw bitstream is first fed
+into an <tt>ogg_sync_state</tt> buffer using <tt>ogg_sync_buffer()</tt>
+and <tt>ogg_sync_wrote()</tt>. After each block we submit to the sync
+buffer, we should check to see if we can frame and extract a complete
+page or pages using <tt>ogg_sync_pageout()</tt>. Extra pages are
+buffered; allowing them to build up in the <tt>ogg_sync_state</tt>
+buffer will eventually exhaust memory.<p>
+
+The Ogg pages returned from <tt>ogg_sync_pageout</tt> need not be
+decoded further to be used as landmarks in seeking; seeking can be
+either a rough process of simply jumping to approximately intuited
+portions of the bitstream, or it can be a precise bisection process
+that captures pages and inspects data position. When seeking,
+however, sequential multiplexing (chaining) must be accounted for;
+beginning play in a new logical bitstream requires initializing a
+synthesis engine with the headers from that bitstream. Vorbis
+bitstreams do not make use of concurent multiplexing (grouping).<p>
+
+<h3>Sorting</h3>
+
+The pages produced by <tt>ogg_sync_pageout</tt> are then sorted by
+serial number to seperate logical bitstreams. Initialize logical
+bitstream buffers (<tt>og_stream_state</tt>) using
+<tt>ogg_stream_init()</tt>. Pages are submitted to the matching
+logical bitstream buffer using <tt>ogg_stream_pagein</tt>; the serial
+number of the page and the stream buffer must match, or the page will
+be rejected. A page submitted out of sequence will simply be noted,
+and in the course of outputting packets, the hole will be flagged
+(<tt>ogg_sync_pageout</tt> and <tt>ogg_stream_packetout</tt> will
+return a negative value at positions where they had to recapture the
+stream).
+
+<h3>Extracting packets</h3>
+
+After submitting page[s] to a logical stream, read available packets
+using <tt>ogg_stream_packetout</tt>.
+
+<h3>Decoding packets</h3>
+
+<h3>Reassembling data segments</h3>
+
+
+<h2>Ogg Bitstream Manipulation Structures</h3>
+
+Two of the Ogg bitstream data structures are intended to be
+transparent to the developer; the fields should be used directly.<p>
+
+<h3>ogg_packet</h3>
+
+<pre>
+typedef struct {
+ unsigned char *packet;
+ long bytes;
+ long b_o_s;
+ long e_o_s;
+
+ size64 frameno;
+
+} ogg_packet;
+</pre>
+
+<dl>
+<dt>packet: <dd>a pointer to the byte data of the raw packet
+<dt>bytes: <dd>the size of the packet' raw data
+<dt>b_o_s: <dd>beginning of stream; nonzero if this is the first packet of
+ the logical bitstream
+<dt>e_o_s: <dd>end of stream; nonzero if this is the last packet of the
+ logical bitstream
+<dt>frameno: <dd>the absolute position of this packet in the original
+ uncompressed data stream.
+</dl>
+
+<h4>encoding notes</h4> The encoder is responsible for setting all of
+the fields of the packet to appropriate values before submission to
+<tt>ogg_stream_packetin()</tt>; however, it is noted that the value in
+<tt>b_o_s</tt> is ignored; the first page produced from a given
+<tt>ogg_stream_state</tt> structure will be stamped as the initial
+page. <tt>e_o_s</tt>, however, must be set; this is the means by
+which the stream encoding primitives handle end of stream and cleanup.
+
+<h4>decoding notes</h4><tt>ogg_stream_packetout()</tt> sets the fields
+to appropriate values. Note that frameno will be >= 0 only in the
+case that the given packet actually represents that position (ie, only
+the last packet completed on any page will have a meaningful
+<tt>frameno</tt>). Intervening frames will see <tt>frameno</tt> set
+to -1.
+
+<h3>ogg_page</h3>
+
+<pre>
+typedef struct {
+ unsigned char *header;
+ long header_len;
+ unsigned char *body;
+ long body_len;
+} ogg_page;
+</pre>
+
+<dl>
+<dt>header: <dd>pointer to the page header data
+<dt>header_len: <dd>length of the page header in bytes
+<dt>body: <dd>pointer to the page body
+<dt>body_len: <dd>length of the page body
+</dl>
+
+Note that although the <tt>header</tt> and <tt>body</tt> pointers do
+not necessarily point into a single contiguous page vector, the page
+body must immediately follow the header in the bitstream.<p>
+
+<h2>Ogg Bitstream Manipulation Functions</h3>
+
+<h3>
+int ogg_page_bos(ogg_page *og);
+</h3>
+
+Returns the 'beginning of stream' flag for the given Ogg page. The
+beginning of stream flag is set on the initial page of a logical
+bitstream.<P>
+
+Zero indicates the flag is cleared (this is not the initial page of a
+logical bitstream). Nonzero indicates the flag is set (this is the
+initial page of a logical bitstream).<p>
+
+<h3>
+int ogg_page_continued(ogg_page *og);
+</h3>
+
+Returns the 'packet continued' flag for the given Ogg page. The packet
+continued flag indicates whether or not the body data of this page
+begins with packet continued from a preceeding page.<p>
+Zero (unset) indicates that the body data begins with a new packet.
+Nonzero (set) indicates that the first packet data on the page is a
+continuation from the preceeding page.
+
+<h3>
+int ogg_page_eos(ogg_page *og);
+</h3>
+
+Returns the 'end of stream' flag for a give Ogg page. The end of page
+flag is set on the last (terminal) page of a logical bitstream.<p>
+
+Zero (unset) indicates that this is not the last page of a logical
+bitstream. Nonzero (set) indicates that this is the last page of a
+logical bitstream and that no addiitonal pages belonging to this
+bitstream may follow.<p>
+
+<h3>
+size64 ogg_page_frameno(ogg_page *og);
+</h3>
+
+Returns the position of this page as an absolute position within the
+original uncompressed data. The position, as returned, is 'frames
+encoded to date up to and including the last whole packet on this
+page'. Partial packets begun on this page but continued to the
+following page are not included. If no packet ends on this page, the
+frame position value will be equal to the frame position value of the
+preceeding page. If none of the original uncompressed data is yet
+represented in the logical bitstream (for example, the first page of a
+bitstream consists only of a header packet; this packet encodes only
+metadata), the value shall be zero.<p>
+
+The units of the framenumber are determined by media mapping. A
+vorbis audio bitstream, for example, defines one frame to be the
+channel values from a single sampling period (eg, a 16 bit stereo
+bitstream consists of two samples of two bytes for a total of four
+bytes, thus a frame would be four bytes). A video stream defines one
+frame to be a single frame of video.<p>
+
+<h3>
+int ogg_page_pageno(ogg_page *og);
+</h3>
+
+Returns the sequential page number of the given Ogg page. The first
+page in a logical bitstream is numbered zero; following pages are
+numbered in increasing monotonic order.<p>
+
+<h3>
+int ogg_page_serialno(ogg_page *og);
+</h3>
+
+Returns the serial number of the given Ogg page. The serial number is
+used as a handle to distinguish various logical bitstreams in a
+physical Ogg bitstresm. Every logical bitstream within a
+physical bitstream must use a unique (within the scope of the physical
+bitstream) serial number, which is stamped on all bitstream pages.<p>
+
+<h3>
+int ogg_page_version(ogg_page *og);
+</h3>
+
+Returns the revision of the Ogg bitstream structure of the given page.
+Currently, the only permitted number is zero. Later revisions of the
+bitstream spec will increment this version should any changes be
+incompatable.</p>
+
+<h3>
+int ogg_stream_clear(ogg_stream_state *os);
+</h3>
+
+Clears and deallocates the internal storage of the given Ogg stream.
+After clearing, the stream structure is not initialized for use;
+<tt>ogg_stream_init</tt> must be called to reinitialize for use.
+Use <tt>ogg_stream_reset</tt> to reset the stream state
+to a fresh, intiialized state.<p>
+
+<tt>ogg_stream_clear</tt> does not call <tt>free()</tt> on the pointer
+<tt>os</tt>, allowing use of this call on stream structures in static
+or automatic storage. <tt>ogg_stream_destroy</tt>is a complimentary
+function that frees the pointer as well.<p>
+
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+int ogg_stream_destroy(ogg_stream_state *os);
+</h3>
+
+Clears and deallocates the internal storage of the given Ogg stream,
+then frees the storage associated with the pointer <tt>os</tt>.<p>
+
+<tt>ogg_stream_clear</tt> does not call <tt>free()</tt> on the pointer
+<tt>os</tt>, allowing use of that call on stream structures in static
+or automatic storage.<p>
+
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+int ogg_stream_init(ogg_stream_state *os,int serialno);
+</h3>
+
+Initialize the storage associated with <tt>os</tt> for use as an Ogg
+stream. This call is used to initialize a stream for both encode and
+decode. The given serial number is the serial number that will be
+stamped on pages of the produced bitstream (during encode), or used as
+a check that pages match (during decode).<p>
+
+Returns zero on success, nonzero on failure.<p>
+
+<h3>
+int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+</h3>
+
+Used during encoding to add the given raw packet to the given Ogg
+bitstream. The contents of <tt>op</tt> are copied;
+<tt>ogg_stream_packetin</tt> does not retain any pointers into
+<tt>op</tt>'s storage. The encoding proccess buffers incoming packets
+until enough packets have been assembled to form an entire page;
+<tt>ogg_stream_pageout</tt> is used to read complete pages.<p>
+
+Returns zero on success, nonzero on failure.<p>
+
+<h3>
+int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
+</h3>
+
+Used during decoding to read raw packets from the given logical
+bitstream. <tt>ogg_stream_packetout</tt> will only return complete
+packets for which checksumming indicates no corruption. The size and
+contents of the packet exactly match those given in the encoding
+process. <p>
+
+Returns zero if the next packet is not ready to be read (not buffered
+or incomplete), positive if it returned a complete packet in
+<tt>op</tt> and negative if there is a gap, extra bytes or corruption
+at this position in the bitstream (essentially that the bitstream had
+to be recaptured). A negative value is not necessarily an error. It
+would be a common occurence when seeking, for example, which requires
+recapture of the bitstream at the position decoding continued.<p>
+
+Iff the return value is positive, <tt>ogg_stream_packetout</tt> placed
+a packet in <tt>op</tt>. The data in <t>op</tt> points to static
+storage that is valid until the next call to
+<tt>ogg_stream_pagein</tt>, <tt>ogg_stream_clear</tt>,
+<tt>ogg_stream_reset</tt>, or <tt>ogg_stream_destroy</tt>. The
+pointers are not invalidated by more calls to
+<tt>ogg_stream_packetout</tt>.<p>
+
+<h3>
+int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
+</h3>
+
+Used during decoding to buffer the given complete, pre-verified page
+for decoding into raw Ogg packets. The given page must be framed,
+normally produced by <tt>ogg_sync_pageout</tt>, and from the logical
+bitstream associated with <tt>os</tt> (the serial numbers must match).
+The contents of the given page are copied; <tt>ogg_stream_pagein</tt>
+retains no pointers into <tt>og</tt> storage.<p>
+
+Returns zero on success and non-zero on failure.<p>
+
+<h3>
+int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
+</h3>
+
+Used during encode to read complete pages from the stream buffer. The
+returned page is ready for sending out to the real world.<p>
+
+Returns zero if there is no complete page ready for reading. Returns
+nonzero when it has placed data for a complete page into
+<tt>og</tt>. Note that the storage returned in og points into internal
+storage; the pointers in <tt>og</tt> are valid until the next call to
+<tt>ogg_stream_pageout</tt>, <tt>ogg_stream_packetin</tt>,
+<tt>ogg_stream_reset</tt>, <tt>ogg_stream_clear</tt> or
+<tt>ogg_stream_destroy</tt>.
+
+<h3>
+int ogg_stream_reset(ogg_stream_state *os);
+</h3>
+
+Resets the given stream's state to that of a blank, unused stream;
+this may be used during encode or decode. <p>
+
+Note that if used during encode, it does not alter the stream's serial
+number. In addition, the next page produced during encoding will be
+marked as the 'initial' page of the logical bitstream.<p>
+
+When used during decode, this simply clears the data buffer of any
+pending pages. Beginning and end of stream cues are read from the
+bitstream and are unaffected by reset.<p>
+
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+char *ogg_sync_buffer(ogg_sync_state *oy, long size);
+</h3>
+
+This call is used to buffer a raw bitstream for framing and
+verification. <tt>ogg_sync_buffer</tt> handles stream capture and
+recapture, checksumming, and division into Ogg pages (as required by
+<tt>ogg_stream_pagein</tt>).<p>
+
+<tt>ogg_sync_buffer</tt> exposes a buffer area into which the decoder
+copies the next (up to) <tt>size</tt> bytes. We expose the buffer
+(rather than taking a buffer) in order to avoid an extra copy many
+uses; this way, for example, <tt>read()</tt> can transfer data
+directly into the stream buffer without first needing to place it in
+temporary storage.<p>
+
+Returns a pointer into <tt>oy</tt>'s internal bitstream sync buffer;
+the remaining space in the sync buffer is at least <tt>size</tt>
+bytes. The decoder need not write all of <tt>size</tt> bytes;
+<tt>ogg_sync_wrote</tt> is used to inform the engine how many bytes
+were actually written. Use of <tt>ogg_sync_wrote</tt> after writing
+into the exposed buffer is mandantory.<p>
+
+<h3>
+int ogg_sync_clear(ogg_sync_state *oy);
+</h3>
+
+<tt>ogg_sync_clear</tt>
+
+Clears and deallocates the internal storage of the given Ogg sync
+buffer. After clearing, the sync structure is not initialized for
+use; <tt>ogg_sync_init</tt> must be called to reinitialize for use.
+Use <tt>ogg_sync_reset</tt> to reset the sync state and buffer to a
+fresh, intiialized state.<p>
+
+<tt>ogg_sync_clear</tt> does not call <tt>free()</tt> on the pointer
+<tt>oy</tt>, allowing use of this call on sync structures in static
+or automatic storage. <tt>ogg_sync_destroy</tt>is a complimentary
+function that frees the pointer as well.<p>
+
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+int ogg_sync_destroy(ogg_sync_state *oy);
+</h3>
+
+Clears and deallocates the internal storage of the given Ogg sync
+buffer, then frees the storage associated with the pointer
+<tt>oy</tt>.<p>
+
+<tt>ogg_sync_clear</tt> does not call <tt>free()</tt> on the pointer
+<tt>oy</tt>, allowing use of that call on stream structures in static
+or automatic storage.<p>
+
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+int ogg_sync_init(ogg_sync_state *oy);
+</h3>
+
+Initializes the sync buffer <tt>oy</tt> for use.<p>
+Returns zero on success and non-zero on failure. This function always
+succeeds.<p>
+
+<h3>
+int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
+</h3>
+
+Reads complete, framed, verified Ogg pages from the sync buffer,
+placing the page data in <tt>og</tt>.<p>
+
+Returns zero when there's no complete pages buffered for
+retrieval. Returns negative when a loss of sync or recapture occurred
+(this is not necessarily an error; recapture would be required after
+seeking, for example). Returns positive when a page is returned in
+<tt>og</tt>. Note that the data in <tt>og</tt> points into the sync
+buffer storage; the pointers are valid until the next call to
+<tt>ogg_sync_buffer</tt>, <tt>ogg_sync_clear</tt>,
+<tt>ogg_sync_destroy</tt> or <tt>ogg_sync_reset</tt>.
+
+
+<h3>
+int ogg_sync_reset(ogg_sync_state *oy);
+</h3>
+
+<tt>ogg_sync_reset</tt> resets the sync state in <tt>oy</tt> to a
+clean, empty state. This is useful, for example, when seeking to a
+new location in a bitstream.<p>
+
+Returns zero on success, nonzero on failure.<p>
+
+<h3>
+int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
+</h3>
+
+Used to inform the sync state as to how many bytes were actually
+written into the exposed sync buffer. It must be equal to or less
+than the size of the buffer requested.<p>
+
+Returns zero on success and non-zero on failure; failure occurs only
+when the number of bytes written were larger than the buffer.<p>
+
+<hr>
+<a href="http://www.xiph.org/">
+<img src="white-xifish.png" align=left border=0>
+</a>
+<font size=-2 color=#505050>
+
+Ogg is a <a href="http://www.xiph.org">Xiphophorus</a> effort to
+protect essential tenets of Internet multimedia from corporate
+hostage-taking; Open Source is the net's greatest tool to keep
+everyone honest. See <a href="http://www.xiph.org/about.html">About
+Xiphophorus</a> for details.
+<p>
+
+Ogg Vorbis is the first Ogg audio CODEC. Anyone may
+freely use and distribute the Ogg and Vorbis specification,
+whether in a private, public or corporate capacity. However,
+Xiphophorus and the Ogg project (xiph.org) reserve the right to set
+the Ogg/Vorbis specification and certify specification compliance.<p>
+
+Xiphophorus's Vorbis software CODEC implementation is distributed
+under the Lesser/Library GNU Public License. This does not restrict
+third parties from distributing independent implementations of Vorbis
+software under other licenses.<p>
+
+OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of
+<a href="http://www.xiph.org/">Xiphophorus</a>. These pages are
+copyright (C) 1994-2000 Xiphophorus. All rights reserved.<p>
+
+</body>
+
+
+
+
+
+
diff --git a/doc/stream.png b/doc/stream.png
new file mode 100644
index 00000000..6e9dca88
--- /dev/null
+++ b/doc/stream.png
Binary files differ
diff --git a/doc/v-comment.html b/doc/v-comment.html
new file mode 100644
index 00000000..a425eb03
--- /dev/null
+++ b/doc/v-comment.html
@@ -0,0 +1,194 @@
+<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
+<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
+<nobr><img src="white-ogg.png"><img src="vorbisword2.png"></nobr><p>
+
+
+<h1><font color=#000070>
+Ogg Vorbis comment field specification
+</font></h1>
+
+<em>Last update to this document: June 16, 2000</em><p>
+
+The text comment header is the second (of three) header packets that
+begin a Vorbis bitstream. It is meant for short, text comments,
+not arbitrary metadata; arbitrary metadata belongs in a
+metadata stream (usually an XML stream type).<p>
+
+<h2>Comment use rationale</h2>
+
+
+The comment field is meant to be used much like someone jotting a
+quick note on the bottom of a CDR. It should be a little information to
+remember the disc by and explain it to others; a short, to-the-point
+text note that need not only be a couple words, but isn't going to be
+more than a short paragraph. The essentials, in other words, whatever
+they turn out to be, eg:
+
+<blockquote>
+"Honest Bob and the Factory-to-Dealer-Incentives, _I'm Still Around_,
+opening for Moxy Fruvous, 1997"
+</blockquote>
+
+<h2>Structure</h2>
+
+The comment header logically is a list of eight-bit-clean vectors; the
+number of vectors is bounded to 2^32-1 and the length of each vector
+is limited to 2^32-1 bytes. The vector length is encoded; the vector
+is not null terminated. In addition to the vector list, there is a
+single vector for vendor name (also 8 bit clean, length encoded in 32
+bits). Libvorbis currently sets the vendor string to "Xiphophorus
+libVorbis I 20000508".<p>
+
+The comment vectors are structured similarly to a UNIX environment.
+That is, comment fields consist of a field name and a field value and
+look like:
+
+<pre>
+comment[0]="ARTIST=me";
+comment[1]="TITLE=the sound of vorbis";
+</pre>
+
+<h2>Content vector format</h2>
+
+<ul>
+<li>A case-insensitive field name that may consist of ASCII 0x20 through
+0x7D, 0x3D ('=') excluded. ASCII 0x41 through 0x5A inclusive (A-Z) is
+to be considered equivalent to ASCII 0x61 through 0x7A inclusive
+(a-z).
+
+<li>The field name is immediately followed by ASCII 0x3D ('='); this
+equals sign is used to terminate the field name.
+
+<li>0x3D is followed by 8 bit clean UTF-8 field contents to the end of
+the field.
+</ul>
+
+<h3>Field names</h3>
+
+Below is a proposed, minimal list of standard filed names with a
+description of intended use. No single or group of field names is
+mandatory; a comment header may contain one, all or none of the names
+in this list.
+<dl>
+<dt>TITLE<dd>Track name
+
+<dt>VERSION<dd>The version field may be used to differentiate multiple version of the same track title in a single collection.
+
+<dt>ALBUM<dd>The collection name to which this track belongs
+
+<dt>ARTIST<dd>Track performer
+
+<dt>ORGANIZATION<dd>Name of the organization producing the track (ie,
+the 'record label')
+
+<dt>DESCRIPTION<dd>A short text description of the contents
+
+<dt>GENRE<dd>A short text indication of music genre
+
+<dt>DATE<dd>Date the track was recorded
+
+<dt>LOCATION<dd>Location where track was recorded
+
+<dt>COPYRIGHT<dd>Copyright information
+</dl>
+
+<h3>Implications</h3>
+<ul>
+<li>
+Field names should not be 'internationalized'; this is a
+concession to simplicity not an attempt to exclude the majority of
+the world that doesn't speak English. Field *contents*, however,
+are represented in UTF-8 to allow easy representation of any language.
+<li>
+We have the length of the entirety of the field and restrictions on
+the field name so that the field name is bounded in a known way. Thus
+we also have the length of the field contents.
+<li>
+Individual 'vendors' may use non-standard field names within
+reason. The proper use of comment fields should be clear through
+context at this point. Abuse will be discouraged.
+<li>
+There is no vendor-specific prefix to 'nonstandard' field names.
+Vendors should make some effort to avoid arbitrarily polluting the
+common namespace.
+<li>
+Field names are not required to be unique (occur once) within a
+comment header. As an example, assume a track was recorded by three
+well know artists; the following is permissible:
+<pre>
+ ARTIST=Dizzy Gillespie
+ ARTIST=Sonny Rollins
+ ARTIST=Sonny Stitt
+</pre>
+
+</ul>
+
+<h2>Encoding</h2>
+
+The comment header comprises the entirety of the second bitstream
+header packet. Unlike the first bitstream header packet, it is not
+generally the only packet on the second page and may not be restricted
+to within the second bitstream page. The length of the comment header
+packet is [practically] unbounded. The comment header packet is not
+optional; it must be present in the bitstream even if it is
+effectively empty.<p>
+
+The comment header is encoded as follows (as per Ogg's standard
+bitstream mapping which renders least-significant-bit of the word to be
+coded into the least significant available bit of the current
+bitstream octet first):
+
+<ol>
+<li>
+Vendor string length (32 bit unsigned quantity specifying number of octets)
+
+<li>
+Vendor string ([vendor string length] octets coded from beginning of string to end of string, not null terminated)
+
+<li>Number of comment fields (32 bit unsigned quantity specifying number of fields)
+
+<li>Comment field 0 length (if [Number of comment fields]>0; 32 bit unsigned quantity specifying number of octets)
+
+<li>
+Comment field 0 ([Comment field 0 length] octets coded from beginning of string to end of string, not null terminated)
+
+<li>Comment field 1 length (if [Number of comment fields]>1...)...
+</ol>
+
+This is actually somewhat easier to describe in code; implementation of the above can be found in vorbis/lib/info.c:_vorbis_pack_comment(),_vorbis_unpack_comment()
+
+<hr>
+<a href="http://www.xiph.org/">
+<img src="white-xifish.png" align=left border=0>
+</a>
+<font size=-2 color=#505050>
+
+Ogg is a <a href="http://www.xiph.org">Xiphophorus</a> effort to
+protect essential tenets of Internet multimedia from corporate
+hostage-taking; Open Source is the net's greatest tool to keep
+everyone honest. See <a href="http://www.xiph.org/about.html">About
+Xiphophorus</a> for details.
+<p>
+
+Ogg Vorbis is the first Ogg audio CODEC. Anyone may
+freely use and distribute the Ogg and Vorbis specification,
+whether in a private, public or corporate capacity. However,
+Xiphophorus and the Ogg project (xiph.org) reserve the right to set
+the Ogg/Vorbis specification and certify specification compliance.<p>
+
+Xiphophorus's Vorbis software CODEC implementation is distributed
+under the Lesser/Library GNU Public License. This does not restrict
+third parties from distributing independent implementations of Vorbis
+software under other licenses.<p>
+
+OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of
+<a href="http://www.xiph.org/">Xiphophorus</a>. These pages are
+copyright (C) 1994-2000 Xiphophorus. All rights reserved.<p>
+
+</body>
+
+
+
+
+
+
diff --git a/doc/vorbis.html b/doc/vorbis.html
new file mode 100644
index 00000000..27e3a5b0
--- /dev/null
+++ b/doc/vorbis.html
@@ -0,0 +1,196 @@
+<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
+<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
+<nobr><img src="white-ogg.png"><img src="vorbisword2.png"></nobr><p>
+
+
+<h1><font color=#000070>
+Ogg Vorbis encoding format documentation
+</font></h1>
+
+<em>Last update to this document: July 15, 1999</em><br>
+<em>Last update to Vorbis documentation: July 21, 1999</em><p>
+
+<table><tr><td>
+<img src=wait.png>
+</td><td valign=center>
+As of writing, not all the below document
+links are live. They will be populated as we complete the
+documents.
+</td></tr></table>
+
+<p>
+<h2>Documents</h2>
+<ul>
+<li><a href="packet.html">Vorbis packet structure</a>
+<li><a href="envelope.html">Temporal envelope shaping and blocksize</a>
+<li><a href="mdct.html">Time domain segmentation and MDCT transform</a>
+<li><a href="resolution.html">The resolution floor</a>
+<li><a href="residuals.html">MDCT-domain fine structure</a><p>
+
+<li><a href="probmodel.html">The Vorbis probability model</a>
+
+<li><a href="bitpack.html">The Vorbis bitpacker</a><p>
+
+<li><a href="oggstream.html">Ogg bitstream overview</a>
+<li><a href="framing.html">Ogg logical bitstream and framing spec</a>
+<li><a href="vorbis-stream.html">Vorbis packet->Ogg bitstream
+ mapping</a><p>
+
+<li><a href="programming.html">Programming with libvorbis</a><p>
+</ul>
+
+<h2>Description</h2>
+Ogg Vorbis is a general purpose compressed audio format
+for high quality (44.1-48.0kHz, 16+ bit, polyphonic) audio and music
+at moderate fixed and variable bitrates (40-80 kb/s/channel). This
+places Vorbis in the same class as audio representations including
+MPEG-1 audio layer 3, MPEG-4 audio (AAC and TwinVQ), and PAC.<p>
+
+Vorbis is the first of a planned family of Ogg multimedia coding
+formats being developed as part of Xiphophorus's Ogg multimedia
+project. See <a href="http://www.xiph.org/">http://www.xiph.org/</a>
+for more information.
+
+<h2>Vorbis technical documents</h2>
+
+A Vorbis encoder takes in overlapping (but contiguous) short-time
+segments of audio data. The encoder analyzes the content of the audio
+to determine an optimal compact representation; this phase of encoding
+is known as <em>analysis</em>. For each short-time block of sound,
+the encoder then packs an efficient representation of the signal, as
+determined by analysis, into a raw packet much smaller than the size
+required by the original signal; this phase is <em>coding</em>.
+Lastly, in a streaming environment, the raw packets are then
+structured into a continuous stream of octets; this last phase is
+<em>streaming</em>. Note that the stream of octets is referred to both
+as a 'byte-' and 'bit-'stream; the latter usage is acceptible as the
+stream of octets is a physical representation of a true logical
+bit-by-bit stream.<p>
+
+A Vorbis decoder performs a mirror image process of extracting the
+original sequence of raw packets from an Ogg stream (<em>stream
+decomposition</em>), reconstructing the signal representation from the
+raw data in the packet (<em>decoding</em>) and them reconstituting an
+audio signal from the decoded representation (<em>synthesis</em>).<p>
+
+The <a href="programming.html">Programming with libvorbis</a>
+documents discuss use of the reference Vorbis codec library
+(libvorbis) produced by Xiphophorus.<p>
+
+The data representations and algorithms necessary at each step to
+encode and decode Ogg Vorbis bitstreams are described by the below
+documents in sufficient detail to construct a complete Vorbis codec.
+Note that at the time of writing, Vorbis is still in a 'Request For
+Comments' stage of development; despite being in advanced stages of
+development, input from the multimedia community is welcome.<p>
+
+<h3>Vorbis analysis and synthesis</h3>
+
+Analysis begins by seperating an input audio stream into individual,
+overlapping short-time segments of audio data. These segments are
+then transformed into an alternate representation, seeking to
+represent the original signal in a more efficient form that codes into
+a smaller number of bytes. The analysis and transformation stage is
+the most complex element of producing a Vorbis bitstream.<p>
+
+The corresponding synthesis step in the decoder is simpler; there is
+no analysis to perform, merely a mechanical, deterministic
+reconstruction of the original audio data from the transform-domain
+representation.<p>
+
+<ul>
+<li><a href="packet.html">Vorbis packet structure</a>: Describes the basic analysis components necessary to produce Vorbis packets and the structure of the packet itself.
+<li><a href="envelope.html">Temporal envelope shaping and blocksize</a>: Use of temporal envelope shaping and variable blocksize to minimize time-domain energy leakage during wide dynamic range and spectral energy swings. Also discusses time-related principles of psychoacoustics.
+<li><a href="mdct.html">Time domain segmentation and MDCT transform</a>: Division of time domain data into individual overlapped, windowed short-time vectors and transformation using the MDCT
+<li><a href="resolution.html">The resolution floor</a>: Use of frequency doamin psychoacoustics, and the MDCT-domain noise, masking and resolution floors
+<li><a href="residuals.html">MDCT-domain fine structure</a>: Production, quantization and massaging of MDCT-spectrum fine structure
+</ul>
+
+<h3>Vorbis coding and decoding</h3>
+
+Coding and decoding converts the transform-domain representation of
+the original audio produced by analysis to and from a bitwise packed
+raw data packet. Coding and decoding consist of two logically
+orthogonal concepts, <em>back-end coding</em> and <em>bitpacking</em>.<p>
+
+<em>Back-end coding</em> uses a probability model to represent the raw numbers
+of the audio representation in as few physical bits as possible;
+familiar examples of back-end coding include Huffman coding and Vector
+Quantization.<p>
+
+<em>Bitpacking</em> arranges the variable sized words of the back-end
+coding into a vector of octets without wasting space. The octets
+produced by coding a single short-time audio segment is one raw Vorbis
+packet.<p>
+
+<ul>
+
+<li><a href="probmodel.html">The Vorbis probability model</a>
+
+<li><a href="bitpack.html">The Vorbis bitpacker</a>: Arrangement of
+variable bit-length words into an octet-aligned packet.
+
+</ul>
+
+<h3>Vorbis streaming and stream decomposition</h3>
+
+Vorbis packets contain the raw, bitwise-compressed representation of a
+snippet of audio. These packets contain no structure and cannot be
+strung together directly into a stream; for streamed transmission and
+storage, Vorbis packets are encoded into an Ogg bitstream.<p>
+
+<ul>
+
+<li><a href="oggstream.html">Ogg bitstream overview</a>: High-level
+description of Ogg logical bitstreams, how logical bitstreams
+(of mixed media types) can be combined into physical bitstreams, and
+restrictions on logical-to-physical mapping. Note that this document is
+not specific only to Ogg Vorbis.
+
+<li><a href="framing.html">Ogg logical bitstream and framing
+spec</a>: Low level, complete specification of Ogg logical
+bitstream pages. Note that this document is not specific only to Ogg
+Vorbis.
+
+<li><a href="vorbis-stream.html">Vorbis bitstream mapping</a>:
+Specifically describes mapping Vorbis data into an
+Ogg physical bitstream.
+
+</ul>
+
+
+<hr>
+<a href="http://www.xiph.org/">
+<img src="white-xifish.png" align=left border=0>
+</a>
+<font size=-2 color=#505050>
+
+Ogg is a <a href="http://www.xiph.org">Xiphophorus</a> effort to
+protect essential tenets of Internet multimedia from corporate
+hostage-taking; Open Source is the net's greatest tool to keep
+everyone honest. See <a href="http://www.xiph.org/about.html">About
+Xiphophorus</a> for details.
+<p>
+
+Ogg Vorbis is the first Ogg audio CODEC. Anyone may
+freely use and distribute the Ogg and Vorbis specification,
+whether in a private, public or corporate capacity. However,
+Xiphophorus and the Ogg project (xiph.org) reserve the right to set
+the Ogg/Vorbis specification and certify specification compliance.<p>
+
+Xiphophorus's Vorbis software CODEC implementation is distributed
+under the Lesser/Library GNU Public License. This does not restrict
+third parties from distributing independent implementations of Vorbis
+software under other licenses.<p>
+
+OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of
+<a href="http://www.xiph.org/">Xiphophorus</a>. These pages are
+copyright (C) 1994-2000 Xiphophorus. All rights reserved.<p>
+
+</body>
+
+
+
+
+
+
diff --git a/doc/vorbisword2.png b/doc/vorbisword2.png
new file mode 100644
index 00000000..12e3d316
--- /dev/null
+++ b/doc/vorbisword2.png
Binary files differ
diff --git a/doc/wait.png b/doc/wait.png
new file mode 100644
index 00000000..2d10af60
--- /dev/null
+++ b/doc/wait.png
Binary files differ
diff --git a/doc/white-ogg.png b/doc/white-ogg.png
new file mode 100644
index 00000000..45dc0acd
--- /dev/null
+++ b/doc/white-ogg.png
Binary files differ
diff --git a/doc/white-xifish.png b/doc/white-xifish.png
new file mode 100644
index 00000000..ab25cc8f
--- /dev/null
+++ b/doc/white-xifish.png
Binary files differ
diff --git a/examples/.cvsignore b/examples/.cvsignore
new file mode 100644
index 00000000..98db8779
--- /dev/null
+++ b/examples/.cvsignore
@@ -0,0 +1,4 @@
+encoder_example
+decoder_example
+chaining_example
+vorbisfile_example
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 00000000..ab36bd18
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,87 @@
+# vorbis makefile configured for use with gcc on any platform
+
+# $Id: Makefile.in,v 1.13.2.1 2000/09/27 06:20:54 jack 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/vorbisfile.h \
+ ../include/vorbis/backends.h \
+ ../include/vorbis/codebook.h
+OFILES = encoder_example.o decoder_example.o chaining_example.o \
+ vorbisfile_example.o seeking_test.o
+BINFILES = encoder_example decoder_example chaining_example \
+ vorbisfile_example seeking_test
+
+all:
+ $(MAKE) target CFLAGS="$(OPT)"
+
+debug:
+ $(MAKE) target CFLAGS="$(DEBUG)"
+
+profile:
+ $(MAKE) target CFLAGS="$(PROFILE)"
+
+target: $(BINFILES)
+
+encoder_example.o: ../include/vorbis/modes.h
+
+encoder_example: $(OFILES) ../lib/libvorbis.a
+ $(CC) $(CFLAGS) $(LDFLAGS) encoder_example.o ../lib/libvorbis.a -o \
+ encoder_example $(LIBS)
+
+decoder_example: $(OFILES) ../lib/libvorbis.a
+ $(CC) $(CFLAGS) $(LDFLAGS) decoder_example.o ../lib/libvorbis.a -o \
+ decoder_example $(LIBS)
+
+chaining_example: $(OFILES) ../lib/libvorbis.a ../lib/vorbisfile.a
+ $(CC) $(CFLAGS) $(LDFLAGS) chaining_example.o \
+ ../lib/vorbisfile.a ../lib/libvorbis.a \
+ -o chaining_example $(LIBS)
+vorbisfile_example: $(OFILES) ../lib/libvorbis.a ../lib/vorbisfile.a
+ $(CC) $(CFLAGS) $(LDFLAGS) vorbisfile_example.o \
+ ../lib/vorbisfile.a ../lib/libvorbis.a \
+ -o vorbisfile_example $(LIBS)
+
+seeking_test: $(OFILES) ../lib/libvorbis.a ../lib/vorbisfile.a
+ $(CC) $(CFLAGS) $(LDFLAGS) seeking_test.o \
+ ../lib/vorbisfile.a ../lib/libvorbis.a \
+ -o seeking_test $(LIBS)
+
+selftest:
+
+$(OFILES): $(HFILES)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ -rm -f *.o *.a test* *~ *.out ogg config.* \
+ encoder_example decoder_example chaining_example \
+ vorbisfile_example seeking_test
+
+distclean: clean
+ -rm -f Makefile
+
diff --git a/examples/chaining_example.c b/examples/chaining_example.c
new file mode 100644
index 00000000..a0fa24b0
--- /dev/null
+++ b/examples/chaining_example.c
@@ -0,0 +1,69 @@
+/********************************************************************
+ * *
+ * 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: illustrate simple use of chained bitstream and vorbisfile.a
+ last mod: $Id: chaining_example.c,v 1.5.6.1 2000/09/27 06:20:54 jack Exp $
+
+ ********************************************************************/
+
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+int main(){
+ OggVorbis_File ov;
+ int i;
+
+ /* open the file/pipe on stdin */
+ if(ov_open(stdin,&ov,NULL,-1)==-1){
+ printf("Could not open input as an OggVorbis file.\n\n");
+ exit(1);
+ }
+
+ /* print details about each logical bitstream in the input */
+ if(ov_seekable(&ov)){
+ printf("Input bitstream contained %ld logical bitstream section(s).\n",
+ ov_streams(&ov));
+ printf("Total bitstream playing time: %ld seconds\n\n",
+ (long)ov_time_total(&ov,-1));
+
+ }else{
+ printf("Standard input was not seekable.\n"
+ "First logical bitstream information:\n\n");
+ }
+
+ for(i=0;i<ov_streams(&ov);i++){
+ vorbis_info *vi=ov_info(&ov,i);
+ printf("\tlogical bitstream section %d information:\n",i+1);
+ printf("\t\t%ldHz %d channels bitrate %ldkbps serial number=%ld\n",
+ vi->rate,vi->channels,ov_bitrate(&ov,i)/1000,
+ ov_serialnumber(&ov,i));
+ printf("\t\tcompressed length: %ld bytes ",(long)(ov_raw_total(&ov,i)));
+ printf(" play time: %lds\n",(long)ov_time_total(&ov,i));
+ }
+
+ ov_clear(&ov);
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/decoder_example.c b/examples/decoder_example.c
index 35fb4a0d..84864710 100644
--- a/examples/decoder_example.c
+++ b/examples/decoder_example.c
@@ -12,7 +12,7 @@
********************************************************************
function: simple example decoder
- last mod: $Id: decoder_example.c,v 1.11.2.3 2000/09/02 05:19:24 xiphmont Exp $
+ last mod: $Id: decoder_example.c,v 1.11.2.4 2000/09/27 06:20:54 jack Exp $
********************************************************************/
@@ -25,7 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
-#include "vorbis/codec.h"
+#include <vorbis/codec.h>
#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
#include <io.h>
diff --git a/examples/encoder_example.c b/examples/encoder_example.c
index 42876098..0d6eb818 100644
--- a/examples/encoder_example.c
+++ b/examples/encoder_example.c
@@ -12,7 +12,7 @@
********************************************************************
function: simple example encoder
- last mod: $Id: encoder_example.c,v 1.13.2.2 2000/09/06 13:28:33 msmith Exp $
+ last mod: $Id: encoder_example.c,v 1.13.2.3 2000/09/27 06:20:54 jack Exp $
********************************************************************/
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <time.h>
#include <math.h>
-#include "vorbis/mode_C.h"
+#include <vorbis/mode_C.h>
#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
#include <io.h>
diff --git a/examples/seeking_example.c b/examples/seeking_example.c
new file mode 100644
index 00000000..c1df857d
--- /dev/null
+++ b/examples/seeking_example.c
@@ -0,0 +1,66 @@
+/********************************************************************
+ * *
+ * 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: illustrate seeking, and test it too
+ last mod: $Id: seeking_example.c,v 1.3.4.1 2000/09/27 06:20:54 jack Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "vorbis/vorbisfile.h"
+#include "../lib/misc.h"
+
+int main(){
+ OggVorbis_File ov;
+ int i;
+
+ /* open the file/pipe on stdin */
+ if(ov_open(stdin,&ov,NULL,-1)==-1){
+ printf("Could not open input as an OggVorbis file.\n\n");
+ exit(1);
+ }
+
+ /* print details about each logical bitstream in the input */
+ if(ov_seekable(&ov)){
+ double length=ov_time_total(&ov,-1);
+ printf("testing seeking to random places in %g seconds....\n",length);
+ for(i=0;i<100;i++){
+ double val=(double)rand()/RAND_MAX*length;
+ ov_time_seek(&ov,val);
+ printf("\r\t%d [%gs]... ",i,val);
+ fflush(stdout);
+ }
+
+ printf("\r \nOK.\n\n");
+ }else{
+ printf("Standard input was not seekable.\n");
+ }
+
+ ov_clear(&ov);
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/vorbisfile_example.c b/examples/vorbisfile_example.c
new file mode 100644
index 00000000..ac9e78f9
--- /dev/null
+++ b/examples/vorbisfile_example.c
@@ -0,0 +1,91 @@
+/********************************************************************
+ * *
+ * 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 using vorbisfile
+ last mod: $Id: vorbisfile_example.c,v 1.1.6.1 2000/09/27 06:20:54 jack Exp $
+
+ ********************************************************************/
+
+/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to
+ stdout using vorbisfile. Using vorbisfile is much simpler than
+ dealing with libvorbis. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+char pcmout[4096]; /* take 4k out of the data segment, not the stack */
+
+int main(int argc, char **argv){
+ OggVorbis_File vf;
+ int eof=0;
+ int current_section;
+
+#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(ov_open(stdin, &vf, NULL, 0) < 0) {
+ fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
+ exit(1);
+ }
+
+ /* Throw the comments plus a few lines about the bitstream we're
+ decoding */
+ {
+ char **ptr=ov_comment(&vf,-1)->user_comments;
+ vorbis_info *vi=ov_info(&vf,-1);
+ 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",ov_comment(&vf,-1)->vendor);
+ }
+
+ while(!eof){
+ long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,&current_section);
+ switch(ret){
+ case 0:
+ /* EOF */
+ eof=1;
+ break;
+ case -1:
+ /* error in the stream. Not a problem, just reporting it in
+ case we (the app) cares. In this case, we don't. */
+ break;
+ default:
+ /* we don't bother dealing with sample rate changes, etc, but
+ you'll have to*/
+ fwrite(pcmout,1,ret,stdout);
+ break;
+ }
+ }
+
+ /* cleanup */
+ ov_clear(&vf);
+
+ fprintf(stderr,"Done.\n");
+ return(0);
+}
+
diff --git a/include/.cvsignore b/include/.cvsignore
new file mode 100644
index 00000000..282522db
--- /dev/null
+++ b/include/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 00000000..756b65f7
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = vorbis
diff --git a/include/vorbis/.cvsignore b/include/vorbis/.cvsignore
new file mode 100644
index 00000000..282522db
--- /dev/null
+++ b/include/vorbis/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/include/vorbis/Makefile.am b/include/vorbis/Makefile.am
new file mode 100644
index 00000000..77402344
--- /dev/null
+++ b/include/vorbis/Makefile.am
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+includedir = $(prefix)/include/vorbis
+
+include_HEADERS = backends.h codec.h mode_B.h mode_D.h modes.h\
+ codebook.h mode_A.h mode_C.h mode_E.h vorbisfile.h
+
+SUBDIRS = book
+
diff --git a/include/vorbis/book/.cvsignore b/include/vorbis/book/.cvsignore
new file mode 100644
index 00000000..282522db
--- /dev/null
+++ b/include/vorbis/book/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/include/vorbis/book/Makefile.am b/include/vorbis/book/Makefile.am
new file mode 100644
index 00000000..bd7c445f
--- /dev/null
+++ b/include/vorbis/book/Makefile.am
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+includedir = $(prefix)/include/vorbis/book
+
+include_HEADERS = lsp12_0.vqh res0_1024a_192_5.vqh res0_128a_192_4.vqh \
+ lsp30_0.vqh res0_1024a_256_1.vqh res0_128a_192_5.vqh \
+ res0_1024a_128_1.vqh res0_1024a_256_2.vqh res0_128a_256_1.vqh \
+ res0_1024a_128_2.vqh res0_1024a_256_3.vqh res0_128a_256_2.vqh \
+ res0_1024a_128_3.vqh res0_1024a_256_4.vqh res0_128a_256_3.vqh \
+ res0_1024a_128_4.vqh res0_1024a_256_5.vqh res0_128a_256_4.vqh \
+ res0_1024a_128_5.vqh res0_1024a_350_1.vqh res0_128a_256_5.vqh \
+ res0_1024a_128_6.vqh res0_1024a_350_2.vqh res0_128a_350_1.vqh \
+ res0_1024a_128_7.vqh res0_1024a_350_3.vqh res0_128a_350_2.vqh \
+ res0_1024a_128_8.vqh res0_1024a_350_4.vqh res0_128a_350_3.vqh \
+ res0_1024a_128_9.vqh res0_1024a_350_5.vqh res0_128a_350_4.vqh \
+ res0_1024a_160_1.vqh res0_128a_128_1.vqh res0_128a_350_5.vqh \
+ res0_1024a_160_2.vqh res0_128a_128_2.vqh resaux0_1024a_128.vqh \
+ res0_1024a_160_3.vqh res0_128a_128_3.vqh resaux0_1024a_160.vqh \
+ res0_1024a_160_4.vqh res0_128a_128_4.vqh resaux0_1024a_192.vqh \
+ res0_1024a_160_5.vqh res0_128a_128_5.vqh resaux0_1024a_256.vqh \
+ res0_1024a_160_6.vqh res0_128a_160_1.vqh resaux0_1024a_350.vqh \
+ res0_1024a_160_7.vqh res0_128a_160_2.vqh resaux0_128a_128.vqh \
+ res0_1024a_160_8.vqh res0_128a_160_3.vqh resaux0_128a_160.vqh \
+ res0_1024a_160_9.vqh res0_128a_160_4.vqh resaux0_128a_192.vqh \
+ res0_1024a_192_1.vqh res0_128a_160_5.vqh resaux0_128a_256.vqh \
+ res0_1024a_192_2.vqh res0_128a_192_1.vqh resaux0_128a_350.vqh \
+ res0_1024a_192_3.vqh res0_128a_192_2.vqh res0_1024a_192_4.vqh \
+ res0_128a_192_3.vqh
diff --git a/include/vorbis/codec.h b/include/vorbis/codec.h
index 6a5954ee..adb128ac 100644
--- a/include/vorbis/codec.h
+++ b/include/vorbis/codec.h
@@ -12,7 +12,7 @@
********************************************************************
function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.27.2.2 2000/08/31 08:59:58 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.27.2.3 2000/09/27 06:20:56 jack Exp $
********************************************************************/
@@ -26,9 +26,8 @@ extern "C"
#define MAX_BARK 27
-#include "os_types.h"
+#include <ogg/ogg.h>
#include "vorbis/codebook.h"
-#include "vorbis/internal.h"
typedef void vorbis_look_transform;
typedef void vorbis_info_time;
@@ -150,81 +149,6 @@ typedef struct vorbis_info{
float 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 ****************************************************/
@@ -247,7 +171,7 @@ typedef struct vorbis_dsp_state{
long nW;
long centerW;
- ogg_int64_t frameno;
+ ogg_int64_t granulepos;
ogg_int64_t sequence;
ogg_int64_t glue_bits;
@@ -295,7 +219,7 @@ typedef struct vorbis_block{
int mode;
int eofflag;
- ogg_int64_t frameno;
+ ogg_int64_t granulepos;
ogg_int64_t sequence;
vorbis_dsp_state *vd; /* For read-only access of configuration */
@@ -348,42 +272,6 @@ typedef struct vorbis_comment{
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);
diff --git a/lib/.cvsignore b/lib/.cvsignore
new file mode 100644
index 00000000..0839b71d
--- /dev/null
+++ b/lib/.cvsignore
@@ -0,0 +1,6 @@
+*.la
+*.lo
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 00000000..766f88a7
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,21 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(top_srcdir)/include
+
+lib_LTLIBRARIES = libvorbis.la
+
+libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c lpc.c\
+ analysis.c synthesis.c psy.c info.c time0.c floor0.c\
+ res0.c mapping0.c registry.c codebook.c sharedbook.c\
+ iir.c vorbisfile.c\
+ envelope.h lpc.h lsp.h bookinternal.h misc.h psy.h\
+ masking.h sharedbook.h iir.h os.h
+libvorbis_la_LDFLAGS = -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@
+
+debug:
+ $(MAKE) all CFLAGS="@DEBUG@"
+
+profile:
+ $(MAKE) all CFLAGS="@PROFILE@"
diff --git a/lib/analysis.c b/lib/analysis.c
index 09f69484..81191d57 100644
--- a/lib/analysis.c
+++ b/lib/analysis.c
@@ -12,15 +12,15 @@
********************************************************************
function: single-block PCM analysis mode dispatch
- last mod: $Id: analysis.c,v 1.33.2.2 2000/09/02 09:39:19 xiphmont Exp $
+ last mod: $Id: analysis.c,v 1.33.2.3 2000/09/27 06:20:58 jack Exp $
********************************************************************/
#include <stdio.h>
#include <string.h>
#include <math.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
-#include "bitwise.h"
#include "registry.h"
#include "scales.h"
#include "os.h"
@@ -38,9 +38,9 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
vb->res_bits=0;
/* first things first. Make sure encode is ready */
- _oggpack_reset(&vb->opb);
+ oggpack_reset(&vb->opb);
/* Encode the packet type */
- _oggpack_write(&vb->opb,0,1);
+ oggpack_write(&vb->opb,0,1);
/* currently lazy. Short block dispatches to 0, long to 1. */
@@ -49,10 +49,10 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
vb->mode=mode;
/* Encode frame mode, pre,post windowsize, then dispatch */
- _oggpack_write(&vb->opb,mode,vd->modebits);
+ oggpack_write(&vb->opb,mode,vd->modebits);
if(vb->W){
- _oggpack_write(&vb->opb,vb->lW,1);
- _oggpack_write(&vb->opb,vb->nW,1);
+ oggpack_write(&vb->opb,vb->lW,1);
+ oggpack_write(&vb->opb,vb->nW,1);
fprintf(stderr,"*");
}else{
fprintf(stderr,".");
@@ -63,11 +63,11 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
/* set up the packet wrapper */
- op->packet=_oggpack_buffer(&vb->opb);
- op->bytes=_oggpack_bytes(&vb->opb);
+ op->packet=oggpack_get_buffer(&vb->opb);
+ op->bytes=oggpack_bytes(&vb->opb);
op->b_o_s=0;
op->e_o_s=vb->eofflag;
- op->frameno=vb->frameno;
+ op->granulepos=vb->granulepos;
op->packetno=vb->sequence; /* for sake of completeness */
return(0);
diff --git a/lib/block.c b/lib/block.c
index f2411e40..20d18ec7 100644
--- a/lib/block.c
+++ b/lib/block.c
@@ -12,7 +12,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.38.2.2 2000/09/02 05:19:24 xiphmont Exp $
+ last mod: $Id: block.c,v 1.38.2.3 2000/09/27 06:20:58 jack Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
@@ -26,13 +26,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
#include "window.h"
#include "envelope.h"
#include "mdct.h"
#include "lpc.h"
-#include "bitwise.h"
#include "registry.h"
#include "sharedbook.h"
#include "bookinternal.h"
@@ -98,7 +98,7 @@ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
vb->localalloc=0;
vb->localstore=NULL;
if(v->analysisp)
- _oggpack_writeinit(&vb->opb);
+ oggpack_writeinit(&vb->opb);
return(0);
}
@@ -152,7 +152,7 @@ void _vorbis_block_ripcord(vorbis_block *vb){
int vorbis_block_clear(vorbis_block *vb){
if(vb->vd)
if(vb->vd->analysisp)
- _oggpack_writeclear(&vb->opb);
+ oggpack_writeclear(&vb->opb);
_vorbis_block_ripcord(vb);
if(vb->localstore)free(vb->localstore);
@@ -512,7 +512,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
}
vb->vd=v;
vb->sequence=v->sequence;
- vb->frameno=v->frameno;
+ vb->granulepos=v->granulepos;
vb->pcmend=vi->blocksizes[v->W];
/* copy the vectors; this uses the local storage in vb */
@@ -559,12 +559,12 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
v->eofflag-=movementW;
/* do not add padding to end of stream! */
if(v->centerW>=v->eofflag){
- v->frameno+=movementW-(v->centerW-v->eofflag);
+ v->granulepos+=movementW-(v->centerW-v->eofflag);
}else{
- v->frameno+=movementW;
+ v->granulepos+=movementW;
}
}else{
- v->frameno+=movementW;
+ v->granulepos+=movementW;
}
}
@@ -578,7 +578,7 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
/* Adjust centerW to allow an easier mechanism for determining output */
v->pcm_returned=v->centerW;
v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
- v->frameno=-1;
+ v->granulepos=-1;
v->sequence=-1;
return(0);
@@ -622,7 +622,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
v->floor_bits+=vb->floor_bits;
v->res_bits+=vb->res_bits;
- if(v->sequence+1 != vb->sequence)v->frameno=-1; /* out of sequence;
+ if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
lose count */
v->sequence=vb->sequence;
@@ -673,7 +673,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
/* track the frame number... This is for convenience, but also
making sure our last packet doesn't end with added padding. If
the last packet is partial, the number of samples we'll have to
- return will be past the vb->frameno.
+ return will be past the vb->granulepos.
This is not foolproof! It will be confused if we begin
decoding at the last page after a seek or hole. In that case,
@@ -681,17 +681,17 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
is. For this reason, vorbisfile will always try to make sure
it reads the last two marked pages in proper sequence */
- if(v->frameno==-1)
- v->frameno=vb->frameno;
+ if(v->granulepos==-1)
+ v->granulepos=vb->granulepos;
else{
- v->frameno+=(centerW-v->centerW);
- if(vb->frameno!=-1 && v->frameno!=vb->frameno){
- if(v->frameno>vb->frameno && vb->eofflag){
+ v->granulepos+=(centerW-v->centerW);
+ if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
+ if(v->granulepos>vb->granulepos && vb->eofflag){
/* partial last frame. Strip the padding off */
- centerW-=(v->frameno-vb->frameno);
+ centerW-=(v->granulepos-vb->granulepos);
}/* else{ Shouldn't happen *unless* the bitstream is out of
spec. Either way, believe the bitstream } */
- v->frameno=vb->frameno;
+ v->granulepos=vb->granulepos;
}
}
diff --git a/lib/bookinternal.h b/lib/bookinternal.h
index 6f0627d2..26a26b7a 100644
--- a/lib/bookinternal.h
+++ b/lib/bookinternal.h
@@ -12,15 +12,15 @@
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: bookinternal.h,v 1.8.6.2 2000/09/02 05:19:24 xiphmont Exp $
+ last mod: $Id: bookinternal.h,v 1.8.6.3 2000/09/27 06:20:59 jack Exp $
********************************************************************/
#ifndef _V_INT_CODEBOOK_H_
#define _V_INT_CODEBOOK_H_
+#include <ogg/ogg.h>
#include "vorbis/codebook.h"
-#include "bitwise.h"
extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c);
diff --git a/lib/codebook.c b/lib/codebook.c
index 6cc1c7bb..b172d77e 100644
--- a/lib/codebook.c
+++ b/lib/codebook.c
@@ -12,16 +12,16 @@
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.17.4.3 2000/09/03 06:24:00 jack Exp $
+ last mod: $Id: codebook.c,v 1.17.4.4 2000/09/27 06:20:59 jack Exp $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
#include "vorbis/codebook.h"
-#include "bitwise.h"
#include "scales.h"
#include "sharedbook.h"
#include "bookinternal.h"
@@ -35,9 +35,9 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
int ordered=0;
/* first the basic parameters */
- _oggpack_write(opb,0x564342,24);
- _oggpack_write(opb,c->dim,16);
- _oggpack_write(opb,c->entries,24);
+ oggpack_write(opb,0x564342,24);
+ oggpack_write(opb,c->dim,16);
+ oggpack_write(opb,c->entries,24);
/* pack the codewords. There are two packings; length ordered and
length random. Decide between the two now. */
@@ -52,25 +52,25 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
deterministically */
long count=0;
- _oggpack_write(opb,1,1); /* ordered */
- _oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
+ oggpack_write(opb,1,1); /* ordered */
+ oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
for(i=1;i<c->entries;i++){
long this=c->lengthlist[i];
long last=c->lengthlist[i-1];
if(this>last){
for(j=last;j<this;j++){
- _oggpack_write(opb,i-count,_ilog(c->entries-count));
+ oggpack_write(opb,i-count,_ilog(c->entries-count));
count=i;
}
}
}
- _oggpack_write(opb,i-count,_ilog(c->entries-count));
+ oggpack_write(opb,i-count,_ilog(c->entries-count));
}else{
/* length random. Again, we don't code the codeword itself, just
the length. This time, though, we have to encode each length */
- _oggpack_write(opb,0,1); /* unordered */
+ oggpack_write(opb,0,1); /* unordered */
/* algortihmic mapping has use for 'unused entries', which we tag
here. The algorithmic mapping happens as usual, but the unused
@@ -79,17 +79,17 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
if(c->lengthlist[i]==0)break;
if(i==c->entries){
- _oggpack_write(opb,0,1); /* no unused entries */
+ oggpack_write(opb,0,1); /* no unused entries */
for(i=0;i<c->entries;i++)
- _oggpack_write(opb,c->lengthlist[i]-1,5);
+ oggpack_write(opb,c->lengthlist[i]-1,5);
}else{
- _oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
+ oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
for(i=0;i<c->entries;i++){
if(c->lengthlist[i]==0){
- _oggpack_write(opb,0,1);
+ oggpack_write(opb,0,1);
}else{
- _oggpack_write(opb,1,1);
- _oggpack_write(opb,c->lengthlist[i]-1,5);
+ oggpack_write(opb,1,1);
+ oggpack_write(opb,c->lengthlist[i]-1,5);
}
}
}
@@ -97,7 +97,7 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
/* is the entry number the desired return value, or do we have a
mapping? If we have a mapping, what type? */
- _oggpack_write(opb,c->maptype,4);
+ oggpack_write(opb,c->maptype,4);
switch(c->maptype){
case 0:
/* no mapping */
@@ -112,10 +112,10 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
}
/* values that define the dequantization */
- _oggpack_write(opb,c->q_min,32);
- _oggpack_write(opb,c->q_delta,32);
- _oggpack_write(opb,c->q_quant-1,4);
- _oggpack_write(opb,c->q_sequencep,1);
+ oggpack_write(opb,c->q_min,32);
+ oggpack_write(opb,c->q_delta,32);
+ oggpack_write(opb,c->q_quant-1,4);
+ oggpack_write(opb,c->q_sequencep,1);
{
int quantvals;
@@ -133,7 +133,7 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
/* quantized values */
for(i=0;i<quantvals;i++)
- _oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
+ oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
}
break;
@@ -152,26 +152,26 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
memset(s,0,sizeof(static_codebook));
/* make sure alignment is correct */
- if(_oggpack_read(opb,24)!=0x564342)goto _eofout;
+ if(oggpack_read(opb,24)!=0x564342)goto _eofout;
/* first the basic parameters */
- s->dim=_oggpack_read(opb,16);
- s->entries=_oggpack_read(opb,24);
+ s->dim=oggpack_read(opb,16);
+ s->entries=oggpack_read(opb,24);
if(s->entries==-1)goto _eofout;
/* codeword ordering.... length ordered or unordered? */
- switch(_oggpack_read(opb,1)){
+ switch(oggpack_read(opb,1)){
case 0:
/* unordered */
s->lengthlist=malloc(sizeof(long)*s->entries);
/* allocated but unused entries? */
- if(_oggpack_read(opb,1)){
+ if(oggpack_read(opb,1)){
/* yes, unused entries */
for(i=0;i<s->entries;i++){
- if(_oggpack_read(opb,1)){
- long num=_oggpack_read(opb,5);
+ if(oggpack_read(opb,1)){
+ long num=oggpack_read(opb,5);
if(num==-1)goto _eofout;
s->lengthlist[i]=num+1;
}else
@@ -180,7 +180,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
}else{
/* all entries used; no tagging */
for(i=0;i<s->entries;i++){
- long num=_oggpack_read(opb,5);
+ long num=oggpack_read(opb,5);
if(num==-1)goto _eofout;
s->lengthlist[i]=num+1;
}
@@ -190,11 +190,11 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
case 1:
/* ordered */
{
- long length=_oggpack_read(opb,5)+1;
+ long length=oggpack_read(opb,5)+1;
s->lengthlist=malloc(sizeof(long)*s->entries);
for(i=0;i<s->entries;){
- long num=_oggpack_read(opb,_ilog(s->entries-i));
+ long num=oggpack_read(opb,_ilog(s->entries-i));
if(num==-1)goto _eofout;
for(j=0;j<num;j++,i++)
s->lengthlist[i]=length;
@@ -208,7 +208,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
}
/* Do we have a mapping to unpack? */
- switch((s->maptype=_oggpack_read(opb,4))){
+ switch((s->maptype=oggpack_read(opb,4))){
case 0:
/* no mapping */
break;
@@ -216,10 +216,10 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
/* implicitly populated value mapping */
/* explicitly populated value mapping */
- s->q_min=_oggpack_read(opb,32);
- s->q_delta=_oggpack_read(opb,32);
- s->q_quant=_oggpack_read(opb,4)+1;
- s->q_sequencep=_oggpack_read(opb,1);
+ s->q_min=oggpack_read(opb,32);
+ s->q_delta=oggpack_read(opb,32);
+ s->q_quant=oggpack_read(opb,4)+1;
+ s->q_sequencep=oggpack_read(opb,1);
{
int quantvals;
@@ -235,7 +235,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
/* quantized values */
s->quantlist=malloc(sizeof(float)*quantvals);
for(i=0;i<quantvals;i++)
- s->quantlist[i]=_oggpack_read(opb,s->q_quant);
+ s->quantlist[i]=oggpack_read(opb,s->q_quant);
if(s->quantlist[quantvals-1]==-1)goto _eofout;
}
@@ -255,7 +255,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
/* returns the number of bits ************************************************/
int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
- _oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
+ oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
return(book->c->lengthlist[a]);
}
@@ -317,17 +317,17 @@ int vorbis_book_encodevs(codebook *book,float *a,oggpack_buffer *b,
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
long ptr=0;
decode_aux *t=book->decode_tree;
- int lok = _oggpack_look(b, t->tabn);
+ int lok = oggpack_look(b, t->tabn);
if (lok >= 0) {
ptr = t->tab[lok];
- _oggpack_adv(b, t->tabl[lok]);
+ oggpack_adv(b, t->tabl[lok]);
if (ptr <= 0)
return -ptr;
}
do{
- switch(_oggpack_read1(b)){
+ switch(oggpack_read1(b)){
case 0:
ptr=t->ptr0[ptr];
break;
@@ -495,7 +495,7 @@ int main(){
oggpack_buffer write;
oggpack_buffer read;
long ptr=0,i;
- _oggpack_writeinit(&write);
+ oggpack_writeinit(&write);
fprintf(stderr,"Testing codebook abstraction...:\n");
@@ -510,11 +510,11 @@ int main(){
fprintf(stderr,"\tpacking/coding %ld... ",ptr);
/* pack the codebook, write the testvector */
- _oggpack_reset(&write);
+ oggpack_reset(&write);
vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory
we can write */
vorbis_staticbook_pack(testlist[ptr],&write);
- fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write));
+ fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write));
for(i=0;i<TESTSIZE;i+=c.dim){
int best=_best(&c,qv+i,1);
vorbis_book_encodev(&c,best,qv+i,&write);
@@ -525,7 +525,7 @@ int main(){
fprintf(stderr,"\tunpacking/decoding %ld... ",ptr);
/* transfer the write data to a read buffer and unpack/read */
- _oggpack_readinit(&read,_oggpack_buffer(&write),_oggpack_bytes(&write));
+ oggpack_readinit(&read,oggpack_get_buffer(&write),oggpack_bytes(&write));
if(vorbis_staticbook_unpack(&read,&s)){
fprintf(stderr,"Error unpacking codebook.\n");
exit(1);
diff --git a/lib/envelope.c b/lib/envelope.c
index 1d0090a5..856f3f6c 100644
--- a/lib/envelope.c
+++ b/lib/envelope.c
@@ -12,7 +12,7 @@
********************************************************************
function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.c,v 1.21.2.2 2000/08/31 09:00:00 xiphmont Exp $
+ last mod: $Id: envelope.c,v 1.21.2.3 2000/09/27 06:20:59 jack Exp $
Preecho calculation.
@@ -22,12 +22,12 @@
#include <string.h>
#include <stdio.h>
#include <math.h>
+#include <ogg/ogg.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
@@ -115,16 +115,16 @@ static float _ve_deltai(envelope_lookup *ve,IIR_state *iir,
float *workB=alloca(sizeof(float)*n2),B=0.;
long i;
- /*_analysis_output("A",frameno,pre,n,0,0);
- _analysis_output("B",frameno,post,n,0,0);*/
+ /*_analysis_output("A",granulepos,pre,n,0,0);
+ _analysis_output("B",granulepos,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);*/
+ /*_analysis_output("Awin",granulepos,workA,n,0,0);
+ _analysis_output("Bwin",granulepos,workB,n,0,0);*/
drft_forward(&ve->drft,workA);
drft_forward(&ve->drft,workB);
@@ -140,8 +140,8 @@ static float _ve_deltai(envelope_lookup *ve,IIR_state *iir,
}
}
- /*_analysis_output("Afft",frameno,workA,n,0,0);
- _analysis_output("Bfft",frameno,workB,n,0,0);*/
+ /*_analysis_output("Afft",granulepos,workA,n,0,0);
+ _analysis_output("Bfft",granulepos,workB,n,0,0);*/
for(i=0;i<n;i++){
A+=workA[i]*workA[i];
@@ -191,10 +191,10 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
float m=_ve_deltai(ve,iir,filtered-ve->winlength,filtered);
if(m>vi->preecho_thresh){
- /*frameno++;*/
+ /*granulepos++;*/
return(0);
}
- /*frameno++;*/
+ /*granulepos++;*/
}
j+=vi->blocksizes[0]/2;
diff --git a/lib/floor0.c b/lib/floor0.c
index 731ea127..bd204815 100644
--- a/lib/floor0.c
+++ b/lib/floor0.c
@@ -12,15 +12,15 @@
********************************************************************
function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.23.2.4 2000/09/26 22:31:50 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.23.2.5 2000/09/27 06:20:59 jack Exp $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
-#include "bitwise.h"
#include "registry.h"
#include "lpc.h"
#include "lsp.h"
@@ -91,25 +91,25 @@ static void floor0_free_look(vorbis_look_floor *i){
static void floor0_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);
+ 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);
+ oggpack_write(opb,info->books[j],8);
}
static vorbis_info_floor *floor0_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;
+ 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;
@@ -117,7 +117,7 @@ static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
if(info->numbooks<1)goto err_out;
for(j=0;j<info->numbooks;j++){
- info->books[j]=_oggpack_read(opb,8);
+ info->books[j]=oggpack_read(opb,8);
if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
}
return(info);
@@ -272,7 +272,7 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
if(val<0)val=0; /* likely */
if(val>maxval)val=maxval; /* not bloody likely */
- _oggpack_write(&vb->opb,val,info->ampbits);
+ oggpack_write(&vb->opb,val,info->ampbits);
if(val>0)
amp=(float)val/maxval*info->ampdB;
else
@@ -284,7 +284,7 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
/* 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));
+ 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);
@@ -347,7 +347,7 @@ static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
vorbis_info_floor0 *info=look->vi;
int j,k;
- int ampraw=_oggpack_read(&vb->opb,info->ampbits);
+ 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;
float amp=(float)ampraw/maxval*info->ampdB;
diff --git a/lib/framing.c b/lib/framing.c
deleted file mode 100644
index 3d892fcf..00000000
--- a/lib/framing.c
+++ /dev/null
@@ -1,1623 +0,0 @@
-/********************************************************************
- * *
- * 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.2 2000/08/31 09:00:00 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/info.c b/lib/info.c
new file mode 100644
index 00000000..990691d7
--- /dev/null
+++ b/lib/info.c
@@ -0,0 +1,558 @@
+/********************************************************************
+ * *
+ * 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: maintain the info structure, info <-> header packets
+ last mod: $Id: info.c,v 1.30.2.1 2000/09/27 06:20:59 jack Exp $
+
+ ********************************************************************/
+
+/* general handling of the header and the vorbis_info structure (and
+ substructures) */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "vorbis/backends.h"
+#include "sharedbook.h"
+#include "bookinternal.h"
+#include "registry.h"
+#include "window.h"
+#include "psy.h"
+#include "misc.h"
+#include "os.h"
+
+/* helpers */
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static void _v_writestring(oggpack_buffer *o,char *s){
+ while(*s){
+ oggpack_write(o,*s++,8);
+ }
+}
+
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+ while(bytes--){
+ *buf++=oggpack_read(o,8);
+ }
+}
+
+void vorbis_comment_init(vorbis_comment *vc){
+ memset(vc,0,sizeof(vorbis_comment));
+}
+
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+ vc->user_comments=realloc(vc->user_comments,
+ (vc->comments+2)*sizeof(char *));
+ vc->comment_lengths=realloc(vc->comment_lengths,
+ (vc->comments+2)*sizeof(int));
+ vc->user_comments[vc->comments]=strdup(comment);
+ vc->comment_lengths[vc->comments]=strlen(comment);
+ vc->comments++;
+ vc->user_comments[vc->comments]=NULL;
+}
+
+void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
+ char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+ strcpy(comment, tag);
+ strcat(comment, "=");
+ strcat(comment, contents);
+ vorbis_comment_add(vc, comment);
+}
+
+/* This is more or less the same as strncasecmp - but that doesn't exist
+ * everywhere, and this is a fairly trivial function, so we include it */
+static int tagcompare(const char *s1, const char *s2, int n){
+ int c=0;
+ while(c < n){
+ if(toupper(s1[c]) != toupper(s2[c]))
+ return !0;
+ c++;
+ }
+ return 0;
+}
+
+char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
+ long i;
+ int found = 0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+ 1);
+
+ strcpy(fulltag, tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+ if(count == found)
+ /* We return a pointer to the data, not a copy */
+ return vc->user_comments[i] + taglen;
+ else
+ found++;
+ }
+ }
+ return NULL; /* didn't find anything */
+}
+
+int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
+ int i,count=0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+1);
+ strcpy(fulltag,tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+ count++;
+ }
+
+ return count;
+}
+
+void vorbis_comment_clear(vorbis_comment *vc){
+ if(vc){
+ long i;
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])free(vc->user_comments[i]);
+ if(vc->user_comments)free(vc->user_comments);
+ if(vc->comment_lengths)free(vc->comment_lengths);
+ if(vc->vendor)free(vc->vendor);
+ }
+ memset(vc,0,sizeof(vorbis_comment));
+}
+
+/* used by synthesis, which has a full, alloced vi */
+void vorbis_info_init(vorbis_info *vi){
+ memset(vi,0,sizeof(vorbis_info));
+}
+
+void vorbis_info_clear(vorbis_info *vi){
+ int i;
+
+ for(i=0;i<vi->modes;i++)
+ if(vi->mode_param[i])free(vi->mode_param[i]);
+ /*if(vi->mode_param)free(vi->mode_param);*/
+
+ for(i=0;i<vi->maps;i++) /* unpack does the range checking */
+ _mapping_P[vi->map_type[i]]->free_info(vi->map_param[i]);
+ /*if(vi->map_param)free(vi->map_param);*/
+
+ for(i=0;i<vi->times;i++) /* unpack does the range checking */
+ _time_P[vi->time_type[i]]->free_info(vi->time_param[i]);
+ /*if(vi->time_param)free(vi->time_param);*/
+
+ for(i=0;i<vi->floors;i++) /* unpack does the range checking */
+ _floor_P[vi->floor_type[i]]->free_info(vi->floor_param[i]);
+ /*if(vi->floor_param)free(vi->floor_param);*/
+
+ for(i=0;i<vi->residues;i++) /* unpack does the range checking */
+ _residue_P[vi->residue_type[i]]->free_info(vi->residue_param[i]);
+ /*if(vi->residue_param)free(vi->residue_param);*/
+
+ /* the static codebooks *are* freed if you call info_clear, because
+ decode side does alloc a 'static' codebook. Calling clear on the
+ full codebook does not clear the static codebook (that's our
+ responsibility) */
+ for(i=0;i<vi->books;i++){
+ /* just in case the decoder pre-cleared to save space */
+ if(vi->book_param[i]){
+ vorbis_staticbook_clear(vi->book_param[i]);
+ free(vi->book_param[i]);
+ }
+ }
+ /*if(vi->book_param)free(vi->book_param);*/
+
+ for(i=0;i<vi->psys;i++)
+ _vi_psy_free(vi->psy_param[i]);
+ /*if(vi->psy_param)free(vi->psy_param);*/
+
+ memset(vi,0,sizeof(vorbis_info));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+ vi->version=oggpack_read(opb,32);
+ if(vi->version!=0)return(-1);
+
+ vi->channels=oggpack_read(opb,8);
+ vi->rate=oggpack_read(opb,32);
+
+ vi->bitrate_upper=oggpack_read(opb,32);
+ vi->bitrate_nominal=oggpack_read(opb,32);
+ vi->bitrate_lower=oggpack_read(opb,32);
+
+ vi->blocksizes[0]=1<<oggpack_read(opb,4);
+ vi->blocksizes[1]=1<<oggpack_read(opb,4);
+
+ if(vi->rate<1)goto err_out;
+ if(vi->channels<1)goto err_out;
+ if(vi->blocksizes[0]<8)goto err_out;
+ if(vi->blocksizes[1]<vi->blocksizes[0])goto err_out;
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(-1);
+}
+
+static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
+ int i;
+ int vendorlen=oggpack_read(opb,32);
+ if(vendorlen<0)goto err_out;
+ vc->vendor=calloc(vendorlen+1,1);
+ _v_readstring(opb,vc->vendor,vendorlen);
+ vc->comments=oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=calloc(vc->comments+1,sizeof(char **));
+ vc->comment_lengths=calloc(vc->comments+1, sizeof(int));
+
+ for(i=0;i<vc->comments;i++){
+ int len=oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=calloc(len+1,1);
+ _v_readstring(opb,vc->user_comments[i],len);
+ }
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_comment_clear(vc);
+ return(-1);
+}
+
+/* all of the real encoding details are here. The modes, books,
+ everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+ int i;
+
+ /* codebooks */
+ vi->books=oggpack_read(opb,8)+1;
+ /*vi->book_param=calloc(vi->books,sizeof(static_codebook *));*/
+ for(i=0;i<vi->books;i++){
+ vi->book_param[i]=calloc(1,sizeof(static_codebook));
+ if(vorbis_staticbook_unpack(opb,vi->book_param[i]))goto err_out;
+ }
+
+ /* time backend settings */
+ vi->times=oggpack_read(opb,6)+1;
+ /*vi->time_type=malloc(vi->times*sizeof(int));*/
+ /*vi->time_param=calloc(vi->times,sizeof(void *));*/
+ for(i=0;i<vi->times;i++){
+ vi->time_type[i]=oggpack_read(opb,16);
+ if(vi->time_type[i]<0 || vi->time_type[i]>=VI_TIMEB)goto err_out;
+ vi->time_param[i]=_time_P[vi->time_type[i]]->unpack(vi,opb);
+ if(!vi->time_param[i])goto err_out;
+ }
+
+ /* floor backend settings */
+ vi->floors=oggpack_read(opb,6)+1;
+ /*vi->floor_type=malloc(vi->floors*sizeof(int));*/
+ /*vi->floor_param=calloc(vi->floors,sizeof(void *));*/
+ for(i=0;i<vi->floors;i++){
+ vi->floor_type[i]=oggpack_read(opb,16);
+ if(vi->floor_type[i]<0 || vi->floor_type[i]>=VI_FLOORB)goto err_out;
+ vi->floor_param[i]=_floor_P[vi->floor_type[i]]->unpack(vi,opb);
+ if(!vi->floor_param[i])goto err_out;
+ }
+
+ /* residue backend settings */
+ vi->residues=oggpack_read(opb,6)+1;
+ /*vi->residue_type=malloc(vi->residues*sizeof(int));*/
+ /*vi->residue_param=calloc(vi->residues,sizeof(void *));*/
+ for(i=0;i<vi->residues;i++){
+ vi->residue_type[i]=oggpack_read(opb,16);
+ if(vi->residue_type[i]<0 || vi->residue_type[i]>=VI_RESB)goto err_out;
+ vi->residue_param[i]=_residue_P[vi->residue_type[i]]->unpack(vi,opb);
+ if(!vi->residue_param[i])goto err_out;
+ }
+
+ /* map backend settings */
+ vi->maps=oggpack_read(opb,6)+1;
+ /*vi->map_type=malloc(vi->maps*sizeof(int));*/
+ /*vi->map_param=calloc(vi->maps,sizeof(void *));*/
+ for(i=0;i<vi->maps;i++){
+ vi->map_type[i]=oggpack_read(opb,16);
+ if(vi->map_type[i]<0 || vi->map_type[i]>=VI_MAPB)goto err_out;
+ vi->map_param[i]=_mapping_P[vi->map_type[i]]->unpack(vi,opb);
+ if(!vi->map_param[i])goto err_out;
+ }
+
+ /* mode settings */
+ vi->modes=oggpack_read(opb,6)+1;
+ /*vi->mode_param=calloc(vi->modes,sizeof(void *));*/
+ for(i=0;i<vi->modes;i++){
+ vi->mode_param[i]=calloc(1,sizeof(vorbis_info_mode));
+ vi->mode_param[i]->blockflag=oggpack_read(opb,1);
+ vi->mode_param[i]->windowtype=oggpack_read(opb,16);
+ vi->mode_param[i]->transformtype=oggpack_read(opb,16);
+ vi->mode_param[i]->mapping=oggpack_read(opb,8);
+
+ if(vi->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+ if(vi->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+ if(vi->mode_param[i]->mapping>=vi->maps)goto err_out;
+ }
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(-1);
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+ the first page that identifies basic parameters, a second packet
+ with bitstream comments and a third packet that holds the
+ codebook. */
+
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
+ oggpack_buffer opb;
+
+ if(op){
+ oggpack_readinit(&opb,op->packet,op->bytes);
+
+ /* Which of the three types of header is this? */
+ /* Also verify header-ness, vorbis */
+ {
+ char buffer[6];
+ int packtype=oggpack_read(&opb,8);
+ memset(buffer,0,6);
+ _v_readstring(&opb,buffer,6);
+ if(memcmp(buffer,"vorbis",6)){
+ /* not a vorbis header */
+ return(-1);
+ }
+ switch(packtype){
+ case 0x01: /* least significant *bit* is read first */
+ if(!op->b_o_s){
+ /* Not the initial packet */
+ return(-1);
+ }
+ if(vi->rate!=0){
+ /* previously initialized info header */
+ return(-1);
+ }
+
+ return(_vorbis_unpack_info(vi,&opb));
+
+ case 0x03: /* least significant *bit* is read first */
+ if(vi->rate==0){
+ /* um... we didn't get the initial header */
+ return(-1);
+ }
+
+ return(_vorbis_unpack_comment(vc,&opb));
+
+ case 0x05: /* least significant *bit* is read first */
+ if(vi->rate==0 || vc->vendor==NULL){
+ /* um... we didn;t get the initial header or comments yet */
+ return(-1);
+ }
+
+ return(_vorbis_unpack_books(vi,&opb));
+
+ default:
+ /* Not a valid vorbis header type */
+ return(-1);
+ break;
+ }
+ }
+ }
+ return(-1);
+}
+
+/* pack side **********************************************************/
+
+static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+ /* preamble */
+ oggpack_write(opb,0x01,8);
+ _v_writestring(opb,"vorbis");
+
+ /* basic information about the stream */
+ oggpack_write(opb,0x00,32);
+ oggpack_write(opb,vi->channels,8);
+ oggpack_write(opb,vi->rate,32);
+
+ oggpack_write(opb,vi->bitrate_upper,32);
+ oggpack_write(opb,vi->bitrate_nominal,32);
+ oggpack_write(opb,vi->bitrate_lower,32);
+
+ oggpack_write(opb,ilog2(vi->blocksizes[0]),4);
+ oggpack_write(opb,ilog2(vi->blocksizes[1]),4);
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+ char temp[]="Xiphophorus libVorbis I 20000508";
+
+ /* preamble */
+ oggpack_write(opb,0x03,8);
+ _v_writestring(opb,"vorbis");
+
+ /* vendor */
+ oggpack_write(opb,strlen(temp),32);
+ _v_writestring(opb,temp);
+
+ /* comments */
+
+ oggpack_write(opb,vc->comments,32);
+ if(vc->comments){
+ int i;
+ for(i=0;i<vc->comments;i++){
+ if(vc->user_comments[i]){
+ oggpack_write(opb,vc->comment_lengths[i],32);
+ _v_writestring(opb,vc->user_comments[i]);
+ }else{
+ oggpack_write(opb,0,32);
+ }
+ }
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+ int i;
+ oggpack_write(opb,0x05,8);
+ _v_writestring(opb,"vorbis");
+
+ /* books */
+ oggpack_write(opb,vi->books-1,8);
+ for(i=0;i<vi->books;i++)
+ if(vorbis_staticbook_pack(vi->book_param[i],opb))goto err_out;
+
+ /* times */
+ oggpack_write(opb,vi->times-1,6);
+ for(i=0;i<vi->times;i++){
+ oggpack_write(opb,vi->time_type[i],16);
+ _time_P[vi->time_type[i]]->pack(vi->time_param[i],opb);
+ }
+
+ /* floors */
+ oggpack_write(opb,vi->floors-1,6);
+ for(i=0;i<vi->floors;i++){
+ oggpack_write(opb,vi->floor_type[i],16);
+ _floor_P[vi->floor_type[i]]->pack(vi->floor_param[i],opb);
+ }
+
+ /* residues */
+ oggpack_write(opb,vi->residues-1,6);
+ for(i=0;i<vi->residues;i++){
+ oggpack_write(opb,vi->residue_type[i],16);
+ _residue_P[vi->residue_type[i]]->pack(vi->residue_param[i],opb);
+ }
+
+ /* maps */
+ oggpack_write(opb,vi->maps-1,6);
+ for(i=0;i<vi->maps;i++){
+ oggpack_write(opb,vi->map_type[i],16);
+ _mapping_P[vi->map_type[i]]->pack(vi,vi->map_param[i],opb);
+ }
+
+ /* modes */
+ oggpack_write(opb,vi->modes-1,6);
+ for(i=0;i<vi->modes;i++){
+ oggpack_write(opb,vi->mode_param[i]->blockflag,1);
+ oggpack_write(opb,vi->mode_param[i]->windowtype,16);
+ oggpack_write(opb,vi->mode_param[i]->transformtype,16);
+ oggpack_write(opb,vi->mode_param[i]->mapping,8);
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+err_out:
+ return(-1);
+}
+
+int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code){
+ vorbis_info *vi=v->vi;
+ oggpack_buffer opb;
+
+ /* first header packet **********************************************/
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_info(&opb,vi))goto err_out;
+
+ /* build the packet */
+ if(v->header)free(v->header);
+ v->header=malloc(oggpack_bytes(&opb));
+ memcpy(v->header,opb.buffer,oggpack_bytes(&opb));
+ op->packet=v->header;
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=1;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ /* second header packet (comments) **********************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_comment(&opb,vc))goto err_out;
+
+ if(v->header1)free(v->header1);
+ v->header1=malloc(oggpack_bytes(&opb));
+ memcpy(v->header1,opb.buffer,oggpack_bytes(&opb));
+ op_comm->packet=v->header1;
+ op_comm->bytes=oggpack_bytes(&opb);
+ op_comm->b_o_s=0;
+ op_comm->e_o_s=0;
+ op_comm->granulepos=0;
+
+ /* third header packet (modes/codebooks) ****************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_books(&opb,vi))goto err_out;
+
+ if(v->header2)free(v->header2);
+ v->header2=malloc(oggpack_bytes(&opb));
+ memcpy(v->header2,opb.buffer,oggpack_bytes(&opb));
+ op_code->packet=v->header2;
+ op_code->bytes=oggpack_bytes(&opb);
+ op_code->b_o_s=0;
+ op_code->e_o_s=0;
+ op_code->granulepos=0;
+
+ oggpack_writeclear(&opb);
+ return(0);
+ err_out:
+ oggpack_writeclear(&opb);
+ memset(op,0,sizeof(ogg_packet));
+ memset(op_comm,0,sizeof(ogg_packet));
+ memset(op_code,0,sizeof(ogg_packet));
+
+ if(v->header)free(v->header);
+ if(v->header1)free(v->header1);
+ if(v->header2)free(v->header2);
+ v->header=NULL;
+ v->header1=NULL;
+ v->header2=NULL;
+ return(-1);
+}
+
diff --git a/lib/mapping0.c b/lib/mapping0.c
index 0f7c050a..09ec757f 100644
--- a/lib/mapping0.c
+++ b/lib/mapping0.c
@@ -12,16 +12,16 @@
********************************************************************
function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.15.2.2 2000/09/02 05:19:25 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.15.2.3 2000/09/27 06:20:59 jack Exp $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
#include "vorbis/backends.h"
-#include "bitwise.h"
#include "bookinternal.h"
#include "registry.h"
#include "psy.h"
@@ -147,16 +147,16 @@ static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,oggpack_buffer
int i;
vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
- _oggpack_write(opb,info->submaps-1,4);
+ oggpack_write(opb,info->submaps-1,4);
/* we don't write the channel submappings if we only have one... */
if(info->submaps>1){
for(i=0;i<vi->channels;i++)
- _oggpack_write(opb,info->chmuxlist[i],4);
+ oggpack_write(opb,info->chmuxlist[i],4);
}
for(i=0;i<info->submaps;i++){
- _oggpack_write(opb,info->timesubmap[i],8);
- _oggpack_write(opb,info->floorsubmap[i],8);
- _oggpack_write(opb,info->residuesubmap[i],8);
+ oggpack_write(opb,info->timesubmap[i],8);
+ oggpack_write(opb,info->floorsubmap[i],8);
+ oggpack_write(opb,info->residuesubmap[i],8);
}
}
@@ -166,20 +166,20 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
vorbis_info_mapping0 *info=calloc(1,sizeof(vorbis_info_mapping0));
memset(info,0,sizeof(vorbis_info_mapping0));
- info->submaps=_oggpack_read(opb,4)+1;
+ info->submaps=oggpack_read(opb,4)+1;
if(info->submaps>1){
for(i=0;i<vi->channels;i++){
- info->chmuxlist[i]=_oggpack_read(opb,4);
+ info->chmuxlist[i]=oggpack_read(opb,4);
if(info->chmuxlist[i]>=info->submaps)goto err_out;
}
}
for(i=0;i<info->submaps;i++){
- info->timesubmap[i]=_oggpack_read(opb,8);
+ info->timesubmap[i]=oggpack_read(opb,8);
if(info->timesubmap[i]>=vi->times)goto err_out;
- info->floorsubmap[i]=_oggpack_read(opb,8);
+ info->floorsubmap[i]=oggpack_read(opb,8);
if(info->floorsubmap[i]>=vi->floors)goto err_out;
- info->residuesubmap[i]=_oggpack_read(opb,8);
+ info->residuesubmap[i]=oggpack_read(opb,8);
if(info->residuesubmap[i]>=vi->residues)goto err_out;
}
@@ -196,7 +196,6 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
#include "envelope.h"
#include "mdct.h"
#include "psy.h"
-#include "bitwise.h"
#include "scales.h"
/* no time mapping implementation for now */
diff --git a/include/vorbis/os_types.h.in b/lib/os.h
index 936ff5d6..344692eb 100644
--- a/include/vorbis/os_types.h.in
+++ b/lib/os.h
@@ -1,5 +1,5 @@
-#ifndef _OS_TYPES_H
-#define _OS_TYPES_H
+#ifndef _OS_H
+#define _OS_H
/********************************************************************
* *
* THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
@@ -14,44 +14,47 @@
********************************************************************
function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id: os_types.h.in,v 1.3.2.1 2000/08/31 08:05:47 xiphmont Exp $
+ last mod: $Id: os.h,v 1.9.2.1 2000/09/27 06:20:59 jack Exp $
********************************************************************/
-#if defined (_WIN32)
-#if !defined(__GNUC__)
+#include <math.h>
+#ifndef _V_IFDEFJAIL_H_
+#define _V_IFDEFJAIL_H_
-/* MSVC/Borland */
-typedef __int64 ogg_int64_t;
-typedef __int32 ogg_int32_t;
-typedef unsigned __int32 ogg_uint32_t;
-typedef __int16 ogg_int16_t;
+#ifndef M_PI
+#define M_PI (3.1415926539)
+#endif
-#else
+#ifndef __GNUC__
+#ifdef _WIN32
+# include <malloc.h>
+# define rint(x) (floor((x)+0.5))
+#endif
+#endif
-/* Cygwin */
-#include <_G_config.h>
-typedef _G_int64_t ogg_int64_t;
-typedef _G_int32_t ogg_int32_t;
-typedef unsigned _G_int32_t ogg_uint32_t;
-typedef _G_int16_t ogg_int16_t;
+#ifdef _WIN32
+# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
+#else /* if not _WIN32 */
+# define FAST_HYPOT hypot
#endif
-#else
-#ifdef __BEOS__
-/* Be */
-#include <inttypes.h>
#endif
-#include <sys/types.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
-/* filled in by configure */
-typedef @SIZE16@ ogg_int16_t;
-typedef @SIZE32@ ogg_int32_t;
-typedef @USIZE32@ ogg_uint32_t;
-typedef @SIZE64@ ogg_int64_t;
+#ifdef USE_MEMORY_H
+#include <memory.h>
+#endif
+#ifndef min
+# define min(x,y) ((x)>(y)?(y):(x))
#endif
-#endif
+#ifndef max
+# define max(x,y) ((x)<(y)?(y):(x))
+#endif
+#endif /* _OS_H */
diff --git a/lib/psytune.c b/lib/psytune.c
index 5c13bfba..bbe57584 100644
--- a/lib/psytune.c
+++ b/lib/psytune.c
@@ -13,7 +13,7 @@
function: simple utility that runs audio through the psychoacoustics
without encoding
- last mod: $Id: psytune.c,v 1.6.2.2 2000/09/26 22:31:50 xiphmont Exp $
+ last mod: $Id: psytune.c,v 1.6.2.3 2000/09/27 06:20:59 jack Exp $
********************************************************************/
@@ -150,8 +150,7 @@ typedef struct {
lpc_lookup lpclook;
} vorbis_look_floor0;
-
-long frameno=0;
+long granulepos=0;
/* hacked from floor0.c */
static void floorinit(vorbis_look_floor0 *look,int n,int m,int ln){
@@ -279,7 +278,7 @@ int main(int argc,char *argv[]){
for(i=0;i<2;i++){
float amp;
- analysis("pre",frameno,pcm[i],framesize,0,0);
+ analysis("pre",granulepos,pcm[i],framesize,0,0);
/* do the psychacoustics */
for(j=0;j<framesize;j++)
@@ -287,7 +286,7 @@ int main(int argc,char *argv[]){
mdct_forward(&m_look,pcm[i],pcm[i]);
- analysis("mdct",frameno,pcm[i],framesize/2,1,1);
+ analysis("mdct",granulepos,pcm[i],framesize/2,1,1);
_vp_compute_mask(&p_look,pcm[i],floor,decay[i]);
@@ -298,7 +297,7 @@ int main(int argc,char *argv[]){
/*r(j=0;j<framesize/2;j++)
if(fabs(pcm[i][j])<1.)pcm[i][j]=0;*/
- analysis("quant",frameno,pcm[i],framesize/2,1,1);
+ analysis("quant",granulepos,pcm[i],framesize/2,1,1);
/* re-add floor */
for(j=0;j<framesize/2;j++){
@@ -313,14 +312,14 @@ int main(int argc,char *argv[]){
}
}
- analysis("final",frameno,pcm[i],framesize/2,1,1);
+ analysis("final",granulepos,pcm[i],framesize/2,1,1);
/* take it back to time */
mdct_backward(&m_look,pcm[i],pcm[i]);
for(j=0;j<framesize/2;j++)
out[i][j]+=pcm[i][j]*window[j];
- frameno++;
+ granulepos++;
}
/* write data. Use the part of buffer we're about to shift out */
diff --git a/lib/res0.c b/lib/res0.c
index a962b829..3631f9b7 100644
--- a/lib/res0.c
+++ b/lib/res0.c
@@ -12,7 +12,7 @@
********************************************************************
function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.17.2.3 2000/09/02 09:39:20 xiphmont Exp $
+ last mod: $Id: res0.c,v 1.17.2.4 2000/09/27 06:21:00 jack Exp $
********************************************************************/
@@ -25,8 +25,8 @@
#include <string.h>
#include <math.h>
#include <stdio.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
-#include "bitwise.h"
#include "registry.h"
#include "bookinternal.h"
#include "sharedbook.h"
@@ -70,19 +70,19 @@ void res0_free_look(vorbis_look_residue *i){
void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
int j,acc=0;
- _oggpack_write(opb,info->begin,24);
- _oggpack_write(opb,info->end,24);
+ oggpack_write(opb,info->begin,24);
+ oggpack_write(opb,info->end,24);
- _oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and
+ oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and
code with a partitioned book */
- _oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
- _oggpack_write(opb,info->groupbook,8); /* group huffman book */
+ oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
+ oggpack_write(opb,info->groupbook,8); /* group huffman book */
for(j=0;j<info->partitions;j++){
- _oggpack_write(opb,info->secondstages[j],4); /* zero *is* a valid choice */
+ oggpack_write(opb,info->secondstages[j],4); /* zero *is* a valid choice */
acc+=info->secondstages[j];
}
for(j=0;j<acc;j++)
- _oggpack_write(opb,info->booklist[j],8);
+ oggpack_write(opb,info->booklist[j],8);
}
@@ -91,20 +91,20 @@ vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
int j,acc=0;
vorbis_info_residue0 *info=calloc(1,sizeof(vorbis_info_residue0));
- info->begin=_oggpack_read(opb,24);
- info->end=_oggpack_read(opb,24);
- info->grouping=_oggpack_read(opb,24)+1;
- info->partitions=_oggpack_read(opb,6)+1;
- info->groupbook=_oggpack_read(opb,8);
+ info->begin=oggpack_read(opb,24);
+ info->end=oggpack_read(opb,24);
+ info->grouping=oggpack_read(opb,24)+1;
+ info->partitions=oggpack_read(opb,6)+1;
+ info->groupbook=oggpack_read(opb,8);
for(j=0;j<info->partitions;j++){
- int cascade=info->secondstages[j]=_oggpack_read(opb,4);
+ int cascade=info->secondstages[j]=oggpack_read(opb,4);
if(cascade>1)goto errout; /* temporary! when cascading gets
reworked and actually used, we don't
want old code to DTWT */
acc+=cascade;
}
for(j=0;j<acc;j++)
- info->booklist[j]=_oggpack_read(opb,8);
+ info->booklist[j]=oggpack_read(opb,8);
if(info->groupbook>=vi->books)goto errout;
for(j=0;j<acc;j++)
diff --git a/lib/scales.h b/lib/scales.h
index a19abba2..184bec0f 100644
--- a/lib/scales.h
+++ b/lib/scales.h
@@ -12,7 +12,7 @@
********************************************************************
function: linear scale -> dB, Bark and Mel scales
- last mod: $Id: scales.h,v 1.5.6.1 2000/09/02 05:19:25 xiphmont Exp $
+ last mod: $Id: scales.h,v 1.5.6.2 2000/09/27 06:21:00 jack Exp $
********************************************************************/
@@ -23,8 +23,8 @@
/* 20log10(x) */
#define DYNAMIC_RANGE_dB 200.
-#define todB(x) ((x)==0?-9.e40:log(fabs(x))*8.6858896)
-#define todB_nn(x) ((x)==0?-9.e40:log(x)*8.6858896)
+#define todB(x) ((x)==0?-9.e38:log(fabs(x))*8.6858896)
+#define todB_nn(x) ((x)==0?-9.e38:log(x)*8.6858896)
#define fromdB(x) (exp((x)*.11512925))
diff --git a/lib/sharedbook.c b/lib/sharedbook.c
index 54c7ca51..5afb4a03 100644
--- a/lib/sharedbook.c
+++ b/lib/sharedbook.c
@@ -12,17 +12,17 @@
********************************************************************
function: basic shared codebook operations
- last mod: $Id: sharedbook.c,v 1.7.4.3 2000/09/02 05:19:25 xiphmont Exp $
+ last mod: $Id: sharedbook.c,v 1.7.4.4 2000/09/27 06:21:00 jack Exp $
********************************************************************/
#include <stdlib.h>
#include <math.h>
#include <string.h>
+#include <ogg/ogg.h>
#include "os.h"
#include "vorbis/codec.h"
#include "vorbis/codebook.h"
-#include "bitwise.h"
#include "scales.h"
#include "sharedbook.h"
diff --git a/lib/synthesis.c b/lib/synthesis.c
index d9108eac..4c481a90 100644
--- a/lib/synthesis.c
+++ b/lib/synthesis.c
@@ -12,14 +12,14 @@
********************************************************************
function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.17.4.1 2000/08/31 09:00:02 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.17.4.2 2000/09/27 06:21:00 jack Exp $
********************************************************************/
#include <stdio.h>
+#include <ogg/ogg.h>
#include "vorbis/codec.h"
#include "registry.h"
-#include "bitwise.h"
#include "misc.h"
#include "os.h"
@@ -31,23 +31,23 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
/* first things first. Make sure decode is ready */
_vorbis_block_ripcord(vb);
- _oggpack_readinit(opb,op->packet,op->bytes);
+ oggpack_readinit(opb,op->packet,op->bytes);
/* Check the packet type */
- if(_oggpack_read(opb,1)!=0){
+ if(oggpack_read(opb,1)!=0){
/* Oops. This is not an audio data packet */
return(-1);
}
/* read our mode and pre/post windowsize */
- mode=_oggpack_read(opb,vd->modebits);
+ mode=oggpack_read(opb,vd->modebits);
if(mode==-1)return(-1);
vb->mode=mode;
vb->W=vi->mode_param[mode]->blockflag;
if(vb->W){
- vb->lW=_oggpack_read(opb,1);
- vb->nW=_oggpack_read(opb,1);
+ vb->lW=oggpack_read(opb,1);
+ vb->nW=oggpack_read(opb,1);
if(vb->nW==-1) return(-1);
}else{
vb->lW=0;
@@ -55,7 +55,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
}
/* more setup */
- vb->frameno=op->frameno;
+ vb->granulepos=op->granulepos;
vb->sequence=op->packetno-3; /* first block is third packet */
vb->eofflag=op->e_o_s;
diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
index b7c80cfb..f3b179fb 100644
--- a/lib/vorbisfile.c
+++ b/lib/vorbisfile.c
@@ -12,7 +12,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.27.2.2 2000/08/31 09:00:02 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.27.2.3 2000/09/27 06:21:00 jack Exp $
********************************************************************/
@@ -306,9 +306,9 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
vorbis_comment_clear(vf->vc+i);
break;
}
- if(ogg_page_frameno(&og)!=-1){
+ if(ogg_page_granulepos(&og)!=-1){
vf->serialnos[i]=ogg_page_serialno(&og);
- vf->pcmlengths[i]=ogg_page_frameno(&og);
+ vf->pcmlengths[i]=ogg_page_granulepos(&og);
break;
}
}
@@ -413,14 +413,14 @@ static int _process_packet(OggVorbis_File *vf,int readp){
if(vf->decode_ready){
ogg_packet op;
int result=ogg_stream_packetout(&vf->os,&op);
- ogg_int64_t frameno;
+ ogg_int64_t granulepos;
/* 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;
+ granulepos=op.granulepos;
if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
header handling. The
header packets aren't
@@ -438,7 +438,7 @@ static int _process_packet(OggVorbis_File *vf,int readp){
}
/* update the pcm offset. */
- if(frameno!=-1 && !op.e_o_s){
+ if(granulepos!=-1 && !op.e_o_s){
int link=(vf->seekable?vf->current_link:0);
int i,samples;
@@ -449,18 +449,18 @@ static int _process_packet(OggVorbis_File *vf,int readp){
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
+ granulepos 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
+ So, we need a previous granulepos 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;
+ granulepos-=samples;
for(i=0;i<link;i++)
- frameno+=vf->pcmlengths[i];
- vf->pcm_offset=frameno;
+ granulepos+=vf->pcmlengths[i];
+ vf->pcm_offset=granulepos;
}
return(1);
}
@@ -766,7 +766,7 @@ int ov_raw_seek(OggVorbis_File *vf,long 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
+ from a page has the 'granulepos' field set, and that's how the
helper updates the offset */
switch(_process_packet(vf,1)){
@@ -851,9 +851,9 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
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 */
+ ogg_int64_t granulepos=ogg_page_granulepos(&og);
+ if(granulepos<target){
+ best=ret; /* raw offset of packet with granulepos */
begin=vf->offset; /* raw offset of next packet */
}else{
end=bisect;
diff --git a/libvorbis.spec b/libvorbis.spec
new file mode 100644
index 00000000..9c528e35
--- /dev/null
+++ b/libvorbis.spec
@@ -0,0 +1,73 @@
+Summary: The OGG Vorbis lossy audio compression codec.
+Name: vorbis
+Version: 0.0
+Release: 1
+Copyright: GPL
+Group: Development/Libraries
+Source: http://www.xiph.org/vorbis/download/%{name}-%{version}.src.tgz
+Url: http://www.xiph.org/vorbis/index.html
+BuildRoot: /var/tmp/vorbis-root
+
+%description
+Ogg Vorbis is a fully Open, non-proprietary, patent-and-royalty-free,
+general-purpose compressed audio format for high quality (44.1-48.0kHz,
+16+ bit, polyphonic) audio and music at fixed and variable bitrates
+from 16 to 128 kbps/channel. This places Vorbis in the same class as
+audio representations including MPEG-1 audio layer 3, MPEG-4
+audio (AAC and TwinVQ), and PAC.
+
+%package devel
+Copyright: LGPL
+Summary: Development library for OGG Vorbis
+Group: Development/Libraries
+
+%description devel
+Ogg Vorbis is a fully Open, non-proprietary, patent-and-royalty-free,
+general-purpose compressed audio format for high quality (44.1-48.0kHz,
+16+ bit, polyphonic) audio and music at fixed and variable bitrates
+from 16 to 128 kbps/channel. This places Vorbis in the same class as
+audio representations including MPEG-1 audio layer 3, MPEG-4
+audio (AAC and TwinVQ), and PAC.
+
+%prep
+%setup -q
+
+%build
+rm -rf $RPM_BUILD_ROOT
+CFLAGS="${RPM_OPT_FLAGS}" ./configure --prefix=/usr
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+install -d $RPM_BUILD_ROOT/usr/include/vorbis
+install -d $RPM_BUILD_ROOT/usr/include/vorbis/book
+install -d $RPM_BUILD_ROOT/usr/lib
+install -d $RPM_BUILD_ROOT/usr/bin
+install -m 0755 lib/libvorbis.a $RPM_BUILD_ROOT/usr/lib/
+install -m 0755 lib/vorbisfile.a $RPM_BUILD_ROOT/usr/lib/
+install -m 0644 include/vorbis/*.h $RPM_BUILD_ROOT/usr/include/vorbis/
+install -m 0644 include/vorbis/book/*.vqh $RPM_BUILD_ROOT/usr/include/vorbis/book/
+install -m 0755 -s huff/{residuesplit,huffbuild} $RPM_BUILD_ROOT/usr/bin
+install -m 0755 -s vq/{genericvqtrain,lspvqtrain,residuevqtrain,\
+vqbuild,vqcascade,vqmetrics,vqpartition} \
+ $RPM_BUILD_ROOT/usr/bin/
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+%doc README
+/usr/bin/*
+
+%files devel
+%defattr(-,root,root)
+%doc README docs/*.{png,html}
+/usr/include/vorbis/*
+/usr/lib/*
+
+%changelog
+* Sat Apr 29 2000 Peter Jones <pjones@redhat.com>
+- first pass.